Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -ref5ef16518466c92687b869cabfa16eaf3365dc0 -rd5139b271f460d32a11a3d755eb3593a7e309d92 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision ef5ef16518466c92687b869cabfa16eaf3365dc0) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision d5139b271f460d32a11a3d755eb3593a7e309d92) @@ -18,125 +18,322 @@ // TODO for testing only remove #include "mibspi.h" +#include "FPGA.h" // TODO for testing only remove #include "AlarmMgmt.h" #include "Common.h" #include "Heaters.h" #include "TemperatureSensors.h" +#include "SystemCommMessages.h" #include "PIControllers.h" +#include "TaskGeneral.h" +#include "Timers.h" -#define MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE 0.795 ///< Main primary heater (heater A) max duty cycle (79.5%) -#define SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE 0.25 ///< Small Primary heater (heater B) max duty cycle (25%) -#define TRIMMER_HEATER_MAX_DUTY_CYCLE 0.25 ///< Trimmer heater max duty cycle (25%) -#define HEATERS_MIN_DUTY_CYCLE 0.00 ///< Primary and trimmer heaters min duty cycle (0.00%) +/** + * @addtogroup Heaters + * @{ + */ -#define PRIMARY_HEATERS_P_COEFFICIENT 0.005 -#define PRIMARY_HEATERS_I_COEFFICIENT 0.001 +#define MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE 0.89 ///< Main primary heater (heater A) max duty cycle (89%) +#define SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE 0.50 ///< Small Primary heater (heater B) max duty cycle (50%) +#define TRIMMER_HEATER_MAX_DUTY_CYCLE 0.50 ///< Trimmer heater max duty cycle (50%) +#define HEATERS_MIN_DUTY_CYCLE 0.00 ///< Primary and trimmer heaters minimum duty cycle (0.00%) -#define TRIMMER_HEATER_P_COEFFICIENT 0.003 -#define TRIMMER_HEATER_I_COEFFICIENT 0.001 +#define PRIMARY_HEATERS_P_COEFFICIENT 0.02 ///< Primary heaters proportional coefficient +#define PRIMARY_HEATERS_I_COEFFICIENT 0.001 ///< Primary heaters integral coefficient -// TODO make these macros functions -#define INITIAL_DUTY_CYCLE_MAIN_PRIMARY_HEATER 0.50 -#define INITIAL_DUTY_CYCLE_SMALL_PRIMARY_HEATER 0.10 -#define INITIAL_DUTY_CYCLE_TRIMMER_HEATER 0.10 +#define TRIMMER_HEATER_P_COEFFICIENT 0.02 ///< Trimmer heater proportional coefficient +#define TRIMMER_HEATER_I_COEFFICIENT 0.001 ///< Trimmer heater integral coefficient -typedef enum heaters_self_tesst_states +#define CONTROLLER_CHECK_INTERVAL_COUNT 10U ///< Time interval count to check the PI controller +#define TEMP_SENSORS_INTERVAL_COUNT 10U ///< Temperature sensors interval count + +#define HEATERS_DATA_PUBLISH_INTERVAL (500 / TASK_GENERAL_INTERVAL ) ///< Heaters data publish interval + +#define SMALL_PRIMARY_AND_TRIMMER_HEATERS_POST_TARGET_TEMPERATURE 40U ///< Small primary and trimmer heaters target temperature during POST +#define MAIN_PRIMARY_HEATER_POST_TARGET_TEMPERATURE 35U ///< Main primary heater target temperature during POST +#define HEATERS_POST_HEAT_UP_TIME_SECONDS 50U ///< The time that the heaters are heated up to reach to the target temperature during POST +#define HEATERS_POST_TEMPERATURE_TOLERANCE 1U ///< Tolerance of the sensors to the target temperature during POST + +/// Heaters self test enums +typedef enum heaters_self_test_states { - HEATERS_SELF_TEST_START = 0, - HEATERS_SELF_TEST_START_SMALL_PRIMARY_AND_TRIMMER, - HEATERS_SELF_TEST_START_MAIN_PRIMARY, - HEATERS_SELF_TEST_COMPLETE, - NUM_OF_HEATERS_SELF_TEST_STATES + HEATERS_SELF_TEST_START = 0, ///< Heaters self test start state + HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS, ///< Heaters self test small primary and trimmer heaters state + HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER, ///< Heaters self test start main primary state + HEATERS_SELF_TEST_COMPLETE, ///< Heaters self test complete state + NUM_OF_HEATERS_SELF_TEST_STATES ///< Number of heaters self test states } HEATERS_SELF_TEST_STATES_T ; +/// Primary heaters exec states typedef enum primary_heaters_exec_states { - PRIMARY_HEATERS_EXEC_STATE_OFF = 0, - PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET, - NUM_OF_PRIMARY_HEATERS_EXEC_STATES + PRIMARY_HEATERS_EXEC_STATE_OFF = 0, ///< Primary heaters exec state off + PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET, ///< Primary heaters exec state control to target (PI controller state) + NUM_OF_PRIMARY_HEATERS_EXEC_STATES ///< Number of primary heaters exec states } PRIMARY_HEATERS_EXEC_STATES_T; +/// Trimmer heater exec states typedef enum trimmer_heater_exec_states { - TRIMMER_HEATER_EXEC_STATE_OFF = 0, - TRIMMER_HEATER_EXEC_STATE_CONTROL_TO_TARGET, - NUM_OF_TRIMMER_HEATER_EXEC_STATES + TRIMMER_HEATER_EXEC_STATE_OFF = 0, ///< Trimmer heater exec state off + TRIMMER_HEATER_EXEC_STATE_CONTROL_TO_TARGET, ///< Trimmer heater exec state control to target (PI controller state) + NUM_OF_TRIMMER_HEATER_EXEC_STATES ///< Number of trimmer heater exec states } TRIMMER_HEATER_EXEC_STATES_T; +/// Name of the heaters states +typedef enum name_of_heaters +{ + PRIMARY_HEATER = 0, ///< Primary heater + TRIMMER_HEATER, ///< Trimmer heater + NUM_OF_HEATERS ///< Number of heaters +} NAME_OF_HEATER_T; + // Private variables -static SELF_TEST_STATUS_T heatersSelfTestResult; -static HEATERS_SELF_TEST_STATES_T heatersSelfTestState; -static PRIMARY_HEATERS_EXEC_STATES_T primaryHeatersExecState; -static TRIMMER_HEATER_EXEC_STATES_T trimmerHeaterExecState; -static F32 smallPrimaryHeaterPWMDutyCycle; -static F32 mainPrimaryHeaterPWMDutyCycle; -static F32 trimmerHeaterPWMDutyCycle; +static SELF_TEST_STATUS_T heatersSelfTestResult; ///< Heaters self test results +static HEATERS_SELF_TEST_STATES_T heatersSelfTestState; ///< Heaters self test state +static PRIMARY_HEATERS_EXEC_STATES_T primaryHeatersExecState; ///< Primary heaters exec state +static TRIMMER_HEATER_EXEC_STATES_T trimmerHeaterExecState; ///< Trimmer heater exec state +static F32 primaryHeaterTargetTemperature; ///< Primary heaters target temperature +static F32 trimmerHeaterTargetTemperature; ///< Trimmer heater target temperature + +static F32 mainPrimaryHeaterDutyCycle; ///< Main primary heater duty cycle +static F32 smallPrimaryHeaterDutyCycle; ///< Small primary heater duty cycle +static F32 trimmerHeaterDutyCycle; ///< Trimmer heater duty cycle +static U32 primaryHeaterTimerCounter; ///< Primary heater timer counter +static U32 trimmerHeaterTimerCounter; ///< Trimmer heater timer counter +static U32 dataPublicationTimerCounter; ///< Data publication timer counter +static BOOL isPrimaryHeaterOn; ///< Flag to show if the primary heater is on +static BOOL isTrimmerHeaterOn; ///< Flag to show if the trimmer heater is on + +static OVERRIDE_U32_T heatersDataPublishInterval = { HEATERS_DATA_PUBLISH_INTERVAL, + HEATERS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Heaters data publish time interval +static U32 selfTestElapsedTime; ///< Self test elapsed time variable + // private functions prototypes +static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestStart ( void ); +static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters ( void ); +static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestMainPrimaryHeater ( void ); + static PRIMARY_HEATERS_EXEC_STATES_T handlePrimaryHeaterStateOff ( void ); static PRIMARY_HEATERS_EXEC_STATES_T handlePrimaryHeaterStateControlToTarget ( void ); -static void setMainPrimaryHeaterPWM( F32 pwm ); +static TRIMMER_HEATER_EXEC_STATES_T handleTrimmerHeaterStateOff ( void ); +static TRIMMER_HEATER_EXEC_STATES_T handleTrimmerHeaterControlToTarget ( void ); + +static void setMainPrimaryHeaterPWM ( F32 pwm ); static void setSmallPrimaryHeaterPWM ( F32 pwm ); -static void setTrimmerHeaterPWM( F32 pwm ); +static void setTrimmerHeaterPWM ( F32 pwm ); +static void resetHeaterState ( NAME_OF_HEATER_T heater ); +static void publishHeatersData ( void ); +static DATA_GET_PROTOTYPE( U32, getPublishHeatersDataInterval ); -// TODo GPIO for enabling the primary heater +// TODO: Remove the below code. FOR TESTING ONLY #define PRIMARY_HEATER_MIBSPI1_PORT_MASK 0x00000002 // (CS1 - re-purposed as input GPIO) -#define TOGGLEPRIMAYHEATER() ( ( mibspiREG1->PC2 & PRIMARY_HEATER_MIBSPI1_PORT_MASK ) != 0 ) +#define TOGGLEPRIMAYHEATER() (( mibspiREG1->PC2 & PRIMARY_HEATER_MIBSPI1_PORT_MASK ) != 0) +//TODO: Remove the above code. FOR TESTING ONLY // Public functions +/*********************************************************************//** + * @brief + * The initHeaters function initializes the variables and the PI controllers + * for the primary and trimmer heaters + * @details + * Inputs : none + * Outputs : heatersSelfTestResult, heatersSelfTestState, + * primaryHeatersExecState, trimmerHeaterExecState, primaryHeaterTargetTemperature + * trimmerHeaterTargetTemperature, primaryHeaterTimerCounter, + * trimmerHeaterTimerCounter, dataPublicationTimerCounter + * @return none + *************************************************************************/ void initHeaters ( void ) { - heatersSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; - heatersSelfTestState = HEATERS_SELF_TEST_START; - primaryHeatersExecState = PRIMARY_HEATERS_EXEC_STATE_OFF; - trimmerHeaterExecState = TRIMMER_HEATER_EXEC_STATE_OFF; - smallPrimaryHeaterPWMDutyCycle = 0.0; - mainPrimaryHeaterPWMDutyCycle = 0.0; - trimmerHeaterPWMDutyCycle = 0.0; + heatersSelfTestState = HEATERS_SELF_TEST_START; + primaryHeatersExecState = PRIMARY_HEATERS_EXEC_STATE_OFF; + trimmerHeaterExecState = TRIMMER_HEATER_EXEC_STATE_OFF; + primaryHeaterTargetTemperature = 0.0; + trimmerHeaterTargetTemperature = 0.0; + primaryHeaterTimerCounter = 0; + trimmerHeaterTimerCounter = 5; + dataPublicationTimerCounter = 0; + isPrimaryHeaterOn = FALSE; + isTrimmerHeaterOn = FALSE; + selfTestElapsedTime = 0; + + // Initialize the PI controller for the primary heaters + initializePIController( PI_CONTROLLER_ID_PRIMARY_HEATER, HEATERS_MIN_DUTY_CYCLE, + PRIMARY_HEATERS_P_COEFFICIENT, PRIMARY_HEATERS_I_COEFFICIENT, + HEATERS_MIN_DUTY_CYCLE, + MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE + SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE ); + + // Initialize the PI controller for the trimmer heater + initializePIController( PI_CONTROLLER_ID_TRIMMER_HEATER, HEATERS_MIN_DUTY_CYCLE, + TRIMMER_HEATER_P_COEFFICIENT, TRIMMER_HEATER_I_COEFFICIENT, + HEATERS_MIN_DUTY_CYCLE, TRIMMER_HEATER_MAX_DUTY_CYCLE ); } -void startPrimaryHeater ( void ) +/*********************************************************************//** + * @brief + * The setPrimaryHeaterTargetTemperature function sets the primary heater + * target temperature + * @details + * Inputs : none + * Outputs : primaryHeaterTargetTemperature + * @param targetTemp + * @return none + *************************************************************************/ +void setPrimaryHeaterTargetTemperature ( F32 targetTemp ) { - setMainPrimaryHeaterPWM ( 0.5 ); - setSmallPrimaryHeaterPWM ( 0.25 ); + primaryHeaterTargetTemperature = targetTemp; } -void startTrimmerHeater ( void ) +/*********************************************************************//** + * @brief + * The setTrimmerHeaterTargetTemperature function sets the trimmer heater + * target temperature + * @details + * Inputs : trimmerHeaterTargetTemperature + * Outputs : none + * @param targetTemp : targetTemp + * @return none + *************************************************************************/ +void setTrimmerHeaterTargetTemperature ( F32 targetTemp ) { - setTrimmerHeaterPWM ( INITIAL_DUTY_CYCLE_MAIN_PRIMARY_HEATER ); + trimmerHeaterTargetTemperature = targetTemp; } +/*********************************************************************//** + * @brief + * The startPrimaryHeater function starts the primary heaters. It resets + * the primary heaters state and sets the main primary heater duty cycle + * @details + * Inputs : mainPrimaryHeaterDutyCycle, primaryHeaterTargetTemperature, + * isPrimaryHeaterOn + * Outputs : isPrimaryHeaterOn + * @param none + * @return status + *************************************************************************/ +BOOL startPrimaryHeater ( void ) +{ + BOOL status = FALSE; + + if ( primaryHeaterTargetTemperature != 0.0 ) + { + resetHeaterState ( PRIMARY_HEATER ); + setMainPrimaryHeaterPWM ( mainPrimaryHeaterDutyCycle ); + isPrimaryHeaterOn = TRUE; + status = TRUE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The startTrimmerHeater function starts the trimmer heater. It resets the + * trimmer heater's state and sets the duty cycle of the trimmer heater + * @details + * Inputs : trimmerHeaterDutyCycle, trimmerHeaterTargetTemperature, + * isTrimmerHeaterOn + * Outputs : isTrimmerHeaterOn + * @param none + * @return status + *************************************************************************/ +BOOL startTrimmerHeater ( void ) +{ + BOOL status = FALSE; + + if ( trimmerHeaterTargetTemperature != 0.0 ) + { + resetHeaterState ( TRIMMER_HEATER ); + setTrimmerHeaterPWM ( trimmerHeaterDutyCycle ); + isTrimmerHeaterOn = TRUE; + status = TRUE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The stopPrimaryHeater function stops the primary heaters + * @details + * Inputs : isPrimaryHeaterOn + * Outputs : isPrimaryHeaterOn + * @param none + * @return none + *************************************************************************/ void stopPrimaryHeater ( void ) { - setMainPrimaryHeaterPWM ( 0.0 ); - setSmallPrimaryHeaterPWM ( 0.0 ); + setMainPrimaryHeaterPWM ( HEATERS_MIN_DUTY_CYCLE ); + setSmallPrimaryHeaterPWM ( HEATERS_MIN_DUTY_CYCLE ); + isPrimaryHeaterOn = FALSE; } +/*********************************************************************//** + * @brief + * The stopTrimmerHeater function stops the trimmer heater + * @details + * Inputs : isTrimmerHeaterOn + * Outputs : isTrimmerHeaterOn + * @param none + * @return none + *************************************************************************/ +void stopTrimmerHeater ( void ) +{ + setTrimmerHeaterPWM ( HEATERS_MIN_DUTY_CYCLE ); + isTrimmerHeaterOn = FALSE; +} + +/*********************************************************************//** + * @brief + * The execHeatersMonitor function + * @details + * Inputs : none + * Outputs : none + * @return none + *************************************************************************/ +void execHeatersMonitor ( void ) +{ + // TODO Decide the parts of this function + +} + +/*********************************************************************//** + * @brief + * The execHeatersSelfTest function executes the heaters self test + * @details + * Inputs : heatersSelfTestState + * Outputs : none + * @param none + * @return heatersSelfTestState + *************************************************************************/ SELF_TEST_STATUS_T execHeatersSelfTest ( void ) { switch ( heatersSelfTestState ) { case HEATERS_SELF_TEST_START: - + heatersSelfTestState = handleHeatersSelfTestStart(); break; - case HEATERS_SELF_TEST_START_SMALL_PRIMARY_AND_TRIMMER: + case HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS: + heatersSelfTestState = handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters(); break; - case HEATERS_SELF_TEST_START_MAIN_PRIMARY: + case HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER: + heatersSelfTestState = handleHeatersSelfTestMainPrimaryHeater(); break; - case HEATERS_SELF_TEST_COMPLETE: + case HEATERS_SELF_TEST_COMPLETE: + // POST is done. Do nothing break; default: - SET_ALARM_WITH_2_U32_DATA ( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_SELF_TEST_INVALID_STATE, heatersSelfTestState ); heatersSelfTestState = HEATERS_SELF_TEST_COMPLETE; @@ -146,88 +343,592 @@ return heatersSelfTestResult; } - +/*********************************************************************//** + * @brief + * The execPrimaryHeaters function executes the primary heaters + * @details + * Inputs : primaryHeatersExecState + * Outputs : primaryHeatersExecState + * @param none + * @return none + *************************************************************************/ void execPrimaryHeaters ( void ) { switch ( primaryHeatersExecState ) { case PRIMARY_HEATERS_EXEC_STATE_OFF: - primaryHeatersExecState = handlePrimaryHeaterStateOff(); break; case PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET: - primaryHeatersExecState = handlePrimaryHeaterStateControlToTarget(); break; default: - SET_ALARM_WITH_2_U32_DATA ( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_PRIMARY_HEATER_EXEC_INVALID_STATE, primaryHeatersExecState ); primaryHeatersExecState = PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET; break; } } +/*********************************************************************//** + * @brief + * The execTrimmerHeater function executes the trimmer heater + * @details + * Inputs : trimmerHeaterExecState + * Outputs : trimmerHeaterExecState + * @param none + * @return none + *************************************************************************/ void execTrimmerHeater ( void ) { switch ( trimmerHeaterExecState ) { case TRIMMER_HEATER_EXEC_STATE_OFF: - + trimmerHeaterExecState = handleTrimmerHeaterStateOff(); break; case TRIMMER_HEATER_EXEC_STATE_CONTROL_TO_TARGET: - + trimmerHeaterExecState = handleTrimmerHeaterControlToTarget(); break; default: - SET_ALARM_WITH_2_U32_DATA ( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_TRIMMER_HEATER_EXEC_INVALID_STATE, trimmerHeaterExecState ); trimmerHeaterExecState = TRIMMER_HEATER_EXEC_STATE_CONTROL_TO_TARGET; break; } } -static void setMainPrimaryHeaterPWM( F32 pwm ) +// Private functions + +/*********************************************************************//** + * @brief + * The handleHeatersSelfTestStart function starts the small primary and + * the trimmer heaters for self test + * @details + * Inputs : heatersSelfTestResult, selfTestElapsedTime + * Outputs : heatersSelfTestResult, selfTestElapsedTime + * @param none + * @return state (HEATERS_SELF_TEST_STATES_T) + *************************************************************************/ +static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestStart ( void ) { - etpwmSetCmpA( etpwmREG1, (U32)( (S32)( ( pwm * (F32)(etpwmREG1->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + // Code temporarily disabled since POST is not tested yet + // TODO once POST is tested and implemented, remove #ifndef +#ifndef _VECTORCAST_ + heatersSelfTestResult = SELF_TEST_STATUS_PASSED; + return HEATERS_SELF_TEST_COMPLETE; +#else + heatersSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; + setSmallPrimaryHeaterPWM ( SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE ); + setTrimmerHeaterPWM ( TRIMMER_HEATER_MAX_DUTY_CYCLE ); + selfTestElapsedTime = getMSTimerCount(); + + return HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS; +#endif } -static void setSmallPrimaryHeaterPWM ( F32 pwm ) +/*********************************************************************//** + * @brief + * The handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters function checks + * if the time on the small primary and trimmer heaters has elapsed and + * if time has elapsed, it checks the thermocouple temperature shared + * among the two heaters. If they are in range, it sets the main primary + * heater and transitions to the next state. If it fails, it set an alarm + * and fails the test + * @details + * Inputs : heatersSelfTestResult, selfTestElapsedTime + * Outputs : heatersSelfTestResult, selfTestElapsedTime + * @param none + * @return state (HEATERS_SELF_TEST_STATES_T) + *************************************************************************/ +static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters ( void ) { - etpwmSetCmpB( etpwmREG1, (U32)( (S32)( ( pwm * (F32)(etpwmREG1->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + HEATERS_SELF_TEST_STATES_T state = HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS; + + if ( didTimeout( selfTestElapsedTime, HEATERS_POST_HEAT_UP_TIME_SECONDS ) ) + { + setSmallPrimaryHeaterPWM ( 0 ); + setTrimmerHeaterPWM ( 0 ); + + F32 convertedTemperature = getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP ); + + if ( fabs(convertedTemperature - SMALL_PRIMARY_AND_TRIMMER_HEATERS_POST_TARGET_TEMPERATURE) > HEATERS_POST_TEMPERATURE_TOLERANCE ) + { + //TODO alarm + // TODO POST failed + heatersSelfTestResult = SELF_TEST_STATUS_FAILED; + state = HEATERS_SELF_TEST_COMPLETE; + } + else + { + setMainPrimaryHeaterPWM ( MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ); + selfTestElapsedTime = getMSTimerCount(); + state = HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER; + } + } + + return state; } -static void setTrimmerHeaterPWM( F32 pwm ) + +/*********************************************************************//** + * @brief + * The handleHeatersSelfTestMainPrimaryHeater function checks + * if the time on the main primary heater has elapsed and it it has elapsed, + * it checks to ensure the thermocouples temperature is within the tolerance + * of the target temperature. It then transitions to the complete state + * @details + * Inputs : heatersSelfTestResult + * Outputs : heatersSelfTestResult + * @param none + * @return state (HEATERS_SELF_TEST_STATES_T) + *************************************************************************/ +static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestMainPrimaryHeater ( void ) { - etpwmSetCmpA( etpwmREG3, (U32)( (S32)( ( pwm * (F32)(etpwmREG3->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + HEATERS_SELF_TEST_STATES_T state = HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER; + + if ( didTimeout( selfTestElapsedTime, HEATERS_POST_HEAT_UP_TIME_SECONDS ) ) + { + setMainPrimaryHeaterPWM ( 0 ); + + F32 convertedTemperature = getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP ); + + if ( fabs(convertedTemperature - MAIN_PRIMARY_HEATER_POST_TARGET_TEMPERATURE ) > HEATERS_POST_TEMPERATURE_TOLERANCE ) + { + //TODO alarm + // TODO POST failed + heatersSelfTestResult = SELF_TEST_STATUS_FAILED; + } + else + { + heatersSelfTestResult = SELF_TEST_STATUS_PASSED; + } + + state = HEATERS_SELF_TEST_COMPLETE; + } + + return state; } +/*********************************************************************//** + * @brief + * The handlePrimaryHeaterStateOff function handles the primary heaters at + * off state + * @details + * Inputs : isPrimaryHeaterOn + * Outputs : state (PRIMARY_HEATERS_EXEC_STATES_T) + * @param none + * @return state (PRIMARY_HEATERS_EXEC_STATES_T) + *************************************************************************/ static PRIMARY_HEATERS_EXEC_STATES_T handlePrimaryHeaterStateOff ( void ) { - PRIMARY_HEATERS_EXEC_STATES_T state = PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET; + PRIMARY_HEATERS_EXEC_STATES_T state = PRIMARY_HEATERS_EXEC_STATE_OFF; + // TODO for testing only. remove +#ifdef DEBUG_ENABLED +#ifdef ENABLE_DIP_SWITCHES + if ( TOGGLEPRIMAYHEATER() ) + { + setPrimaryHeaterTargetTemperature ( 37 ); + startPrimaryHeater(); + F32 pumpPWM = 1; + etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + F32 fanPWM = 0.25; + etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + } +#endif +#endif + // TODO remove this code for testing + + if ( isPrimaryHeaterOn ) + { + state = PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET; + } + return state; } + +/*********************************************************************//** + * @brief + * The handlePrimaryHeaterStateControlToTarget function handles the primary + * heaters at control state when the heaters are active + * @details + * Inputs : primaryHeaterTimerCounter, mainPrimaryHeaterDutyCycle, + * smallPrimaryHeaterDutyCycle, isPrimaryHeaterOn + * Outputs : primaryHeaterTimerCounter, mainPrimaryHeaterDutyCycle, + * smallPrimaryHeaterDutyCycle + * @param none + * @return state (PRIMARY_HEATERS_EXEC_STATES_T) + *************************************************************************/ static PRIMARY_HEATERS_EXEC_STATES_T handlePrimaryHeaterStateControlToTarget ( void ) { PRIMARY_HEATERS_EXEC_STATES_T state = PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET; - // TODO remove this code for testing - if ( TOGGLEPRIMAYHEATER() ) + if ( ++primaryHeaterTimerCounter >= CONTROLLER_CHECK_INTERVAL_COUNT ) { - startPrimaryHeater(); + F32 outletTemp = getTemperatureValue ( TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ); + mainPrimaryHeaterDutyCycle = runPIController ( PI_CONTROLLER_ID_PRIMARY_HEATER, + primaryHeaterTargetTemperature, outletTemp ); + + if ( mainPrimaryHeaterDutyCycle >= MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ) + { + // The duty cycle from the PI controller was greater than max duty cycle of the main primary + // heater. So subtract the remaining from the max main primary heater duty cycle and set + // the rest to the small primary heater + smallPrimaryHeaterDutyCycle = mainPrimaryHeaterDutyCycle - MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE; + mainPrimaryHeaterDutyCycle = MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE; + setMainPrimaryHeaterPWM ( mainPrimaryHeaterDutyCycle ); + setSmallPrimaryHeaterPWM ( smallPrimaryHeaterDutyCycle ); + } + else + { + setMainPrimaryHeaterPWM ( mainPrimaryHeaterDutyCycle ); + smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; + setSmallPrimaryHeaterPWM ( smallPrimaryHeaterDutyCycle ); + } + primaryHeaterTimerCounter = 0; } + publishHeatersData(); + // TODO remove this code +#ifdef DEBUG_ENABLED +#ifdef ENABLE_DIP_SWITCHES if ( !TOGGLEPRIMAYHEATER() ) { stopPrimaryHeater(); + F32 pumpPWM = 0; + etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + F32 fanPWM = 0; + etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); } +#endif +#endif + // TODO Remove this code + + if ( ! isPrimaryHeaterOn ) + { + state = PRIMARY_HEATERS_EXEC_STATE_OFF; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleTrimmerHeaterStateOff function handles the trimmer heater at + * off state + * @details + * Inputs : isTrimmerHeaterOn + * Outputs : state (TRIMMER_HEATER_EXEC_STATES_T) + * @param none + * @return state (TRIMMER_HEATER_EXEC_STATES_T) + *************************************************************************/ +static TRIMMER_HEATER_EXEC_STATES_T handleTrimmerHeaterStateOff ( void ) +{ + TRIMMER_HEATER_EXEC_STATES_T state = TRIMMER_HEATER_EXEC_STATE_OFF; + + // TODO for testing only. remove +#ifdef DEBUG_ENABLED +#ifdef ENABLE_DIP_SWITCHES + if ( TOGGLEPRIMAYHEATER() ) + { + setTrimmerHeaterTargetTemperature ( 38 ); + startTrimmerHeater(); + //F32 pumpPWM = 1; + //etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + //temporaryStartROPump(); + //temporaryStartFan(); + //F32 fanPWM = 0.25; + //etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + //etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + //temporaryStartROPump(); + //temporaryStartFan(); + } +#endif +#endif // TODO remove this code for testing + if ( isTrimmerHeaterOn ) + { + state = TRIMMER_HEATER_EXEC_STATE_CONTROL_TO_TARGET; + } return state; } +/*********************************************************************//** + * @brief + * The handleTrimmerHeaterControlToTarget function handles the trimmer + * heater at control state when the heater is active + * @details + * Inputs : trimmerHeaterTimerCounter, trimmerHeaterDutyCycle + * Outputs : trimmerHeaterTimerCounter, trimmerHeaterDutyCycle, + * isTrimmerHeaterOn + * @param none + * @return state (TRIMMER_HEATER_EXEC_STATES_T) + *************************************************************************/ +static TRIMMER_HEATER_EXEC_STATES_T handleTrimmerHeaterControlToTarget ( void ) +{ + TRIMMER_HEATER_EXEC_STATES_T state = TRIMMER_HEATER_EXEC_STATE_CONTROL_TO_TARGET; + + if ( ++trimmerHeaterTimerCounter >= CONTROLLER_CHECK_INTERVAL_COUNT ) + { + F32 outletTemp = getTemperatureValue ( TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ); + trimmerHeaterDutyCycle = runPIController ( PI_CONTROLLER_ID_TRIMMER_HEATER, + trimmerHeaterTargetTemperature, outletTemp ); + setTrimmerHeaterPWM ( trimmerHeaterDutyCycle ); + trimmerHeaterTimerCounter = 0; + } + publishHeatersData(); + + // TODO remove this code +#ifdef DEBUG_ENABLED +#ifdef ENABLE_DIP_SWITCHES + if ( !TOGGLEPRIMAYHEATER() ) + { + stopTrimmerHeater(); + //F32 pumpPWM = 0; + //etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + //temporaryStartROPump(); + //temporaryStartFan(); + //F32 fanPWM = 0; + //etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + //etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + //temporaryStopROPump(); + //temporaryStopFan(); + } +#endif +#endif + // TODO Remove this code + + if ( ! isTrimmerHeaterOn ) + { + state = TRIMMER_HEATER_EXEC_STATE_OFF; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The setMainPrimaryHeaterPWM function sets the PWM of the main primary + * heater + * @details + * Inputs : none + * Outputs : none + * @param : pwm : To set the PWM + * @return none + *************************************************************************/ +static void setMainPrimaryHeaterPWM ( F32 pwm ) +{ + etpwmSetCmpA( etpwmREG1, (U32)( (S32)( ( pwm * (F32)(etpwmREG1->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); +} + +/*********************************************************************//** + * @brief + * The setSmallPrimaryHeaterPWM function sets the PWM of the small primary + * heater + * @details + * Inputs : none + * Outputs : none + * @param: pwm : To set the PWM + * @return none + *************************************************************************/ +static void setSmallPrimaryHeaterPWM ( F32 pwm ) +{ + etpwmSetCmpB( etpwmREG1, (U32)( (S32)( ( pwm * (F32)(etpwmREG1->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); +} + +/*********************************************************************//** + * @brief + * The setTrimmerHeaterPWM function sets the PWM of the trimmer heater + * @details + * Inputs : none + * Outputs : none + * @param : pwm : To set the PWM + * @return none + *************************************************************************/ +static void setTrimmerHeaterPWM ( F32 pwm ) +{ + etpwmSetCmpA( etpwmREG3, (U32)( (S32)( ( pwm * (F32)(etpwmREG3->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); +} + +/*********************************************************************//** + * @brief + * The resetHeaterState function resets the PI controller of the selected + * heater + * @details + * Inputs : mainPrimaryHeaterDutyCycle, trimmerHeaterDutyCycle + * Outputs : mainPrimaryHeaterDutyCycle, trimmerHeaterDutyCycle + * @param : heater (NAME_OF_HEATER) : Name of the heater to reset + * @return none + *************************************************************************/ +static void resetHeaterState ( NAME_OF_HEATER_T heater ) +{ + if ( heater == PRIMARY_HEATER ) + { + mainPrimaryHeaterDutyCycle = MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE; + resetPIController ( PI_CONTROLLER_ID_PRIMARY_HEATER, MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ); + } + else if ( heater == TRIMMER_HEATER ) + { + trimmerHeaterDutyCycle = TRIMMER_HEATER_MAX_DUTY_CYCLE; + resetPIController ( PI_CONTROLLER_ID_TRIMMER_HEATER, TRIMMER_HEATER_MAX_DUTY_CYCLE ); + } +} + +/*********************************************************************//** + * @brief + * The getPublishHeatersDataInterval function set the publish interval + * either from override or from actual data + * @details + * Inputs : heatersDataPublishInterval + * Outputs : none + * @param : none + * @return result + *************************************************************************/ +U32 getPublishHeatersDataInterval ( void ) +{ + U32 result = heatersDataPublishInterval.data; + + if ( OVERRIDE_KEY == heatersDataPublishInterval.override ) + { + result = heatersDataPublishInterval.ovData; + } + + return result; +} + +/************************************************************************* + * @brief + * The publishTemperatureData function publishes the temperature sensors + * data into the USB debug port at the defined time interval + * @details + * Inputs : dataPublicationTimerCounter + * Outputs : dataPublicationTimerCounter + * @param none + * @return none + *************************************************************************/ +static void publishHeatersData ( void ) +{ + if ( ++dataPublicationTimerCounter >= getPublishHeatersDataInterval() ) + { + broadcastHeatersData ( (U32)(mainPrimaryHeaterDutyCycle*100), + (U32)(smallPrimaryHeaterDutyCycle*100), + (U32)(trimmerHeaterDutyCycle*100) ); + //NOTE: This section will be removed +#ifdef DEBUG_ENABLED + { + char debugTempStr[ 256 ]; + // TODO: clean up. + // To the reviewers: please ignore this section + /*sprintf( debugTempStr, "MPDC: %2d, SPDC: %2d, THDC: %2d, TPi: %6.2f, TPo: %6.2f, TD1: %6.2f, " + "TD2: %6.2f, TRo: %6.2f, TDi: %6.2f, TPh: %6.2f, TTh: %6.2f, PTarg: %6.2f, TTarg: %6.2f, ROFlow: %6.2f, PCJ: %6.2f, TCJ: %6.2f\r\n", + (U32)(mainPrimaryHeaterDutyCycle*100), (U32)(smallPrimaryHeaterDutyCycle*100), (U32)(trimmerHeaterDutyCycle*100), + getTemperatureValue ( TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE_TEMP_SESNOR ), + primaryHeaterTargetTemperature, trimmerHeaterTargetTemperature, + (F32)(10909.0909/getFPGAROPumpFlowRate()), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION_TEMP_SENSOR )) + //(F32)(convertedPriJC*0.0625), + //(F32)(convertedTriJC*0.0625)); //TODO Remove flow reader later + sprintf( debugTempStr, "MPDC: %2d, SPDC: %2d, THDC: %2d, TPi: %6.2f, TPo: %6.2f, TRo: %6.2f, TPh: %6.2f, TTh: %6.2f, PCJ: %6.2f, TCJ: %6.2f," + "TPI: %6.2f, TTI: %6.2f\r\n", + (U32)(mainPrimaryHeaterDutyCycle*100), (U32)(smallPrimaryHeaterDutyCycle*100), (U32)(trimmerHeaterDutyCycle*100), + getTemperatureValue ( TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP ), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE_TEMP_SENSOR), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE_TEMP_SENSOR));*/ + sprintf( debugTempStr, "MPDC: %2d, SPDC: %2d, THDC: %2d, TPi: %6.2f, TPo: %6.2f, PriCJ: %6.2f, PriTC: %6.2f, TpriInt: %6.2f, TRo: %6.2f, TriCJ: %6.2f," + "TriTC: %6.2f, TtriInt: %6.2f, ROFlow: %6.2f\r\n", + (U32)(mainPrimaryHeaterDutyCycle*100), (U32)(smallPrimaryHeaterDutyCycle*100), (U32)(trimmerHeaterDutyCycle*100), + getTemperatureValue ( TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP ), + getTemperatureValue ( TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE_TEMP_SENSOR ), + getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP ), + (F32)(10909.0909/getFPGAROPumpFlowRate()) + ); + + sendDebugData ( (U08*)debugTempStr, strlen(debugTempStr) ); + } +#endif + dataPublicationTimerCounter = 0; + } +} + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + +/************************************************************************* + * @brief + * The testSetHeatersPublishIntervalOverride function overrides the heaters + * publish data time interval + * @details + * Inputs : heatersDataPublishInterval + * Outputs : heatersDataPublishInterval + * @param value + * @return result + *************************************************************************/ +BOOL testSetHeatersPublishIntervalOverride ( U32 value ) +{ + BOOL result = FALSE; + + if ( isTestingActivated() ) + { + U32 interval = value / TASK_GENERAL_INTERVAL; + + result = TRUE; + heatersDataPublishInterval.ovData = interval; + heatersDataPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/************************************************************************* + * @brief + * The testResetHeatersPublishIntervalOverride function resets the heaters + * publish time interval to its previous time interval + * @details + * Inputs : heatersDataPublishInterval + * Outputs : heatersDataPublishInterval + * @param none + * @return result + *************************************************************************/ +BOOL testResetHeatersPublishIntervalOverride ( void ) +{ + BOOL result = FALSE; + + if ( isTestingActivated() ) + { + result = TRUE; + heatersDataPublishInterval.override = OVERRIDE_RESET; + heatersDataPublishInterval.ovData = heatersDataPublishInterval.ovInitData; + } + + return result; +} + +/**@}*/