123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- /*
- This software is subject to the license described in the License.txt file
- included with this software distribution. You may not use this file except in compliance
- with this license.
- Copyright (c) Dynastream Innovations Inc. 2012
- All rights reserved.
- */
- #include "StdAfx.h"
- #include "HRMDisplay.h"
- /**************************************************************************
- * HRMDisplay::ANT_eventNotification
- *
- * Process ANT channel event
- *
- * ucEventCode_: code of ANT channel event
- * pucEventBuffer_: pointer to buffer containing data received from ANT,
- * or a pointer to the transmit buffer in the case of an EVENT_TX
- *
- * returns: N/A
- *
- **************************************************************************/
- void HRMDisplay::ANT_eventNotification(UCHAR ucEventCode_, UCHAR* pucEventBuffer_)
- {
- switch(ucEventCode_)
- {
- case EVENT_RX_ACKNOWLEDGED:
- case EVENT_RX_BURST_PACKET: // intentional fall thru
- case EVENT_RX_BROADCAST:
- HandleReceive((UCHAR*) pucEventBuffer_);
- break;
- default:
- break;
- }
- }
- /**************************************************************************
- * HRMDisplay::InitializeSim
- *
- * Initializes simulator variables
- *
- * returns: N/A
- *
- **************************************************************************/
- void HRMDisplay::InitializeSim()
- {
- ucBPM = 0;
- ucEventCount = 0;
- ucPreviousEventCount = 0;
- usTime1024 = 0;
- usPreviousTime1024 = 0;
- ulElapsedTime2 = 0;
- ucStatePage = HRM_INIT_PAGE;
- ulAcumEventCount = 0;
- ulAcumTime1024 = 0;
- usR_RInterval1024 = 0;
- ucCalcBPM = 0;
- ucMfgID = 0;
- ucHwVersion = 0;
- ucSwVersion = 0;
- ucModelNum = 0;
- usSerialNum = 0;
- }
- /**************************************************************************
- * HRMDisplay::HandleReceive
- *
- * Decodes received data
- *
- * pucRxBuffer_: pointer to the buffer containing the received data
- *
- * returns: N/A
- *
- **************************************************************************/
- void HRMDisplay::HandleReceive(UCHAR* pucRxBuffer_)
- {
- static UCHAR ucNoEventCount = 0; // Successive transmissions with no new HR events
- UCHAR ucPageNum = 0;
- UCHAR ucEventDiff = 0;
- USHORT usTimeDiff1024 = 0;
- //Remove page toggle bit
- ucPageNum = pucRxBuffer_[0] & ~HRM_TOGGLE_MASK;
- //Removed, according to profile, bytes 4-7 should be decoded regardless of data page number
- //// Do not process undefined pages
- //if(!( ucPageNum == HRM_PAGE0 || ucPageNum == HRM_PAGE1
- // || ucPageNum == HRM_PAGE2 || ucPageNum == HRM_PAGE3
- // || ucPageNum == HRM_PAGE4))
- // return;
- // Monitor page toggle bit
- if(ucStatePage != HRM_EXT_PAGE)
- {
- if(ucStatePage == HRM_INIT_PAGE)
- {
- ucStatePage = (pucRxBuffer_[0] & HRM_TOGGLE_MASK) >>7;
- // Initialize previous values to correctly get the cumulative values
- ucPreviousEventCount = pucRxBuffer_[6];
- usPreviousTime1024 = pucRxBuffer_[4];
- usPreviousTime1024 += pucRxBuffer_[5]<<8;
- }
- else if(ucStatePage != ((pucRxBuffer_[0] & HRM_TOGGLE_MASK) >>7))
- {
- // First page toggle was seen, enable advanced data
- ucStatePage = HRM_EXT_PAGE;
- }
- }
-
-
- // Handle basic data
- ucEventCount = pucRxBuffer_[6];
- usTime1024 = pucRxBuffer_[4];
- usTime1024 += pucRxBuffer_[5]<<8;
- ucBPM = pucRxBuffer_[7];
- // Handle background data, if supported
- if(ucStatePage == HRM_EXT_PAGE)
- {
- switch(ucPageNum)
- {
- case HRM_PAGE1:
- ulElapsedTime2 = pucRxBuffer_[1];
- ulElapsedTime2 += pucRxBuffer_[2] << 8;
- ulElapsedTime2 += pucRxBuffer_[3] << 16;
- break;
- case HRM_PAGE2:
- ucMfgID = pucRxBuffer_[1];
- usSerialNum = pucRxBuffer_[2];
- usSerialNum += pucRxBuffer_[3] << 8;
- break;
- case HRM_PAGE3:
- ucHwVersion = pucRxBuffer_[1];
- ucSwVersion = pucRxBuffer_[2];
- ucModelNum = pucRxBuffer_[3];
- break;
- case HRM_PAGE4:
- usPreviousTime1024 = pucRxBuffer_[2];
- usPreviousTime1024 += pucRxBuffer_[3] << 8;
- break;
- default:
- break;
- }
- }
- // Only need to do calculations if dealing with a new event
- if(ucEventCount != ucPreviousEventCount)
- {
- ucNoEventCount = 0;
- // Update cumulative event count
- if(ucEventCount > ucPreviousEventCount)
- ucEventDiff = ucEventCount - ucPreviousEventCount;
- else
- ucEventDiff = (UCHAR) 0xFF - ucPreviousEventCount + ucEventCount + 1;
- ulAcumEventCount += ucEventDiff;
- // Update cumulative time
- if(usTime1024 > usPreviousTime1024)
- usTimeDiff1024 = usTime1024 - usPreviousTime1024;
- else
- usTimeDiff1024 = (USHORT) (0xFFFF - usPreviousTime1024 + usTime1024 + 1);
- ulAcumTime1024 += usTimeDiff1024;
- // Calculate R-R Interval
- if(ucEventDiff == 1)
- usR_RInterval1024 = usTimeDiff1024;
- // Calculate heart rate (from timing data), in bpm
- if(usTimeDiff1024 > 0)
- ucCalcBPM = (UCHAR) ( ((USHORT) ucEventDiff * 0xF000) / usTimeDiff1024 ); // 1 min = 0xF000 = 60 * 1024
- }
- else
- {
- ucNoEventCount++;
- if(ucNoEventCount >= MAX_NO_EVENTS)
- {
- ucCalcBPM = HRM_INVALID_BPM; // No new valid HR data has been received
- }
- }
-
- // Display data
- UpdateDisplay(ucPageNum);
- // Update previous time and event count
- if(ucPageNum != HRM_PAGE4)
- usPreviousTime1024 = usTime1024; // only if not previously obtained from HRM message
- ucPreviousEventCount = ucEventCount;
- }
- /**************************************************************************
- * HRMDisplay::UpdateDisplay
- *
- * Shows received decoded data on GUI
- *
- * ucPageNum_: received page
- *
- * returns: N/A
- *
- **************************************************************************/
- void HRMDisplay::UpdateDisplay(UCHAR ucPageNum_)
- {
- // Display basic data
- this->label_Trn_TimeDisplay->Text = usTime1024.ToString();
- this->label_Trn_EventCountDisplay->Text = ucEventCount.ToString();
- if(ucBPM)
- this->label_Trn_RawPulseDisplay->Text = ucBPM.ToString();
- else
- this->label_Trn_RawPulseDisplay->Text = "---"; // Invalid heart rate
-
- // Display background data, if available
- if(ucStatePage == HRM_EXT_PAGE)
- {
- this->label_Calc_waitToggle->Visible = false; // Page toggle was seen, so show in GUI
- switch(ucPageNum_)
- {
- case HRM_PAGE1:
- this->label_Glb_BattTimeDisplay->Text = (ulElapsedTime2*2).ToString();
- break;
- case HRM_PAGE2:
- this->label_Glb_ManfIDDisplay->Text = ucMfgID.ToString();
- this->label_Glb_SerialNumDisplay->Text = usSerialNum.ToString();
- break;
- case HRM_PAGE3:
- this->label_Glb_HardwareVerDisplay->Text = ucHwVersion.ToString();
- this->label_Glb_SoftwareVerDisplay->Text = ucSwVersion.ToString();
- this->label_Glb_ModelNumDisplay->Text = ucModelNum.ToString();
- break;
- case HRM_PAGE4:
- this->label_Trn_LastEventTimeDisplay->Text = usPreviousTime1024.ToString();
- break;
- default:
- break;
- }
- }
-
- // Display calculated data
- // Cumulative time (in s)
- this->label_Calc_ElapsedSecsDisplay->Text = System::Math::Round((DOUBLE) ulAcumTime1024/1024,3).ToString();
-
- // R-R interval (in ms)
- if(ucStatePage == HRM_EXT_PAGE)
- this->label_Calc_RRIntervalDisplay->Text = System::Math::Round(((DOUBLE) usR_RInterval1024*1000/1024),3).ToString(); // Convert to ms
- else
- this->label_Calc_RRIntervalDisplay->Text = "---";
- // Cumulative event count
- this->label_Calc_TotEventCountDisplay->Text = ulAcumEventCount.ToString();
- // Heart rate (from timing data)
- if(ucCalcBPM)
- {
- this->label_Calc_PulseDisplay->Text = ucCalcBPM.ToString();
- this->label_Calc_InstPulseDisplay->Text = ucBPM.ToString();
- }
- else
- {
- this->label_Calc_PulseDisplay->Text = "---"; // Invalid heart rate
- this->label_Calc_InstPulseDisplay->Text = "---";
- }
- }
|