Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -r9edf2e3e949892479c72dacb1248dc75a3313b97 -r5f1b50a1d9a7bd6ea17bb666e28ccfeafe56432c --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 9edf2e3e949892479c72dacb1248dc75a3313b97) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 5f1b50a1d9a7bd6ea17bb666e28ccfeafe56432c) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-2026 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 OperationModes.c * -* @author (last) Vinayakam Mani -* @date (last) 06-Aug-2024 +* @author (last) Dara Navaei +* @date (last) 03-May-2026 * * @author (original) Vinayakam Mani -* @date (original) 06-Aug-2024 +* @date (original) 07-Aug-2024 * ***************************************************************************/ @@ -22,6 +22,7 @@ #include "ModePostGenDialysate.h" #include "ModeService.h" #include "ModeStandby.h" +#include "ModeUpdate.h" #include "MessageSupport.h" #include "Messaging.h" #include "OperationModes.h" @@ -50,21 +51,24 @@ static OVERRIDE_U32_T ddOpModePublishInterval = { BROADCAST_DD_OP_MODE_INTERVAL, BROADCAST_DD_OP_MODE_INTERVAL, 0, 0 }; static U32 dataPublishCounter; ///< Interval counter used to determine when to broadcast operation mode. Initialize to 11 to stagger broadcast. static U32 currentSubState; ///< The currently active sub state. +static U32 testRequestedSubMode; ///< Requested operation sub mode from dialin. +static BOOL testChangeSubMode; ///< Flag to determine change operation sub mode request status. /// This matrix determines legal transitions from one mode to another. static const DD_OP_MODE_T MODE_TRANSITION_TABLE[ NUM_OF_DD_MODES - 1 ][ NUM_OF_DD_MODES - 1 ] = { - // from to-> FAULT SERVICE INIT STANBY PREG GEND POSG HEAT HCOL ROPS - /* FAUL */{ DD_MODE_FAUL, DD_MODE_SERV, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG }, - /* SERV */{ DD_MODE_NLEG, DD_MODE_SERV, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG }, - /* INIT */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_INIT, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG }, - /* STAN */{ DD_MODE_FAUL, DD_MODE_SERV, DD_MODE_INIT, DD_MODE_STAN, DD_MODE_PREG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_HEAT, DD_MODE_HCOL, DD_MODE_ROPS }, - /* PREG */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_PREG, DD_MODE_GEND, DD_MODE_POSG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG }, - /* GEND */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_GEND, DD_MODE_POSG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG }, - /* POSG */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_POSG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG }, - /* HEAT */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_HEAT, DD_MODE_HCOL, DD_MODE_NLEG }, - /* HCOL */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_HCOL, DD_MODE_NLEG }, - /* ROPS */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_ROPS }, + // from to-> FAULT SERVICE INIT STANBY PREG GEND POSG HEAT HCOL ROPS UPDATE + /* FAUL */{ DD_MODE_FAUL, DD_MODE_SERV, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_UPDT}, + /* SERV */{ DD_MODE_NLEG, DD_MODE_SERV, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_UPDT}, + /* INIT */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_INIT, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_UPDT}, + /* STAN */{ DD_MODE_FAUL, DD_MODE_SERV, DD_MODE_INIT, DD_MODE_STAN, DD_MODE_PREG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_HEAT, DD_MODE_HCOL, DD_MODE_ROPS, DD_MODE_UPDT}, + /* PREG */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_PREG, DD_MODE_GEND, DD_MODE_POSG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG}, + /* GEND */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_GEND, DD_MODE_POSG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG}, + /* POSG */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_POSG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG}, + /* HEAT */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_HEAT, DD_MODE_HCOL, DD_MODE_NLEG, DD_MODE_NLEG}, + /* HCOL */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_HCOL, DD_MODE_NLEG, DD_MODE_NLEG}, + /* ROPS */{ DD_MODE_FAUL, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_ROPS, DD_MODE_NLEG}, + /* UPDT */{ DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_STAN, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_NLEG, DD_MODE_UPDT}, }; // ********** private function prototypes ********** @@ -74,6 +78,8 @@ static U32 getDDOpModePublishInterval( void ); static void broadcastOperationMode( void ); static void sendOperationStatusEvent( void ); +static void testRequestNewDDOperationSubMode( void ); +static BOOL testValidateDDSubModeChangeRequest( DD_OP_MODE_T reqMode, U32 reqSubMode ); /*********************************************************************//** * @brief @@ -98,6 +104,8 @@ currentSubMode = 0; currentSubState = NO_SUB_STATE; dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + testRequestedSubMode = 0; + testChangeSubMode = FALSE; transitionToNewOperationMode( DD_MODE_INIT ); @@ -106,6 +114,7 @@ initServiceMode(); initInitAndPOSTMode(); initStandbyMode(); + initUpdateMode(); initGenDialysateMode(); initPreGenDialysateMode(); initPostGenDialysateMode(); @@ -129,7 +138,7 @@ * and invalid operation mode encountered. * @return none *************************************************************************/ -void execOperationModes( void ) +void execDDOperationModes( void ) { DD_OP_MODE_T newMode; U32 priorSubMode = currentSubMode; @@ -164,6 +173,13 @@ sendOperationStatusEvent(); } + // Is DD sub mode change request active? + if ( TRUE == testChangeSubMode ) + { + testChangeSubMode = FALSE; + testRequestNewDDOperationSubMode(); + } + // mode specific processing to be done continuously switch ( currentMode ) { @@ -211,6 +227,10 @@ // currentSubMode = execROPermeateSampleMode(); // break; + case DD_MODE_UPDT: + currentSubMode = execUpdateMode(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_STATE, (U32)currentMode ) currentMode = DD_MODE_FAUL; @@ -393,6 +413,10 @@ // currentSubMode = transitionToROPermeateSampleMode(); // break; + case DD_MODE_UPDT: + currentSubMode = transitionToUpdateMode(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_TRANSITION_TO, (U32)newMode ) break; @@ -421,8 +445,8 @@ { OP_MODES_DATA_T data; - data.currentMode = (U32)currentMode; - data.currentSubMode = currentSubMode; + data.opMode = (U32)currentMode; + data.subMode = currentSubMode; broadcastData( MSG_ID_DD_OP_MODE_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( OP_MODES_DATA_T ) ); @@ -585,4 +609,152 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetOperationSubMode function will transition to a given operation + * sub mode if the transition is legal. + * @details \b Inputs: none + * @details \b Outputs: request new sub mode function called + * @param message a pointer to the message to handle which includes the + * override value for the new mode and sub mode change. + * @return TRUE if request successful, FALSE if not + *************************************************************************/ +BOOL testSetOperationSubMode( MESSAGE_T *message ) +{ + OP_MODES_DATA_T payload; + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + if( sizeof(OP_MODES_DATA_T) == message->hdr.payloadLen ) + { + DD_OP_MODE_T reqMode; + U32 reqSubMode; + + memcpy( (U08*)(&payload), message->payload, sizeof( OP_MODES_DATA_T ) ); + + reqMode = (DD_OP_MODE_T)payload.opMode; + reqSubMode = payload.subMode; + + if ( reqMode < NUM_OF_DD_MODES ) + { + // verify if the requested submode transition is valid + result = testValidateDDSubModeChangeRequest( reqMode, reqSubMode ); + + //send mode change request only if the requested sub mode transition is valid + if ( TRUE == result ) + { + if ( currentMode != reqMode ) + { + requestNewOperationMode( reqMode ); + testRequestedSubMode = reqSubMode; + testChangeSubMode = TRUE; + } + // requested sub mode change only as the requested operation mode is current mode + else if ( currentSubMode != reqSubMode ) + { + testRequestedSubMode = reqSubMode; + testChangeSubMode = TRUE; + } + } + + } + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testRequestNewDDOperationSubMode function requests transition to a new + * DD operation sub mode. + * @details \b Inputs: currentMode, testRequestedSubMode + * @details \b Outputs: none + * @return none + *************************************************************************/ +static void testRequestNewDDOperationSubMode( void ) +{ + switch ( currentMode ) + { + case DD_MODE_FAUL: + testSignalNewDDFaultSubMode( testRequestedSubMode ); + break; + + case DD_MODE_STAN: + testSignalNewDDStandbySubMode( testRequestedSubMode ); + break; + + case DD_MODE_PREG: + testSignalNewDDPreGenDialysateSubMode( testRequestedSubMode ); + break; + + case DD_MODE_GEND: + testSignalNewDDGenDialysateSubMode( testRequestedSubMode ); + break; + + case DD_MODE_POSG: + testSignalNewDDPostGenDialysateSubMode( testRequestedSubMode ); + break; + + // transition request is not supported yet. Update once the modes are implemented + case DD_MODE_SERV: + case DD_MODE_INIT: + case DD_MODE_HEAT: + case DD_MODE_HCOL: + case DD_MODE_ROPS: + default: + break; + } +} + +/*********************************************************************//** + * @brief + * The testValidateDDSubModeChangeRequest function validates transition + * request to a new DD operation sub mode. + * @details \b Inputs: none + * @details \b Outputs: none + * @param reqMode DD operation mode enumeration + * @param reqSubMode operation sub mode requested + * @return TRUE if request is legal, FALSE if not. + *************************************************************************/ +static BOOL testValidateDDSubModeChangeRequest( DD_OP_MODE_T reqMode, U32 reqSubMode ) +{ + BOOL result = FALSE; + + switch ( reqMode ) + { + case DD_MODE_FAUL: + result = testValidateDDFaultChangeReq( reqSubMode ); + break; + + case DD_MODE_STAN: + result = testValidateDDStandbyChangeReq( reqSubMode ); + break; + + case DD_MODE_PREG: + result = testValidateDDPreGenDialysateChangeReq( reqSubMode ); + break; + + case DD_MODE_GEND: + result = testValidateDDGenDialysateChangeReq( reqSubMode ); + break; + + case DD_MODE_POSG: + result = testValidateDDPostGenDialysateChangeReq( reqSubMode ); + break; + + // No need to validate the request for the following modes as it is not supported + case DD_MODE_SERV: + case DD_MODE_INIT: + case DD_MODE_HEAT: + case DD_MODE_HCOL: + case DD_MODE_ROPS: + default: + break; + } + + return result; +} + /**@}*/