Index: firmware/App/HDCommon.h =================================================================== diff -u -rf9a866abfc44db38c01cb795fea894cce1042eec -re8053e6bdafd0638102e01c4250dfd74c0850ba1 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision f9a866abfc44db38c01cb795fea894cce1042eec) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision e8053e6bdafd0638102e01c4250dfd74c0850ba1) @@ -25,7 +25,7 @@ #define HD_VERSION_MAJOR 0 #define HD_VERSION_MINOR 6 #define HD_VERSION_MICRO 0 -#define HD_VERSION_BUILD 56 +#define HD_VERSION_BUILD 58 // ********** development build switches ********** Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r402885eda2ed755a079c854d1228ac5f76cbec7c -re8053e6bdafd0638102e01c4250dfd74c0850ba1 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 402885eda2ed755a079c854d1228ac5f76cbec7c) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision e8053e6bdafd0638102e01c4250dfd74c0850ba1) @@ -7,8 +7,8 @@ * * @file ModeStandby.c * -* @author (last) Dara Navaei -* @date (last) 22-Sep-2022 +* @author (last) Darren Cox +* @date (last) 12-Oct-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -57,6 +57,7 @@ static BOOL flushStartReqReceived; ///< Flag indicates user has requested initiation of flush mode. static BOOL heatDisinfectStartReqReceived; ///< Flag indicates user has requested initiation of heat disinfect mode. static BOOL chemDisinfectStartReqReceived; ///< Flag indicates user has requested initiation of chemical disinfect mode. +static GENERIC_CONFIRM_ID_T disinfectCancelReqID; ///< ID of requested cancel disinfect mode. static DG_DISINFECT_STATE_T dgDisinfectState; ///< DG disinfect state to be boadcast to UI. static U32 dataPublishCounter = 0; ///< Disinfects data publish counter. @@ -67,6 +68,8 @@ // ********** private function prototypes ********** +static void handleDisinfectCancel( BOOL stop ); + static HD_STANDBY_STATE_T handleStandbyModeStartState( void ); static HD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ); static HD_STANDBY_STATE_T handleStandbyModeWaitForDisinfectState( void ); @@ -104,6 +107,7 @@ dataPublishCounter = 0; heatDisinfectStartReqReceived = FALSE; chemDisinfectStartReqReceived = FALSE; + disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; } @@ -168,6 +172,8 @@ { BOOL stop = isStopButtonPressed(); + handleDisinfectCancel( stop ); + #ifndef RUN_WITHOUT_DG // State machine to get DG to prep a reservoir so we can start a treatment switch ( currentStandbyState ) @@ -491,6 +497,87 @@ /*********************************************************************//** * @brief + * The handleDisinfectCancel function handles + * DG disinfect cancel UI interaction. + * @details Inputs: none + * @details Outputs: none + * @param stop button status + * @return none + *************************************************************************/ +static void handleDisinfectCancel( BOOL stop ) +{ + CONFIRMATION_REQUEST_STATUS_T confirm_status; + GENERIC_CONFIRM_ID_T confirm_id; + + if ( ( STANDBY_DG_FLUSH_IN_PROGRESS_STATE == currentStandbyState ) || + ( STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE == currentStandbyState ) || + ( STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE == currentStandbyState ) ) + { + if ( ( TRUE == stop ) && ( GENERIC_CONFIRM_ID_NONE == disinfectCancelReqID ) ) + { + if ( STANDBY_DG_FLUSH_IN_PROGRESS_STATE == currentStandbyState ) + { + confirm_id = GENERIC_CONFIRM_ID_DISINFECT_STOP_WATERFLUSH; + } + else if ( STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE == currentStandbyState ) + { + confirm_id = GENERIC_CONFIRM_ID_DISINFECT_STOP_HEAT; + } + else if ( STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE == currentStandbyState ) + { + confirm_id = GENERIC_CONFIRM_ID_DISINFECT_STOP_CHEMICAL; + } + // Send message to UI to indicate user request to cancel disinfect + disinfectCancelReqID = addConfirmationRequest( confirm_id, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0 ); + } + else if ( GENERIC_CONFIRM_ID_NONE != disinfectCancelReqID ) + { + // Get the confirmation request. It consumes the request if completed and responds to UI. + confirm_status = getConfirmationRequestStatus( disinfectCancelReqID ); + switch ( confirm_status ) + { + case CONFIRMATION_REQUEST_STATUS_ACCEPTED : + // Clear request active status + disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; + + switch ( currentStandbyState ) + { + case STANDBY_DG_FLUSH_IN_PROGRESS_STATE: + cmdStopDGFlush(); + break; + + case STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE: + cmdStopDGHeatDisinfect(); + break; + + case STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE: + cmdStopDGChemicalDisinfect(); + break; + + default: + // UI Confirm already closed. Nothing to do. + break; + } + break; + + case CONFIRMATION_REQUEST_STATUS_TIMEOUT : + case CONFIRMATION_REQUEST_STATUS_REJECTED : + // Clear request active status + disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; + break; + + case CONFIRMATION_REQUEST_STATUS_PENDING: + case CONFIRMATION_REQUEST_STATUS_UNUSED: + default : + // Nothing to do + break; + } + } + } +} + +/*********************************************************************//** + * @brief * The handleStandbyModeStartState function handles the standby start state. * This state waits for the door to be closed and then initiates homing of * pumps and valves and transitions to the wait for treatment state. Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -r402885eda2ed755a079c854d1228ac5f76cbec7c -re8053e6bdafd0638102e01c4250dfd74c0850ba1 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 402885eda2ed755a079c854d1228ac5f76cbec7c) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision e8053e6bdafd0638102e01c4250dfd74c0850ba1) @@ -7,8 +7,8 @@ * * @file OperationModes.c * -* @author (last) Dara Navaei -* @date (last) 22-Sep-2022 +* @author (last) Darren Cox +* @date (last) 12-Oct-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -38,11 +38,22 @@ * @{ */ -// ********** private data ********** +// ********** private definitions ********** #define BROADCAST_HD_OP_MODE_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< HD operation mode broadcast interval (in task interval/sec). #define DATA_PUBLISH_COUNTER_START_COUNT 11 ///< Data publish counter start count. +#define NUM_CONFIRM_REQUESTS 4 ///< Number of available confirmation requests. +#define CONFIRMATION_REQUEST_TIMEOUT_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Confirmation response timeout in ms +/// Structure for confirmation request. +typedef struct +{ + GENERIC_CONFIRM_ID_T requestID; ///< Request ID + GENERIC_CONFIRM_COMMAND_T requestType; ///< Request Type + U32 timeStamp; ///< Timestamp for request + CONFIRMATION_REQUEST_STATUS_T status; ///< Request status (pending, accepted, rejected) +} CONFIRMATION_REQUEST_T; + // ********** private data ********** static volatile BOOL modeRequest[ NUM_OF_MODES - 1 ]; ///< Pending operation mode change requests. @@ -53,6 +64,12 @@ /// Interval (in task intervals) at which to publish operation mode data to CAN bus. static OVERRIDE_U32_T opModePublishInterval = { BROADCAST_HD_OP_MODE_INTERVAL, BROADCAST_HD_OP_MODE_INTERVAL, BROADCAST_HD_OP_MODE_INTERVAL, 0 }; static U32 priorSubMode = 0; ///< The prior submode state. +/// Local structure init for saving confirmation requests +static CONFIRMATION_REQUEST_T confirmRequests[NUM_CONFIRM_REQUESTS] = + { GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, }; /// This matrix determines legal transitions from one mode to another static const HD_OP_MODE_T MODE_TRANSITION_TABLE[ NUM_OF_MODES - 1 ][ NUM_OF_MODES - 1 ] = { @@ -71,6 +88,7 @@ static HD_OP_MODE_T arbitrateModeRequest( void ); static void transitionToNewOperationMode( HD_OP_MODE_T newMode ); static void broadcastOperationMode( void ); +static void updateConfirmationRequestTimeouts( void ); /*********************************************************************//** * @brief @@ -200,6 +218,8 @@ } priorSubMode = currentSubMode; + updateConfirmationRequestTimeouts( ); + // Broadcast current operation mode on interval broadcastOperationMode(); } @@ -415,7 +435,154 @@ } } +/*********************************************************************//** + * @brief + * The updateConfirmationRequestTimeouts function checks the status of + * all active confirmation requests and updates the timeout. + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] status updated if timeout. + * @param none + * @return none + *************************************************************************/ +void updateConfirmationRequestTimeouts( void ) +{ + U08 i; + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( CONFIRMATION_REQUEST_STATUS_PENDING == confirmRequests[ i ].status ) + { + if ( TRUE == didTimeout( confirmRequests[ i ].timeStamp, CONFIRMATION_REQUEST_TIMEOUT_MS ) ) + { + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_TIMEOUT; + } + } + } +} + +/*********************************************************************//** + * @brief + * The getConfirmationRequestStatus function returns the status of a confirmation request + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] cleared if completed. + * @param request ID + * @return CONFIRMATION_REQUEST_STATUS_T + *************************************************************************/ +CONFIRMATION_REQUEST_STATUS_T getConfirmationRequestStatus( GENERIC_CONFIRM_ID_T request_id ) +{ + U08 i; + CONFIRMATION_REQUEST_STATUS_T status = CONFIRMATION_REQUEST_STATUS_PENDING; + BOOL pending = FALSE; + U08 pending_index = 0; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].requestID == request_id ) + { + status = confirmRequests[ i ].status; + if ( CONFIRMATION_REQUEST_STATUS_PENDING != status) + { + // Send UI clear + if ( CONFIRMATION_REQUEST_STATUS_TIMEOUT == confirmRequests[ i ].status ) + { + sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_TIMEOUT_CLOSE, 0 ); + } + else + { + sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_ACCEPT_CLOSE, 0 ); + } + + // Clear the confirmation request, it is done and consumed + confirmRequests[ i ].requestID = GENERIC_CONFIRM_ID_NONE; + confirmRequests[ i ].requestType = GENERIC_CONFIRM_CMD_REQUEST_OPEN; + confirmRequests[ i ].timeStamp = 0; + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_UNUSED; + } + } + else if ( CONFIRMATION_REQUEST_STATUS_PENDING == confirmRequests[ i ].status ) + { + if ( TRUE == pending ) + { + // Is this newer than other pending request? + if ( confirmRequests[ i ].timeStamp > confirmRequests[ pending_index ].timeStamp ) + { + pending_index = i; + pending = TRUE; + } + } + else + { + pending_index = i; + pending = TRUE; + } + } + } + if ( ( CONFIRMATION_REQUEST_STATUS_PENDING != status ) && ( TRUE == pending ) ) + { + // Last confirmation cleared, pending request must be resent to UI + sendConfirmationRequest( confirmRequests[ pending_index ].requestID, confirmRequests[ pending_index ].requestType, 0 ); + } + + return status; +} + +/*********************************************************************//** + * @brief + * The setConfirmationRequestStatus function sets the status of a confirmation request + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] status. + * @param request ID + * @param new status + * @return CONFIRMATION_REQUEST_STATUS_T + *************************************************************************/ +void setConfirmationRequestStatus( GENERIC_CONFIRM_ID_T request_id, CONFIRMATION_REQUEST_STATUS_T status ) +{ + U08 i; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].requestID == request_id ) + { + confirmRequests[ i ].status = status; + break; + } + } +} + +/*********************************************************************//** + * @brief + * The addConfirmationRequest function sends a confirmation request to UI + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] new added. + * @param request_id - confirm id / type + * @param request_type - confirm command + * @return request ID - will be non-zero if added + *************************************************************************/ +GENERIC_CONFIRM_ID_T addConfirmationRequest( GENERIC_CONFIRM_ID_T request_id, GENERIC_CONFIRM_COMMAND_T request_type, U32 reject_reason ) +{ + U08 i; + GENERIC_CONFIRM_ID_T new_id = GENERIC_CONFIRM_ID_NONE; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].status == CONFIRMATION_REQUEST_STATUS_UNUSED ) + { + // Save the confirmation request info + confirmRequests[ i ].requestID = request_id; + confirmRequests[ i ].requestType = request_type; + confirmRequests[ i ].timeStamp = getMSTimerCount(); + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_PENDING; + new_id = request_id; + sendConfirmationRequest( request_id, request_type, reject_reason ); + + break; + } + } + + return new_id; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r5c7b301b677c60519a9d89f4624c6020958de752 -re8053e6bdafd0638102e01c4250dfd74c0850ba1 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 5c7b301b677c60519a9d89f4624c6020958de752) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e8053e6bdafd0638102e01c4250dfd74c0850ba1) @@ -7,8 +7,8 @@ * * @file SystemComm.c * -* @author (last) Michael Garthwaite -* @date (last) 12-Oct-2022 +* @author (last) Dara Navaei +* @date (last) 18-Oct-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -1159,6 +1159,10 @@ handleDGUsageInfoData( message ); break; + case MSG_ID_UI_CONFIRMATION_RESULT: + handleUIConfirmationResponse( message ); + break; + // NOTE: this always must be the last case case MSG_ID_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); @@ -1436,7 +1440,7 @@ handleTestSwitchesPublishIntervalOverrideRequest( message ); break; - case MSG_ID_HD_BATTERY_REMAINING_PERCENT_OVERRIDE: + case MSG_ID_HD_BATTERY_REMAINING_CAP_MWH_OVERRIDE: handleBatteryRemainingPercentOverrideRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r742d2fb15db80b1458b64704d499a790b0cf7989 -re8053e6bdafd0638102e01c4250dfd74c0850ba1 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 742d2fb15db80b1458b64704d499a790b0cf7989) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision e8053e6bdafd0638102e01c4250dfd74c0850ba1) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.c * -* @author (last) Michael Garthwaite -* @date (last) 12-Oct-2022 +* @author (last) Dara Navaei +* @date (last) 18-Oct-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" @@ -3260,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 *************************************************************************/ @@ -5154,7 +5221,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 { Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r5c7b301b677c60519a9d89f4624c6020958de752 -re8053e6bdafd0638102e01c4250dfd74c0850ba1 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 5c7b301b677c60519a9d89f4624c6020958de752) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision e8053e6bdafd0638102e01c4250dfd74c0850ba1) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.h * -* @author (last) Michael Garthwaite -* @date (last) 28-Sep-2022 +* @author (last) Dara Navaei +* @date (last) 18-Oct-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 @@ -434,7 +431,15 @@ // 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 );