Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r6e7270b9f5408f602dd090eae1bf4414297a5187 -rf760ffc4b10556e5186e9ceb90294262063440ca --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 6e7270b9f5408f602dd090eae1bf4414297a5187) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision f760ffc4b10556e5186e9ceb90294262063440ca) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2023 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file SystemCommMessages.c * -* @author (last) Dara Navaei -* @date (last) 25-May-2022 +* @author (last) Sean Nash +* @date (last) 27-Jan-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -28,20 +28,23 @@ #include "Fans.h" #include "FPGA.h" #include "ModeStandby.h" +#include "ModeInitPOST.h" #include "OperationModes.h" #include "RTC.h" #include "SampleWater.h" #include "SafetyShutdown.h" #include "SystemComm.h" #include "SystemCommMessages.h" #include "Temperatures.h" +#include "Timers.h" #include "TreatmentEnd.h" #include "TreatmentRecirc.h" #include "TreatmentStop.h" #include "Utilities.h" #include "Valves.h" #include "WatchdogMgmt.h" -#include "HDDefs.h" +#include "HDDefs.h" +#include "TaskPriority.h" /** * @addtogroup SystemCommMessages @@ -64,6 +67,7 @@ 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. + /// List of message IDs that are requested not to be transmitted. static BLOCKED_MSGS_DATA_T blockedMessagesForXmit = { 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -90,7 +94,6 @@ U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) { BOOL result = 0; - BOOL error = FALSE; BOOL blocked = FALSE; U32 msgSize = 0; U32 sizeMod, sizePad; @@ -163,17 +166,13 @@ { if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) { - error = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL, (U32)(msg.hdr.msgID) ) } } } - if ( FALSE == error ) - { - // Add serialized message data to appropriate out-going comm buffer - result = addToCommBuffer( buffer, data, msgSize ); - } + // Add serialized message data to appropriate out-going comm buffer + result = addToCommBuffer( buffer, data, msgSize ); } else { @@ -792,14 +791,14 @@ *************************************************************************/ void handleUITreatmentLogDataRequest( MESSAGE_T *message ) { + BOOL ack = FALSE; + if ( 0 == message->hdr.payloadLen ) { + ack = TRUE; sendTreatmentLogDataToUI(); } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, ack ); } /*********************************************************************//** @@ -888,24 +887,26 @@ /*********************************************************************//** * @brief - * The handleSetHDStandbyDisinfectSubmode function handles setting the + * The handleSetHDStandbyDisinfectSubmodeRequest function handles setting the * standby submode to wait for disisnfect state. - * @details Inputs: none + * @details Inputs: 1=initiate, 0=cancel * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleSetHDStandbyDisinfectSubmodeRequest( MESSAGE_T *message ) { - BOOL result = FALSE; + U32 cmd; - // The payload should be 0 in this case because there is mode in this command - if ( 0 == message->hdr.payloadLen ) + if ( sizeof( U32 ) == message->hdr.payloadLen ) { - signalInitiateStandbyDisinfectSubmode(); + memcpy( &cmd, &message->payload[0], sizeof( U32 ) ); + signalInitiateStandbyDisinfectSubmode( cmd ); } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); + else + { + handleSetHDStandbyDisinfectSubmodeResponse( FALSE, REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT ); + } } /*********************************************************************//** @@ -1423,7 +1424,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; @@ -1432,9 +1433,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 ); @@ -1568,23 +1569,20 @@ * @details Inputs: none * @details Outputs: DG start/stop trimmer heater command msg constructed and queued. * @param start TRUE indicates start heater, FALSE indicates stop heater - * @param trimmerHtrTemp target temperature for trimmer heater * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendDGStartStopTrimmerHeaterCommand( BOOL start, F32 trimmerHtrTemp ) +BOOL sendDGStartStopTrimmerHeaterCommand( BOOL start ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // Create a message record blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD; - msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( F32 ); + msg.hdr.msgID = MSG_ID_HD_START_STOP_TRIMMER_HEATER_CMD; + msg.hdr.payloadLen = sizeof( BOOL ); memcpy( payloadPtr, &start, sizeof( BOOL ) ); - payloadPtr += sizeof( BOOL ); - memcpy( payloadPtr, &trimmerHtrTemp, sizeof( F32 ) ); // 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 ); @@ -2002,27 +2000,6 @@ } -#ifdef EMC_TEST_BUILD -BOOL broadcastCANErrorCount( U32 count ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // Create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_CAN_ERROR_COUNT; - msg.hdr.payloadLen = sizeof( U32 ); - - memcpy( payloadPtr, &count, sizeof( U32 ) ); - - // 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_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} -#endif - // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** @@ -2219,7 +2196,7 @@ memcpy( payloadPtr, &passed, sizeof( BOOL ) ); // 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_BROADCAST, ACK_NOT_REQUIRED ); // TODO - make ack required when UI ready + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_REQUIRED ); return result; } @@ -2250,6 +2227,32 @@ /*********************************************************************//** * @brief + * The sendUIRequestPOSTFinalResult function constructs a reqeust for UI POST + * final result message and queues the msg for transmit on the appropriate + * CAN channel. + * @details Inputs: none + * @details Outputs: request for UI POST final result msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendUIRequestPOSTFinalResult( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_UI_FINAL_POST_RESULT; + 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_UI, ACK_REQUIRED ); + + return result; + +} + +/*********************************************************************//** + * @brief * The handleUIPOSTFinalResult function handles a UI POST final result message. * @details Inputs: none * @details Outputs: UI POST final result delivered to InitPOST mode. @@ -2264,8 +2267,7 @@ BOOL passed; memcpy( &passed, payloadPtr, sizeof( BOOL ) ); - - // TODO - handle UI POST final result + signalUIPOSTFinalResult( passed ); } else { @@ -2304,17 +2306,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 @@ -2329,10 +2350,8 @@ TEMPERATURE_SENSORS_DATA_T payload; memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); - setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); + setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant, payload.heatDisinfect ); } - // TODO - what to do if invalid payload length? - // TODO - how to know if DG stops sending these? } /*********************************************************************//** @@ -2346,12 +2365,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 ); } } @@ -2637,111 +2656,111 @@ return result; } -/*********************************************************************//** - * @brief - * The handleChangeUFSettingsRequest function handles a ultrafiltration - * change settings request message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeUFSettingsRequest( MESSAGE_T *message ) -{ - if ( message->hdr.payloadLen == sizeof(F32) ) - { - F32 uFVolume; - - memcpy( &uFVolume, message->payload, sizeof(F32) ); - - verifyUFSettingsChange( uFVolume ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } -} - -/*********************************************************************//** - * @brief - * The handleChangeUFSettingsConfirmation function handles a ultrafiltration - * change setting confirmation message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeUFSettingsConfirmation( MESSAGE_T *message ) -{ - if ( message->hdr.payloadLen == sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ) - { - UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T payload; - - memcpy( &payload, message->payload, sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ); - - verifyUFSettingsConfirmation( payload.volume_mL, payload.adjustType ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } -} - -/*********************************************************************//** - * @brief - * The handleChangeTreatmentDurationRequest function handles a treatment - * duration setting change message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeTreatmentDurationRequest( MESSAGE_T *message ) -{ - if ( message->hdr.payloadLen == sizeof(U32) ) - { +/*********************************************************************//** + * @brief + * The handleChangeUFSettingsRequest function handles a ultrafiltration + * change settings request message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeUFSettingsRequest( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(F32) ) + { + F32 uFVolume; + + memcpy( &uFVolume, message->payload, sizeof(F32) ); + + verifyUFSettingsChange( uFVolume ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The handleChangeUFSettingsConfirmation function handles a ultrafiltration + * change setting confirmation message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeUFSettingsConfirmation( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ) + { + UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T payload; + + memcpy( &payload, message->payload, sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ); + + verifyUFSettingsConfirmation( payload.volume_mL, payload.adjustType ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The handleChangeTreatmentDurationRequest function handles a treatment + * duration setting change message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeTreatmentDurationRequest( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(U32) ) + { U32 timeInMin; - - memcpy( &timeInMin, message->payload, sizeof(U32) ); - verifyTreatmentDurationSettingChange( timeInMin ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } -} -/*********************************************************************//** - * @brief - * The handleChangeBloodDialysateRateChangeRequest function handles a blood - * and dialysate rate settings change message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeBloodDialysateRateChangeRequest( MESSAGE_T *message ) -{ - U32 expPayloadSize = sizeof(U32) + sizeof(U32); - - if ( expPayloadSize == message->hdr.payloadLen ) - { - U32 bloodRate; - U32 dialRate; - - memcpy( &bloodRate, &message->payload[0], sizeof(U32) ); - memcpy( &dialRate, &message->payload[sizeof(U32)], sizeof(U32) ); - - verifyBloodAndDialysateRateSettingsChange( bloodRate, dialRate ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } + memcpy( &timeInMin, message->payload, sizeof(U32) ); + verifyTreatmentDurationSettingChange( timeInMin ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } } /*********************************************************************//** * @brief + * The handleChangeBloodDialysateRateChangeRequest function handles a blood + * and dialysate rate settings change message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeBloodDialysateRateChangeRequest( MESSAGE_T *message ) +{ + U32 expPayloadSize = sizeof(U32) + sizeof(U32); + + if ( expPayloadSize == message->hdr.payloadLen ) + { + U32 bloodRate; + U32 dialRate; + + memcpy( &bloodRate, &message->payload[0], sizeof(U32) ); + memcpy( &dialRate, &message->payload[sizeof(U32)], sizeof(U32) ); + + verifyBloodAndDialysateRateSettingsChange( bloodRate, dialRate ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief * The handleChangePressureLimitsRequest function handles a pressure limits * change message from the UI. * @details Inputs: none @@ -3065,6 +3084,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 @@ -3078,11 +3102,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 ) ); } @@ -3093,6 +3112,30 @@ /*********************************************************************//** * @brief + * The sendFWVersionRequest function constructs a firmware version request + * message and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Firmware version request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendFWVersionRequest( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_REQUEST_FW_VERSIONS; + msg.hdr.payloadLen = sizeof( UI_VERSIONS_T ); // usually UI sends this request w/ UI version info - we will leave that blank + + // 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 handleUIVersionResponse function handles a response to request for * UI version information. * @details Inputs: none @@ -3182,22 +3225,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.lastServiceEpochDate, 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 @@ -3232,7 +3280,72 @@ 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 ) +{ + 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, FALSE ); +} + +/*********************************************************************//** + * @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 *************************************************************************/ @@ -3589,14 +3702,14 @@ /*********************************************************************//** * @brief - * The handleHDSetArterialPressureOffsetRequest function handles a request to - * set the arterial pressure offset. + * The handleHDDialInPumpRotorCountOverrideRequest function handles a request to + * override the dialysate inlet pump rotor count. * @details Inputs: none * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ -void handleHDSetArterialPressureOffsetRequest( MESSAGE_T *message ) +void handleHDDialInPumpRotorCountOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; BOOL result = FALSE; @@ -3607,11 +3720,11 @@ memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); if ( FALSE == payload.reset ) { - result = testSetArterialPressureOffsetOverride( payload.state.f32 ); + result = testSetDialysateInPumpRotorCountOverride( payload.state.u32 ); } else { - result = testResetArterialPressureOffsetOverride(); + result = testResetDialysateInPumpRotorCountOverride(); } } @@ -5158,7 +5271,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 { @@ -6394,15 +6507,11 @@ BOOL result = FALSE; // Verify payload length - if ( sizeof( F32 ) == message->hdr.payloadLen ) + if ( 0 == message->hdr.payloadLen ) { if ( TRUE == isTestingActivated() ) { - F32 dacVRef; - - result = TRUE; - memcpy( &dacVRef, message->payload, sizeof( F32 ) ); - setSyringePumpDACVref( dacVRef ); + result = setSyringePumpDACVref(); } } @@ -7020,6 +7129,45 @@ } /*********************************************************************//** + * @brief + * The sendHDUsageRecord function sends out the HD service record. + * @details Inputs: none + * @details Outputs: HD system record msg constructed and queued + * @param payloadCurrNum: current payload number + * @param payloadTotalNum: total number of payloads + * @param length: buffer length to be written + * @param srvcRcrdAddress: start address of the usage record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendHDUsageRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* sysRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SEND_USAGE_INFO_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, sysRcrdAddress, length ); + + // 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_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** * @brief * The handleUIServiceModeRequest function handles a request to enter service * mode. @@ -7032,15 +7180,25 @@ { BOOL status = FALSE; HD_OP_MODE_T currentMode = getCurrentOperationMode(); + DG_OP_MODE_T currentDGMode = getDGOpMode(); REQUEST_REJECT_REASON_CODE_T reject; if ( 0 == message->hdr.payloadLen ) { if ( ( MODE_STAN == currentMode ) || ( MODE_FAUL == currentMode ) ) { - status = TRUE; requestNewOperationMode( MODE_SERV ); - reject = REQUEST_REJECT_REASON_NONE; + + if ( ( DG_MODE_STAN == currentDGMode ) || ( DG_MODE_FAUL == currentDGMode ) ) + { + status = TRUE; + cmdSetDGToServiceMode(); + reject = REQUEST_REJECT_REASON_NONE; + } + else + { + reject = REQUEST_REJECT_REASON_DG_NOT_IN_STANDBY_IDLE_STATE; + } } else { @@ -7086,6 +7244,141 @@ } /*********************************************************************//** + * @brief + * The sendRequestForDGResendAlarms function sends out the HD request for + * DG re-send all active alarms. + * @details Inputs: none + * @details Outputs: DG alarms re-send request msg constructed and queued + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendRequestForDGResendAlarms( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_ALARMS; + 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 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( DG_SERVICE_RECORD_T ) ) + { + DG_SERVICE_RECORD_T payload; + + memcpy( &payload, message->payload, sizeof( 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( DG_USAGE_INFO_RECORD_T ) ) + { + DG_USAGE_INFO_RECORD_T payload; + + memcpy( &payload, message->payload, sizeof( DG_USAGE_INFO_RECORD_T ) ); + setHDVersionDGUsageInfo( &payload ); + } +} + +/*********************************************************************//** + * @brief + * The handleSetHDServiceTime function sets the HD service time once the + * command is received from UI + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetHDServiceTime( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( 0 == message->hdr.payloadLen ) + { + result = setServiceTime(); + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); +} + +/*********************************************************************//** * @brief * The handleGetHDUsageInfoRecord function handles a request to get the HD * usage information record. @@ -7241,15 +7534,16 @@ /*********************************************************************//** * @brief - * The handleSendBloodLeakEmbeddedModeCommandResponse function sends out + * The sendBloodLeakEmbeddedModeCommandResponse function sends out * the blood leak embedded mode command response. * @details Inputs: none * @details Outputs: blood leak embedded mode command response msg constructed and queued + * @param cmd: the command its response is being sent * @param responseLen: the length of the buffer * @param response: pointer to the response buffer * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL handleSendBloodLeakEmbeddedModeCommandResponse( U32 responseLen, U08* response ) +BOOL sendBloodLeakEmbeddedModeCommandResponse( U08 cmd, U32 responseLen, U08* response ) { BOOL result; MESSAGE_T msg; @@ -7258,8 +7552,10 @@ // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_SEND_BLOOD_LEAK_EMB_MODE_RESPONSE; - msg.hdr.payloadLen = sizeof( U32 ) + responseLen; + msg.hdr.payloadLen = sizeof( U08 ) + sizeof( U32 ) + responseLen; + memcpy( payloadPtr, &cmd, sizeof( U08 ) ); + payloadPtr += sizeof( U08 ); memcpy( payloadPtr, &responseLen, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, response, responseLen ); @@ -7270,4 +7566,217 @@ return result; } +/*********************************************************************//** +* @brief +* The handleResendAllAlarmsCommand function handles a request to re-send +* all active HD alarms. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleResendAllAlarmsCommand( MESSAGE_T* message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + handleResendActiveAlarmsRequest(); + result = TRUE; + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The sendDGServiceModeRequest function constructs a service mode request msg + * to the DG and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG Service mode request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGServiceModeRequest() +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_SERVICE_MODE; + 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 handleTestBloodPumpSetPWM function handles a request to override +* the Blood pumps duty cycle. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleTestBloodPumpSetPWM( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( F32 ) ); + + result = testSetBloodPumpTargetDutyCycle( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleTestDialInSetPWM function handles a request to override +* the Dialysate Inlet pumps duty cycle. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleTestDialInSetPWM( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( F32 ) ); + + result = testSetDialInPumpTargetDutyCycle( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleTestDialOutSetPWM function handles a request to override +* the Dialysate Outlet pumps duty cycle. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleTestDialOutSetPWM( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( F32 ) ); + + result = testSetDialOutPumpTargetDutyCycle( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleTestHDNVRecordCRCOverride function handles a request to override +* the selected NV record's CRC. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleTestHDNVRecordCRCOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); + result = testSetNVRecordCRCOverride( payload.index, (U16)payload.state.u32 ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleAirPumpIntervalOverrideRequest function handles a request to override +* the air pump's broadcast interval. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleAirPumpIntervalOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetAirPumpDataPublishIntervalOverride( (U32)( payload.state.u32 ) ); + } + else + { + result = testResetAirPumpDataPublishIntervalOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleAirPumpSetState function handles a request to set the +* air pump state. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleAirPumpSetState( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( U32 ) == message->hdr.payloadLen ) + { + U32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( U32 ) ); + + result = testSetAirPump( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/