Index: firmware/App/Controllers/DryBiCart.c =================================================================== diff -u --- firmware/App/Controllers/DryBiCart.c (revision 0) +++ firmware/App/Controllers/DryBiCart.c (revision a8a6babaca9203b780b4b44f9c15f73e3c0bf2a3) @@ -0,0 +1,462 @@ +/************************************************************************** +* +* Copyright (c) 2025-2026 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 DryBiCart.c +* +* @author (original) Sameer poyil +* @date (original) 23-Oct-2025 +* +* @author (original) Sameer poyil +* @date (original) 23-Oct-2025 +* +***************************************************************************/ + +//#include "AlarmMgmt.h" +#include "Common.h" +#include "DDDefs.h" +#include "DryBiCart.h" +#include "Level.h" +#include "Messaging.h" +#include "OperationModes.h" +#include "PressureSensor.h" +#include "PersistentAlarm.h" +#include "Pressure.h" +#include "TaskGeneral.h" +#include "Timers.h" +#include "Valves.h" + +/** + * @addtogroup DryBiCart + * @{ + */ + +// ********** private definitions ********** + +#define DRY_BICART_DATA_PUBLISH_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the balancing chamber data published. +#define DRY_BICART_FILL_MAX_PRESSURE 12.0F ///< Maximum pressure that drybicart can withstand. +#define DRY_BICART_FILL_COMPLETE_PRESSURE 10.0F ///< Maximum pressure reached to inidcate the drybicart fill being completed. +#define DRY_BICART_FILL_INITIATE_PRESSURE 5.0F ///< Minimum pressure required to initiate the drybicart fill process. +#define DRY_BICART_VENT_COMPLETE_PRESSURE 0.0F ///< Pressure reached to inidcate the drybicart venting being completed. +#define DRY_BICART_VENT_TIME_MS ( 1 * MS_PER_SECOND ) ///< Wait time to vent dry bibag gas before actuating Bicarb chamber(F) venting. +#define DRY_BICART_VENT_MAX_TIME_MS ( 10 * MS_PER_SECOND ) ///< Max time to vent both bicart and Chamber F. +#define DRY_BICART_FILL_DURATION_DIFF_MS 500 ///< Fill duration difference between last and current fill cycle. +#define DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT 10 ///< Default max fill cycle allowed for dry bicart fill/mix with water. +#define DRY_BICART_MAX_FILL_CYCLE_CNT 30 ///< Max fill cycle allowed (by override) for dry bicart fill/mix with water. + +/// Payload record structure for dry bicart fill request +typedef struct +{ + U32 startStop; ///< Dry bicart fill request start:1 and stop: 0 +} DRY_BICART_FILL_START_CMD_PAYLOAD_T; + +// ********** private data ********** + +static DRY_BICART_FILL_EXEC_STATE_T dryBiCartFillExecState; ///< Current state of dry bicart fill executive state machine. +static U32 dryBiCartFillStartTime; ///< Dry bicart fill start time. +static U32 biCartFillCycleCounter; ///< Number of drybicart fill cycle +static OVERRIDE_U32_T biCartMaxFillCycleCount; ///< Maximum number of drybicart fill cycle ( overrideable) +static U32 lastFillDurationInMS; ///< Previous time duration to fill the bicart fill. +static U32 currentFillDurationInMS; ///< Current time duartion to fill the bicart fill. +static OVERRIDE_U32_T dryBiCartFillRequested; ///< Start/stop Dry bicart fill. +static OVERRIDE_U32_T dryBiCartDataPublishInterval; ///< Dry bicart data publish interval. +static U32 dryBiCartDataPublicationTimerCounter; ///< Used to schedule drybicart data publication to CAN bus. + +// ********** private function prototypes ********** + +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterStartState(void); +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterEndState(void); +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasStartState(void); +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasEndState(void); +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillDurationCheckState(void); +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillCompleteState(void); + +static void publishDryBicartData( void ); +static U32 getDryBicartFillDataPublishInterval( void ); + +/*********************************************************************//** + * @brief + * The The initDryBiCart function initializes the DryBiCart module. + * @details \b Inputs: none + * @details \b Outputs: unit variables initialized + * @return none + *************************************************************************/ +void initDryBiCart( void ) +{ + dryBiCartFillExecState = DRY_BICART_START_STATE; + dryBiCartDataPublishInterval.data = DRY_BICART_DATA_PUBLISH_INTERVAL; + dryBiCartDataPublishInterval.ovData = DRY_BICART_DATA_PUBLISH_INTERVAL; + dryBiCartDataPublishInterval.ovInitData = 0; + dryBiCartDataPublishInterval.override = OVERRIDE_RESET; + biCartMaxFillCycleCount.data = DRY_BICART_MAX_FILL_CYCLE_CNT; + biCartMaxFillCycleCount.ovData = DRY_BICART_MAX_FILL_CYCLE_CNT; + biCartMaxFillCycleCount.ovInitData = 0; + biCartMaxFillCycleCount.override = OVERRIDE_RESET; + dryBiCartFillRequested.data = FALSE; + dryBiCartFillRequested.ovData = FALSE; + dryBiCartFillRequested.ovInitData = FALSE; + dryBiCartFillRequested.override = 0; + dryBiCartFillStartTime = 0; + lastFillDurationInMS = 0; + currentFillDurationInMS = 0; + dryBiCartDataPublicationTimerCounter = 0; + biCartFillCycleCounter = 0; +} + +/*********************************************************************//** + * @brief + * The transitionToDryBicart function prepares for transition to + * dry bicart fill/degas operations. + * @details \b Inputs: none + * @details \b Outputs: dryBiCartFillExecState,dryBiCartDataPublishInterval, + * biCartFillCycleCounter, dryBiCartFillStartTime + * @return none + *************************************************************************/ +void transitionToDryBicart( void ) +{ + initDryBiCart(); +} + +/*********************************************************************//** + * @brief + * The execDryBicartFillMode function executes the dry bicart fill (mixing water + * with dry sodium bicarbonate ) state machine. + * @details \b Inputs: dryBiCartFillExecState + * @details \b Outputs: dryBiCartFillExecState + * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong dry bicart fill state + * invoked. + * @return current state. + *************************************************************************/ +U32 execDryBicartFillMode( void ) +{ + // execute drybicart fill state machine + switch ( dryBiCartFillExecState ) + { + case DRY_BICART_START_STATE: + if ( TRUE == getU32OverrideValue( &dryBiCartFillRequested ) ) + { + dryBiCartFillExecState = DRY_BICART_FILL_WATER_START_STATE; + } + break; + + case DRY_BICART_FILL_WATER_START_STATE: + dryBiCartFillExecState = handleDryBicartFillWaterStartState(); + break; + + case DRY_BICART_FILL_WATER_END_STATE: + dryBiCartFillExecState = handleDryBicartFillWaterEndState(); + break; + + case DRY_BICART_DEGAS_START_STATE: + dryBiCartFillExecState = handleDryBicartDegasStartState(); + break; + + case DRY_BICART_DEGAS_END_STATE: + dryBiCartFillExecState = handleDryBicartDegasEndState(); + break; + + case DRY_BICART_FILL_DURATION_CHECK_STATE: + dryBiCartFillExecState = handleDryBicartFillDurationCheckState(); + break; + + case DRY_BICART_FILL_COMPLETE_STATE: + dryBiCartFillExecState = handleDryBicartFillCompleteState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DRY_BICART_FILL_INVALID_EXEC_STATE, dryBiCartFillExecState ); + break; + } + + //Publish dry bicart data + publishDryBicartData(); + + return dryBiCartFillExecState; +} + +/*********************************************************************//** + * @brief + * The handleDryBicartFillWaterStartState function initiates the water fill + * into dry bicarbonate cartridge. + * @details \b Inputs: none + * @details \b Outputs: valve states + * @return the next drybicart fill state. + *************************************************************************/ +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterStartState( void ) +{ + DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_WATER_START_STATE; + + // Close vent valves and descaling valve + setValveState( D80_VALV, VALVE_STATE_CLOSED ); + setValveState( D81_VALV, VALVE_STATE_CLOSED ); + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + setValveState( D85_VALV, VALVE_STATE_CLOSED ); + + //Open D65 + setValveState( D65_VALV, VALVE_STATE_OPEN ); + //Initiate timer to measure length of fill + dryBiCartFillStartTime = getMSTimerCount(); + state = DRY_BICART_FILL_WATER_END_STATE; + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDryBicartFillWaterEndState function closes the valve opened + * for Dry bicart fill. + * @details \b Inputs: D66 pressure sensor reading + * @details \b Outputs: valve states + * @return the next drybicart fill state. + *************************************************************************/ +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterEndState( void ) +{ + DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_WATER_END_STATE; + F32 d66Pressure = getFilteredPressure( D66_PRES ); + + // Close dry bicart inlet water if bicart is filled with water + if ( d66Pressure >= DRY_BICART_FILL_COMPLETE_PRESSURE ) + { + setValveState( D65_VALV, VALVE_STATE_CLOSED ); + lastFillDurationInMS = currentFillDurationInMS; + currentFillDurationInMS = calcTimeSince( dryBiCartFillStartTime ); + //Increment number of fill cycle + biCartFillCycleCounter++; + state = DRY_BICART_DEGAS_START_STATE; + } + + //TODO:Handle timeout alarm for opening D65 valve too long + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDryBicartDegasStartState function actuates the vent valve + * present in the Bicart assembly. + * @details \b Inputs: none + * @details \b Outputs: valve states + * @return the next drybicart fill state. + *************************************************************************/ +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasStartState( void ) +{ + DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_DEGAS_START_STATE; + + //Vent bicart + setValveState( D85_VALV, VALVE_STATE_OPEN ); + + //Initiate timer to measure length of bicart vent + dryBiCartFillStartTime = getMSTimerCount(); + state = DRY_BICART_DEGAS_END_STATE; + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDryBicartDegasEndState function open vent valve present in + * the F Chamber (Bicarb) and closes the vent valve once pressure is met. + * @details \b Inputs: D66 pressure sensor reading + * @details \b Outputs: valve states + * @return the next drybicart fill state. + *************************************************************************/ +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasEndState( void ) +{ + DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_DEGAS_END_STATE; + F32 d66Pressure = getFilteredPressure( D66_PRES ); + + if ( TRUE == didTimeout( dryBiCartFillStartTime, DRY_BICART_VENT_TIME_MS ) ) + { + //Vent chamber F + setValveState( D64_VALV, VALVE_STATE_OPEN ); + dryBiCartFillStartTime = getMSTimerCount(); + } + + // D66 pressure drops or time out + if ( ( d66Pressure <= DRY_BICART_VENT_COMPLETE_PRESSURE ) || + ( TRUE == didTimeout( dryBiCartFillStartTime, DRY_BICART_VENT_MAX_TIME_MS ) ) ) + { + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + setValveState( D85_VALV, VALVE_STATE_CLOSED ); + state = DRY_BICART_FILL_DURATION_CHECK_STATE; + } + + //TODO: Alarm when vent timeout exceeded, but pressure not dropped below expected PSI (0 psi) + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDryBicartFillDurationCheckState function checks the fill duration + * between last and current fill and exits if the duration is reduced over period + * or number of fill cycle done. + * @details \b Inputs: none + * @details \b Outputs: valve states + * @return the next drybicart fill state. + *************************************************************************/ +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillDurationCheckState( void ) +{ + DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_DURATION_CHECK_STATE; + U32 diffInFillDuration = calcTimeBetween( currentFillDurationInMS ,lastFillDurationInMS ); + U32 dryBiCartMaxFillCount = getU32OverrideValue( &biCartMaxFillCycleCount ); + F32 d66Pressure = getFilteredPressure( D66_PRES ); + + // Fill time shortens over the period or number of fill cycle exceeded + if ( ( diffInFillDuration <= DRY_BICART_FILL_DURATION_DIFF_MS ) || + ( biCartFillCycleCounter >= dryBiCartMaxFillCount ) ) + { + state = DRY_BICART_FILL_COMPLETE_STATE; + } + else + { + // Stop drycart fill if fill request flag is set to false. + if ( FALSE == getU32OverrideValue( &dryBiCartFillRequested ) ) + { + state = DRY_BICART_START_STATE; + } + else + { + // transition to next fill cycle and degas + state = DRY_BICART_FILL_WATER_START_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDryBicartFillCompleteState function terminal for the dry bicart + * fill states. + * @details \b Inputs: none + * @details \b Outputs: valve states + * @return the next drybicart fill state. + *************************************************************************/ +static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillCompleteState( void ) +{ + DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_COMPLETE_STATE; + + //TODO : Do nothing or any cleanup later + + return state; +} + +/*********************************************************************//** + * @brief + * The getCurrentDryBiCartFillExecState function returns the current state + * of the dry bicart fill state. + * @details \b Inputs: dryBiCartFillExecState + * @details \b Outputs: none + * @return the current state of dry bicart fill states. + *************************************************************************/ +DRY_BICART_FILL_EXEC_STATE_T getCurrentDryBiCartFillExecState( void ) +{ + return dryBiCartFillExecState; +} + +/*********************************************************************//** + * @brief + * The getDryBicartFillDataPublishInterval function gets the dry bicart + * fill data publish interval. + * @details \b Inputs: dryBiCartDataPublishInterval + * @details \b Outputs: none + * @return the interval at dry bicart fill data being published. + *************************************************************************/ +static U32 getDryBicartFillDataPublishInterval( void ) +{ + U32 result = getU32OverrideValue( &dryBiCartDataPublishInterval ); + + return result; +} + +/*********************************************************************//** + * @brief + * The publishDryBicartData function broadcasts the dry bicart + * data at defined interval. + * @details \b Inputs: dryBiCartDataPublicationTimerCounter + * @details \b Outputs: DD dry bicart data broadcast message sent + * @details \b Message \Sent: MSG_ID_DD_DRY_BICART_DATA to publish the dry bicart + * data. + * @return none + *************************************************************************/ +static void publishDryBicartData( void ) +{ + if ( ++dryBiCartDataPublicationTimerCounter >= getDryBicartFillDataPublishInterval() ) + { + DRY_BICART_DATA_T data; + + data.dryBiCartFillExecState = (U32)dryBiCartFillExecState; + data.dryBiCartFillCycleCounter = biCartFillCycleCounter; + data.dryBiCartMaxFillCycleCount = getU32OverrideValue( &biCartMaxFillCycleCount ); + data.dryBiCartFillRequest = getU32OverrideValue( &dryBiCartFillRequested ); + data.dryBiCartLastFillTime = lastFillDurationInMS; + data.dryBiCartCurrentFillTime = currentFillDurationInMS; + + broadcastData( MSG_ID_DD_DRY_BICART_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( DRY_BICART_DATA_T ) ); + + dryBiCartDataPublicationTimerCounter = 0; + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testDDDryBiCartDataPublishIntervalOverride function overrides the + * DD dry bicart data publish interval. + * @details \b Inputs: dryBiCartDataPublishInterval + * @details \b Outputs: dryBiCartDataPublishInterval + * @param Override message from Dialin which includes the interval + * (in ms) to override the DD dry bicart data publish interval to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = u32BroadcastIntervalOverride( message, &dryBiCartDataPublishInterval, TASK_GENERAL_INTERVAL ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartFillCycleMaxCountOverride function sets the override value + * of the max dry bicart fill cycle count. + * @details Inputs: biCartMaxFillCycleCount + * @details Outputs: biCartMaxFillCycleCount + * @param message Override message from Dialin which includes the override + * value to override the max dry bicart fill cycle count. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartFillCycleMaxCountOverride( MESSAGE_T *message ) +{ + BOOL result = u32Override( message, &biCartMaxFillCycleCount, 0, DRY_BICART_MAX_FILL_CYCLE_CNT ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartFillRequestOverride function starts/stops the dry bicart + * fill. + * @details \b Inputs: tester logged in + * @details \b Outputs: dryBiCartFillRequested + * @param message set message from Dialin which includes the dry bicart fill + * start/stop. + * @return TRUE if set request is successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartFillRequestOverride( MESSAGE_T *message ) +{ + BOOL result = u32Override( message, &dryBiCartFillRequested, FALSE, TRUE ); + + return result; +} + +/**@}*/ Index: firmware/App/Controllers/DryBiCart.h =================================================================== diff -u --- firmware/App/Controllers/DryBiCart.h (revision 0) +++ firmware/App/Controllers/DryBiCart.h (revision a8a6babaca9203b780b4b44f9c15f73e3c0bf2a3) @@ -0,0 +1,60 @@ +/************************************************************************** +* +* Copyright (c) 2025-2026 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 DryBiCart.h +* +* @author (original) Sameer poyil +* @date (original) 10-Nov-2025 +* +* @author (original) Sameer poyil +* @date (original) 10-Nov-2025 +* +***************************************************************************/ + +#ifndef __DRY_BICART_H__ +#define __DRY_BICART_H__ + +#include "DDCommon.h" +#include "DDDefs.h" + +/** + * @defgroup DryBiCart DryBiCart + * @brief DryBiCart unit. Performs dry bicart functions via a state machine. + * + * @addtogroup DryBiCart + * @{ + */ + +// ********** public definitions ********** + + +/// dry bicart data structure +typedef struct +{ + U32 dryBiCartFillExecState; ///< Dry bicart execution state + U32 dryBiCartFillCycleCounter; ///< Dry bicart fill cycle counter + U32 dryBiCartMaxFillCycleCount; ///< Dry bicart fill cycle max count + U32 dryBiCartFillRequest; ///< Dry bicart fill request + U32 dryBiCartLastFillTime; ///< Dry bicart last fill duration in milli second + U32 dryBiCartCurrentFillTime; ///< Dry bicart current fill duration in milli second + } DRY_BICART_DATA_T; + +// ********** public function prototypes ********** + + void initDryBiCart( void ); // Initialize dry bicart unit +void transitionToDryBicart( void ); // Prepares for transition to dry bicart execution +U32 execDryBicartFillMode( void ); // Execute the dry bicart state machine + +DRY_BICART_FILL_EXEC_STATE_T getCurrentDryBiCartFillExecState( void ); // Get the current state of the dry bicart fill execution + +BOOL testDryBiCartDataPublishIntervalOverride( MESSAGE_T *message ); // To override the dry bicart data publish interval +BOOL testDryBiCartFillCycleMaxCountOverride( MESSAGE_T *message ); // To override the dry bicart max fill cycle +BOOL testDryBiCartFillRequestOverride( MESSAGE_T *message ); // To override the dry bicart fill start/stop request + +/**@}*/ + +#endif