Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -reb877ae36c28eb83553ee11ccccf42e2c4a5b4d2 -ra31707ccbf01a1b40f8500bc491dc9c616e7a163 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision eb877ae36c28eb83553ee11ccccf42e2c4a5b4d2) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision a31707ccbf01a1b40f8500bc491dc9c616e7a163) @@ -1,267 +1,325 @@ /************************************************************************** - * - * Copyright (c) 2019-2019 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 - * - * @date 19-Sep-2019 - * @author S. Nash - * - * @brief Top-level state machine for the HD operation modes. - * - **************************************************************************/ +* +* Copyright (c) 2019-2020 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) Sean Nash +* @date (last) 24-Sep-2020 +* +* @author (original) Dara Navaei +* @date (original) 05-Nov-2019 +* +***************************************************************************/ #include "gio.h" -#include "Common.h" -#include "OperationModes.h" - +#include "HDCommon.h" #include "ModeInitPOST.h" #include "ModeService.h" #include "ModeFault.h" #include "ModeStandby.h" -#include "ModePrescription.h" -#include "ModeOpParams.h" +#include "ModeTreatmentParams.h" #include "ModePreTreat.h" #include "ModeTreatment.h" #include "ModePostTreat.h" +#include "OperationModes.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" +/** + * @addtogroup HDOperationModes + * @{ + */ + // ********** private data ********** -static volatile BOOL modeRequest[NUM_OF_MODES - 1]; -static OP_MODE currentMode = MODE_INIT; +/// HD operation mode broadcast interval (in task interval/sec). +#define BROADCAST_HD_OP_MODE_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) -// this matrix determines legal transitions from one mode to another -static const OP_MODE MODE_TRANSITION_TABLE[NUM_OF_MODES - 1][NUM_OF_MODES - 1] = { -// from to-> FAULT SERVICE INIT STANBY PRESCRIP. OP.PARAMS PRE-TREAT TREATMENT POST_TREA - /* FAUL */{ MODE_FAUL, MODE_SERV, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, - MODE_NLEG, }, - /* SERV */{ MODE_FAUL, MODE_SERV, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, - MODE_NLEG, }, - /* INIT */{ MODE_FAUL, MODE_NLEG, MODE_INIT, MODE_STAN, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, - MODE_NLEG, }, - /* STAN */{ MODE_FAUL, MODE_SERV, MODE_NLEG, MODE_STAN, MODE_PRES, MODE_NLEG, MODE_NLEG, MODE_NLEG, - MODE_NLEG, }, - /* PRES */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_PRES, MODE_OPAR, MODE_NLEG, MODE_NLEG, - MODE_NLEG, }, - /* OPAR */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_PRES, MODE_OPAR, MODE_PRET, MODE_NLEG, - MODE_NLEG, }, - /* PRET */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_PRET, MODE_TREA, - MODE_NLEG, }, - /* TREA */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_TREA, - MODE_POST, }, - /* POST */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_STAN, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, - MODE_POST, }, }; +// ********** private data ********** +static volatile BOOL modeRequest[ NUM_OF_MODES - 1 ]; ///< Pending operation mode change requests. +static HD_OP_MODE_T lastMode = MODE_INIT; ///< Last operation mode prior to current mode. +static HD_OP_MODE_T currentMode = MODE_INIT; ///< Current operation mode. +static U32 currentSubMode = 0; ///< The currently active state of the active mode. +static U32 broadcastModeIntervalCtr = 11; ///< Interval counter used to determine when to broadcast operation mode. Initialize to 11 to stagger broadcast. +/// 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 }; + +/// 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 ] = { +// From to-> FAULT SERVICE INIT STANBY TRT.PARAMS PRE-TREAT TREATMENT POST_TREA +/* FAUL */{ MODE_FAUL, MODE_SERV, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, }, +/* SERV */{ MODE_FAUL, MODE_SERV, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, }, +/* INIT */{ MODE_FAUL, MODE_NLEG, MODE_INIT, MODE_STAN, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, }, +/* STAN */{ MODE_FAUL, MODE_SERV, MODE_NLEG, MODE_STAN, MODE_TPAR, MODE_NLEG, MODE_NLEG, MODE_NLEG, }, +/* TPAR */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_STAN, MODE_TPAR, MODE_PRET, MODE_NLEG, MODE_NLEG, }, +/* PRET */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_STAN, MODE_NLEG, MODE_PRET, MODE_TREA, MODE_POST, }, +/* TREA */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_TREA, MODE_POST, }, +/* POST */{ MODE_FAUL, MODE_NLEG, MODE_NLEG, MODE_STAN, MODE_NLEG, MODE_NLEG, MODE_NLEG, MODE_POST, }, }; + // ********** private function prototypes ********** -static OP_MODE arbitrateModeRequest( void ); -static void transitionToNewOperationMode( OP_MODE newMode ); +static HD_OP_MODE_T arbitrateModeRequest( void ); +static void transitionToNewOperationMode( HD_OP_MODE_T newMode ); +static void broadcastOperationMode( void ); -/************************************************************************* - * @brief execOperationModes - * The execOperationModes function initializes the Operation Modes module. - * @details - * Inputs : none - * Outputs : Operation Modes module initialized. - * @param none +/*********************************************************************//** + * @brief + * The initOperationModes function initializes the Operation Modes module. + * @details Inputs: none + * @details Outputs: Operation Modes module initialized. * @return none *************************************************************************/ void initOperationModes( void ) { U32 i; - // initialize mode requests to none pending + // Initialize mode requests to none pending for ( i = 0; i < ( NUM_OF_MODES - 1 ); i++ ) { - modeRequest[i] = FALSE; + modeRequest[ i ] = FALSE; } - // start in init mode + // Start in init mode currentMode = MODE_INIT; + currentSubMode = 0; transitionToNewOperationMode( MODE_INIT ); - // call initializers for the individual modes + // Call initializers for the individual modes initFaultMode(); initServiceMode(); initInitAndPOSTMode(); initStandbyMode(); - initPrescriptionMode(); - initOpParamsMode(); + initTreatParamsMode(); initPreTreatmentMode(); initTreatmentMode(); initPostTreatmentMode(); } -/************************************************************************* - * @brief execOperationModes +/*********************************************************************//** + * @brief * The execOperationModes function executes the Operation Modes state machine. - * @details - * Inputs : none - * Outputs : currentMode is set by state machine. - * @param none + * @details Inputs: none + * @details Outputs: currentMode is set by state machine. * @return none *************************************************************************/ void execOperationModes( void ) { - OP_MODE newMode; + HD_OP_MODE_T newMode; - // any new mode requests? - newMode = arbitrateModeRequest(); // will return current mode if no pending requests - newMode = MODE_TRANSITION_TABLE[currentMode][newMode]; + // Any new mode requests? + newMode = arbitrateModeRequest(); // Will return current mode if no pending requests + newMode = MODE_TRANSITION_TABLE[ currentMode ][ newMode ]; - // is requested new mode valid and legal at this time? + // Is requested new mode valid and legal at this time? if ( newMode >= MODE_NLEG ) { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, newMode ) newMode = currentMode; } - // has mode changed? + // Has mode changed? if ( currentMode != newMode ) { - // handle transition to new mode + // Handle transition to new mode + lastMode = currentMode; transitionToNewOperationMode( newMode ); currentMode = newMode; } - // mode specific processing to be done continuously + // Mode specific processing to be done continuously switch ( currentMode ) { case MODE_FAUL: - execFaultMode(); + currentSubMode = execFaultMode(); break; case MODE_SERV: - execServiceMode(); + currentSubMode = execServiceMode(); break; case MODE_INIT: - execInitAndPOSTMode(); + currentSubMode = execInitAndPOSTMode(); break; case MODE_STAN: - execStandbyMode(); + currentSubMode = execStandbyMode(); break; - case MODE_PRES: - execPrescriptionMode(); + case MODE_TPAR: + currentSubMode = execTreatParamsMode(); break; - case MODE_OPAR: - execOpParamsMode(); - break; - case MODE_PRET: - execPreTreatmentMode(); + currentSubMode = execPreTreatmentMode(); break; case MODE_TREA: - execTreatmentMode(); + currentSubMode = execTreatmentMode(); break; case MODE_POST: - execPostTreatmentMode(); + currentSubMode = execPostTreatmentMode(); break; default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_STATE, currentMode ) currentMode = MODE_FAUL; - // TODO - trigger s/w fault + currentSubMode = 0; break; - } // end switch + } // End switch + + // Broadcast current operation mode on interval + broadcastOperationMode(); } -/************************************************************************* - * @brief requestNewOperationMode - * The requestNewOperationMode function initializes the Operation Modes module. - * @details - * Inputs : none - * Outputs : Initializes the Operation Modes module. - * @param none +/*********************************************************************//** + * @brief + * The requestNewOperationMode function requests transition to a new + * operation mode. The request will be arbitrated when the state machine + * is next executed. + * @details Inputs: none + * @details Outputs: modeRequest[] * @return none *************************************************************************/ -void requestNewOperationMode( OP_MODE newMode ) +void requestNewOperationMode( HD_OP_MODE_T newMode ) { - // validate requested mode + // Validate requested mode if ( newMode < MODE_NLEG ) { - // make request - modeRequest[newMode] = TRUE; + // Make request + modeRequest[ newMode ] = TRUE; } else - { // invalid mode requested - // TODO - trigger s/w fault + { // Invalid mode requested + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_REQUESTED, newMode ) } } -/************************************************************************* - * @brief getCurrentOperationMode - * The getCurrentOperationMode function initializes the Operation Modes module. - * @details - * Inputs : none - * Outputs : Initializes the Operation Modes module. - * @param none - * @return none +/*********************************************************************//** + * @brief + * The getCurrentOperationMode function gets the current operation mode. + * @details Inputs: currentMode + * @details Outputs: none + * @return the current operation mode *************************************************************************/ -OP_MODE getCurrentOperationMode( void ) +HD_OP_MODE_T getCurrentOperationMode( void ) { return currentMode; } -/************************************************************************* - * @brief arbitrateModeRequest - * The arbitrateModeRequest function initializes the Operation Modes module. - * @details - * Inputs : none - * Outputs : Initializes the Operation Modes module. - * @param none +/*********************************************************************//** + * @brief + * The getPreviousOperationMode function gets the previous operation mode. + * @details Inputs: lastMode + * @details Outputs: none + * @return the previous operation mode + *************************************************************************/ +HD_OP_MODE_T getPreviousOperationMode( void ) +{ + return lastMode; +} + +/*********************************************************************//** + * @brief + * The initiateAlarmAction function initiate an alarm or alarm recovery + * action according to the current operation mode. + * @details Inputs: currentMode + * @details Outputs: given action forwarded to current operation mode for execution + * @param action ID of action to be initiated * @return none *************************************************************************/ -static OP_MODE arbitrateModeRequest( void ) +void initiateAlarmAction( ALARM_ACTION_T action ) { - OP_MODE reqMode = currentMode; + // Forward request to the current operation mode + switch ( currentMode ) + { + case MODE_FAUL: + signalAlarmActionToFaultMode( action ); + break; + case MODE_SERV: + signalAlarmActionToServiceMode( action ); + break; + case MODE_INIT: + signalAlarmActionToInitAndPOSTMode( action ); + break; + case MODE_STAN: + signalAlarmActionToStandbyMode( action ); + break; + case MODE_TPAR: + signalAlarmActionToTreatParamsMode( action ); + break; + case MODE_PRET: + signalAlarmActionToPreTreatmentMode( action ); + break; + case MODE_TREA: + signalAlarmActionToTreatmentMode( action ); + break; + case MODE_POST: + signalAlarmActionToPostTreatmentMode( action ); + break; + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_SIGNAL_ACTION, currentMode ) + break; + } +} + +/*********************************************************************//** + * @brief + * The arbitrateModeRequest function arbitrates any pending mode transition + * requests. + * @details Inputs: modeRequest[] + * @details Outputs: modeRequest[] is reset + * @return the next operation mode (current mode if no requests pending) + *************************************************************************/ +static HD_OP_MODE_T arbitrateModeRequest( void ) +{ + HD_OP_MODE_T reqMode = currentMode; U32 i; - // block additional requests until after mode arbitration - // TODO - disable priority task + // Block additional requests until after mode arbitration + _disable_IRQ(); - // select highest priority mode request -or- current mode if no requests pending + // Select highest priority mode request -or- current mode if no requests pending for ( i = 0; i < MODE_NLEG; i++ ) { - if ( modeRequest[i] != FALSE ) + if ( modeRequest[ i ] != FALSE ) { - reqMode = (OP_MODE)i; + reqMode = (HD_OP_MODE_T)i; break; } } - // clear all requests now that an arbitration winner is selected + // Clear all requests now that an arbitration winner is selected for ( i = 0; i < MODE_NLEG; i++ ) { - modeRequest[i] = FALSE; + modeRequest[ i ] = FALSE; } - // un-block requests - // TODO - enable priority task + // Un-block requests + _enable_IRQ(); return reqMode; } -/************************************************************************* - * @brief transitionToNewOperationMode - * The transitionToNewOperationMode function initializes the Operation Modes module. - * @details - * Inputs : none - * Outputs : Initializes the Operation Modes module. - * @param none +/*********************************************************************//** + * @brief + * The transitionToNewOperationMode function calls the transition to function + * for a new operation mode that we are transitioning to. + * @details Inputs: none + * @details Outputs: transition function called for new mode * @return none *************************************************************************/ -static void transitionToNewOperationMode( OP_MODE newMode ) +static void transitionToNewOperationMode( HD_OP_MODE_T newMode ) { - // setup for new operating mode + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_OP_MODE_CHANGE, lastMode, newMode ) + + // Setup for new operating mode switch ( newMode ) { case MODE_FAUL: @@ -276,12 +334,9 @@ case MODE_STAN: transitionToStandbyMode(); break; - case MODE_PRES: - transitionToPrescriptionMode(); + case MODE_TPAR: + transitionToTreatParamsMode(); break; - case MODE_OPAR: - transitionToOpParamsMode(); - break; case MODE_PRET: transitionToPreTreatmentMode(); break; @@ -292,8 +347,107 @@ transitionToPostTreatmentMode(); break; default: - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_TRANSITION_TO, newMode ) break; } } +/*********************************************************************//** + * @brief + * The broadcastOperationMode function sends the current operation mode at + * the prescribed interval. + * @details Inputs: broadcastModeIntervalCtr + * @details Outputs: HD operation mode broadcast message sent. + * @return none + *************************************************************************/ +static void broadcastOperationMode( void ) +{ + if ( ++broadcastModeIntervalCtr >= getU32OverrideValue( &opModePublishInterval ) ) + { + broadcastModeIntervalCtr = 0; + broadcastHDOperationMode( (U32)currentMode, currentSubMode ); + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetOperationMode function will transition to a given operation + * mode if the transition is legal. + * @details Inputs: none + * @details Outputs: modeRequest[] + * @param newMode ID of requested mode to transition to + * @return TRUE if request successful, FALSE if not + *************************************************************************/ +BOOL testSetOperationMode( HD_OP_MODE_T newMode ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + HD_OP_MODE_T check = MODE_TRANSITION_TABLE[ currentMode ][ newMode ]; + + // Is mode transition legal? + if ( check == newMode ) + { + requestNewOperationMode( newMode ); + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetOpModePublishIntervalOverride function sets the override of the + * operation mode publication interval. + * @details Inputs: none + * @details Outputs: opModePublishInterval + * @param ms milliseconds between operation mode broadcasts + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetOpModePublishIntervalOverride( U32 ms ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = ms / TASK_GENERAL_INTERVAL; + + result = TRUE; + opModePublishInterval.ovData = intvl; + opModePublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetOpModePublishIntervalOverride function resets the override of the + * operation mode data publication interval. + * @details Inputs: none + * @details Outputs: opModePublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetOpModePublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + opModePublishInterval.override = OVERRIDE_RESET; + opModePublishInterval.ovData = opModePublishInterval.ovInitData; + } + + return result; +} + +/**@}*/