Changeset 14222 for trunk/FACT++/src/mcp.cc
- Timestamp:
- 06/23/12 12:53:43 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/mcp.cc
r14009 r14222 33 33 { 34 34 private: 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 35 46 DimVersion fDim; 36 47 DimDescribedState fDimFTM; … … 41 52 DimDescribedService fService; 42 53 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 43 109 int Print() const 44 110 { … … 57 123 } 58 124 59 int StopRun( const EventImp &)125 int StopRun() 60 126 { 61 127 if (fDimFTM.state()==FTM::State::kTriggerOn) … … 76 142 } 77 143 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 80 150 fRunType = ""; 81 151 Message("Reseting configuration states of FAD and FTM"); 82 Dim::SendCommandNB("FTM_CONTROL/RESET_CONFIGURE"); 152 153 Dim::SendCommandNB("FTM_CONTROL/RESET_CONFIGURE"); 83 154 Dim::SendCommandNB("FAD_CONTROL/RESET_CONFIGURE"); 155 84 156 Update(MCP::State::kIdle); 85 157 return MCP::State::kIdle; … … 134 206 fNumEvents = evt.Get<int64_t>(8); 135 207 fRunType = evt.Ptr<char>(16); 208 209 fNumReset = 0; 136 210 137 211 ostringstream str; … … 204 278 fDimFAD.state() >= FAD::State::kConnected && 205 279 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 291 282 if (fDimFTM.state() >-2 && 292 283 fDimFAD.state() >-2 && 293 284 fDimLog.state() >-2 && 294 fDimRC.state() >-2)285 fDimRC.state() >-2) 295 286 return MCP::State::kConnected; 296 287 … … 298 289 fDimFAD.state() >-2 || 299 290 fDimLog.state() >-2 || 300 fDimRC.state() >-2)291 fDimRC.state() >-2) 301 292 return MCP::State::kConnecting; 302 293 303 294 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(); 304 486 } 305 487 306 488 public: 307 489 StateMachineMCP(ostream &out=cout) : StateMachineDim(out, "MCP"), 490 fFadNeedsReset(4), fNumConnectedFtu(40), 308 491 fDimFTM("FTM_CONTROL"), 309 492 fDimFAD("FAD_CONTROL"), … … 334 517 fDimRC.SetCallback(bind(&StateMachineMCP::HandleStateChange, this)); 335 518 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 336 524 // State names 337 525 AddStateName(MCP::State::kDimNetworkNA, "DimNetworkNotAvailable", 338 526 "DIM dns server not available."); 339 340 527 AddStateName(MCP::State::kDisconnected, "Disconnected", 341 528 "Neither ftmctrl, fadctrl, datalogger nor rate control online."); 342 343 529 AddStateName(MCP::State::kConnecting, "Connecting", 344 530 "Either ftmctrl, fadctrl, datalogger or rate control not online."); 345 346 531 AddStateName(MCP::State::kConnected, "Connected", 347 532 "All needed subsystems online."); 348 349 533 AddStateName(MCP::State::kIdle, "Idle", 350 534 "Waiting for next configuration command"); 351 352 535 AddStateName(MCP::State::kConfiguring1, "Configuring1", 353 536 "Starting configuration procedure, checking Datalogger state"); 354 355 537 AddStateName(MCP::State::kConfiguring2, "Configuring2", 356 538 "Waiting for FTM and Datalogger to get ready"); 357 358 539 AddStateName(MCP::State::kConfiguring3, "Configuring3", 359 540 "Waiting for FADs and rate control to get ready"); 360 541 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 361 551 AddStateName(MCP::State::kConfigured, "Configured", 362 552 "Everything is configured, trigger will be switched on now"); 363 364 553 AddStateName(MCP::State::kTriggerOn, "TriggerOn", 365 554 "The trigger is switched on, waiting for FAD to receive data"); 366 367 555 AddStateName(MCP::State::kTakingData, "TakingData", 368 556 "The trigger is switched on, FADs are sending data"); … … 377 565 378 566 AddEvent("STOP") 379 (bind(&StateMachineMCP::StopRun, this , placeholders::_1))567 (bind(&StateMachineMCP::StopRun, this)) 380 568 ("Stops the trigger (either disables the FTM trigger or the internal DRS trigger)"); 381 569 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)) 384 572 ("If a configuration blockes because a system cannot configure itself properly, " 385 573 "this command can be called to leave the configuration procedure. The command "
Note:
See TracChangeset
for help on using the changeset viewer.