Changeset 17636
- Timestamp:
- 03/27/14 16:11:06 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/fscctrl.cc
r17623 r17636 28 28 class ConnectionFSC : public Connection 29 29 { 30 boost::array<unsigned char, 4096> fArray; 31 vector<unsigned char> input_buffer; 32 boost::array<unsigned char, sizeof(FSC::BinaryOutput_t)> one_message; 30 FSC::BinaryOutput_t fMsg; // A single message 33 31 34 32 bool fIsVerbose; 35 bool fDump; 36 37 ofstream fDumpStream;33 34 size_t fNumConsecutiveErrors; // Number of consecutive messages with errors 35 size_t fNumConsecutiveMessages; // Number of consecutive message which are ok 38 36 39 37 … … 56 54 virtual void UpdateCur(float, const vector<float>&) 57 55 { 58 }59 60 /*61 virtual void UpdateError()62 {63 if (!fIsVerbose)64 return;65 66 Out() << endl << kRed << "Error received:" << endl;67 Out() << fError;68 if (fIsHexOutput)69 Out() << Converter::GetHex<uint16_t>(fError, 16) << endl;70 }71 */72 73 void Dump(const string &str)74 {75 if (!fDumpStream.is_open())76 {77 fDumpStream.open("socket_dump-fsc.txt", ios::app);78 if (!fDumpStream)79 {80 //ostringstream str;81 //str << "Open file " << name << ": " << strerror(errno) << " (errno=" << errno << ")";82 //Error(str);83 84 return;85 }86 }87 88 fDumpStream << str << endl;89 56 } 90 57 … … 107 74 } 108 75 109 uint16_t fletcher16( uint8_t const *data, size_t bytes ) 110 { 111 uint16_t sum1 = 0xff, sum2 = 0xff; 76 template<typename T> 77 uint16_t fletcher16(const T *t, size_t cnt) 78 { 79 const uint8_t *data = reinterpret_cast<const uint8_t*>(t); 80 81 size_t bytes = cnt*sizeof(T); 82 83 uint16_t sum1 = 0xff; 84 uint16_t sum2 = 0xff; 112 85 113 86 while (bytes) … … 115 88 size_t tlen = bytes > 20 ? 20 : bytes; 116 89 bytes -= tlen; 90 117 91 do { 118 92 sum2 += sum1 += *data++; 119 93 } while (--tlen); 94 120 95 sum1 = (sum1 & 0xff) + (sum1 >> 8); 121 96 sum2 = (sum2 & 0xff) + (sum2 >> 8); 122 97 } 123 /* Second reduction step to reduce sums to 8 bits */ 98 99 // Second reduction step to reduce sums to 8 bits 124 100 sum1 = (sum1 & 0xff) + (sum1 >> 8); 125 101 sum2 = (sum2 & 0xff) + (sum2 >> 8); 102 126 103 return sum2 << 8 | sum1; 127 104 } 128 129 /* ProcessMessage is only called from HandleRead, when enough bytes were received from the FSC 130 * The bytes of one message were already stored in *one_message*. 131 * We convert it to an instance of FSC::BinaryOutput_t 132 * then we check the two checksums 133 * and then update the DimServices or not depending on the checksums 134 */ 135 void ProcessMessage() { 136 137 FSC::BinaryOutput_t* bin_out; 138 bin_out = (FSC::BinaryOutput_t*)one_message.data(); 139 140 if (fIsVerbose) { 105 106 bool CheckChecksum() 107 { 108 const uint16_t volt_checksum = fletcher16(fMsg.adc_values, kNumVoltageChannels); 109 const uint16_t resi_checksum = fletcher16(fMsg.ad7719_values, kNumResistanceChannels); 110 111 const bool volt_ok = volt_checksum == fMsg.adc_values_checksum; 112 const bool resi_ok = resi_checksum == fMsg.ad7719_values_checksum; 113 114 if (volt_ok && resi_ok) 115 return true; 116 117 fNumConsecutiveErrors++; 118 119 ostringstream out; 120 out << "Checksum error (V:"; 121 out << hex << setfill('0'); 122 123 if (volt_ok) 124 out << "----|----"; 125 else 126 { 127 out << setw(4) << volt_checksum; 128 out << "|"; 129 out << setw(4) << fMsg.adc_values_checksum; 130 } 131 132 out << ", R:"; 133 134 if (resi_ok) 135 out << "----|----"; 136 else 137 { 138 out << setw(4) << resi_checksum; 139 out << "|"; 140 out << setw(4) << fMsg.ad7719_values_checksum; 141 } 142 143 out << ", " << dec; 144 out << "Nok=" << fNumConsecutiveMessages << ", "; 145 out << "Nerr=" << fNumConsecutiveErrors << ")"; 146 147 Warn(out); 148 149 fNumConsecutiveMessages = 0; 150 151 return false; 152 } 153 154 void ProcessMessage() 155 { 156 if (fIsVerbose) 141 157 Out() << "Received one_message of FSC::BinaryOutput_t ... will now process it" << endl; 142 } 143 144 145 uint16_t volt_checksum = fletcher16( (uint8_t const *)&one_message[offsetof(FSC::BinaryOutput_t,adc_values)], 146 sizeof(bin_out->adc_values) ); 147 if (volt_checksum != bin_out->adc_values_checksum ){ 148 ostringstream out; 149 out << "volt checksums are different. We calculated " << volt_checksum << " transmitted was: "; 150 out << bin_out->adc_values_checksum << "."; 151 Warn(out); 152 StartRead(); 158 159 if (!CheckChecksum()) 153 160 return; 154 } 155 156 uint16_t resist_checksum = fletcher16( (uint8_t const *)&one_message[offsetof(FSC::BinaryOutput_t,ad7719_values)], 157 sizeof(bin_out->ad7719_values) ); 158 if (resist_checksum != bin_out->ad7719_values_checksum ){ 159 ostringstream out; 160 out << "resist checksums are different. We calculated " << resist_checksum << " transmitted was: "; 161 out << bin_out->ad7719_values_checksum << "."; 162 Warn(out); 163 StartRead(); 164 return; 165 } 166 167 vector<int> volt (bin_out->adc_values, 168 bin_out->adc_values + sizeof(bin_out->adc_values) / sizeof(uint16_t) 169 ); 170 171 vector<float> resist(bin_out->ad7719_values, 172 bin_out->ad7719_values + sizeof(bin_out->ad7719_values) / sizeof(uint32_t) 173 ); 174 float time= float(bin_out->time_sec) + float(bin_out->time_ms)/1000.; 175 176 if (volt.size()!=84 || resist.size()!=64) { 177 ostringstream out; 178 179 out << "Something went wrong in vector constructors " << volt.size() << " voltages and "; 180 out << resist.size() << " resistances received; 84 and 64 expected)"; 181 Warn(out); 182 StartRead(); 183 return; 184 } 185 161 162 // That looks a bit odd because it copies the values twice for no reason. 163 // This is historical and keeps the following code consistent with the 164 // previous code which was reading ascii data from the fsc 165 vector<float> volt( fMsg.adc_values, fMsg.adc_values + kNumVoltageChannels); 166 vector<float> resist(fMsg.ad7719_values, fMsg.ad7719_values + kNumResistanceChannels); 167 168 const float time = fMsg.time_sec + fMsg.time_ms/1000.; 169 186 170 // We want to convert the pure ADC values from the FSC board to mV and kOhm respectively 187 171 // So we do: 188 for (unsigned int i=0; i<volt.size(); i++) {172 for (unsigned int i=0; i<volt.size(); i++) 189 173 volt[i] /= 10; 190 } 191 for (unsigned int i=0; i<resist.size(); i++) {174 175 for (unsigned int i=0; i<resist.size(); i++) 192 176 resist[i] *= (6.25 * 1024) / (1 << 25); 193 }194 195 177 196 178 int mapv[] = … … 208 190 -1 209 191 }; 210 211 192 212 193 int mapc[] = … … 487 468 UpdateCur( time, currents); 488 469 UpdateHum( time, humidities); 489 490 } 491 492 void StartRead() { 493 // DN: 20140318 494 async_read_some(ba::buffer(fArray), 495 boost::bind(&ConnectionFSC::HandleRead, this, 496 dummy::error, 497 dummy::bytes_transferred) 498 ); 499 500 // FIXME: Add timeout here 501 } 502 503 void HandleRead(const boost::system::error_code& err, size_t bytes_received) { 470 471 fNumConsecutiveErrors = 0; 472 fNumConsecutiveMessages++; 473 } 474 475 void StartRead() 476 { 477 ba::async_read(*this, ba::buffer(&fMsg, sizeof(FSC::BinaryOutput_t)), 478 boost::bind(&ConnectionFSC::HandleRead, this, 479 dummy::error, dummy::bytes_transferred)); 480 481 AsyncWait(fInTimeout, 35000, &Connection::HandleReadTimeout); // 30s 482 } 483 484 void HandleRead(const boost::system::error_code& err, size_t bytes_received) 485 { 504 486 // Do not schedule a new read if the connection failed. 505 487 if (bytes_received==0 || err) 506 488 { 507 489 if (err==ba::error::eof) 508 {509 490 return; 510 }511 491 512 492 // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category)) … … 523 503 return; 524 504 } 525 526 input_buffer.insert(input_buffer.end(), fArray.data(), fArray.data()+bytes_received); 527 if (input_buffer.size() >= sizeof(FSC::BinaryOutput_t)){ 528 for (unsigned int i=0; i<sizeof(FSC::BinaryOutput_t); i++){ 529 one_message[i] = input_buffer[i]; 530 } 531 input_buffer.erase(input_buffer.begin(),input_buffer.begin()+sizeof(FSC::BinaryOutput_t)); 532 ProcessMessage(); 533 } 534 505 506 ProcessMessage(); 535 507 StartRead(); 536 508 } 537 509 538 void ConnectionEstablished() { 510 void ConnectionEstablished() 511 { 512 fNumConsecutiveErrors = 0; 513 fNumConsecutiveMessages = 0; 514 539 515 StartRead(); 540 516 } 541 517 542 /*543 518 void HandleReadTimeout(const bs::error_code &error) 544 519 { … … 575 550 PostClose(); 576 551 } 577 */578 552 579 553 public: 580 554 ConnectionFSC(ba::io_service& ioservice, MessageImp &imp) : Connection(ioservice, imp()), 581 fIsVerbose(false) , fDump(false)555 fIsVerbose(false) 582 556 { 583 557 SetLogStream(&imp); … … 587 561 { 588 562 fIsVerbose = b; 589 }590 591 void SetDumpStream(bool b)592 {593 fDump = b;594 563 } 595 564 … … 837 806 } 838 807 839 int SetDumpStream(const EventImp &evt)840 {841 if (!CheckEventSize(evt.GetSize(), "SetDumpStream", 1))842 return T::kSM_FatalError;843 844 fFSC.SetDumpStream(evt.GetBool());845 846 return T::GetCurrentState();847 }848 849 808 public: 850 809 StateMachineFSC(ostream &out=cout) : … … 863 822 ("set verbosity state" 864 823 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data"); 865 866 T::AddEvent("DUMP_STREAM", "B:1")867 (bind(&StateMachineFSC::SetDumpStream, this, placeholders::_1))868 (""869 "");870 824 871 825 // Conenction commands
Note:
See TracChangeset
for help on using the changeset viewer.