Ignore:
Timestamp:
06/23/12 12:53:43 (12 years ago)
Author:
tbretz
Message:
Added an automatic procedure to perform a create reset.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/mcp.cc

    r14009 r14222  
    3333{
    3434private:
     35    vector<bool> fFadConnected;
     36    vector<bool> fFadNeedsReset;
     37
     38    vector<bool> fFadCratesForReset;
     39    vector<bool> fFadBoardsForConnection;
     40
     41    uint16_t fNumConnectedFtu;
     42    uint16_t fNumConnectedFad;
     43
     44    uint16_t fNumReset;
     45
    3546    DimVersion fDim;
    3647    DimDescribedState fDimFTM;
     
    4152    DimDescribedService fService;
    4253
     54    Time fFadTimeout;
     55
     56    int HandleFadConnections(const EventImp &d)
     57    {
     58        if (d.GetSize()!=41)
     59            return GetCurrentState();
     60
     61        const uint8_t *ptr = d.Ptr<uint8_t>();
     62
     63        fNumConnectedFad = 0;
     64        fFadConnected.assign(40, false);
     65
     66        vector<bool> reset(4);
     67
     68        for (int i=0; i<40; i++)
     69        {
     70            const uint8_t stat1 = ptr[i]&3;
     71            const uint8_t stat2 = ptr[i]>>3;
     72
     73            // disconnected: ignore
     74            if (stat1==0 && stat2==0)
     75                continue;
     76
     77            fFadConnected[i] = true;
     78
     79            if (stat1>=2 && stat2==8)
     80                fNumConnectedFad++;
     81
     82            // Does not need reset
     83            if (stat1>2 && stat2==8)
     84                continue;
     85
     86            // Not configured (stat1==2?kLedGreen:kLedGreenCheck)
     87            // Connection problem (stat1==1&&stat2==1?kLedRed:kLedOrange)
     88            reset[i/10] = true;
     89        }
     90        return GetCurrentState();
     91    }
     92
     93    int HandleFtmStaticData(const EventImp &d)
     94    {
     95        if (d.GetSize()!=sizeof(FTM::DimStaticData))
     96            return GetCurrentState();
     97
     98        const FTM::DimStaticData &sdata = d.Ref<FTM::DimStaticData>();
     99
     100        fNumConnectedFtu = 0;
     101        for (int i=0; i<40; i++)
     102        {
     103            if (sdata.IsActive(i))
     104                fNumConnectedFtu++;
     105        }
     106        return GetCurrentState();
     107    }
     108
    43109    int Print() const
    44110    {
     
    57123    }
    58124
    59     int StopRun(const EventImp &)
     125    int StopRun()
    60126    {
    61127        if (fDimFTM.state()==FTM::State::kTriggerOn)
     
    76142    }
    77143
    78     int Reset(const EventImp &)
    79     {
     144    int Reset()
     145    {
     146        if (GetCurrentState()<MCP::State::kConfiguring1 ||
     147            GetCurrentState()>MCP::State::kConfigured)
     148            return GetCurrentState();
     149
    80150        fRunType = "";
    81151        Message("Reseting configuration states of FAD and FTM");
    82         Dim::SendCommandNB("FTM_CONTROL/RESET_CONFIGURE");
     152
     153        Dim::SendCommandNB("FTM_CONTROL/RESET_CONFIGURE");
    83154        Dim::SendCommandNB("FAD_CONTROL/RESET_CONFIGURE");
     155
    84156        Update(MCP::State::kIdle);
    85157        return MCP::State::kIdle;
     
    134206        fNumEvents = evt.Get<int64_t>(8);
    135207        fRunType   = evt.Ptr<char>(16);
     208
     209        fNumReset  = 0;
    136210
    137211        ostringstream str;
     
    204278            fDimFAD.state() >= FAD::State::kConnected &&
    205279            fDimLog.state() >= kSM_Ready)
    206         {
    207             if (GetCurrentState()==MCP::State::kConfiguring1)
    208             {
    209                 if (fDimLog.state()<30/*kSM_WaitForRun*/)
    210                 {
    211                     Message("Starting datalogger");
    212                     Dim::SendCommandNB("DATA_LOGGER/START_RUN_LOGGING");
    213                 }
    214                 Message("Configuring Trigger (FTM)");
    215                 Dim::SendCommandNB("FTM_CONTROL/CONFIGURE", fRunType);
    216                 Update(MCP::State::kConfiguring2);
    217                 return MCP::State::kConfiguring2;
    218             }
    219 
    220             if (GetCurrentState()==MCP::State::kConfiguring2)
    221             {
    222                 // FIMXE: Reset in case of error
    223                 if ((/*fDimFTM.state() != FTM::State::kConfiguring2 &&*/
    224                      fDimFTM.state() != FTM::State::kConfigured) ||
    225                     fDimLog.state()<30 || fDimLog.state()>0xff)
    226                     return GetCurrentState();
    227 
    228                 // FIMXE: This is to make sure that the rate control
    229                 // has received the correct trigger setup already...
    230                 //usleep(1000000);
    231 
    232                 Message("Starting Rate Control");
    233                 Dim::SendCommandNB("RATE_CONTROL/CALIBRATE");
    234 
    235                 ConfigureFAD();
    236                 Update(MCP::State::kConfiguring3);
    237                 return MCP::State::kConfiguring3;
    238             }
    239 
    240             if (GetCurrentState()==MCP::State::kConfiguring3)
    241             {
    242                 if (fDimFTM.state() != FTM::State::kConfigured ||
    243                     fDimFAD.state() != FAD::State::kConfigured ||
    244                     fDimRC.state()  <  RateControl::State::kSettingGlobalThreshold)
    245                     return GetCurrentState();
    246 
    247                 Message("Starting Trigger (FTM)");
    248                 Dim::SendCommandNB("FTM_CONTROL/START_TRIGGER");
    249                 Update(MCP::State::kConfigured);
    250                 return MCP::State::kConfigured;
    251             }
    252 
    253             if (GetCurrentState()==MCP::State::kConfigured)
    254             {
    255                 if (fDimFTM.state() != FTM::State::kTriggerOn)
    256                     return GetCurrentState();
    257 
    258                 Update(MCP::State::kTriggerOn);
    259 
    260                 return MCP::State::kTriggerOn;
    261             }
    262 
    263             if (GetCurrentState()==MCP::State::kTriggerOn)
    264             {
    265                 if (fDimFAD.state() != FAD::State::kWritingData)
    266                     return GetCurrentState();
    267 
    268                 Update(MCP::State::kTakingData);
    269 
    270                 return MCP::State::kTakingData;
    271             }
    272 
    273             if (GetCurrentState()==MCP::State::kTakingData)
    274             {
    275                 if (fDimFTM.state()==FTM::State::kTriggerOn &&
    276                     fDimFAD.state()==FAD::State::kWritingData)
    277                     return MCP::State::kTakingData;
    278 
    279                 Update(MCP::State::kIdle);
    280             }
    281 
    282             return MCP::State::kIdle;
    283         }
    284 
    285         /*
    286         if (fDimFTM.state() >= FTM::State::kConnected &&
    287             fDimFAD.state() >= FAD::State::kConnected &&
    288             fDimLog.state() >= kSM_Ready)
    289             return MCP::State::kIdle;
    290          */
     280            return GetCurrentState();
     281
    291282        if (fDimFTM.state() >-2 &&
    292283            fDimFAD.state() >-2 &&
    293284            fDimLog.state() >-2 &&
    294             fDimRC.state() >-2)
     285            fDimRC.state()  >-2)
    295286            return MCP::State::kConnected;
    296287
     
    298289            fDimFAD.state() >-2 ||
    299290            fDimLog.state() >-2 ||
    300             fDimRC.state() >-2)
     291            fDimRC.state()  >-2)
    301292            return MCP::State::kConnecting;
    302293
    303294        return MCP::State::kDisconnected;
     295    }
     296
     297    int Execute()
     298    {
     299        // ========================================================
     300
     301        if (GetCurrentState()==MCP::State::kConfiguring1)
     302        {
     303            if (fDimLog.state()<30/*kSM_WaitForRun*/)
     304            {
     305                Message("Starting datalogger");
     306                Dim::SendCommandNB("DATA_LOGGER/START_RUN_LOGGING");
     307            }
     308
     309            Message("Configuring Trigger (FTM)");
     310            Dim::SendCommandNB("FTM_CONTROL/CONFIGURE", fRunType);
     311
     312            Update(MCP::State::kConfiguring2);
     313            return MCP::State::kConfiguring2;
     314        }
     315
     316        // --------------------------------------------------------
     317
     318        if (GetCurrentState()==MCP::State::kConfiguring2)
     319        {
     320            // FIMXE: Reset in case of error
     321            if ((/*fDimFTM.state() != FTM::State::kConfiguring2 &&*/
     322                 fDimFTM.state() != FTM::State::kConfigured) ||
     323                fDimLog.state()<30 || fDimLog.state()>0xff)
     324                return MCP::State::kConfiguring2;
     325
     326            // FIMXE: This is to make sure that the rate control
     327            // has received the correct trigger setup already...
     328            //usleep(1000000);
     329
     330            Message("Starting Rate Control");
     331            Dim::SendCommandNB("RATE_CONTROL/CALIBRATE");
     332
     333            ConfigureFAD();
     334
     335            fFadTimeout = Time();
     336
     337            Update(MCP::State::kConfiguring3);
     338            return MCP::State::kConfiguring3;
     339        }
     340
     341        // --------------------------------------------------------
     342
     343        if (GetCurrentState()==MCP::State::kConfiguring3)
     344        {
     345            // If everything is configured but the FADs
     346            // we run into a timeout and some FAD need to be reset
     347            // then we start an automatic crate reset
     348            if (fDimFTM.state() == FTM::State::kConfigured &&
     349                fDimFAD.state() != FAD::State::kConfigured &&
     350                fDimRC.state()  >=  RateControl::State::kSettingGlobalThreshold &&
     351                fFadTimeout+boost::posix_time::seconds(15)<Time() &&
     352                count(fFadNeedsReset.begin(), fFadNeedsReset.end(), true)>0)
     353            {
     354                Update(MCP::State::kCrateReset0);
     355                return MCP::State::kCrateReset0;
     356            }
     357
     358            // If something is not yet properly configured: keep state
     359            if (fDimFTM.state() != FTM::State::kConfigured ||
     360                fDimFAD.state() != FAD::State::kConfigured ||
     361                fDimRC.state()  <  RateControl::State::kSettingGlobalThreshold)
     362                return MCP::State::kConfiguring3;
     363
     364            Message("Starting Trigger (FTM)");
     365            Dim::SendCommandNB("FTM_CONTROL/START_TRIGGER");
     366
     367            Update(MCP::State::kConfigured);
     368            return MCP::State::kConfigured;
     369        }
     370
     371        // --------------------------------------------------------
     372
     373        if (GetCurrentState()==MCP::State::kConfigured)
     374        {
     375            if (fDimFTM.state() != FTM::State::kTriggerOn)
     376                return MCP::State::kConfigured;
     377
     378            Update(MCP::State::kTriggerOn);
     379            return MCP::State::kTriggerOn;
     380        }
     381
     382        // --------------------------------------------------------
     383
     384        if (GetCurrentState()==MCP::State::kTriggerOn)
     385        {
     386            if (fDimFAD.state() != FAD::State::kWritingData)
     387                return MCP::State::kTriggerOn;
     388
     389            Update(MCP::State::kTakingData);
     390            return MCP::State::kTakingData;
     391        }
     392
     393        // --------------------------------------------------------
     394
     395        if (GetCurrentState()==MCP::State::kTakingData)
     396        {
     397            if (fDimFTM.state()==FTM::State::kTriggerOn &&
     398                fDimFAD.state()==FAD::State::kWritingData)
     399                return MCP::State::kTakingData;
     400
     401            Update(MCP::State::kIdle);
     402            return MCP::State::kIdle;
     403        }
     404
     405        // ========================================================
     406
     407        if (GetCurrentState()==MCP::State::kCrateReset0)
     408        {
     409            static const struct Data { int32_t id; char on; } __attribute__((__packed__)) d = { -1, 0 };
     410
     411            Dim::SendCommandNB("FTM_CONTROL/ENABLE_FTU", &d, sizeof(Data));
     412
     413            fFadCratesForReset      = fFadNeedsReset;
     414            fFadBoardsForConnection = fFadConnected;
     415
     416            for (int c=0; c<4; c++)
     417                if (fFadNeedsReset[c])
     418                    for (int b=0; b<10; b++)
     419                        Dim::SendCommandNB("FAD_CONTROL/DISCONNECT", uint16_t(c*10+b));
     420
     421            fNumReset++;
     422
     423            Update(MCP::State::kCrateReset1);
     424            return MCP::State::kCrateReset1;
     425        }
     426
     427        // --------------------------------------------------------
     428
     429        if (GetCurrentState()==MCP::State::kCrateReset1)
     430        {
     431            if (fNumConnectedFtu>0 || count(fFadNeedsReset.begin(), fFadNeedsReset.end(), true)>0)
     432                return MCP::State::kCrateReset1;
     433
     434            for (int i=0; i<4; i++)
     435                if (fFadCratesForReset[i])
     436                    Dim::SendCommandNB("FAD_CONTROL/RESET_CRATE", uint16_t(i));
     437
     438            fFadTimeout = Time();
     439
     440            Update(MCP::State::kCrateReset2);
     441            return MCP::State::kCrateReset2;
     442        }
     443
     444        // --------------------------------------------------------
     445
     446        if (GetCurrentState()==MCP::State::kCrateReset2)
     447        {
     448            if (fFadTimeout+boost::posix_time::seconds(45)>Time())
     449                return MCP::State::kCrateReset2;
     450
     451            static const struct Data { int32_t id; char on; } __attribute__((__packed__)) d = { -1, 1 };
     452
     453            Dim::SendCommandNB("FTM_CONTROL/ENABLE_FTU", &d, sizeof(Data));
     454
     455            for (int c=0; c<4; c++)
     456                if (fFadCratesForReset[c])
     457                    for (int b=0; b<10; b++)
     458                        if (fFadBoardsForConnection[c*10+b])
     459                            Dim::SendCommandNB("FAD_CONTROL/CONNECT", uint16_t(c*10+b));
     460
     461            Update(MCP::State::kCrateReset3);
     462            return MCP::State::kCrateReset3;
     463        }
     464
     465        // --------------------------------------------------------
     466
     467        if (GetCurrentState()==MCP::State::kCrateReset3)
     468        {
     469            if (fNumConnectedFtu<40 || fFadBoardsForConnection!=fFadConnected)
     470                return MCP::State::kCrateReset3;
     471
     472            if (count(fFadNeedsReset.begin(), fFadNeedsReset.end(), true)>0 && fNumReset<6)
     473            {
     474                Update(MCP::State::kCrateReset0);
     475                return MCP::State::kCrateReset0;
     476            }
     477
     478            // restart configuration
     479            Update(MCP::State::kConfiguring1);
     480            return MCP::State::kConfiguring1;
     481        }
     482
     483        // ========================================================
     484
     485        return GetCurrentState();
    304486    }
    305487
    306488public:
    307489    StateMachineMCP(ostream &out=cout) : StateMachineDim(out, "MCP"),
     490        fFadNeedsReset(4), fNumConnectedFtu(40),
    308491        fDimFTM("FTM_CONTROL"),
    309492        fDimFAD("FAD_CONTROL"),
     
    334517        fDimRC.SetCallback(bind(&StateMachineMCP::HandleStateChange, this));
    335518
     519        Subscribe("FAD_CONTROL/CONNECTIONS")
     520            (bind(&StateMachineMCP::HandleFadConnections, this, placeholders::_1));
     521        Subscribe("FTM_CONTROL/STATIC_DATA")
     522            (bind(&StateMachineMCP::HandleFtmStaticData, this, placeholders::_1));
     523
    336524        // State names
    337525        AddStateName(MCP::State::kDimNetworkNA, "DimNetworkNotAvailable",
    338526                     "DIM dns server not available.");
    339 
    340527        AddStateName(MCP::State::kDisconnected, "Disconnected",
    341528                     "Neither ftmctrl, fadctrl, datalogger nor rate control online.");
    342 
    343529        AddStateName(MCP::State::kConnecting, "Connecting",
    344530                     "Either ftmctrl, fadctrl, datalogger or rate control not online.");
    345 
    346531        AddStateName(MCP::State::kConnected, "Connected",
    347532                     "All needed subsystems online.");
    348 
    349533        AddStateName(MCP::State::kIdle, "Idle",
    350534                     "Waiting for next configuration command");
    351 
    352535        AddStateName(MCP::State::kConfiguring1, "Configuring1",
    353536                     "Starting configuration procedure, checking Datalogger state");
    354 
    355537        AddStateName(MCP::State::kConfiguring2, "Configuring2",
    356538                     "Waiting for FTM and Datalogger to get ready");
    357 
    358539        AddStateName(MCP::State::kConfiguring3, "Configuring3",
    359540                     "Waiting for FADs and rate control to get ready");
    360541
     542        AddStateName(MCP::State::kCrateReset0, "CrateReset0",
     543                     "Disabling FTUs, disconnecting FADs");
     544        AddStateName(MCP::State::kCrateReset1, "CrateReset1",
     545                     "Waiting for FTUs to be disabled and for FADs to be disconnected");
     546        AddStateName(MCP::State::kCrateReset2, "CrateReset2",
     547                     "Waiting 45s");
     548        AddStateName(MCP::State::kCrateReset3, "CrateReset3",
     549                     "Waiting for FTUs to be enabled and for FADs to be re-connected");
     550
    361551        AddStateName(MCP::State::kConfigured, "Configured",
    362552                     "Everything is configured, trigger will be switched on now");
    363 
    364553        AddStateName(MCP::State::kTriggerOn, "TriggerOn",
    365554                     "The trigger is switched on, waiting for FAD to receive data");
    366 
    367555        AddStateName(MCP::State::kTakingData, "TakingData",
    368556                     "The trigger is switched on, FADs are sending data");
     
    377565
    378566        AddEvent("STOP")
    379             (bind(&StateMachineMCP::StopRun, this, placeholders::_1))
     567            (bind(&StateMachineMCP::StopRun, this))
    380568            ("Stops the trigger (either disables the FTM trigger or the internal DRS trigger)");
    381569
    382         AddEvent("RESET", MCP::State::kConfiguring1, MCP::State::kConfiguring2, MCP::State::kConfiguring3, MCP::State::kConfigured)
    383             (bind(&StateMachineMCP::Reset, this, placeholders::_1))
     570        AddEvent("RESET")
     571            (bind(&StateMachineMCP::Reset, this))
    384572            ("If a configuration blockes because a system cannot configure itself properly, "
    385573             "this command can be called to leave the configuration procedure. The command "
Note: See TracChangeset for help on using the changeset viewer.