Index: firmware/App/Controllers/AirPump.c =================================================================== diff -u -r395522dffef1348e176564925656012f529c1910 -r98bd6dd355e8736e020b3900ca971120c26ad8a6 --- firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 395522dffef1348e176564925656012f529c1910) +++ firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 98bd6dd355e8736e020b3900ca971120c26ad8a6) @@ -7,16 +7,18 @@ * * @file AirPump.c * -* @author (last) Dara Navaei -* @date (last) 19-Dec-2025 +* @author (last) Varshini Nagabooshanam +* @date (last) 21-May-2026 * * @author (original) Sean Nash * @date (original) 19-Sep-2024 * ***************************************************************************/ #include "AirPump.h" +#include "AirTrap.h" #include "AlarmMgmtTD.h" +#include "GLXferPump.h" #include "Messaging.h" #include "OperationModes.h" #include "PersistentAlarm.h" @@ -32,20 +34,23 @@ #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. +#define AIR_PUMP_STALL_PERSISTENCE ( 150 / TASK_GENERAL_INTERVAL ) ///< Stall duration before alarm (150 ms) #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. + F32 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 U08 airPumpStallCounter; ///< Air pump stall counter +static U16 currentAirPumpRPM; ///< Current air pump RPM +static F32 currentAirPumpPowerLevel; ///< Current air pump power level setting in % duty cycle (0..100%). static U32 airPumpDataPublicationTimerCounter; ///< Air pump data broadcast timer counter. static OVERRIDE_U32_T airPumpDataPublishInterval; ///< Air pump data broadcast interval (in ms). @@ -54,6 +59,7 @@ static AIR_PUMP_STATE_T handleAirPumpStartState( void ); static AIR_PUMP_STATE_T handleAirPumpOffState( void ); static AIR_PUMP_STATE_T handleAirPumpOnState ( void ); +static void checkAirPumpStallCondition( void ); static void publishAirPumpData( void ); /*********************************************************************//** @@ -72,6 +78,8 @@ airPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; currentAirPumpState = AIR_PUMP_STATE_INIT; currentAirPumpPowerLevel = AIR_PUMP_MOTOR_OFF; + currentAirPumpRPM = 0; + airPumpStallCounter = 0; airPumpDataPublishInterval.data = AIR_PUMP_DATA_PUB_INTERVAL; airPumpDataPublishInterval.ovData = AIR_PUMP_DATA_PUB_INTERVAL; airPumpDataPublishInterval.ovInitData = AIR_PUMP_DATA_PUB_INTERVAL; @@ -86,24 +94,41 @@ * @details \b Outputs: currentAirPumpState, currentAirPumpMotorPowerLevel * @param state Air pump state to set * @param power Power level to set air pump to - * @return none + * @return TRUE if set else FALSE *************************************************************************/ -void setAirPumpState( AIR_PUMP_STATE_T state, U08 power ) +BOOL setAirPumpState( AIR_PUMP_STATE_T state, F32 power ) { - if ( state < NUM_OF_AIR_PUMP_STATES ) + BOOL result = FALSE; + // There is a limitation on the TD circuit to be able to run the pump at the low speed. + // Change planned in next version of the board. right now limiting the pump duty cycle below 24% + //BOOL validInput = ( power == AIR_PUMP_DUTY_CYCLE_MIN) || ( power >= AIR_PUMP_DUTY_CYCLE_LIMIT && power <= AIR_PUMP_DUTY_CYCLE_MAX); + BOOL validInput = ( ( ( power >= AIR_PUMP_DUTY_CYCLE_MIN ) && ( power <= AIR_PUMP_DUTY_CYCLE_MAX ) ) ) ? TRUE : FALSE; + + // need to pass the result immediately to user when user enter invalid range + if ( FALSE == validInput ) { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_AIR_PUMP_DUTY_CYCLE_OUT_OF_RANGE, power ) + result = FALSE; + } + // unsigned integer never be less than 0 + else 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; + result = TRUE; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_AIR_PUMP_INVALID_STATE1, (U32)state ) + result = FALSE; } + + return result; } /*********************************************************************//** @@ -147,6 +172,10 @@ break; } + // Check stall condition + checkAirPumpStallCondition(); + // update the speed every tick + currentAirPumpRPM = getAirPumpMotorRPM(); publishAirPumpData(); } @@ -205,6 +234,35 @@ /*********************************************************************//** * @brief + * The checkAirPumpStallCondition function detects an air pump stall. + * @details \b Alarm: ALARM_ID_TD_AIR_PUMP_STALL when the air pump is + * commanded on and the measured RPM is zero for multiple controller cycles. + * @details \b Inputs: currentAirPumpPowerLevel, currentAirPumpRPM + * @details \b Outputs: airPumpStallCounter + * @return none + *************************************************************************/ +static void checkAirPumpStallCondition( void ) +{ + if ( ( currentAirPumpPowerLevel > 0 ) && ( currentAirPumpRPM == 0 ) ) + { + // we are commanding air pump to run but zero measured pump speed indicates it is not running + if ( ++airPumpStallCounter >= AIR_PUMP_STALL_PERSISTENCE ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_AIR_PUMP_STALL, currentAirPumpPowerLevel, currentAirPumpRPM ); + // Stop H12 air pump + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + // Stop air trap control + endAirTrapControl(); + } + } + else + { + airPumpStallCounter = 0; + } +} + +/*********************************************************************//** + * @brief * The publishAirPumpData function constructs and sends the air pump data * broadcast message. * @details \b Message \b Sent: MSG_ID_TD_AIR_PUMP_DATA @@ -221,7 +279,12 @@ AIR_PUMP_PAYLOAD_T data; data.h12State = getAirPumpState(); - data.h12Power = (U32)currentAirPumpPowerLevel; + data.h12Power = currentAirPumpPowerLevel; + data.h12Rpm = (U32)currentAirPumpRPM; + //TODO:remove after validating pump speed + data.fpgah12Rpm = getAirPumpMotorFPGARPM(); + //TODO:remove after validating pump speed + data.scalarPower = getAirPumpMotorScalarPower(); broadcastData( MSG_ID_TD_AIR_PUMP_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( AIR_PUMP_PAYLOAD_T ) ); airPumpDataPublicationTimerCounter = 0; @@ -255,27 +318,28 @@ * @brief * The testSetAirPump function sets the air pump to a given power level. * @details \b Inputs: none - * @details \b Outputs: currentAirPumpMotorPowerLevel + * @details \b Outputs: none * @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 ) + if ( sizeof( AIR_PUMP_SET_CMD_PAYLOAD_T ) == 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; - } + + result = setAirPumpState( (AIR_PUMP_STATE_T)payload.h12State, payload.h12Power ); + } } return result;