TemperatureDisplay.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except in compliance
  4. with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2012
  6. All rights reserved.
  7. */
  8. #include "StdAfx.h"
  9. #include "TemperatureDisplay.h"
  10. #include "antmessage.h"
  11. static BOOL bCheckPeriod = FALSE;
  12. /**************************************************************************
  13. * TemperatureDisplay::ANT_eventNotification
  14. *
  15. * Process ANT channel event
  16. *
  17. * ucEventCode_: code of ANT channel event
  18. * pucEventBuffer_: pointer to buffer containing data received from ANT,
  19. * or a pointer to the transmit buffer in the case of an EVENT_TX
  20. *
  21. * returns: N/A
  22. *
  23. **************************************************************************/
  24. void TemperatureDisplay::ANT_eventNotification(UCHAR ucEventCode_, UCHAR* pucEventBuffer_)
  25. {
  26. switch(ucEventCode_)
  27. {
  28. case EVENT_RX_ACKNOWLEDGED:
  29. case EVENT_RX_BURST_PACKET: // intentional fall thru
  30. case EVENT_RX_BROADCAST:
  31. HandleReceive((UCHAR*) pucEventBuffer_);
  32. break;
  33. case EVENT_TRANSFER_TX_COMPLETED:
  34. ucAckRetryCount = 0; // Reset retransmission counter
  35. ucMsgExpectingAck = 0; // Clear pending msg code
  36. UpdateDisplayAckStatus(ACK_SUCCESS); // Tx successful
  37. break;
  38. case EVENT_TRANSFER_TX_FAILED:
  39. case EVENT_ACK_TIMEOUT: // Intentional fall thru
  40. if(ucMsgExpectingAck)
  41. {
  42. if(HandleRetransmit())
  43. UpdateDisplayAckStatus(ACK_RETRY); // Data was retransmitted
  44. else
  45. UpdateDisplayAckStatus(ACK_FAIL); // Maximum number of retries exceeded, Tx failed
  46. }
  47. case MESG_CLOSE_CHANNEL_ID:
  48. this->groupBox_RxPeriod->Enabled = false;
  49. break;
  50. case MESG_OPEN_CHANNEL_ID:
  51. bCheckPeriod = TRUE;
  52. break;
  53. default:
  54. break;
  55. }
  56. }
  57. /**************************************************************************
  58. * TemperatureDisplay::InitializeSim
  59. *
  60. * Initializes simulator variables
  61. *
  62. * returns: N/A
  63. *
  64. **************************************************************************/
  65. void TemperatureDisplay::InitializeSim()
  66. {
  67. sTemp = 0;
  68. ucEventCount = 0;
  69. ulElapsedTime2 = 0;
  70. ulAcumEventCount = 0;
  71. usMfgID = 0;
  72. ucHwVersion = 0;
  73. ucSwVersion = 0;
  74. usModelNum = 0;
  75. ulSerialNum = 0;
  76. ucMsgExpectingAck = 0;
  77. ucRqTxTimes = System::Convert::ToByte(this->numericUpDown_Req_Copies->Value);
  78. }
  79. /**************************************************************************
  80. * TemperatureDisplay::HandleReceive
  81. *
  82. * Decodes received data
  83. *
  84. * pucRxBuffer_: pointer to the buffer containing the received data
  85. *
  86. * returns: N/A
  87. *
  88. **************************************************************************/
  89. void TemperatureDisplay::HandleReceive(UCHAR* pucRxBuffer_)
  90. {
  91. UCHAR ucPageNum = 0;
  92. if (bCheckPeriod)
  93. {
  94. bCheckPeriod = FALSE;
  95. this->groupBox_RxPeriod->Enabled = true;
  96. if(radioButton_RxP5Hz->Checked == true )
  97. {
  98. TemperatureData->usMessagePeriod = TemperatureData->MESG_P5HZ_PERIOD;
  99. requestUpdateMesgPeriod(TemperatureData->MESG_P5HZ_PERIOD);
  100. }
  101. else if(radioButton_Rx4Hz->Checked == true )
  102. {
  103. TemperatureData->usMessagePeriod = TemperatureData->MESG_4HZ_PERIOD;
  104. requestUpdateMesgPeriod(TemperatureData->MESG_4HZ_PERIOD);
  105. }
  106. }
  107. // Find out what page has come in
  108. ucPageNum = pucRxBuffer_[0];
  109. // Decode appropraitely
  110. switch (ucPageNum)
  111. {
  112. case TemperatureData->PAGE_0:
  113. case TemperatureData->PAGE_1: // intentional fall through
  114. TemperatureData->Decode(pucRxBuffer_);
  115. break;
  116. case commonData->PAGE80:
  117. case commonData->PAGE81:
  118. case commonData->PAGE82:// intentional fall through
  119. commonData->Decode(pucRxBuffer_);
  120. break;
  121. default:
  122. break;
  123. }
  124. // Move received data to TemperatureDisplay variables
  125. switch (ucPageNum)
  126. {
  127. case TemperatureData->PAGE_0:
  128. ucSupportedPages = TemperatureData->ucSupportedPages;
  129. ucTxInfo = TemperatureData->ucTxInfo;
  130. break;
  131. case TemperatureData->PAGE_1:
  132. // 24 hour low, 24 hour high, current temp
  133. ucEventCount = TemperatureData->ucEventCount;
  134. s24HrLow = TemperatureData->s24HrLow;
  135. s24HrHigh = TemperatureData->s24HrHigh;
  136. sTemp = TemperatureData->sCurrentTemp;
  137. break;
  138. case commonData->PAGE80:
  139. // HW Revision, Manufacturer ID, Model Number
  140. ucHwVersion = commonData->ucHwVersion;
  141. usMfgID = commonData->usMfgID;
  142. usModelNum = commonData->usModelNum;
  143. break;
  144. case commonData->PAGE81:
  145. // SW Revision, Serial Number
  146. ucSwVersion = commonData->ucSwVersion;
  147. ulSerialNum = commonData->ulSerialNum;
  148. break;
  149. default:
  150. break;
  151. }
  152. // Update Cumulative Event Count
  153. ++ulAcumEventCount;
  154. // Display data
  155. UpdateDisplay(ucPageNum);
  156. }
  157. /**************************************************************************
  158. * TemperatureDisplay::UpdateDisplay
  159. *
  160. * Shows received decoded data on GUI
  161. *
  162. * ucPageNum_: received page
  163. *
  164. * returns: N/A
  165. *
  166. **************************************************************************/
  167. void TemperatureDisplay::UpdateDisplay(UCHAR ucPageNum_)
  168. {
  169. // Display basic data
  170. this->label_Trn_EventCountDisplay->Text = ucEventCount.ToString();
  171. if(sTemp != 0x8000)
  172. this->label_Trn_RawTempDisplay->Text = (System::Convert::ToDecimal(sTemp)/100).ToString();
  173. else
  174. this->label_Trn_RawTempDisplay->Text = "Invalid";
  175. if(s24HrHigh != TemperatureData->HIGHLOW_INVALID) // 0x800 is the invalid 1.5 byte number, 0xF800 is sign extended
  176. this->label_Trn_24HrHighDisplay->Text = (System::Convert::ToDecimal(s24HrHigh)/10).ToString();
  177. else
  178. this->label_Trn_24HrHighDisplay->Text = "Invalid";
  179. if(s24HrLow != TemperatureData->HIGHLOW_INVALID)
  180. this->label_Trn_24HrLowDisplay->Text = (System::Convert::ToDecimal(s24HrLow)/10).ToString();
  181. else
  182. this->label_Trn_24HrLowDisplay->Text = "Invalid";
  183. // Decode TxInfo
  184. // Determine Transmission Rate
  185. if((ucTxInfo & TemperatureData->PERIOD_MASK) == TemperatureData->TXINFO_4HZ)
  186. this->label_Glb_MsgPeriod_Display->Text = "4 Hz";
  187. else if((ucTxInfo & TemperatureData->PERIOD_MASK) == TemperatureData->TXINFO_P5HZ)
  188. this->label_Glb_MsgPeriod_Display->Text = "0.5 Hz";
  189. else
  190. this->label_Glb_MsgPeriod_Display->Text = "";
  191. // Determine UTC Time Support
  192. if((ucTxInfo & TemperatureData->UTC_TIME_MASK)== TemperatureData->UTC_TIME_NOT_SUPPORTED)
  193. this->label_UTCTimeDisplay->Text = "Not Supported";
  194. else if ((ucTxInfo & TemperatureData->UTC_TIME_MASK)== TemperatureData->UTC_TIME_NOT_SET)
  195. this->label_UTCTimeDisplay->Text = "Not Set";
  196. else
  197. this->label_UTCTimeDisplay->Text = "Set";
  198. // Determine Local Time Support
  199. if((ucTxInfo & TemperatureData->LOCAL_TIME_MASK)== TemperatureData->LOCAL_TIME_NOT_SUPPORTED)
  200. this->label_LocalTime_Display->Text = "Not Supported";
  201. else if ((ucTxInfo & TemperatureData->LOCAL_TIME_MASK)== TemperatureData->LOCAL_TIME_NOT_SET)
  202. this->label_LocalTime_Display->Text = "Not Set";
  203. else
  204. this->label_LocalTime_Display->Text = "Set";
  205. // Determine supported pages
  206. switch (ucSupportedPages)
  207. {
  208. case TemperatureData->SUPPORTED_PAGES_0:
  209. this->label_Glb_SpprtdPgs_Display->Text = "0";
  210. break;
  211. case TemperatureData->SUPPORTED_PAGES_1 :
  212. this->label_Glb_SpprtdPgs_Display->Text = "1";
  213. break;
  214. case TemperatureData->SUPPORTED_PAGES_0_1 :
  215. this->label_Glb_SpprtdPgs_Display->Text = "0, 1";
  216. break;
  217. default :
  218. break;
  219. }
  220. // Display background data, if available
  221. switch(ucPageNum_)
  222. {
  223. case commonData->PAGE80:
  224. // HW Version, Manufacturer ID, Model Number
  225. this->label_Glb_HardwareVerDisplay->Text = ucHwVersion.ToString();
  226. this->label_Glb_MfgIDDisplay->Text = usMfgID.ToString();
  227. this->label_Glb_ModelNumDisplay->Text = usModelNum.ToString();
  228. break;
  229. case commonData->PAGE81:
  230. // SW Version, Serial Number
  231. this->label_Glb_SoftwareVerDisplay->Text = ucSwVersion.ToString();
  232. if(ulSerialNum != 0xFFFFFFFF)
  233. this->label_Glb_SerialNumDisplay->Text = ulSerialNum.ToString();
  234. else
  235. this->label_Glb_SerialNumDisplay->Text = "No Serial";
  236. break;
  237. case commonData->PAGE82:
  238. // update the values for the battery common data page
  239. if(commonData->IsBatteryVoltageInvalid(commonData->usBatVoltage256)) // Battery voltage
  240. this->labelBattVolt->Text = "Invalid";
  241. else
  242. this->labelBattVolt->Text = System::Math::Round((double)commonData->usBatVoltage256/256,4).ToString("N2");
  243. if (commonData->eTimeResolution == CommonData::TimeResolution::SIXTEEN)
  244. this->labelTimeRes->Text = "16";
  245. else
  246. this->labelTimeRes->Text = "2";
  247. // now that we know the time resolution we can display the run time
  248. this->labelOpTime->Text = (commonData->ulOpTime * (UCHAR) commonData->eTimeResolution).ToString();
  249. switch (commonData->eBatStatus)
  250. {
  251. case CommonData::BatStatus::CRITICAL:
  252. this->labelBattStatus->Text = "Critical";
  253. break;
  254. case CommonData::BatStatus::GOOD:
  255. this->labelBattStatus->Text = "Good";
  256. break;
  257. case CommonData::BatStatus::INVALID:
  258. this->labelBattStatus->Text = "Invalid";
  259. break;
  260. case CommonData::BatStatus::LOW:
  261. this->labelBattStatus->Text = "Low";
  262. break;
  263. case CommonData::BatStatus::NEW:
  264. this->labelBattStatus->Text = "New";
  265. break;
  266. case CommonData::BatStatus::OK:
  267. this->labelBattStatus->Text = "Ok";
  268. break;
  269. default:
  270. break;
  271. }
  272. break;
  273. default:
  274. break;
  275. }
  276. // Display calculated data
  277. // Cumulative event count
  278. this->label_Calc_TotEventCountDisplay->Text = ulAcumEventCount.ToString();
  279. }
  280. /**************************************************************************
  281. * TemperatureDisplay::SendRequestMsg
  282. *
  283. * Sends an acknoledged Page Requset message according to the message code
  284. *
  285. * ucMsgCode_: message ID of the message to send
  286. * Supported messages:
  287. * - Page 80 Request
  288. * - Page 81 Request
  289. *
  290. * returns: N/A
  291. *
  292. **************************************************************************/
  293. void TemperatureDisplay::SendRequestMsg(UCHAR ucMsgCode_)
  294. {
  295. UCHAR aucAckBuffer[8] = {0,0,0,0,0,0,0,0};
  296. switch(ucMsgCode_)
  297. {
  298. case commonData->PAGE80:
  299. case commonData->PAGE81:
  300. case commonData->PAGE82: // Intentional fallthrough
  301. EncodeRequestMsg(ucMsgCode_, aucAckBuffer);
  302. break;
  303. default:
  304. return; // Do not transmit if unsupported message code
  305. }
  306. // Send acknowledged message
  307. if(!ucMsgExpectingAck) // If this message is not a retransmission
  308. {
  309. ucAckRetryCount = 0; // Reset retransmission counter
  310. ucMsgExpectingAck = ucMsgCode_; // Set code to message for which an ACK wil be expected
  311. }
  312. requestAckMsg(aucAckBuffer); // Send message
  313. }
  314. /**************************************************************************
  315. * TemperatureDisplay::HandleRetransmit
  316. *
  317. * Retransmits request message, up to the maximum retransmission number
  318. *
  319. * returns: TRUE if message was retransmitted
  320. * FALSE if maximum number of retransmissions was reached
  321. *
  322. **************************************************************************/
  323. BOOL TemperatureDisplay::HandleRetransmit()
  324. {
  325. BOOL bSuccess = TRUE;
  326. if(ucMsgExpectingAck) // Message still expecting an ack
  327. {
  328. if(ucAckRetryCount++ < MAX_RETRIES)
  329. SendRequestMsg(ucMsgExpectingAck);
  330. else
  331. bSuccess = FALSE;
  332. }
  333. return bSuccess;
  334. }
  335. /**************************************************************************
  336. * TemperatureDisplay::UpdateDisplayAckStatus
  337. *
  338. * Updates display to show if acknowledged request messages were
  339. * transmitted successfully
  340. *
  341. * returns: N/A
  342. *
  343. **************************************************************************/
  344. void TemperatureDisplay::UpdateDisplayAckStatus(UCHAR ucStatus_)
  345. {
  346. switch(ucStatus_)
  347. {
  348. case ACK_SUCCESS:
  349. this->label_AckMsgStatus->ForeColor = System::Drawing::Color::Green;
  350. this->label_AckMsgStatus->Text = "SENT";
  351. break;
  352. case ACK_RETRY:
  353. this->label_AckMsgStatus->ForeColor = System::Drawing::Color::Blue;
  354. this->label_AckMsgStatus->Text = "RTRY";
  355. break;
  356. case ACK_FAIL:
  357. this->label_AckMsgStatus->ForeColor = System::Drawing::Color::Red;
  358. this->label_AckMsgStatus->Text = "FAIL";
  359. break;
  360. default:
  361. break;
  362. }
  363. }
  364. /**************************************************************************
  365. * TemperatureDisplay::EncodeRequestMsg
  366. *
  367. * Encodes the Request Data Page
  368. *
  369. * ucPageID_: ID of the page to request;
  370. * pucTxBuffer_: pointer to the buffer that will store the encoded data
  371. *
  372. * returns: N/A
  373. *
  374. **************************************************************************/
  375. void TemperatureDisplay::EncodeRequestMsg(UCHAR ucPageID_, UCHAR* pucTxBuffer_)
  376. {
  377. ucRqTxTimes &= ~0x80; // clear the MSB (Temp sensor should respond with ack messages)
  378. pucTxBuffer_[0] = commonData->PAGE70; // Command ID
  379. pucTxBuffer_[1] = commonData->RESERVED;
  380. pucTxBuffer_[2] = commonData->RESERVED;
  381. pucTxBuffer_[3] = commonData->RESERVED; // invalid
  382. pucTxBuffer_[4] = commonData->RESERVED; // invalid
  383. pucTxBuffer_[5] = ucRqTxTimes; // number of times for sensor to send, based on UI
  384. pucTxBuffer_[6] = ucPageID_; // Page number to request
  385. pucTxBuffer_[7] = TemperatureData->DATA_REQUEST; // Specify that we are requesting data (not ANT-FS)
  386. }
  387. /**************************************************************************
  388. * TemperatureDisplay::button_Req_Page80_Click
  389. *
  390. * Initates the sending of a message to the sensor to request data page 80
  391. *
  392. * returns: N/A
  393. *
  394. **************************************************************************/
  395. System::Void TemperatureDisplay::button_Req_Page80_Click(System::Object^ sender, System::EventArgs^ e)
  396. {
  397. SendRequestMsg(commonData->PAGE80);
  398. }
  399. /**************************************************************************
  400. * TemperatureDisplay::button_Req_Page81_Click
  401. *
  402. * Initates the sending of a message to the sensor to request data page 81
  403. *
  404. * returns: N/A
  405. *
  406. **************************************************************************/
  407. System::Void TemperatureDisplay::button_Req_Page81_Click(System::Object^ sender, System::EventArgs^ e)
  408. {
  409. SendRequestMsg(commonData->PAGE81);
  410. }
  411. /**************************************************************************
  412. * TemperatureDisplay::button_Req_Page82_Click
  413. *
  414. * Initates the sending of a message to the sensor to request data page 81
  415. *
  416. * returns: N/A
  417. *
  418. **************************************************************************/
  419. System::Void TemperatureDisplay::button_Req_Page82_Click(System::Object^ sender, System::EventArgs^ e)
  420. {
  421. SendRequestMsg(commonData->PAGE82);
  422. }
  423. /**************************************************************************
  424. * TemperatureDisplay::numericUpDown_Req_Copies_ValueChaned
  425. *
  426. * Updates the number of times for the sensor to resend the request
  427. * response when modified in UI
  428. *
  429. * returns: N/A
  430. *
  431. **************************************************************************/
  432. System::Void TemperatureDisplay::numericUpDown_Req_Copies_ValueChaned(System::Object^ sender, System::EventArgs^ e)
  433. {
  434. ucRqTxTimes = System::Convert::ToByte(this->numericUpDown_Req_Copies->Value);
  435. }
  436. /**************************************************************************
  437. * TemperatureDisplay::radioButton_RxPeriod_Changed
  438. *
  439. * Changed the channel period of the display, to make listening to a
  440. * 0.5Hz sensor easier.
  441. *
  442. * returns: N/A
  443. *
  444. **************************************************************************/
  445. System::Void TemperatureDisplay::radioButton_RxPeriod_Changed(System::Object^ sender, System::EventArgs^ e)
  446. {
  447. bCheckPeriod = TRUE;
  448. }