/* 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. */ #pragma once #include "StdAfx.h" #include "MSMDisplay.h" /************************************************************************** * MSMDisplay::InitializeSim * * Initialize the simulator variables * * returns: N/A * **************************************************************************/ void MSMDisplay::InitializeSim() { dbDispAcumDist = 0; usPreviousDist = 0; dbDispAcumTime = 0; usPreviousTime = 0; eCalStatus = MSM::CalibrationStatus::NONE; // initialize calibration stuff msmData->ucMode = System::Convert::ToByte (this->numericUpDownMode->Value); ucPreviousMode = msmData->ucMode; msmData->usScaleFactor10000 = System::Convert::ToUInt16 (this->numericUpDownScaleFactor->Value * msmData->CAL_SF_SCALE_FACTOR); usPreviousScale = msmData->usScaleFactor10000; } /************************************************************************** * MSMDisplay::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 MSMDisplay::ANT_eventNotification(UCHAR ucEventCode_, UCHAR* pucEventBuffer_) { UCHAR ucPageNum = pucEventBuffer_[0]; switch(ucEventCode_) { case EVENT_RX_ACKNOWLEDGED: case EVENT_RX_BURST_PACKET: // intentional fall thru case EVENT_RX_BROADCAST: // check if this is common pages or msm pages if (ucPageNum < commonData->START_COMMON_PAGE) { msmData->Decode(pucEventBuffer_); // check if calibration page if (ucPageNum == msmData->PAGE_CALIBRATION) UpdateCalibration(); } else commonData->Decode(pucEventBuffer_); UpdateDisplay(); break; case EVENT_TRANSFER_TX_COMPLETED: UpdateDisplayAckStatus(msmData->ACK_SUCCESS); // Tx successful break; case EVENT_TRANSFER_TX_FAILED: case EVENT_ACK_TIMEOUT: // Intentional fall thru UpdateDisplayAckStatus(msmData->ACK_FAIL); break; default: break; } } /************************************************************************** * MSMDisplay::UpdateDisplay * * Updates the variables found on the GUI * * returns: N/A * **************************************************************************/ void MSMDisplay::UpdateDisplay() { // update the acumulated variables UpdateAcumValues(); // update the accumulated vaules on the display this->labelDisplayAcumDistance->Text = dbDispAcumDist.ToString("N2"); this->labelDisplayAcumTime->Text = dbDispAcumTime.ToString("N2"); // check for invalid speed if (msmData->IsSpeedValid(msmData->usInstSpeed1000)) this->labelDisplayInstSpeed->Text = ((double) msmData->usInstSpeed1000 / msmData->SPEED_SCALE_FACTOR).ToString("N3"); else this->labelDisplayInstSpeed->Text = "INVALID SPEED"; // check for page 2 data, display it if found if (msmData->bPage2Enabled) { this->labelDisplayLat->Text = (msmData->slLatitude_SC / msmData->SEMI_CIRCLE_CONVERSION).ToString("N6"); this->labelDisplayLong->Text = (msmData->slLongitude_SC / msmData->SEMI_CIRCLE_CONVERSION).ToString("N6"); // update the Rx labels this->labelRxLat->Text = msmData->slLatitude_SC.ToString(); this->labelRxLon->Text = msmData->slLongitude_SC.ToString(); } // check if page 3 data has been received if so, show the data if (msmData->bPage3Enabled) { // check that elevation is valid if (msmData->IsElevationValid()) this->labelDisplayElevation->Text = (((double) msmData->usElevation5 / msmData->ELEVATION_SCALE_FACTOR) - msmData->ELEVATION_OFFSET).ToString("N1"); else this->labelDisplayElevation->Text = "Invalid"; // check that heading data is valid if (msmData->IsHeadingValid()) this->labelDisplayHeading->Text = ((double) msmData->usHeading10 / msmData->HEADING_SCALE_FACTOR).ToString("N1"); else this->labelDisplayHeading->Text = "Invalid"; // set the GPS Fix stuff switch (msmData->ucFixType) { case MSM::GpsFix::NONE: this->labelDisplayFixType->Text = "None"; break; case MSM::GpsFix::INVALID: this->labelDisplayFixType->Text = "Invalid"; break; case MSM::GpsFix::PROPAGATING: this->labelDisplayFixType->Text = "Propagating"; break; case MSM::GpsFix::LAST_KNOWN: this->labelDisplayFixType->Text = "Last Known"; break; case MSM::GpsFix::SEARCHING: this->labelDisplayFixType->Text = "Searching"; break; case MSM::GpsFix::THREE_D: this->labelDisplayFixType->Text = "3D Fix"; break; case MSM::GpsFix::THREE_D_DIF: this->labelDisplayFixType->Text = "3D Differential"; break; case MSM::GpsFix::THREE_D_WAAS: this->labelDisplayFixType->Text = "3D WAAS"; break; case MSM::GpsFix::TWO_D: this->labelDisplayFixType->Text = "2D Fix"; break; case MSM::GpsFix::TWO_D_DIF: this->labelDisplayFixType->Text = "2D Differential"; break; case MSM::GpsFix::TWO_D_WAAS: this->labelDisplayFixType->Text = "2D WAAS"; break; default: this->labelDisplayFixType->Text = "Error"; break; } // update the RX labels this->labelRxElev->Text = msmData->usElevation5.ToString(); this->labelRxHeading->Text = msmData->usHeading10.ToString(); this->labelRxFix->Text = msmData->ucFixType.ToString(); } // the tx variables will show the raw transmitted data decoded, but not scaled into proper units this->labelTxAcumDist->Text = msmData->usAcumDist10.ToString(); this->labelTxAcumTime->Text = msmData->usAcumTime1024.ToString(); this->labelTxInstSpeed->Text = msmData->usInstSpeed1000.ToString(); // update the values for the HW common data page if (commonData->usMfgID != 0) { this->label_Glb_ManfIDDisplay->Text = commonData->usMfgID.ToString(); this->label_Glb_HardwareVerDisplay->Text = commonData->ucHwVersion.ToString(); this->label_Glb_ModelNumDisplay->Text = commonData->usModelNum.ToString(); } // update the values for the SW common data page if (commonData->ulSerialNum != 0) { if(commonData->ulSerialNum == 0xFFFFFFFF) this->label_Glb_SerialNumDisplay->Text = "N/A"; else this->label_Glb_SerialNumDisplay->Text = commonData->ulSerialNum.ToString(); this->label_Glb_SoftwareVerDisplay->Text = commonData->ucSwVersion.ToString(); } // update the values for the battery common data page if (commonData->ulOpTime != 0) { this->labelBattVolt->Text = System::Math::Round((double)commonData->usBatVoltage256/256,4).ToString("N2"); if (commonData->eTimeResolution == CommonData::TimeResolution::SIXTEEN) this->labelTimeRes->Text = "16"; else this->labelTimeRes->Text = "2"; // now that we know the time resolution we can display the run time this->labelOpTime->Text = (commonData->ulOpTime * (UCHAR) commonData->eTimeResolution).ToString(); switch (commonData->eBatStatus) { case CommonData::BatStatus::CRITICAL: this->labelBattStatus->Text = "Critical"; break; case CommonData::BatStatus::GOOD: this->labelBattStatus->Text = "Good"; break; case CommonData::BatStatus::INVALID: this->labelBattStatus->Text = "Invalid"; break; case CommonData::BatStatus::LOW: this->labelBattStatus->Text = "Low"; break; case CommonData::BatStatus::NEW: this->labelBattStatus->Text = "New"; break; case CommonData::BatStatus::OK: this->labelBattStatus->Text = "Ok"; break; default: break; } } // update the date and time info if (commonData->ucDays != 0) { this->labelHours->Text = commonData->ucHours.ToString("D2"); this->labelMinutes->Text = commonData->ucMinutes.ToString("D2"); this->labelSeconds->Text = commonData->ucSeconds.ToString("D2"); this->labelDay->Text = commonData->ucDays.ToString("D2"); this->labelMonth->Text = commonData->ucMonth.ToString("D2"); this->labelYear->Text = commonData->ucYears.ToString("D2"); switch (commonData->eDayOfWeek) { case CommonData::DayOfWeek::SUNDAY: this->labelDayOfWeek->Text = "Sunday"; break; case CommonData::DayOfWeek::MONDAY: this->labelDayOfWeek->Text = "Monday"; break; case CommonData::DayOfWeek::TUESDAY: this->labelDayOfWeek->Text = "Tuesday"; break; case CommonData::DayOfWeek::WEDNESDAY: this->labelDayOfWeek->Text = "Wednesday"; break; case CommonData::DayOfWeek::THURSDAY: this->labelDayOfWeek->Text = "Thursday"; break; case CommonData::DayOfWeek::FRIDAY: this->labelDayOfWeek->Text = "Friday"; break; case CommonData::DayOfWeek::SATURDAY: this->labelDayOfWeek->Text = "Saturday"; break; case CommonData::DayOfWeek::INVALID: this->labelDayOfWeek->Text = "Invalid"; break; default: break; } } } /************************************************************************** * MSMDisplay::UpdateAcumValues * * Updates the accumulated values * * returns: N/A * **************************************************************************/ void MSMDisplay::UpdateAcumValues() { USHORT usRollover; // this is to help protect against rollover using integer math for accumulated values if (usPreviousDist == 0 && usPreviousTime == 0) // check if this is the first transmission { // update the previous values to be current next time usPreviousDist = msmData->usAcumDist10; usPreviousTime = msmData->usAcumTime1024; } else { // update the internal display value for distance usRollover = msmData->usAcumDist10 - usPreviousDist; dbDispAcumDist += (double) usRollover / msmData->DIST_SCALE_FACTOR; // update the internal display value for time usRollover = msmData->usAcumTime1024 - usPreviousTime; dbDispAcumTime += (double) usRollover / msmData->TIME_SCALE_FACTOR; // update the previous values to be current next time usPreviousDist = msmData->usAcumDist10; usPreviousTime = msmData->usAcumTime1024; } } /************************************************************************** * MSMDisplay::UpdateCalibration * * Updates the calibration values and progress * * returns: N/A * **************************************************************************/ void MSMDisplay::UpdateCalibration() { if (eCalStatus == MSM::CalibrationStatus::REQUEST_IN_PROGRESS) { // update the scale factor if it is valid if (msmData->usScaleFactor10000 == msmData->CAL_SCALE_CONF) { // update the scale factor box this->numericUpDownScaleFactor->Value = System::Convert::ToDecimal(msmData->usScaleFactor10000 / msmData->CAL_SF_SCALE_FACTOR); if (msmData->ucMode == ucPreviousMode) { this->labelCalibrationProgress->Text = "Calibration Request Confirmed \nMode Data Supported"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Green; } else if (!msmData->IsCalModeValid(msmData->ucMode)) { this->labelCalibrationProgress->Text = "Calibration Request Confirmed \nMode Data Not Supported"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::CadetBlue; } else { this->labelCalibrationProgress->Text = "Calibration Request Confirmed \nMode Data Invaild"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } } // calibration not supported response is valid else if (!msmData->IsCalScaleValid(msmData->usScaleFactor10000)) { eCalStatus = MSM::CalibrationStatus::NONE; this->labelCalibrationProgress->Text = "Calibration Not Supported"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::CadetBlue; if (msmData->IsCalModeValid(msmData->ucMode)) { this->labelCalibrationProgress->Text = "Calibration Not Supported \nMode Data Invaild: " + msmData->ucMode.ToString(); this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } } // any other respone is invalid else { this->labelCalibrationProgress->Text = "Scale Factor Invalid: " + msmData->usScaleFactor10000.ToString(); this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } } if (eCalStatus == MSM::CalibrationStatus::SET_SCALE_IN_PROGRESS) { // confirmation is given if both the scale factor and mode are the same as was previously sent if (msmData->usScaleFactor10000 == usPreviousScale) { // set the status eCalStatus = MSM::CalibrationStatus::COMPLETE; if (msmData->ucMode == ucPreviousMode) { this->labelCalibrationProgress->Text = "Set Scale Factor Confirmed \nMode Data Supported"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Green; } else if (!msmData->IsCalModeValid(msmData->ucMode)) { this->labelCalibrationProgress->Text = "Set Scale Factor Confirmed \nMode Data Not Supported"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::CadetBlue; } else { this->labelCalibrationProgress->Text = "Set Scale Factor Confirmed \nMode Data Invalid" + msmData->ucMode.ToString(); this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } } // sensor does not support calibration else if (!msmData->IsCalScaleValid(msmData->usScaleFactor10000)) { // set the status eCalStatus = MSM::CalibrationStatus::NONE; this->labelCalibrationProgress->Text = "Set Scale Factor Confirmed \nCalibration Not Supported"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::CadetBlue; // invalid response for the mode if (msmData->IsCalModeValid(msmData->ucMode)) { this->labelCalibrationProgress->Text = "Calibration Not Supported \nMode Data Invalid" + msmData->ucMode.ToString(); this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } } // any other response is invalid else { this->labelCalibrationProgress->Text = "Scale Factor Invalid: " + msmData->usScaleFactor10000.ToString(); this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } } if(eCalStatus == MSM::CalibrationStatus::COMPLETE) { this->labelCalibrationProgress->Text = "Calibration Process Complete"; this->labelCalibrationProgress->BackColor = System::Drawing::SystemColors::Control; } } /************************************************************************** * MSMDisplay::sendCalibrationMsg * * Sends calibration data pages from the display device to the sensor * * MSM::CalibartionStatus calType_: Determines what type of calibration message to send to the sensor * * returns: N/A * **************************************************************************/ void MSMDisplay::SendCalibrationMsg(MSM::CalibrationStatus calType_) { // declare buffer for the acknowledged messages UCHAR aucAckBuffer[8] = {0,0,0,0,0,0,0,0}; switch (calType_) { case MSM::CalibrationStatus::REQUEST_IN_PROGRESS: // set the scale factor to 0 msmData->usScaleFactor10000 = msmData->CAL_SCALE_REQUEST; break; case MSM::CalibrationStatus::SET_SCALE_IN_PROGRESS: // set the scale factor according to the GUI msmData->usScaleFactor10000 = USHORT (this->numericUpDownScaleFactor->Value * msmData->CAL_SF_SCALE_FACTOR); break; default: break; } // update the previous variables to enable checking on return ucPreviousMode = msmData->ucMode; usPreviousScale = msmData->usScaleFactor10000; // get the data loaded into the buffer msmData->EncodeData(msmData->PAGE_CALIBRATION, aucAckBuffer); // make sure the buffer has something in it if (aucAckBuffer[0]) { // send the acknowledged message requestAckMsg(aucAckBuffer); } } /************************************************************************** * MSMDisplay::UpdateDisplayAckStatus * * Updates the display relative to the calibration process after the ACK is received * * UCHAR ackStatus_: this determines if the ACK was a success or a fail * * returns: N/A * **************************************************************************/ void MSMDisplay::UpdateDisplayAckStatus(UCHAR ackStatus_) { switch (ackStatus_) { case msmData->ACK_SUCCESS: if (eCalStatus == MSM::CalibrationStatus::REQUEST_IN_PROGRESS) { this->labelCalibrationProgress->Text = "Calibration Request \nAcknowledgement Recieved"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Orange; } if (eCalStatus == MSM::CalibrationStatus::SET_SCALE_IN_PROGRESS) { this->labelCalibrationProgress->Text = "Set Scale \nAcknowledgement Recieved"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Orange; } break; case msmData->ACK_FAIL: if (eCalStatus == MSM::CalibrationStatus::REQUEST_IN_PROGRESS) { this->labelCalibrationProgress->Text = "Calibration Request \nAcknowledgement Failed"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } if (eCalStatus == MSM::CalibrationStatus::SET_SCALE_IN_PROGRESS) { this->labelCalibrationProgress->Text = "Set Scale \nAcknowledgement Failed"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Red; } break; default: break; } } /************************************************************************** * MSMDisplay::numericUpDownMode_ValueChanged * * Handles the change to the calibration Mode value * * returns: N/A * **************************************************************************/ void MSMDisplay::numericUpDownMode_ValueChanged(System::Object^ sender, System::EventArgs^ e) { msmData->ucMode = System::Convert::ToByte(this->numericUpDownMode->Value); } /************************************************************************** * MSMDisplay::numericUpDownScaleFactor_ValueChanged * * Handles the change to the calibration Scale Factor value * * returns: N/A * **************************************************************************/ void MSMDisplay::numericUpDownScaleFactor_ValueChanged(System::Object^ sender, System::EventArgs^ e) { msmData->usScaleFactor10000 = System::Convert::ToUInt16(this->numericUpDownScaleFactor->Value * msmData->CAL_SF_SCALE_FACTOR); } /************************************************************************** * MSMDisplay::buttonCalibrationRequest_Click * * Initiates the Calibration request to the MSM sensor * * returns: N/A * **************************************************************************/ void MSMDisplay::buttonCalibrationRequest_Click(System::Object^ sender, System::EventArgs^ e) { eCalStatus = MSM::CalibrationStatus::REQUEST_IN_PROGRESS; SendCalibrationMsg(eCalStatus); // update the display this->numericUpDownScaleFactor->Value = System::Convert::ToDecimal(msmData->usScaleFactor10000 / msmData->CAL_SF_SCALE_FACTOR); this->labelCalibrationProgress->Text = "Calibration Request Sent"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Yellow; } /************************************************************************** * MSMDisplay::buttonSetScaleFactor_Click * * Sends a Set Mode/Scale Factor message to the sensor * * returns: N/A * **************************************************************************/ void MSMDisplay::buttonSetScaleFactor_Click(System::Object^ sender, System::EventArgs^ e) { eCalStatus = MSM::CalibrationStatus::SET_SCALE_IN_PROGRESS; SendCalibrationMsg(eCalStatus); // update the display this->labelCalibrationProgress->Text = "Set Scale Factor Sent"; this->labelCalibrationProgress->BackColor = System::Drawing::Color::Yellow; }