Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rd4f40c48a728c866c24bf44a59ff8ddd1e244ca1 -r76fc4506fd38ea6bd317abbaaf85db5aa589a7cc --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision d4f40c48a728c866c24bf44a59ff8ddd1e244ca1) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 76fc4506fd38ea6bd317abbaaf85db5aa589a7cc) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.c * -* @author (last) Dara Navaei -* @date (last) 26-Apr-2023 +* @author (last) Sean Nash +* @date (last) 24-Aug-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -28,14 +28,17 @@ #include "FlowSensors.h" #include "FPGA.h" #include "Heaters.h" +#include "Integrity.h" #include "ModeChemicalDisinfect.h" #include "ModeChemicalDisinfectFlush.h" +#include "ModeDrain.h" #include "ModeFill.h" #include "ModeFlush.h" #include "ModeGenIdle.h" #include "ModeHeatDisinfect.h" #include "ModeHeatDisinfectActiveCool.h" #include "ModeInitPOST.h" +#include "ModeROPermeateSample.h" #include "ModeStandby.h" #include "MsgQueues.h" #include "NVDataMgmt.h" @@ -67,8 +70,22 @@ /// Payload record structure for block message transmission request. typedef struct { - U16 blockedMessages[ MAX_MSGS_BLOCKED_FOR_XMIT ]; + U16 blockedMessages[ MAX_MSGS_BLOCKED_FOR_XMIT ]; ///< Blocked messages array. } BLOCKED_MSGS_DATA_T; + +/// Load cells override payload structure +typedef struct +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T ovRecord; ///< Test override array payload. + BOOL flag; ///< Flag. +} LC_OVERRIDE_PAYLOAD_T; + +/// Flow Sensor override payload structure +typedef struct +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T ovRecord; ///< Test override array payload. + BOOL flag; ///< Flag. +} FS_OVERRIDE_PAYLOAD_T; #pragma pack(pop) // ********** private data ********** @@ -324,7 +341,7 @@ // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_ALARM_TRIGGERED; - msg.hdr.payloadLen = sizeof( U32 ) * 5; + msg.hdr.payloadLen = sizeof( U32 ) * 8; memcpy( payloadPtr, &alarm, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); @@ -439,6 +456,9 @@ *************************************************************************/ void handleRTCSyncFromHD( MESSAGE_T *message ) { + // TODO - remove the code below until the issue for the synchronization + // of the DG RTC to the HD RTC is resolved. +/* // Only sync RTC to HD date/time when ... if ( TRUE == syncDG2HDDateTime() ) { @@ -450,6 +470,7 @@ setRTCEpoch( epoch.epochTime ); } } +*/ } /*********************************************************************//** @@ -574,14 +595,14 @@ /*********************************************************************//** * @brief - * The handleDGServiceScheduleRequest function handles a request for DG - * service information. + * The handleDGServiceScheduleRequestToUI function handles a request for DG + * service information to UI. * @details Inputs: none * @details Outputs: message handled, response constructed and queued for * transmit. * @return none *************************************************************************/ -void handleDGServiceScheduleRequest( MESSAGE_T *message ) +void handleDGServiceScheduleRequestToUI( MESSAGE_T *message ) { MESSAGE_T msg; DG_SERVICE_RECORD_T service; @@ -593,19 +614,19 @@ // Create a message record blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_SERVICE_SCHEDULE_DATA; + msg.hdr.msgID = MSG_ID_DG_SERVICE_SCHEDULE_DATA_TO_UI; msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); if ( 0 == message->hdr.payloadLen ) { - // Fill message payload memcpy( payloadPtr, &service.lastServiceEpochDate, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); + service.serviceIntervalSeconds = ( 0 == service.lastServiceEpochDate ? 0 : service.serviceIntervalSeconds ); memcpy( payloadPtr, &service.serviceIntervalSeconds, 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_DG_2_HD, ACK_REQUIRED ); + serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_2_UI, ACK_REQUIRED ); } /*********************************************************************//** @@ -1099,13 +1120,38 @@ { result = requestDGStop(); } + else if ( ( DG_MODE_STAN == dgMode ) && ( FALSE == startingTreatment.start ) ) + { + result = signalAbortWaterSampling(); + } } sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); } /*********************************************************************//** * @brief + * The handleParkConecentratePumpsCmd function handles a DG concentrate pumps park + * command message from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleParkConecentratePumpsCmd( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == 0 ) + { + result = handleConcentratePumpParkRequest(); + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} + +/*********************************************************************//** + * @brief * The handleStartStopTrimmerHeaterCmd function handles a trimmer heater start/stop * command message from the HD. * @details Inputs: none @@ -1525,9 +1571,9 @@ U32 mode = 0; U32 subMode = 0; - memcpy( payloadPtr, &mode, sizeof( U32 ) ); + memcpy( &mode, payloadPtr, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, &subMode, sizeof( U32 ) ); + memcpy( &subMode, payloadPtr, sizeof( U32 ) ); setHDOperationMode( mode, subMode ); status = TRUE; @@ -1605,7 +1651,7 @@ } // 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_DG_2_HD, ACK_REQUIRED ); + serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_REQUIRED ); } /*********************************************************************//** @@ -1788,7 +1834,120 @@ serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_2_UI, ACK_REQUIRED ); } +/************************************************************************* + * @brief + * The handleStartStopDGROPermeateSample function handles a request to + * start or stop DG RO permeate sample mode. + * @details Inputs: none + * @details Outputs: message handled + * @param message: a pointer to the message to handle + * @return result + *************************************************************************/ +void handleStartStopDGROPermeateSample( MESSAGE_T* message ) +{ + BOOL status = FALSE; + if ( message->hdr.payloadLen == sizeof(U32) ) + { + BOOL startingDGROPermeateSample; + + memcpy( &startingDGROPermeateSample, message->payload, sizeof(U32) ); + + if ( TRUE == startingDGROPermeateSample ) + { + status = startDGROPermeateSample(); + } + else + { + status = stopDGROPermeateSample(); + } + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, status ); +} + +/*********************************************************************//** + * @brief + * The handleReceiveROPermeatSampleDispenseRequest function handles receiving + * the RO permeate sample dispense request + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleReceiveROPermeatSampleDispenseRequest( MESSAGE_T* message ) +{ + BOOL status = FALSE; + + if ( message->hdr.payloadLen == sizeof(U32) ) + { + U32 result; + + memcpy( &result, message->payload, sizeof(U32) ); + + setROPermeateSampleDispenseRequest( result ); + + status = TRUE; + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, status ); +} + +/*********************************************************************//** + * @brief + * The sendROPermeateSampleDispenseReadyToHD function handles sending + * RO permeate sample dispense ready to HD + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +void sendROPermeateSampleDispenseReadyToHD( void ) +{ + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_SEND_RO_PERMEATE_SAMPLE_DISPENSE_READY_TO_HD; + msg.hdr.payloadLen = 0; + + // 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_DG_2_HD, ACK_REQUIRED ); +} + +/*********************************************************************//** + * @brief + * The handleSendDGServiceRecordToHD function handles sending DG service + * record to HD upon request from HD + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSendDGServiceRecordToHD( MESSAGE_T* message ) +{ + MESSAGE_T msg; + DG_SERVICE_RECORD_T service; + U08 *payloadPtr = msg.payload; + + // Get the service record. There are no arrays of service to check and also, raise no alarm since the service record + // has been already checked in POST + getNVRecord2Driver( GET_SRV_RECORD, (U08*)&service, sizeof( DG_SERVICE_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_SEND_SERVICE_SCHEDULE_DATA_TO_HD; + msg.hdr.payloadLen = sizeof( DG_SERVICE_RECORD_T ); + + if ( 0 == message->hdr.payloadLen ) + { + memcpy( payloadPtr, &service, sizeof( DG_SERVICE_RECORD_T ) ); + } + + // 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_DG_2_HD, ACK_REQUIRED ); +} + + // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** @@ -1951,12 +2110,6 @@ *************************************************************************/ void handleTestLoadCellOverrideRequest( MESSAGE_T *message ) { - typedef struct - { - TEST_OVERRIDE_ARRAY_PAYLOAD_T ovRecord; - BOOL flag; - } LC_OVERRIDE_PAYLOAD_T; - LC_OVERRIDE_PAYLOAD_T payload; BOOL result = FALSE; @@ -2182,20 +2335,20 @@ *************************************************************************/ void handleTestMeasuredFlowOverrideRequest( MESSAGE_T *message ) { - TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + FS_OVERRIDE_PAYLOAD_T payload; BOOL result = FALSE; // verify payload length - if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) + if ( sizeof( FS_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) { - memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); - if ( FALSE == payload.reset ) + memcpy( &payload, message->payload, sizeof( FS_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.ovRecord.reset ) { - result = testSetMeasuredFlowRateOverride( payload.index, payload.state.f32 ); + result = testSetMeasuredFlowRateOverride( payload.ovRecord.index, payload.ovRecord.state.f32, payload.flag ); } else { - result = testResetMeasuredFlowRateOverride( payload.index ); + result = testResetMeasuredFlowRateOverride( payload.ovRecord.index ); } } @@ -3771,6 +3924,7 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +#ifndef _RELEASE_ /*********************************************************************//** * @brief * The handleGetDGSoftwareConfigRecord function handles a request to get the DG @@ -3833,6 +3987,7 @@ // Respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); } +#endif /*********************************************************************//** * @brief @@ -4638,16 +4793,10 @@ *************************************************************************/ void handleTestDGDialinCheckIn( MESSAGE_T* message ) { - BOOL status = FALSE; - if ( 0 == message->hdr.payloadLen ) { - status = TRUE; setDialinCheckInTimeStamp(); } - - // respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); } /*********************************************************************//** @@ -4737,4 +4886,181 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); } +/*********************************************************************//** + * @brief + * The handleTestDGSetRecoverFromFaultModeSignal function handles a request to + * set the signal to recover from the fault mode. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDGSetRecoverFromFaultModeSignal( MESSAGE_T* message ) +{ + BOOL status = FALSE; + + if ( 0 == message->hdr.payloadLen ) + { + status = TRUE; + + setRecoverFromFaultModeSignal(); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** + * @brief + * The handleTestDGDrainModeBroadcastOverrideRequest function handles a request + * to override the drain mode state publish interval + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDGDrainModeBroadcastOverrideRequest( 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 = testSetDrainModeDataPublishIntervalOverride( payload.state.u32 ); + } + else + { + result = testResetDrainModeDataPublishIntervalOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleDGROStatusRequest function handles a request + * to get the RO only mode + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGROStatusRequest( MESSAGE_T* message ) +{ + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + BOOL roMode = FALSE; + + if ( 0 == message->hdr.payloadLen ) + { + roMode = isROOnlyModeEnabled(); + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_INVALID_PAYLOAD_LENGTH; + } + sendUIResponseMsg( MSG_ID_DG_RO_ONLY_MODE_STATUS_RESPONSE, roMode, rejReason ); +} + +/*********************************************************************//** + * @brief + * The handleTestHDRAMStatusOverrideRequest function handles a request to + * override the RAM status register. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDGRAMStatusOverrideRequest( 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) ); + if ( FALSE == payload.reset ) + { + result = testSetRAMStatusOverride( payload.index, payload.state.u32 ); + } + else + { + result = testResetRAMStatusOverride( payload.index ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestDGPendingACKOverrideRequest function handles a + * request to override pending ACKs. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDGPendingACKOverrideRequest( 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 = testSetPendingACKOverride( payload.state.u32 ); + } + else + { + result = testResetPendingACKOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestDGReservoirOverrideRequest function handles a request + * to override the reservoir publish interval + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDGReservoirOverrideRequest( 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 = testSetReservoirDataPublishIntervalOverride( payload.state.u32 ); + } + else + { + result = testResetReservoirDataPublishIntervalOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/