/************************************************************************** * * Copyright (c) 2024-2025 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 AirPump.c * * @author (last) Dara Navaei * @date (last) 09-Dec-2025 * * @author (original) Sean Nash * @date (original) 19-Sep-2024 * ***************************************************************************/ #include "AirPump.h" #include "AlarmMgmtTD.h" #include "Messaging.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "TaskGeneral.h" #include "Timers.h" /** * @addtogroup AirPump * @{ */ // ********** private definitions ********** #define AIR_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Air pump data publish interval. #define DATA_PUBLISH_COUNTER_START_COUNT 13 ///< Air pump data publish start counter. #pragma pack(push, 1) /// Payload record structure for air pump test set command message payload. typedef struct { U32 h12State; ///< Air pump state to command. U32 h12Power; ///< Air pump power level to command. } AIR_PUMP_SET_CMD_PAYLOAD_T; #pragma pack(pop) // ********** private data ********** static AIR_PUMP_STATE_T currentAirPumpState; ///< Current air pump control state. static U08 currentAirPumpPowerLevel; ///< Current air pump power level setting. static U32 airPumpDataPublicationTimerCounter; ///< Air pump data broadcast timer counter. static OVERRIDE_U32_T airPumpDataPublishInterval; ///< Air pump data broadcast interval (in ms). // ********** private function prototypes ********** static AIR_PUMP_STATE_T handleAirPumpStartState( void ); static AIR_PUMP_STATE_T handleAirPumpOffState( void ); static AIR_PUMP_STATE_T handleAirPumpOnState ( void ); static void publishAirPumpData( void ); /*********************************************************************//** * @brief * The initAirPump function initializes the air pump driver. * @details \b Inputs: none * @details \b Outputs: Air pump driver unit initialized * @return none *************************************************************************/ void initAirPump(void) { // Initialize driver initGasLiqXferPumpDriver(); // Initialize controller variables airPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; currentAirPumpState = AIR_PUMP_STATE_INIT; currentAirPumpPowerLevel = AIR_PUMP_MOTOR_OFF; airPumpDataPublishInterval.data = AIR_PUMP_DATA_PUB_INTERVAL; airPumpDataPublishInterval.ovData = AIR_PUMP_DATA_PUB_INTERVAL; airPumpDataPublishInterval.ovInitData = AIR_PUMP_DATA_PUB_INTERVAL; airPumpDataPublishInterval.override = OVERRIDE_RESET; } /*********************************************************************//** * @brief * The setAirPumpState function sets the current air pump state machine state. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid state given. * @details \b Inputs: currentAirPumpState * @details \b Outputs: currentAirPumpState, currentAirPumpMotorPowerLevel * @param state Air pump state to set * @param power Power level to set air pump to * @return none *************************************************************************/ void setAirPumpState( AIR_PUMP_STATE_T state, U08 power ) { if ( state < NUM_OF_AIR_PUMP_STATES ) { currentAirPumpState = state; // power level should be 0 (OFF) when pump state is not ON if ( state != AIR_PUMP_STATE_ON ) { power = AIR_PUMP_MOTOR_OFF; } currentAirPumpPowerLevel = power; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_AIR_PUMP_INVALID_STATE1, (U32)state ) } } /*********************************************************************//** * @brief * The getAirPumpState function returns the current air pump state machine. * @details \b Inputs: currentAirPumpState * @details \b Outputs: none * @return current state of the air pump state machine. *************************************************************************/ AIR_PUMP_STATE_T getAirPumpState( void ) { return currentAirPumpState; } /*********************************************************************//** * @brief * The execAirPumpController function executes the air pump state machine. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if the current state is invalid. * @details \b Inputs: currentAirPumpState * @details \b Outputs: currentAirPumpState * @return none *************************************************************************/ void execAirPumpController( void ) { switch( currentAirPumpState ) { case AIR_PUMP_STATE_INIT: currentAirPumpState = handleAirPumpStartState(); break; case AIR_PUMP_STATE_OFF: currentAirPumpState = handleAirPumpOffState(); break; case AIR_PUMP_STATE_ON: currentAirPumpState = handleAirPumpOnState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_AIR_PUMP_INVALID_STATE2, (U32)currentAirPumpState ) break; } publishAirPumpData(); } /*********************************************************************//** * @brief * The handleAirPumpStartState function starts the air pump state machine. * @details \b Inputs: none * @details \b Outputs: none * @return next state of the air pump state machine *************************************************************************/ static AIR_PUMP_STATE_T handleAirPumpStartState( void ) { AIR_PUMP_STATE_T state = AIR_PUMP_STATE_OFF; return state; } /*********************************************************************//** * @brief * The handleAirPumpOffState function stops the air pump * @details \b Inputs: none * @details \b Outputs: Air pump motor turned off * @return next state of the air pump state machine *************************************************************************/ static AIR_PUMP_STATE_T handleAirPumpOffState( void ) { AIR_PUMP_STATE_T state = AIR_PUMP_STATE_OFF; if ( getAirPumpMotorPower() != 0 ) { currentAirPumpPowerLevel = 0; setAirPumpMotorPower( currentAirPumpPowerLevel ); } return state; } /*********************************************************************//** * @brief * The handleAirPumpOnState function starts the air pump * @details \b Inputs: none * @details \b Outputs: Air pump motor turned on. * @return next state of the air pump state machine *************************************************************************/ static AIR_PUMP_STATE_T handleAirPumpOnState( void ) { AIR_PUMP_STATE_T state = AIR_PUMP_STATE_ON; if ( getAirPumpMotorPower() != currentAirPumpPowerLevel ) { setAirPumpMotorPower( currentAirPumpPowerLevel ); } return state; } /*********************************************************************//** * @brief * The publishAirPumpData function constructs and sends the air pump data * broadcast message. * @details \b Message \b Sent: MSG_ID_TD_AIR_PUMP_DATA * @details \b Inputs: airPumpDataPublicationTimerCounter, currentAirPumpState * @details \b Outputs: airPumpDataPublicationTimerCounter * @return none *************************************************************************/ static void publishAirPumpData( void ) { currentAirPumpPowerLevel = getAirPumpMotorPower(); // update local power setting from driver if ( ++airPumpDataPublicationTimerCounter >= getU32OverrideValue( &airPumpDataPublishInterval ) ) { AIR_PUMP_PAYLOAD_T data; data.h12State = getAirPumpState(); data.h12Power = (U32)currentAirPumpPowerLevel; broadcastData( MSG_ID_TD_AIR_PUMP_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( AIR_PUMP_PAYLOAD_T ) ); airPumpDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testAirPumpDataPublishIntervalOverride function overrides the interval * at which the TD air pump data is published. * @details \b Inputs: none * @details \b Outputs: airPumpDataPublishInterval * @param message Override message from Dialin which includes the interval * (in ms) to override the air pump broadcast interval to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testAirPumpDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &airPumpDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testSetAirPump function sets the air pump to a given power level. * @details \b Inputs: none * @details \b Outputs: currentAirPumpMotorPowerLevel * @param message set message from Dialin which includes the state to set * the air pump to. * @return TRUE if set request is successful, FALSE if not *************************************************************************/ BOOL testSetAirPump( MESSAGE_T *message ) { BOOL result = FALSE; // Verify tester has logged in with TD and override type is valid if ( TRUE == isTestingActivated() ) { // Verify payload length is valid if ( sizeof( U32 ) + sizeof( U32 ) == message->hdr.payloadLen ) { U08 *msgPayload = &message->payload[0]; AIR_PUMP_SET_CMD_PAYLOAD_T payload; memcpy( &payload, msgPayload, sizeof( AIR_PUMP_SET_CMD_PAYLOAD_T ) ); setAirPumpState( (AIR_PUMP_STATE_T)payload.h12State, (U08)payload.h12Power ); result = TRUE; } } return result; } /**@}*/