/************************************************************************** * * 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 RinsePump.c * * @author (last) Vinayakam Mani * @date (last) 22-Oct-2025 * * @author (original) Vinayakam Mani * @date (original) 22-Oct-2025 * ***************************************************************************/ #include "FpgaDD.h" #include "Messaging.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "RinsePump.h" #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup RinsePump * @{ */ // ********** private definitions ********** #define RINSE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Rinse pump data publish interval. #define DATA_PUBLISH_COUNTER_START_COUNT 13 ///< Rinse pump data publish start counter. #define RINSE_PUMP_OFF_COUNT 0U ///< Rinse Pump OFF value in count #define RINSE_PUMP_DEFAULT_PWM_PERCENT 10.0F ///< Initial Rinse pump PWM percentage #define RINSE_PUMP_MAX_PWM_PERCENT 100.0F ///< Max Rinse pump PWM percentage #define RINSE_PUMP_PWM_IN_COUNT_MAX 255.0F ///< Rinse pump max count (100% PWM = 255) #define RINSE_PUMP_PWM_PULSE_RESOLUTION_US 10 ///< Rinse pump PWM pulse resolution in 10us // ********** private data ********** static RINSE_PUMP_STATE_T currentRinsePumpState; ///< Current rinse pump control state. static U32 rinsePumpDataPublicationTimerCounter; ///< Rinse pump data broadcast timer counter. static U32 rinsePumpMeasuredSpeed; ///< Rinse pump measured speed static OVERRIDE_F32_T rinsePumpPwmPercentage; ///< Rinse pump PWM percentage. static OVERRIDE_U32_T rinsePumpDataPublishInterval; ///< Rinse pump data broadcast interval (in ms). // ********** private function prototypes ********** static RINSE_PUMP_STATE_T handleRinsePumpStartState( void ); static RINSE_PUMP_STATE_T handleRinsePumpOffState( void ); static RINSE_PUMP_STATE_T handleRinsePumpOnState ( void ); static void publishRinsePumpData( void ); /*********************************************************************//** * @brief * The initRinsePump function initializes the rinse pump driver. * @details \b Inputs: none * @details \b Outputs: Rinse pump driver unit initialized * @return none *************************************************************************/ void initRinsePump(void) { // Initialize controller variables rinsePumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; currentRinsePumpState = RINSE_PUMP_STATE_INIT; rinsePumpDataPublishInterval.data = RINSE_PUMP_DATA_PUB_INTERVAL; rinsePumpDataPublishInterval.ovData = RINSE_PUMP_DATA_PUB_INTERVAL; rinsePumpDataPublishInterval.ovInitData = RINSE_PUMP_DATA_PUB_INTERVAL; rinsePumpDataPublishInterval.override = OVERRIDE_RESET; rinsePumpPwmPercentage.data = RINSE_PUMP_DEFAULT_PWM_PERCENT; rinsePumpPwmPercentage.ovData = RINSE_PUMP_DEFAULT_PWM_PERCENT; rinsePumpPwmPercentage.ovInitData = RINSE_PUMP_DEFAULT_PWM_PERCENT; rinsePumpPwmPercentage.override = OVERRIDE_RESET; rinsePumpMeasuredSpeed = 0; } /*********************************************************************//** * @brief * The setRinsePumpState function sets the current rinse pump state machine state. * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT if invalid state given. * @details \b Inputs: currentRinsePumpState * @details \b Outputs: currentRinsePumpState * @param state Rinse pump state to set * @return none *************************************************************************/ void setRinsePumpState( RINSE_PUMP_STATE_T state ) { if ( state < NUM_OF_RINSE_PUMP_STATES ) { currentRinsePumpState = state; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_RINSE_PUMP_INVALID_STATE1, (U32)state ) } } /*********************************************************************//** * @brief * The getRinsePumpState function returns the current rinse pump state machine. * @details \b Inputs: currentRinsePumpState * @details \b Outputs: none * @return current state of the rinse pump state machine. *************************************************************************/ RINSE_PUMP_STATE_T getRinsePumpState( void ) { return currentRinsePumpState; } /*********************************************************************//** * @brief * The calculateRinsePumpSpeed function calculate rinse pump speed based * on FPGA report pulse width value. * @details \b Inputs: fpgaD79PumpSpeed * @details \b Outputs: rinsePumpMeasuredSpeed * @return none. *************************************************************************/ void calculateRinsePumpSpeed( void ) { // Pulse width in 10us resolution U16 pumpPulseWidth = getFPGAD79RinsePumpSpeed(); U32 pumpSpeedPerSec = US_PER_SECOND / ( pumpPulseWidth * RINSE_PUMP_PWM_PULSE_RESOLUTION_US ); //Speed in RPM rinsePumpMeasuredSpeed = pumpSpeedPerSec * SEC_PER_MIN; } /*********************************************************************//** * @brief * The execRinsePumpController function executes the rinse pump state machine. * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT if the current state is invalid. * @details \b Inputs: currentRinsePumpState * @details \b Outputs: currentRinsePumpState * @return none *************************************************************************/ void execRinsePumpController( void ) { switch( currentRinsePumpState ) { case RINSE_PUMP_STATE_INIT: currentRinsePumpState = handleRinsePumpStartState(); break; case RINSE_PUMP_STATE_OFF: currentRinsePumpState = handleRinsePumpOffState(); break; case RINSE_PUMP_STATE_ON: currentRinsePumpState = handleRinsePumpOnState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_RINSE_PUMP_INVALID_EXEC_STATE, (U32)currentRinsePumpState ) break; } publishRinsePumpData(); } /*********************************************************************//** * @brief * The handleRinsePumpStartState function starts the rinse pump state machine. * @details \b Inputs: none * @details \b Outputs: none * @return next state of the rinse pump state machine *************************************************************************/ static RINSE_PUMP_STATE_T handleRinsePumpStartState( void ) { RINSE_PUMP_STATE_T state = RINSE_PUMP_STATE_OFF; return state; } /*********************************************************************//** * @brief * The handleRinsePumpOffState function stops the rinse pump * @details \b Inputs: none * @details \b Outputs: Rinse pump motor turned off * @return next state of the rinse pump state machine *************************************************************************/ static RINSE_PUMP_STATE_T handleRinsePumpOffState( void ) { RINSE_PUMP_STATE_T state = RINSE_PUMP_STATE_OFF; if ( TRUE == getTestConfigStatus( TEST_CONFIG_ENABLE_4WIRE_RINSE_PUMP ) ) { // Set PWM count zero to stop the pump setFPGAD79RinsePumpPWMControl( RINSE_PUMP_OFF_COUNT ); } else { // Current alpha system uses valve D65 to turn on the rinse pump // and its just On/off control for now. setValveState( D65_VALV, VALVE_STATE_CLOSED ); } return state; } /*********************************************************************//** * @brief * The handleRinsePumpOnState function starts the rinse pump * @details \b Inputs: none * @details \b Outputs: Rinse pump motor turned on. * @return next state of the rinse pump state machine *************************************************************************/ static RINSE_PUMP_STATE_T handleRinsePumpOnState( void ) { RINSE_PUMP_STATE_T state = RINSE_PUMP_STATE_ON; if ( TRUE == getTestConfigStatus( TEST_CONFIG_ENABLE_4WIRE_RINSE_PUMP ) ) { F32 pwmPercent = getF32OverrideValue( &rinsePumpPwmPercentage ); U32 pwmInCount = (U32)( ( pwmPercent / RINSE_PUMP_MAX_PWM_PERCENT ) * RINSE_PUMP_PWM_IN_COUNT_MAX ); //Turn on Rinse pump with given PWM value setFPGAD79RinsePumpPWMControl( pwmInCount ); } else { // Current alpha system uses valve D65 to turn on the rinse pump // and its just On/off control for now. setValveState( D65_VALV, VALVE_STATE_OPEN ); } return state; } /*********************************************************************//** * @brief * The publishRinsePumpData function constructs and sends the rinse pump data * broadcast message. * @details \b Message \b Sent: MSG_ID_DD_RINSE_PUMP_DATA * @details \b Inputs: rinsePumpDataPublicationTimerCounter, currentRinsePumpState * @details \b Outputs: rinsePumpDataPublicationTimerCounter * @return none *************************************************************************/ static void publishRinsePumpData( void ) { if ( ++rinsePumpDataPublicationTimerCounter >= getU32OverrideValue( &rinsePumpDataPublishInterval ) ) { RINSE_PUMP_PAYLOAD_T data; data.d79State = getRinsePumpState(); data.d79PumpPWM = getF32OverrideValue( &rinsePumpPwmPercentage ); data.d79PumpRPM = rinsePumpMeasuredSpeed; broadcastData( MSG_ID_DD_RINSE_PUMP_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( RINSE_PUMP_PAYLOAD_T ) ); rinsePumpDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testRinsePumpDataPublishIntervalOverride function overrides the interval * at which the DD rinse pump data is published. * @details \b Inputs: none * @details \b Outputs: rinsePumpDataPublishInterval * @param message Override message from Dialin which includes the interval * (in ms) to override the rinse pump broadcast interval to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testRinsePumpDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &rinsePumpDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testRinsePumpPWMPercentOverride function sets the override value * of the rinse pump PWM percentage. * @details Inputs: rinsePumpPwmPercentage (0 to 100%) * @details Outputs: rinsePumpPwmPercentage * @param message Override message from Dialin which includes the override * value of the rinse pump PWM percentage. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testRinsePumpPWMPercentOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &rinsePumpPwmPercentage ); return result; } /**@}*/