Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r6311eb9b65fdeec7a285d25e07f3932ac0fb6cf1 -rea6ff77291eee02f351953b76c6720cf860c8be7 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 6311eb9b65fdeec7a285d25e07f3932ac0fb6cf1) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -25,6 +25,7 @@ #include "FPGA.h" #include "InternalADC.h" #include "OperationModes.h" +#include "PIControllers.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" @@ -117,8 +118,6 @@ DATA_DECL( F32, MeasuredBloodPumpMCSpeed, adcBloodPumpMCSpeedRPM, 0.0, 0.0 ); // measured blood pump motor controller speed DATA_DECL( F32, MeasuredBloodPumpMCCurrent, adcBloodPumpMCCurrentmA, 0.0, 0.0 );// measured blood pump motor controller current -static F32 bpFlowError = 0.0; // blood flow error -static F32 bpFlowErrorSum = 0.0; // blood flow error sum static U32 bpControlTimerCounter = 0; // determines when to perform control on blood flow static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; // holds flow samples for a rolling average @@ -164,6 +163,12 @@ // zero rolling flow average buffer resetBloodFlowMovingAverage(); + + // initialize blood flow PI controller + initializePIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, + BP_P_COEFFICIENT, BP_I_COEFFICIENT, + MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE, + BP_MIN_ERROR_SUM, BP_MAX_ERROR_SUM ); } /************************************************************************* @@ -192,9 +197,6 @@ bloodPumpDirection = dir; // set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we'll control to flow when ramp completed bloodPumpPWMDutyCyclePct = BP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) - // reset flow control stats - bpFlowError = 0.0; - bpFlowErrorSum = 0.0; switch ( bloodPumpState ) { @@ -250,9 +252,8 @@ stopBloodPump(); bloodPumpState = BLOOD_PUMP_OFF_STATE; bloodPumpPWMDutyCyclePct = 0.0; - bpFlowError = 0.0; - bpFlowErrorSum = 0.0; bpControlTimerCounter = 0; + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE ); } /************************************************************************* @@ -379,6 +380,7 @@ else if ( bloodPumpPWMDutyCyclePctSet >= bloodPumpPWMDutyCyclePct ) { resetBloodFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp up @@ -415,6 +417,7 @@ else if ( bloodPumpPWMDutyCyclePctSet <= bloodPumpPWMDutyCyclePct ) { resetBloodFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp down @@ -442,30 +445,12 @@ BLOOD_PUMP_STATE_T result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; F32 tgtFlow = (F32)getTargetBloodFlowRate(); F32 actFlow = getMeasuredBloodFlowRate(); - F32 pTerm, iTerm; F32 newPWM; // control at set interval if ( ++bpControlTimerCounter >= BP_CONTROL_INTERVAL ) { - // compute P term - if ( MOTOR_DIR_FORWARD == bloodPumpDirectionSet ) - { - bpFlowError = tgtFlow - actFlow; - } - else - { - bpFlowError = (tgtFlow * -1.0) - (actFlow * -1.0); - } - pTerm = bpFlowError * BP_P_COEFFICIENT; - pTerm = RANGE( pTerm, BP_MIN_PWM_DC_DELTA, BP_MAX_PWM_DC_DELTA ); - // compute I term - bpFlowErrorSum += bpFlowError; - iTerm = RANGE( bpFlowErrorSum, BP_MIN_ERROR_SUM, BP_MAX_ERROR_SUM ); - iTerm *= BP_I_COEFFICIENT; - // compute new PWM duty cycle % for blood pump motor - newPWM = bloodPumpPWMDutyCyclePctSet + pTerm + iTerm; - newPWM = RANGE( newPWM, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE ); + newPWM = runPIController( PI_CONTROLLER_ID_BLOOD_FLOW, tgtFlow, actFlow ); bloodPumpPWMDutyCyclePctSet = newPWM; etpwmSetCmpA( etpwmREG1, (U32)FLOAT_TO_INT_WITH_ROUND( bloodPumpPWMDutyCyclePctSet * (F32)(etpwmREG1->TBPRD) ) ); bpControlTimerCounter = 0; Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r85bfe5051e4d2bf67be39d394f96c075b4e52836 -rea6ff77291eee02f351953b76c6720cf860c8be7 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 85bfe5051e4d2bf67be39d394f96c075b4e52836) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -26,6 +26,7 @@ #include "FPGA.h" #include "InternalADC.h" #include "OperationModes.h" +#include "PIControllers.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" @@ -118,8 +119,6 @@ DATA_DECL( F32, MeasuredDialInPumpMCSpeed, adcDialInPumpMCSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor controller speed DATA_DECL( F32, MeasuredDialInPumpMCCurrent, adcDialInPumpMCCurrentmA, 0.0, 0.0 );// measured dialIn pump motor controller current -static F32 dipFlowError = 0.0; // dialIn flow error -static F32 dipFlowErrorSum = 0.0; // dialIn flow error sum static U32 dipControlTimerCounter = 0; // determines when to perform control on dialIn flow static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; // holds flow samples for a rolling average @@ -165,6 +164,12 @@ // zero rolling flow average buffer resetDialInFlowMovingAverage(); + + // initialize dialysate inlet flow PI controller + initializePIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, + DIP_P_COEFFICIENT, DIP_I_COEFFICIENT, + MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE, + DIP_MIN_ERROR_SUM, DIP_MAX_ERROR_SUM ); } /************************************************************************* @@ -193,9 +198,6 @@ dialInPumpDirection = dir; // set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we'll control to flow when ramp completed dialInPumpPWMDutyCyclePct = DIP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) - // reset flow control stats - dipFlowError = 0.0; - dipFlowErrorSum = 0.0; switch ( dialInPumpState ) { @@ -251,9 +253,8 @@ stopDialInPump(); dialInPumpState = DIAL_IN_PUMP_OFF_STATE; dialInPumpPWMDutyCyclePct = 0.0; - dipFlowError = 0.0; - dipFlowErrorSum = 0.0; dipControlTimerCounter = 0; + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); } /************************************************************************* @@ -380,6 +381,7 @@ else if ( dialInPumpPWMDutyCyclePctSet >= dialInPumpPWMDutyCyclePct ) { resetDialInFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp up @@ -416,6 +418,7 @@ else if ( dialInPumpPWMDutyCyclePctSet <= dialInPumpPWMDutyCyclePct ) { resetDialInFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp down @@ -443,30 +446,12 @@ DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; F32 tgtFlow = (F32)getTargetDialInFlowRate(); F32 actFlow = getMeasuredDialInFlowRate(); - F32 pTerm, iTerm; F32 newPWM; // control at set interval if ( ++dipControlTimerCounter >= DIP_CONTROL_INTERVAL ) { - // compute P term - if ( MOTOR_DIR_FORWARD == dialInPumpDirectionSet ) - { - dipFlowError = tgtFlow - actFlow; - } - else - { - dipFlowError = (tgtFlow * -1.0) - (actFlow * -1.0); - } - pTerm = dipFlowError * DIP_P_COEFFICIENT; - pTerm = RANGE( pTerm, DIP_MIN_PWM_DC_DELTA, DIP_MAX_PWM_DC_DELTA ); - // compute I term - dipFlowErrorSum += dipFlowError; - iTerm = RANGE( dipFlowErrorSum, DIP_MIN_ERROR_SUM, DIP_MAX_ERROR_SUM ); - iTerm *= DIP_I_COEFFICIENT; - // compute new PWM duty cycle % for dialIn pump motor - newPWM = dialInPumpPWMDutyCyclePctSet + pTerm + iTerm; - newPWM = RANGE( newPWM, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); + newPWM = runPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, tgtFlow, actFlow ); dialInPumpPWMDutyCyclePctSet = newPWM; etpwmSetCmpA( etpwmREG1, (U32)FLOAT_TO_INT_WITH_ROUND( dialInPumpPWMDutyCyclePctSet * (F32)(etpwmREG1->TBPRD) ) ); dipControlTimerCounter = 0; Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r1f3647830e9de0a1f0a4e445ce8d72d5525f51fb -rea6ff77291eee02f351953b76c6720cf860c8be7 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 1f3647830e9de0a1f0a4e445ce8d72d5525f51fb) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -28,10 +28,10 @@ typedef enum POST_States { POST_STATE_START = 0, + POST_STATE_WATCHDOG, POST_STATE_ALARM_LAMP, - POST_STATE_STUCK_BUTTON, POST_STATE_FPGA, - POST_STATE_WATCHDOG, + POST_STATE_STUCK_BUTTON, POST_STATE_COMPLETED, POST_STATE_FAILED, NUM_OF_POST_STATES @@ -93,31 +93,33 @@ { SELF_TEST_STATUS_T testStatus = SELF_TEST_STATUS_IN_PROGRESS; + // TODO - send POST status on CAN + // execute current POST state switch ( postState ) { case POST_STATE_START: - postState = POST_STATE_ALARM_LAMP; + postState = POST_STATE_WATCHDOG; break; + case POST_STATE_WATCHDOG: + testStatus = execWatchdogTest(); + postState = handlePOSTStatus( testStatus ); // ignoring return value because last test + break; + case POST_STATE_ALARM_LAMP: testStatus = execAlarmLampTest(); postState = handlePOSTStatus( testStatus ); break; - case POST_STATE_STUCK_BUTTON: - testStatus = execStuckButtonTest(); - postState = handlePOSTStatus( testStatus ); - break; - case POST_STATE_FPGA: testStatus = execFPGATest(); postState = handlePOSTStatus( testStatus ); break; - case POST_STATE_WATCHDOG: - testStatus = execWatchdogTest(); - handlePOSTStatus( testStatus ); // ignoring return value because last test + case POST_STATE_STUCK_BUTTON: + testStatus = execStuckButtonTest(); + handlePOSTStatus( testStatus ); if ( TRUE == tempPOSTPassed ) { postState = POST_STATE_COMPLETED; @@ -139,18 +141,10 @@ break; case POST_STATE_FAILED: -#ifndef RM46_EVAL_BOARD_TARGET - // TODO - send POST status on CAN - // will want POST faults to wait for us to get here before sending us to fault mode - requestNewOperationMode( MODE_FAUL ); -#else - requestNewOperationMode( MODE_STAN ); -#endif - break; - + // should not get here - any failed post test should have already triggered a fault and taken us to fault mode default: - postState = POST_STATE_FAILED; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_MODE_INIT_POST_INVALID_POST_STATE, postState ) + postState = POST_STATE_FAILED; break; } } Index: firmware/App/Services/PIControllers.c =================================================================== diff -u --- firmware/App/Services/PIControllers.c (revision 0) +++ firmware/App/Services/PIControllers.c (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -0,0 +1,205 @@ +/************************************************************************** + * + * 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 PIControllers.c + * + * @date 18-Dec-2019 + * @author L. Baloa + * + * @brief PIControllers service module. Creates a digital PI to be used as + * control loops + * + **************************************************************************/ + +#include "math.h" + +#include "PIControllers.h" + +// ********** private definitions ********** + +typedef struct { + // -- PI's parameters -- + F32 Kp; // Proportional Value + F32 Ki; // Integral Value + F32 uMax; // Maximum control signal + F32 uMin; // Minimum control signal + F32 iMax; // Maximum error sum + F32 iMin; // Minimum error sum + // -- PI's signals -- + F32 referenceSignal; // reference signal + F32 measuredSignal; // measured signal + F32 errorSignal; // reference - measured signal + F32 errorSumBeforeWindUp; // error signal before windup correction + F32 errorSum; // error integral after windup correction + F32 controlSignal; // actual control signal +} PI_CONTROLLER_T; + +#define SET_CONTROLLER( c, id ) ((c) = &piControllers[id]) + +// ********** private data ********** + +// PI Controllers -- definition + +static PI_CONTROLLER_T piControllers[ NUM_OF_PI_CONTROLLERS_IDS ] = +{ // Kp Ki uMax uMin iMax iMin ref meas err esw esum ctrl + { 0.0, 0.0, 1.0, 0.0, 10.0, -10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_LOAD_CELL + { 0.0, 0.0, 1.0, 0.0, 10.0, -10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_BLOOD_FLOW + { 0.0, 0.0, 1.0, 0.0, 10.0, -10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } // PI_CONTROLLER_ID_DIALYSATE_FLOW +}; + +/************************************************************************* + * @brief initializePIController + * Initialize controller before operation. Make sure to call it before \n + * first call to runController function. + * + * @param controllerID - ID filter number + * @param initialControlSignal - Value of the output on the first iteration + * + * @return none + *************************************************************************/ +void initializePIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal, + F32 kP, F32 kI, F32 controlMin, F32 controlMax, F32 iMin, F32 iMax ) +{ + PI_CONTROLLER_T *controller; + + if ( controllerID < NUM_OF_PI_CONTROLLERS_IDS ) + { + SET_CONTROLLER( controller, controllerID ); + + controller->Kp = kP; + controller->Ki = kI; + controller->uMin = controlMin; + controller->uMax = controlMax; + controller->iMin = iMin; + controller->iMax = iMax; + resetPIController( controllerID, initialControlSignal ); + } +} + +/************************************************************************* + * @brief resetPIController + * Reset controller before new set point. Make sure to call it before first \n + * call to runController function. + * + * @param controllerID - ID filter number + * @param initialControlSignal - Value of the output on the first iteration + * + * @return none + *************************************************************************/ +void resetPIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal ) +{ + PI_CONTROLLER_T *controller; + + if ( controllerID < NUM_OF_PI_CONTROLLERS_IDS ) + { + SET_CONTROLLER( controller, controllerID ); + controller->controlSignal = RANGE( initialControlSignal, controller->uMin, controller->uMax ); + controller->referenceSignal = 0.0; + controller->errorSignal = 0.0; + controller->errorSumBeforeWindUp = 0.0; + controller->errorSum = 0.0; + controller->measuredSignal = 0.0; + } +} + +/************************************************************************* + * @brief runPIController + * Call this function whenever a new measured signal sampled is acquired. + * + * @param controllerID - ID filter number + * @param referenceSignal - reference signal value + * @param measuredSignal - latest measured sample + * + * @return value of the control signal + *************************************************************************/ +F32 runPIController(PI_CONTROLLER_ID_T controllerID, F32 referenceSignal, F32 measuredSignal) +{ + PI_CONTROLLER_T *controller; + F32 result = 0.0; + + if ( controllerID < NUM_OF_PI_CONTROLLERS_IDS ) + { + SET_CONTROLLER( controller, controllerID ); + + controller->referenceSignal = referenceSignal; + controller->measuredSignal = measuredSignal; + // calculate error signal + controller->errorSignal = fabs( referenceSignal ) - ( referenceSignal < 0.0 ? ( measuredSignal * -1.0 ) : measuredSignal ); + controller->errorSumBeforeWindUp += controller->errorSignal; + // anti-windup + controller->errorSum = RANGE( controller->errorSumBeforeWindUp, controller->iMin, controller->iMax ); + // calculate control signal + controller->controlSignal += ( controller->Kp * controller->errorSignal ) + ( controller->Ki * controller->errorSum ); + // limit control signal to valid range + controller->controlSignal = RANGE( controller->controlSignal, controller->uMin, controller->uMax ); + result = controller->controlSignal; + } + + return result; +} + +/************************************************************************* + * @brief getPIControllerSignals + * Returns the latest requested signal sample. + * + * @param controllerID - ID filter number + * @param signalID - signal sample ID request + * + * @return latest sample requested + *************************************************************************/ +F32 getPIControllerSignals( PI_CONTROLLER_ID_T controllerID, PI_CONTROLLER_SIGNALS_ID signalID ) +{ + PI_CONTROLLER_T *controller; + F32 output = 0.0; + + if ( controllerID < NUM_OF_PI_CONTROLLERS_IDS ) + { + SET_CONTROLLER( controller, controllerID ); + + switch( signalID ) + { + case CONTROLLER_SIGNAL_REFERENCE: + output = controller->referenceSignal; + break; + + case CONTROLLER_SIGNAL_MEASURED: + output = controller->measuredSignal; + break; + + case CONTROLLER_SIGNAL_ERROR: + output = controller->errorSignal; + break; + + case CONTROLLER_SIGNAL_ERROR_SUM: + output = controller->errorSumBeforeWindUp; + break; + + case CONTROLLER_SIGNAL_ERROR_SUM_AFTER_WINDUP: + output = controller->errorSum; + break; + + case CONTROLLER_SIGNAL_PROPORTIONAL_OUTPUT: + output = controller->Kp * controller->errorSignal; + break; + + case CONTROLLER_SIGNAL_INTEGRAL_OUTPUT: + output = controller->Ki * controller->errorSum; + break; + + case CONTROLLER_SIGNAL_CONTROL: + output = controller->controlSignal; + break; + + default: + output = 0; + break; + } // end of switch + } + + return output; +} + Index: firmware/App/Services/PIControllers.h =================================================================== diff -u --- firmware/App/Services/PIControllers.h (revision 0) +++ firmware/App/Services/PIControllers.h (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -0,0 +1,54 @@ +/************************************************************************** + * + * 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 PIControllers.h + * + * @date 12-Dec-2019 + * @author L. Baloa + * + * @brief Header file for the PI controllers service (PIControllers.c). + * + **************************************************************************/ + +#ifndef __PICONTROLLERS_H__ +#define __PICONTROLLERS_H__ + +#include "Common.h" + +// ********** public definitions ********** + +typedef enum ControllerList +{ + PI_CONTROLLER_ID_LOAD_CELL = 0, + PI_CONTROLLER_ID_BLOOD_FLOW, + PI_CONTROLLER_ID_DIALYSATE_FLOW, + NUM_OF_PI_CONTROLLERS_IDS +} PI_CONTROLLER_ID_T; + +typedef enum ControllerSignals +{ + CONTROLLER_SIGNAL_REFERENCE = 0, + CONTROLLER_SIGNAL_MEASURED, + CONTROLLER_SIGNAL_ERROR, + CONTROLLER_SIGNAL_ERROR_SUM, + CONTROLLER_SIGNAL_ERROR_SUM_AFTER_WINDUP, + CONTROLLER_SIGNAL_PROPORTIONAL_OUTPUT, + CONTROLLER_SIGNAL_INTEGRAL_OUTPUT, + CONTROLLER_SIGNAL_CONTROL, + NUM_OF_CONTROLLER_SIGNAL +} PI_CONTROLLER_SIGNALS_ID; + +// ********** public function prototypes ********** + +void initializePIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal, + F32 kP, F32 kI, F32 controlMin, F32 controlMax, F32 iMin, F32 iMax ); +void resetPIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal ); +F32 runPIController( PI_CONTROLLER_ID_T controllerID, F32 referenceSignal, F32 measuredSignal ); +F32 getPIControllerSignals( PI_CONTROLLER_ID_T controllerID, PI_CONTROLLER_SIGNALS_ID signalID ); + +#endif + Index: firmware/App/Services/WatchdogMgmt.c =================================================================== diff -u -r6311eb9b65fdeec7a285d25e07f3932ac0fb6cf1 -rea6ff77291eee02f351953b76c6720cf860c8be7 --- firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 6311eb9b65fdeec7a285d25e07f3932ac0fb6cf1) +++ firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -24,17 +24,18 @@ // ********** private definitions ********** #define MIN_WATCHDOG_PET_INTERVAL_MS 45 +#define WATCHDOG_POST_TIMEOUT_MS 100 +#define WATCHDOG_RECOVERY_TIME_MS 250 typedef enum Button_Self_Test_States { WATCHDOG_SELF_TEST_STATE_START = 0, WATCHDOG_SELF_TEST_STATE_IN_PROGRESS, + WATCHDOG_SELF_TEST_STATE_RECOVER, WATCHDOG_SELF_TEST_STATE_COMPLETE, NUM_OF_WATCHDOG_SELF_TEST_STATES } WATCHDOG_SELF_TEST_STATE_T; -#define WATCHDOG_POST_TIMEOUT_MS 100 // ms - // ********** private data ********** static U32 lastWatchdogPetTime = 0; @@ -106,8 +107,12 @@ // check to see if watchdog has expired if ( getCPLDWatchdogExpired() == PIN_SIGNAL_HIGH ) { -// activateSafetyShutdown(); -// activateAlarmNoData( ALARM_ID_WATCHDOG_EXPIRED ); + // ignore expired watchdog until after watchdog POST + if ( WATCHDOG_SELF_TEST_STATE_COMPLETE == watchdogSelfTestState ) + { + activateSafetyShutdown(); + activateAlarmNoData( ALARM_ID_WATCHDOG_EXPIRED ); + } } } @@ -165,9 +170,17 @@ activateAlarmNoData( ALARM_ID_WATCHDOG_POST_TEST_FAILED ); result = SELF_TEST_STATUS_FAILED; } - watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_COMPLETE; + watchdogSelfTestTimerCount = getMSTimerCount(); + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_RECOVER; break; + case WATCHDOG_SELF_TEST_STATE_RECOVER: + if ( TRUE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_RECOVERY_TIME_MS ) ) + { + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_COMPLETE; + } + break; + case WATCHDOG_SELF_TEST_STATE_COMPLETE: // if we get called in this state, assume we're doing self test again watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START;