Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -rc25d707f6f5f2463639425e2efd6876bed974304 -rd7b793881e8414f2daf75825d5de4e25a25d10ac --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision c25d707f6f5f2463639425e2efd6876bed974304) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision d7b793881e8414f2daf75825d5de4e25a25d10ac) @@ -7,8 +7,8 @@ * * @file DGInterface.c * -* @author (last) Dong Nguyen -* @date (last) 27-Sep-2022 +* @author (last) Dara Navaei +* @date (last) 07-Nov-2022 * * @author (original) Sean * @date (original) 08-Apr-2020 @@ -24,7 +24,7 @@ #include "ModeInitPOST.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" -#include "OperationModes.h" +#include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemComm.h" #include "SystemCommMessages.h" @@ -57,13 +57,15 @@ static const U32 DIP_RESERVOIRS_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); static const U32 DIP_DG_OP_MODE_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); -// DG status -static DG_OP_MODE_T dgCurrentOpMode = DG_MODE_INIT; ///< Current DG operation mode. -static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. -static BOOL dgStartCommandSent = FALSE; ///< Flag indicates command to start DG has been sent. -static BOOL dgStarted = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop. -static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. +// ********** private data ********** +// DG status +static DG_OP_MODE_T dgCurrentOpMode; ///< Current DG operation mode. +static U32 dgSubMode; ///< Current state (sub-mode) of current DG operation mode. +static BOOL dgStartCommandSent; ///< Flag indicates command to start DG has been sent. +static BOOL dgStarted; ///< Flag indicates whether we have commanded the DG to start or stop. +static BOOL dgTrimmerHeaterOn; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. + // State machine states static U32 timeStartMS = 0; // TODO is this needed? @@ -107,13 +109,17 @@ static DG_DISINFECT_UI_STATES_T disinfectsStatus; ///< DG disinfects status. static DG_MIXING_RATIOS_T dgMixingRatios; ///< DG mixing ratios. +static HEATERS_DATA_T dgHeatersData; ///< DG heaters data. +static DG_SERVICE_AND_USAGE_DATA_T dgServiceAndUsageData; ///< DG service and usage data. // DG command response static DG_CMD_RESPONSE_T dgCmdResp[ NUM_OF_DG_COMMANDS ]; ///< Keep the latest DG command response for each command. // ********** private function prototypes ********** static void checkDGRestart( void ); +static void checkDGTrimmerHeaterStatus( void ); +static void checkDGDataFreshness( ALARM_ID_T alarmID, BOOL *dgFreshDataFlag ); /*********************************************************************//** * @brief @@ -196,7 +202,7 @@ * @param flag to signal the fresh data processing * @return None *************************************************************************/ -void checkDGDataFreshness( ALARM_ID_T alarmID, BOOL *dgFreshDataFlag ) +static void checkDGDataFreshness( ALARM_ID_T alarmID, BOOL *dgFreshDataFlag ) { if ( TRUE == *dgFreshDataFlag ) { @@ -242,6 +248,9 @@ // Check to see if DG has restarted checkDGRestart(); + + // Check the status of the trimmer heater + checkDGTrimmerHeaterStatus(); } /*********************************************************************//** @@ -406,6 +415,22 @@ /*********************************************************************//** * @brief + * The getReservoirWeight function gets the load cell weight of a given reservoir. + * @details Inputs: loadCellWeightInGrams[] + * @details Outputs: none + * @param resID ID of reservoir to get weight for + * @return the current weight of the given reservoir in grams + *************************************************************************/ +F32 getReservoirWeight( DG_RESERVOIR_ID_T resID ) +{ + LOAD_CELL_ID_T lc = ( DG_RESERVOIR_1 == resID ? LOAD_CELL_RESERVOIR_1_PRIMARY : LOAD_CELL_RESERVOIR_2_PRIMARY ); + F32 wt = getLoadCellWeight( lc ); + + return wt; +} + +/*********************************************************************//** + * @brief * The getReservoirBackupWeightLargeFilter function gets the backup load cell weight * of the given reservoir after large (32 sample) filter applied. * @details Inputs: lgFilteredReservoirWeightInGrams[] @@ -464,26 +489,25 @@ /*********************************************************************//** * @brief - * The getReservoirWeight function gets the load cell weight of a given reservoir. - * @details Inputs: loadCellWeightInGrams[] + * The getHDVersionDGServiceAndUsageData function copies the HD version of + * the DG service and usage data into the provided buffer. + * @details Inputs: dgServiceAndUsageData * @details Outputs: none - * @param resID ID of reservoir to get weight for - * @return the current weight of the given reservoir in grams + * @param data which is a pointer of type DG_SERVICE_AND_USAGE_DATA_T that + * is the provided buffer + * @return none *************************************************************************/ -F32 getReservoirWeight( DG_RESERVOIR_ID_T resID ) +void getHDVersionDGServiceAndUsageData( DG_SERVICE_AND_USAGE_DATA_T* data ) { - LOAD_CELL_ID_T lc = ( DG_RESERVOIR_1 == resID ? LOAD_CELL_RESERVOIR_1_PRIMARY : LOAD_CELL_RESERVOIR_2_PRIMARY ); - F32 wt = getLoadCellWeight( lc ); - - return wt; + memcpy( data, &dgServiceAndUsageData, sizeof( DG_SERVICE_AND_USAGE_DATA_T ) ); } /*********************************************************************//** * @brief * The setDGOpMode function sets the latest DG operating mode reported by * the DG. * @details Inputs: none - * @details Outputs: dgCurrentOpMode, dgSubMode + * @details Outputs: dgCurrentOpMode, dgSubMode, dgOpModeDataFreshFlag * @param opMode operating mode reported by DG * @param subMode sub-mode (current state) of operating mode reported by DG * @return none @@ -508,7 +532,8 @@ * The setDialysateTemperatureReadings function sets the latest dialysate * temperatures reported by the DG. * @details Inputs: none - * @details Outputs: dgDialysateTemp, dgRedundantDialysateTemp + * @details Outputs: dgDialysateTemp, dgRedundantDialysateTemp, + * dgDialysateTemperatureDataFreshFlag * @param temp1 dialysate temperature reported by DG * @param temp2 redundant dialysate temperature reported by DG * @return none @@ -526,7 +551,8 @@ * The setDGReservoirsData function sets the latest reservoir data * reported by the DG. * @details Inputs: none - * @details Outputs: dgActiveReservoir, dgReservoirFillVolumeTarget, dgReservoirDrainVolumeTarget + * @details Outputs: dgActiveReservoir, dgReservoirFillVolumeTarget, + * dgReservoirDrainVolumeTarget, dgReservoirsDataFreshFlag * @param resID ID of active reservoir * @param fillVol Reservoir fill to volume reported by DG * @param drainVol Reservoir drain to volume reported by DG @@ -553,7 +579,7 @@ * The setDialysateFlowData function sets the latest dialysate flow rate * and its freshness status. The dialysate flow data is reported by the DG. * @details Inputs: none - * @details Outputs: dgDialysateFlowRateMlMin + * @details Outputs: dgDialysateFlowRateMlMin, dgDialysateFlowDataFreshFlag * @param flowRate latest dialysate flow rate (mL/min) reported by DG * @return none *************************************************************************/ @@ -576,7 +602,8 @@ * every 100 ms. * @details Inputs: none * @details Outputs: loadCellWeightInGrams[], smFilteredReservoirWeightInGrams[], - * lgFilteredReservoirWeightInGrams[] + * lgFilteredReservoirWeightInGrams[], lgLoadCellReadingsTotal[], + * lgLoadCellBackupReadingsTotal[], lgLoadCellReadingsIdx, dgLoadCellDataFreshFlag * @param res1Primary New weight from primary load cell of reservoir 1 * @param res1Backup New weight from backup load cell of reservoir 1 * @param res2Primary New weight from primary load cell of reservoir 2 @@ -642,11 +669,56 @@ *************************************************************************/ void setDGMixingRatios( DG_MIXING_RATIOS_T ratios ) { - memcpy( &dgMixingRatios, &ratios, sizeof(DG_MIXING_RATIOS_T) ); + memcpy( &dgMixingRatios, &ratios, sizeof( DG_MIXING_RATIOS_T ) ); } /*********************************************************************//** * @brief + * The setDGHeatersData function sets heaters data that has been read from DG. + * @details Inputs: none + * @details Outputs: dgHeatersData + * @param data which is a pointer to the received heaters data + * @return none + *************************************************************************/ +void setDGHeatersData( HEATERS_DATA_T *data ) +{ + memcpy( &dgHeatersData, data, sizeof( HEATERS_DATA_T ) ); +} + +/*********************************************************************//** + * @brief + * The setHDVersionDGServiceRecord function sets the HD version of the DG + * service record. + * @details Inputs: none + * @details Outputs: dgServiceAndUsageData + * @param data which is a pointer to the received HD version of the DG service + * record + * @return none + *************************************************************************/ +void setHDVersionDGServiceRecord( HD_VERSION_DG_SERVICE_RECORD_T* data ) +{ + dgServiceAndUsageData.isDGServiceRecordAvailable = TRUE; + memcpy( &dgServiceAndUsageData.dgServiceRecord, data, sizeof( HD_VERSION_DG_SERVICE_RECORD_T ) ); +} + +/*********************************************************************//** + * @brief + * The setHDVersionDGUsageInfo function sets the HD version of the DG + * usage information. + * @details Inputs: none + * @details Outputs: dgServiceAndUsageData + * @param data which is a pointer to the received HD version of the DG usage + * info + * @return none + *************************************************************************/ +void setHDVersionDGUsageInfo( HD_VERSION_DG_USAGE_INFO_T* data ) +{ + dgServiceAndUsageData.isDGUsageInfoAviable = TRUE; + memcpy( &dgServiceAndUsageData.dgUsageInfo, data, sizeof( HD_VERSION_DG_USAGE_INFO_T ) ); +} + +/*********************************************************************//** + * @brief * The cmdSetDGDialysateHeatingParams function sends the dialysate heating * parameters to DG. * @details Inputs: none @@ -732,14 +804,16 @@ * @param resID ID of reservoir to set as active (reservoir for HD to draw from) * @return none *************************************************************************/ -void cmdSetDGActiveReservoir( DG_RESERVOIR_ID_T resID ) +void cmdSetDGActiveReservoir( DG_SWITCH_RSRVRS_CMD_T *cmd ) { + DG_RESERVOIR_ID_T resID = (DG_RESERVOIR_ID_T)cmd->reservoirID; + if ( resID < NUM_OF_DG_RESERVOIRS ) { - dgActiveReservoirSet = resID; + dgActiveReservoirSet = resID; dgCmdResp[ DG_CMD_SWITCH_RESERVOIR ].commandID = DG_CMD_NONE; - sendDGSwitchReservoirCommand( (U32)resID ); + sendDGSwitchReservoirCommand( cmd ); } else { @@ -1044,6 +1118,7 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DIALYSATE_TEMP_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { + // Per PRS 377, PRS 124 checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_HIGH_SAFETY_RANGE, isTDiTempAboveHighSafety, dgDialysateTemp, DIALYSATE_TEMP_HIGH_SAFETY_LIMIT_C ); checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_LOW_SAFETY_RANGE, isTDiTempAboveLowSafety, dgDialysateTemp, DIALYSATE_TEMP_LOW_SAFETY_LIMIT_C ); @@ -1080,7 +1155,35 @@ } } +/*********************************************************************//** + * @brief + * The checkDGTrimmerHeaterStatus function checks to see the status of the + * trimmer heater and set them according to the status of the trimmer heater flag. + * @details Inputs: dgTrimmerHeaterOn, dgHeatersData + * @details Outputs: none + * @return none + *************************************************************************/ +static void checkDGTrimmerHeaterStatus( void ) +{ + U32 trimmerState = dgHeatersData.trimmerHeaterState; + DG_OP_MODE_T dgOp = getDGOpMode(); + if ( ( DG_MODE_GENE == dgOp ) || ( DG_MODE_FILL == dgOp ) || ( DG_MODE_DRAI == dgOp ) ) + { + // In heat disinfect and chemical disinfect, the trimmer heater is controlled by the DG itself so no commands from HD should be sent + // regarding the trimmer heater. + if ( ( TRUE == dgTrimmerHeaterOn ) && ( HEATER_EXEC_STATE_OFF == trimmerState ) ) + { + cmdStartDGTrimmerHeater(); + } + else if ( ( FALSE == dgTrimmerHeaterOn ) && ( trimmerState != HEATER_EXEC_STATE_OFF ) ) + { + cmdStopDGTrimmerHeater(); + } + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Controllers/DialInFlow.h =================================================================== diff -u -r29b65975bb4d6a5720ef39119a9af49fafc902fa -rd7b793881e8414f2daf75825d5de4e25a25d10ac --- firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision 29b65975bb4d6a5720ef39119a9af49fafc902fa) +++ firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision d7b793881e8414f2daf75825d5de4e25a25d10ac) @@ -45,7 +45,7 @@ F32 measMCSpd; F32 measMCCurr; F32 pwmDC; - F32 flowSigStrength; + U32 rotorCount; } DIALIN_PUMP_STATUS_PAYLOAD_T; // ********** public function prototypes ********** @@ -60,6 +60,7 @@ BOOL homeDialInPump( void ); BOOL isDialInPumpRunning( void ); BOOL isDialInPumpRampComplete( void ); +void resetDialInPumpRotorCount( void ); SELF_TEST_STATUS_T execDialInFlowTest( void ); @@ -70,6 +71,7 @@ F32 getMeasuredDialInPumpMCSpeed( void ); F32 getMeasuredDialInPumpMCCurrent( void ); F32 getDialInPumpPWMDutyCyclePct( BOOL init ); +U32 getDialInPumpRotorCount( void ); U32 getPumpRotorErrorPersistTime( F32 mtr_speed, F32 gear_ratio ); BOOL testSetDialInFlowDataPublishIntervalOverride( U32 value ); @@ -85,7 +87,9 @@ BOOL testResetMeasuredDialInPumpMCSpeedOverride( void ); BOOL testSetMeasuredDialInPumpMCCurrentOverride( F32 value ); BOOL testResetMeasuredDialInPumpMCCurrentOverride( void ); -BOOL testSetDialInPumpTargetDutyCycle( F32 value ); +BOOL testSetDialInPumpTargetDutyCycle( F32 value ); +BOOL testSetDialysateInPumpRotorCountOverride( U32 value ); +BOOL testResetDialysateInPumpRotorCountOverride( void ); /**@}*/ Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r34d0843fa73e79ba3b085dd4aaa393a1ec126fd4 -rd7b793881e8414f2daf75825d5de4e25a25d10ac --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 34d0843fa73e79ba3b085dd4aaa393a1ec126fd4) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision d7b793881e8414f2daf75825d5de4e25a25d10ac) @@ -619,18 +619,25 @@ } // If homing has been initiated, wait for syringe pump to home and the verify force sensor calibration - if ( ( TRUE == homingInitiated ) && ( TRUE == isSyringePumpHome() ) ) +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP ) ) { - syringePumpVerifyForceSensorDACCalibration(); - homingInitiated = FALSE; // reset for next time state = STANDBY_WAIT_FOR_TREATMENT_STATE; // Go to wait for treatment state after above check } + else +#endif + { + if ( ( TRUE == homingInitiated ) && ( TRUE == isSyringePumpHome() ) ) + { + syringePumpVerifyForceSensorDACCalibration(); + homingInitiated = FALSE; // reset for next time + state = STANDBY_WAIT_FOR_TREATMENT_STATE; // Go to wait for treatment state after above check + } + } return state; } -// Verify calibration - /*********************************************************************//** * @brief * The handleStandbyModeWaitForTreatmentState function handles wait for Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -ref6283257df7c1f993d58fb934da57ea3e0a7067 -rd7b793881e8414f2daf75825d5de4e25a25d10ac --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision ef6283257df7c1f993d58fb934da57ea3e0a7067) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision d7b793881e8414f2daf75825d5de4e25a25d10ac) @@ -159,6 +159,9 @@ treatmentCompleted = FALSE; rinsebackDone = FALSE; + resetBloodPumpRotorCount(); + resetDialInPumpRotorCount(); + treatmentTimeMS = 0; lastTreatmentTimeStamp = 0; treatmentTimeBroadcastTimerCtr = TREATMENT_TIME_DATA_PUB_INTERVAL; // So we send time data immediately when we begin treatment mode Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -re8053e6bdafd0638102e01c4250dfd74c0850ba1 -rd7b793881e8414f2daf75825d5de4e25a25d10ac --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e8053e6bdafd0638102e01c4250dfd74c0850ba1) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision d7b793881e8414f2daf75825d5de4e25a25d10ac) @@ -1376,6 +1376,10 @@ handleHDBloodPumpRotorCountOverrideRequest( message ); break; + case MSG_ID_DIALYSATE_INLET_PUMP_ROTOR_COUNT_OVERRIDE: + handleHDDialInPumpRotorCountOverrideRequest( message ); + break; + case MSG_ID_BLOOD_PUMP_HOME_CMD: handleTestBloodPumpHomeRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rac5a409920099e701227c507cbda86d5d1ea8bf8 -rd7b793881e8414f2daf75825d5de4e25a25d10ac --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision ac5a409920099e701227c507cbda86d5d1ea8bf8) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision d7b793881e8414f2daf75825d5de4e25a25d10ac) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.c * -* @author (last) Michael Garthwaite -* @date (last) 12-Oct-2022 +* @author (last) Dara Navaei +* @date (last) 03-Nov-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -36,6 +36,7 @@ #include "SystemComm.h" #include "SystemCommMessages.h" #include "Temperatures.h" +#include "Timers.h" #include "TreatmentEnd.h" #include "TreatmentRecirc.h" #include "TreatmentStop.h" @@ -63,6 +64,7 @@ #pragma pack(pop) // ********** private data ********** + static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether an external tester (connected PC) has sent a valid login message. static volatile U16 nextSeqNo = 1; ///< Value of sequence number to use for next transmitted message. @@ -1427,7 +1429,7 @@ * @param activeReservoir reservoir ID to set as active * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendDGSwitchReservoirCommand( U32 activeReservoir ) +BOOL sendDGSwitchReservoirCommand( DG_SWITCH_RSRVRS_CMD_T *cmd ) { BOOL result; MESSAGE_T msg; @@ -1436,9 +1438,9 @@ // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_SWITCH_RESERVOIR_CMD; - msg.hdr.payloadLen = sizeof( U32 ); + msg.hdr.payloadLen = sizeof( DG_SWITCH_RSRVRS_CMD_T ); - memcpy( payloadPtr, &activeReservoir, sizeof( U32 ) ); + memcpy( payloadPtr, cmd, sizeof( DG_SWITCH_RSRVRS_CMD_T ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_DG, ACK_REQUIRED ); @@ -1582,7 +1584,7 @@ // Create a message record blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD; + msg.hdr.msgID = MSG_ID_HD_START_STOP_TRIMMER_HEATER_CMD; msg.hdr.payloadLen = sizeof( BOOL ); memcpy( payloadPtr, &start, sizeof( BOOL ) ); @@ -2309,17 +2311,36 @@ *************************************************************************/ void handleLoadCellReadingsFromDG( MESSAGE_T *message ) { - if ( message->hdr.payloadLen == sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ) + if ( message->hdr.payloadLen == sizeof( LOAD_CELL_DATA_T ) ) { - LOAD_CELL_READINGS_PAYLOAD_T payload; + LOAD_CELL_DATA_T payload; - memcpy( &payload, message->payload, sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ); - setNewLoadCellReadings( payload.res1PrimaryLoadCell, payload.res1BackupLoadCell, payload.res2PrimaryLoadCell, payload.res2BackupLoadCell ); + memcpy( &payload, message->payload, sizeof( LOAD_CELL_DATA_T ) ); + setNewLoadCellReadings( payload.loadCellA1inGram, payload.loadCellA2inGram, payload.loadCellB1inGram, payload.loadCellB2inGram ); } } /*********************************************************************//** * @brief + * The handleDGHeatersData function handles the heaters data reading from DG. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGHeatersData( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof( HEATERS_DATA_T ) ) + { + HEATERS_DATA_T payload; + + memcpy( &payload, message->payload, sizeof( HEATERS_DATA_T ) ); + setDGHeatersData( &payload ); + } +} + +/*********************************************************************//** + * @brief * The handleDGTemperatureData function handles a temperature readings * broadcast message from the DG. * @details Inputs: none @@ -2349,12 +2370,12 @@ *************************************************************************/ void handleDialysateFlowData( MESSAGE_T *message ) { - if ( message->hdr.payloadLen == sizeof( DIALYSATE_FLOW_METER_DATA_T ) ) + if ( message->hdr.payloadLen == sizeof( FLOW_SENSORS_DATA_T ) ) { - DIALYSATE_FLOW_METER_DATA_T payload; + FLOW_SENSORS_DATA_T payload; - memcpy( &payload, message->payload, sizeof( DIALYSATE_FLOW_METER_DATA_T ) ); - setDialysateFlowData( payload.measuredDialysateFlowRate ); + memcpy( &payload, message->payload, sizeof( FLOW_SENSORS_DATA_T ) ); + setDialysateFlowData( payload.dialysateFlowRateLPM ); } } @@ -3068,6 +3089,11 @@ HD_VERSIONS_T payload; U08 *payloadPtr = msg.payload; + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_VERSION; + msg.hdr.payloadLen = sizeof( HD_VERSIONS_T ); + if ( message->hdr.payloadLen == sizeof( UI_VERSIONS_T ) ) { // Get UI version data from this request msg and have it recorded @@ -3081,11 +3107,6 @@ payload.compatibilityRev = (U32)SW_COMPATIBILITY_REV; getFPGAVersions( &payload.fpgaId, &payload.fpgaMajor, &payload.fpgaMinor, &payload.fpgaLab ); - // Create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_HD_VERSION; - msg.hdr.payloadLen = sizeof( HD_VERSIONS_T ); - // Fill message payload memcpy( payloadPtr, &payload, sizeof( HD_VERSIONS_T ) ); } @@ -3185,22 +3206,27 @@ { MESSAGE_T msg; HD_SERVICE_RECORD_T service; + DG_SERVICE_AND_USAGE_DATA_T dgData; + U08 *payloadPtr = msg.payload; getNVRecord2Driver( GET_SRV_RECORD, (U08*)&service, sizeof( HD_SERVICE_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + getHDVersionDGServiceAndUsageData( &dgData ); - U08 *payloadPtr = msg.payload; + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SERVICE_SCHEDULE_DATA; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); - if ( message->hdr.payloadLen == sizeof( U32 ) + sizeof( U32 ) ) + if ( 0 == message->hdr.payloadLen ) { - // Create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_HD_SERVICE_SCHEDULE_DATA; - msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); - // Fill message payload memcpy( payloadPtr, &service.lastServiceEpochDate, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &service.serviceIntervalSeconds, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &dgData.dgServiceRecord.lastServiceDateEpoch, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &dgData.dgServiceRecord.serviceIntervalSeconds, sizeof( U32 ) ); } // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer @@ -3235,7 +3261,73 @@ serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); } +/*********************************************************************//** + * @brief + * The handleUIConfirmationResponse function handles a UI response for + * confirmation request. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleUIConfirmationResponse( MESSAGE_T *message ) +{ + BOOL result = FALSE; + U08* payloadPtr = message->payload; + if ( message->hdr.payloadLen == 2 * sizeof(U32) ) + { + U32 request_id; + U32 status; + + memcpy( &request_id, payloadPtr, sizeof(U32) ); + payloadPtr += sizeof(U32); + memcpy( &status, payloadPtr, sizeof(U32) ); + + if ( ( CONFIRMATION_REQUEST_STATUS_REJECTED == status ) || + ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == status ) ) + { + setConfirmationRequestStatus( (GENERIC_CONFIRM_ID_T) request_id, (CONFIRMATION_REQUEST_STATUS_T) status ); + } + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); +} + +/*********************************************************************//** + * @brief + * The sendConfirmationRequest function sends a confirmation request to UI + * @details Inputs: none + * @details Outputs: none + * @param request ID + * @param request type + * @param reject reason + * @return request ID - will be non-zero if sent + *************************************************************************/ +void sendConfirmationRequest( GENERIC_CONFIRM_ID_T request_id, GENERIC_CONFIRM_COMMAND_T request_type, U32 reject_reason ) +{ + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + U32 temp_request = request_id; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_UI_CONFIRMATION; + // The payload length is U32 Request ID, U32 Type, U32 Reject Reason + msg.hdr.payloadLen = 3 * sizeof( U32 ); + + memcpy( payloadPtr, &temp_request, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + temp_request = request_type; + memcpy( payloadPtr, &temp_request, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &reject_reason, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_NOT_REQUIRED ); +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -5161,7 +5253,7 @@ memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); if ( FALSE == payload.reset ) { - result = testSetBatteryRemainingPercentOverride( payload.state.u32 ); + result = testSetBatteryRemainingPercentOverride( payload.state.f32 ); } else { @@ -6397,14 +6489,11 @@ BOOL result = FALSE; // Verify payload length - if ( sizeof( F32 ) == message->hdr.payloadLen ) + if ( 0 == message->hdr.payloadLen ) { if ( TRUE == isTestingActivated() ) { - F32 dacVRef; - - memcpy( &dacVRef, message->payload, sizeof( F32 ) ); // TODO - Payload no longer used. Update Dialin command and expected payload len in f/w. - result = setSyringePumpDACVref(); + result = setSyringePumpDACVref(); } } @@ -7123,6 +7212,96 @@ } /*********************************************************************//** + * @brief + * The sendDGUsageInfoRequestToDG function constructs a request msg + * to the DG to request the DG usage info and queues the msg for transmit + * on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG usage info result request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGUsageInfoRequestToDG( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_USAGE_INFO; + msg.hdr.payloadLen = 0; + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_DG, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendDGServiceRequestToDG function constructs a request msg + * to the DG to request the DG service record and queues the msg for transmit + * on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG usage info result request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGServiceRequestToDG( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_SERVICE_RECORD; + msg.hdr.payloadLen = 0; + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_DG, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleDGServiceScheduleData function receives the HD version of the + * DG service record. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGServiceScheduleData( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof( HD_VERSION_DG_SERVICE_RECORD_T ) ) + { + HD_VERSION_DG_SERVICE_RECORD_T payload; + + memcpy( &payload, message->payload, sizeof( HD_VERSION_DG_SERVICE_RECORD_T ) ); + setHDVersionDGServiceRecord( &payload ); + } +} + +/*********************************************************************//** + * @brief + * The handleDGUsageInfoData function receives the HD version of the + * DG usage info. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGUsageInfoData( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof( HD_VERSION_DG_USAGE_INFO_T ) ) + { + HD_VERSION_DG_USAGE_INFO_T payload; + + memcpy( &payload, message->payload, sizeof( HD_VERSION_DG_USAGE_INFO_T ) ); + setHDVersionDGUsageInfo( &payload ); + } +} + +/*********************************************************************//** * @brief * The handleGetHDUsageInfoRecord function handles a request to get the HD * usage information record. Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rfc65332fb8fa0e83ddccbdc72592cc4a4b41e382 -rd7b793881e8414f2daf75825d5de4e25a25d10ac --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision fc65332fb8fa0e83ddccbdc72592cc4a4b41e382) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision d7b793881e8414f2daf75825d5de4e25a25d10ac) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.h * -* @author (last) Michael Garthwaite -* @date (last) 28-Sep-2022 +* @author (last) Dara Navaei +* @date (last) 03-Nov-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -63,9 +63,6 @@ #define ACK_REQUIRED TRUE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver. #define ACK_NOT_REQUIRED FALSE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver. -#define ACK_REQUIRED TRUE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver. -#define ACK_NOT_REQUIRED FALSE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver. - // ********** public function prototypes ********** // Serialize message @@ -139,15 +136,18 @@ void handleUIPOSTFinalResult( MESSAGE_T *message ); // MSG_ID_LOAD_CELL_READINGS -void handleLoadCellReadingsFromDG( MESSAGE_T *message ); +void handleLoadCellReadingsFromDG( MESSAGE_T *message ); + +// MSG_ID_DG_HEATERS_DATA +void handleDGHeatersData( MESSAGE_T *message ); // MSG_ID_DG_TEMPERATURE_DATA: void handleDGTemperatureData( MESSAGE_T *message ); // MSG_ID_RO_PUMP_DATA: void handleROPumpData( MESSAGE_T *message ); -// MSG_ID_DG_DIALYSATE_FLOW_METER_DATA: +// MSG_ID_DG_FLOW_SENSORS_DATA void handleDialysateFlowData( MESSAGE_T *message ); // MSG_ID_DRAIN_PUMP_DATA: @@ -357,7 +357,7 @@ BOOL sendDialysateHeatingParamsToDG( DG_CMD_DIALYSATE_HEATING_PARAMS_T *params ); // MSG_ID_DG_SWITCH_RESERVOIR_CMD -BOOL sendDGSwitchReservoirCommand( U32 activeReservoir ); +BOOL sendDGSwitchReservoirCommand( DG_SWITCH_RSRVRS_CMD_T *cmd ); // MSG_ID_DG_CHANGE_VALVE_SETTING_CMD BOOL sendDGChangeValveSettingCommand( U32 valveSettingCmd ); @@ -431,10 +431,30 @@ // MSG_ID_HD_SET_SW_CONFIG_RECORD void handleSetHDSoftwareConfigRecord( MESSAGE_T *message ); +// MSG_ID_HD_SEND_ALARMS_COMMAND +void handleResendAllAlarmsCommand( MESSAGE_T* message ); +// MSG_ID_UI_CONFIRMATION_RESULT +void handleUIConfirmationResponse( MESSAGE_T *message ); + +// MSG_ID_HD_REQUEST_UI_CONFIRMATION +void sendConfirmationRequest( GENERIC_CONFIRM_ID_T request_id, GENERIC_CONFIRM_COMMAND_T request_type, U32 reject_reason ); + // MSG_ID_HD_REQUEST_DG_ALARMS BOOL sendRequestForDGResendAlarms( void ); +// MSG_ID_HD_REQUEST_DG_USAGE_INFO +BOOL sendDGUsageInfoRequestToDG( void ); + +// MSG_ID_HD_REQUEST_DG_SERVICE_INFO +BOOL sendDGServiceRequestToDG( void ); + +// MSG_ID_DG_SERVICE_SCHEDULE_DATA +void handleDGServiceScheduleData( MESSAGE_T *message ); + +// MSG_ID_DG_USAGE_DATA +void handleDGUsageInfoData( MESSAGE_T *message ); + // *********** public test support message functions ********** // MSG_TESTER_LOG_IN