Index: firmware/App/Controllers/ConcentratePumps.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -36,7 +36,7 @@ #define CONCENTRATE_PUMP_FORWARD_DIR 0x1 ///< Concentrate pump forward direction configuration. #define CONCENTRATE_PUMP_REVERSE_DIR 0x0 ///< Concentrate pump reverse direction configuration. -#define CONCENTRATE_PUMP_SPEED_INCREMENT 1.5 ///< Speed increase (mL/min) when controlling concentrate pump to target step speed. TODO it was 8.0 +#define CONCENTRATE_PUMP_SPEED_INCREMENT 2.0 ///< Speed increase (mL/min) when controlling concentrate pump to target step speed. #define CONCENTRATE_PUMP_MIN_SPEED 3.0 ///< Minimum speed for concentrate pump in mL per min. #define CONCENTRATE_PUMP_ERROR_TOLERANCE 0.02 ///< Measured speed needs to be within 2% of commanded speed. #define CONCENTRATE_PUMP_ZERO_FLOW_RATE 0xFFFF ///< Pulse width value when zero flow rate or pump is off. @@ -53,7 +53,9 @@ #define CONCENTRATE_PUMP_VOLUME_PER_PULSE ( CONCENTRATE_PUMP_VOLUME_PER_REV / CONCENTRATE_PUMP_PULSE_PER_REV ) #define CONCENTRATE_PUMP_DATA_PUBLISH_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is monitored. -#define CONCENTRATE_PUMP_CONTROL_INTERVAL ( 50 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is controlled. + +#define CONCENTRATE_PUMP_CONTROL_INTERVAL ( 50 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is controlled. + #define CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for concentrate pump speed control error. /// Enumeration of concentrate pump states. Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -305,6 +305,9 @@ drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; drainPumpControlModeSet = drainPumpControlMode; drainControlTimerCounter = 0; + pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; + pendingDrainPumpCmdTarget = 0.0; + pendingDrainPumpCmdCountDown = 0; } /*********************************************************************//** Index: firmware/App/Controllers/Fans.h =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/Fans.h (.../Fans.h) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/Fans.h (.../Fans.h) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -64,9 +64,6 @@ BOOL testSetFanPublishIntervalOverride( U32 value ); BOOL testResetFanPublishIntervalOverride( void ); -BOOL testSetFanRPMOverride( U32 fanId, F32 rpm ); -BOOL testResetFanRPMOverride( U32 fanId ); - /**@}*/ #endif Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -174,6 +174,7 @@ { if( heater < NUM_OF_DG_HEATERS ) { +#ifndef DISABLE_HEATERS_AND_TEMPS // Assume the target temperature has not changed heatersStatus[ heater ].hasTargetTempChanged = FALSE; @@ -184,6 +185,7 @@ heatersStatus[ heater ].hasTargetTempChanged = TRUE; // TODO alarm if temperature if out of range or just reject? } +#endif } else { @@ -215,13 +217,16 @@ { BOOL status = FALSE; + if( heater < NUM_OF_DG_HEATERS ) { +#ifndef DISABLE_HEATERS_AND_TEMPS if ( TRUE == heatersStatus[ heater ].hasTargetTempChanged ) { status = TRUE; heatersStatus[ heater ].startHeaterSignal = TRUE; } +#endif } else { @@ -322,9 +327,11 @@ if ( TRUE == heaterCmdPtr->startHeater ) { +#ifndef DISABLE_TRIMMER_HEATER if ( ( MINIMUM_TARGET_TEMPERATURE <= heaterCmdPtr->targetTemp ) && ( heaterCmdPtr->targetTemp <= MAXIMUM_TARGET_TEMPERATURE ) ) { cmdResponse.rejected = FALSE; + #ifndef DISABLE_HEATERS_AND_TEMPS heatersStatus[ DG_TRIMMER_HEATER ].targetTemp = heaterCmdPtr->targetTemp; heatersStatus[ DG_TRIMMER_HEATER ].startHeaterSignal = TRUE; @@ -334,6 +341,7 @@ { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; } +#endif } else { @@ -820,12 +828,12 @@ if ( trimmerHeaterInternalTemp > HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_C ) { isTempOut = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_INTERNAL_TEMP_OUT_OF_RANGE, trimmerHeaterInternalTemp ); + //SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_INTERNAL_TEMP_OUT_OF_RANGE, trimmerHeaterInternalTemp ); } else if ( trimmerHeaterColdJunctionTemp > HEATERS_MAX_ALLOWED_COLD_JUNCTION_TEMPERATURE_C ) { isTempOut = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_CJ_TEMP_OUT_OF_RANGE, trimmerHeaterColdJunctionTemp ); + //SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_CJ_TEMP_OUT_OF_RANGE, trimmerHeaterColdJunctionTemp ); } // If it is above the range for the first time, stop the trimmer heater Index: firmware/App/Controllers/LoadCell.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -95,7 +95,7 @@ * @details Outputs: LoadCell module initialized. * @return none *************************************************************************/ - void initLoadCell( void ) +void initLoadCell( void ) { U32 i; U32 j; Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -74,8 +74,6 @@ /// Initial conversion factor from target flow rate to PWM duty cycle estimate. #define ROP_FLOW_TO_PWM_DC(flow) ( ROP_FLOW_TO_PWM_SLOPE * flow + ROP_FLOW_TO_PWM_INTERCEPT ) -#define FLOW_SENSOR_ZERO_READING 0xFFFF ///< Flow sensor reading indicates zero flow (or flow lower than can be detected by sensor). - #define MAX_ALLOWED_FLOW_DEVIATION 0.1 ///< Max allowed deviation from target flow. #define FLOW_OUT_OF_RANGE_PERSISTENT_INTERVAL ( 12 * MS_PER_SECOND ) ///< Flow out of range time out in counts. #define MAX_PRESSURE_TARGET_TOLERANCE 5 ///< Pressure tolerance from maximum set pressure by user in psi. @@ -314,12 +312,16 @@ roControlTimerCounter = 0; isROPumpOn = FALSE; targetROPumpMaxPressure = 0; + pendingROPumpCmdMaxPressure = 0.0; + pendingROPumpCmdTargetFlow = 0.0; + pendingROPumpCmdCountDown = 0; resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, MIN_RO_PUMP_DUTY_CYCLE ); } /*********************************************************************//** * @brief - * The execROPumpMonitor function executes the RO pump monitor. + * The execROPumpMonitor function executes the RO pump monitor. The RO flow + * sensor is read, filtered, converted to L/min and calibrated. * @details Inputs: measuredFlowReadingsSum, flowFilterCounter, * measuredROFlowRateLPM, measuredROFlowRateLPM, roPumpState, * flowOutOfRangeCounter, roPumpControlMode @@ -351,20 +353,20 @@ // Read flow at the control set if ( ++flowFilterCounter >= FLOW_SAMPLES_TO_AVERAGE ) { - F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER ); + F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER ); // Convert flow sensor period to L/min + // Apply calibration to flow sensor reading measuredROFlowRateLPM.data = pow(flow, 4) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].fourthOrderCoeff + pow(flow, 3) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].thirdOrderCoeff + pow(flow, 2) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].secondOrderCoeff + - flow * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].gain + + flow * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].gain + flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].offset; - // If the flow is less than a certain value, FPGA will return 0xFFFF meaning that - // the flow is 0. - if ( FLOW_SENSOR_ZERO_READING == roFlowReading ) - { - measuredROFlowRateLPM.data = 0.0; - } + // If the flow is less than a certain value, FPGA will return 0xFFFF meaning that the flow is 0. + if ( FLOW_SENSOR_ZERO_READING == roFlowReading ) + { + measuredROFlowRateLPM.data = 0.0; + } measuredFlowReadingsSum = 0; flowFilterCounter = 0; Index: firmware/App/Controllers/Switches.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/Switches.c (.../Switches.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/Switches.c (.../Switches.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -94,15 +94,15 @@ switch ( i ) { case CONCENTRATE_CAP: - currentSwitchStatus = ( getFPGAConcentrateCapStatus() != 0 ? STATE_OPEN : STATE_CLOSED ); + currentSwitchStatus = getFPGAConcentrateCapStatus(); break; case DIALYSATE_CAP: - currentSwitchStatus = ( getFPGADialysateCapStatus() != 0 ? STATE_OPEN : STATE_CLOSED ); + currentSwitchStatus = getFPGADialysateCapStatus(); break; case FLUID_DOOR: - currentSwitchStatus = ( getFPGAGFluidDoorStatus() != 0 ? STATE_OPEN : STATE_CLOSED ); + currentSwitchStatus = getFPGAGFluidDoorStatus(); break; default: Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r103d68b3ba3059d3988923fb1fb8ead0eccfd526 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 103d68b3ba3059d3988923fb1fb8ead0eccfd526) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -164,7 +164,7 @@ static BOOL isADCReadValid( U32 sensorIndex, U32 fpgaError, U32 fpgaCount ); static void processADCRead( U32 sensorIndex, S32 adc ); static void publishTemperatureSensorsData( void ); -static void monitorTemperatureSnsrs( U32 sensorIndex ); +static void monitorTemperatureSnsrs( U32 sensorIndex, F32 temperature ); /*********************************************************************//** * @brief @@ -373,7 +373,7 @@ if ( sensorIndex < NUM_OF_TEMPERATURE_SENSORS ) { - if ( OVERRIDE_KEY == tempSensors[ sensorIndex ].temperatureValues.override ) + if ( tempSensors[ sensorIndex ].temperatureValues.override == OVERRIDE_KEY ) { temperature = tempSensors[ sensorIndex ].temperatureValues.ovData; } @@ -713,7 +713,7 @@ tempSensors[ sensorIndex ].temperatureValues.data = temperature; // Monitor the temperature value - monitorTemperatureSnsrs( sensorIndex ); + monitorTemperatureSnsrs( sensorIndex, temperature ); } /*********************************************************************//** @@ -879,14 +879,17 @@ * @details Inputs: tempSensors * @details Outputs: tempSensors * @param sensorIndex the index of the temperature sensor + * @param temperature the temperature value to be checked * @return none *************************************************************************/ -static void monitorTemperatureSnsrs( U32 sensorIndex ) +static void monitorTemperatureSnsrs( U32 sensorIndex, F32 temperature ) { - F32 temperature = getTemperatureValue( sensorIndex ); + // The maximum allowed temperature is different for the sensors that are in the fluid path + // with the ones that are not in the fluid path + F32 maxLimit = tempSensors[ sensorIndex ].maxAllowedTemperature; // Check both temperature and to be in range - if ( ( temperature < TEMP_SENSORS_MIN_ALLOWED_DEGREE_C ) || ( temperature > tempSensors[ sensorIndex ].maxAllowedTemperature ) ) + if ( ( temperature < TEMP_SENSORS_MIN_ALLOWED_DEGREE_C ) || ( temperature > maxLimit ) ) { // TODO investigate //checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_OUT_OF_RANGE, TRUE, sensorIndex, temperature ); @@ -915,7 +918,7 @@ if ( sensorIndex < NUM_OF_TEMPERATURE_SENSORS ) { - if ( TRUE == isTestingActivated() ) + if ( isTestingActivated() ) { result = TRUE; tempSensors[ sensorIndex ].temperatureValues.ovData = temperature; @@ -941,7 +944,7 @@ if ( sensorIndex < NUM_OF_TEMPERATURE_SENSORS ) { - if ( TRUE == isTestingActivated() ) + if ( isTestingActivated() ) { result = TRUE; tempSensors[ sensorIndex ].temperatureValues.override = OVERRIDE_RESET; @@ -965,7 +968,7 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() ) + if ( isTestingActivated() ) { U32 interval = value / TASK_PRIORITY_INTERVAL; @@ -989,7 +992,7 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() ) + if ( isTestingActivated() ) { result = TRUE; tempSensorsPublishInterval.override = OVERRIDE_RESET; Index: firmware/App/Controllers/Thermistors.c =================================================================== diff -u -rd3819286869611f9c02add72a0f8e321598fdf42 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Controllers/Thermistors.c (.../Thermistors.c) (revision d3819286869611f9c02add72a0f8e321598fdf42) +++ firmware/App/Controllers/Thermistors.c (.../Thermistors.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -1,8 +1,25 @@ +/************************************************************************** +* +* Copyright (c) 2019-2021 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 Thermistors.c +* +* @author (last) Dara Navaei +* @date (last) 06-Nov-2021 +* +* @author (original) Dara Navaei +* @date (original) 25-Nov-2020 +* +***************************************************************************/ #include // For temperature calculations #include "FPGA.h" #include "InternalADC.h" +#include "MessageSupport.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "Thermistors.h" @@ -330,7 +347,8 @@ sensorsData.powerSupply2Thermistor = getThermistorTemperatureValue( THERMISTOR_POWER_SUPPLY_2 ); // Broadcast the thermistors data - broadcastThermistorsData( &sensorsData ); + broadcastData( MSG_ID_DG_THERMISTORS_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&sensorsData, sizeof( THERMISTORS_DATA_T ) ); + // Reset the counter dataPublishCounter = 0; } Index: firmware/App/DGCommon.h =================================================================== diff -u -r6225c12de69db32e83c9d1f55fbabca3e7e32a3a -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/DGCommon.h (.../DGCommon.h) (revision 6225c12de69db32e83c9d1f55fbabca3e7e32a3a) +++ firmware/App/DGCommon.h (.../DGCommon.h) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -25,7 +25,7 @@ #define DG_VERSION_MAJOR 0 #define DG_VERSION_MINOR 6 #define DG_VERSION_MICRO 0 -#define DG_VERSION_BUILD 16 +#define DG_VERSION_BUILD 81 // ********** build switches ********** @@ -34,7 +34,7 @@ // TODO: Removed debug build flags when release build is ready // #define BOARD_WITH_NO_HARDWARE 1 // #define TASK_TIMING_OUTPUT_ENABLED 1 // re-purposes drain pump enable pin for task timing -// #define DISABLE_HEATERS_AND_TEMPS 1 +// #define DISABLE_HEATERS_AND_TEMPS 1 // #define DISABLE_ACCELS 1 // #define SKIP_POST 1 #define SKIP_CAL_CHECK 1 @@ -48,15 +48,18 @@ #define IGNORE_RO_PUMP_MONITOR 1 #define DISABLE_RO_RATIO_CHECK 1 // #define DISABLE_COND_SENSOR_CHECK 1 -// #define DISABLE_WATER_QUALITY_CHECK 1 + #define DISABLE_WATER_QUALITY_CHECK 1 #define DISABLE_RTC_CONFIG 1 #define THD_USING_TRO_CONNECTOR 1 + #define DISABLE_FLOW_CHECK_IN_FILL 1 #define IGNORE_CONC_PUMP_IN_HEAT_DISINFECT 1 // Turn these flags on to disable dialysate mixing #define DISABLE_DIALYSATE_CHECK 1 #define DISABLE_MIXING 1 //#define DISABLE_FLOW_CONTROL_TREATMENT 1 + #define DISABLE_TRIMMER_HEATER 1 + #define DIALYSATE_FLOW_METER_ENABLED 1 #define DISABLE_ACK_ALARM 1 #include Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -15,6 +15,7 @@ * ***************************************************************************/ +#include "ConcentratePumps.h" #include "ConductivitySensors.h" #include "DrainPump.h" #include "Heaters.h" @@ -49,16 +50,24 @@ #define DIALYSATE_DRAIN_TIME_OUT ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Dialysate drain time out. +/// Time period to wait for concentrate lines to rinse. +#define RINSE_CONCENTRATE_LINES_WAIT ( 25 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +/// Reserver the concentrate speed to rinse out concentrate lines. +#define RINSE_SPEED ( ( CONCENTRATE_PUMP_MAX_SPEED - 3.0 ) * -1.0 ) + // ********** private data ********** static DG_DRAIN_STATE_T drainState; ///< Currently active drain state. static U32 drainEmptyTareTimerCtr; ///< Timer counter for delay between drain complete and load cell tare. static U32 dialysateDrainStartTime; ///< Dialysate drain start time. +static BOOL rinseConcentrateLines; ///< Flag indicates to rinse concentrate lines. +static U32 rinseConcentrateLinesTimerCtr; ///< Timer counter for rinsing concentrate lines. // ********** private function prototypes ********** static DG_DRAIN_STATE_T handleDrainStateStart( void ); static DG_DRAIN_STATE_T handleDrainStateDrain( void ); static DG_DRAIN_STATE_T handleDrainStateTare( void ); +static DG_DRAIN_STATE_T handleRinseState( void ); /*********************************************************************//** * @brief @@ -69,9 +78,11 @@ *************************************************************************/ void initDrainMode( void ) { - drainState = DG_DRAIN_STATE_START; - drainEmptyTareTimerCtr = 0; - dialysateDrainStartTime = 0; + drainState = DG_DRAIN_STATE_START; + drainEmptyTareTimerCtr = 0; + dialysateDrainStartTime = 0; + rinseConcentrateLines = FALSE; + rinseConcentrateLinesTimerCtr = 0; } /*********************************************************************//** @@ -141,6 +152,10 @@ drainState = handleDrainStateTare(); break; + case DG_DRAIN_STATE_RINSE: + drainState = handleRinseState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_MODE_INVALID_EXEC_STATE, drainState ) drainState = DG_DRAIN_STATE_START; @@ -152,6 +167,30 @@ /*********************************************************************//** * @brief + * The getCurrentDrainState function returns the current state of the drain mode. + * @details Inputs: drainState + * @details Outputs: none + * @return the current state of drain mode. + *************************************************************************/ +DG_DRAIN_STATE_T getCurrentDrainState( void ) +{ + return drainState; +} + +/*********************************************************************//** + * @brief + * The signalDrainModeRinseConcentrateLines function sets the flag for drain + * mode to rinse concentrate lines. + * @details Inputs: none + * @details Outputs: rinseConcentrateLines + * @return none + *************************************************************************/ +void signalDrainModeRinseConcentrateLines( BOOL rinse ) +{ + rinseConcentrateLines = rinse; +} + +/*********************************************************************//** * The handleDrainStateStart function handles the drain start state of * the drain mode state machine. * @details Inputs: none @@ -187,7 +226,7 @@ // if we have reached our target drain to volume (by weight) or cannot drain anymore, we are done draining - go back to generation idle mode if ( TRUE == hasTargetDrainVolumeBeenReached( inactiveReservoir, DRAIN_WEIGHT_UNCHANGE_TIMEOUT ) ) { - setDrainPumpTargetRPM( 0 ); + signalDrainPumpHardStop(); if ( DG_RESERVOIR_1 == inactiveReservoir ) { @@ -234,25 +273,52 @@ { drainEmptyTareTimerCtr = 0; tareLoadCellsAtEmpty( inactiveReservoir ); - requestNewOperationMode( DG_MODE_GENE ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_CLOSED ); + + if ( TRUE == rinseConcentrateLines ) + { + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, RINSE_SPEED ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, RINSE_SPEED ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + } + rinseConcentrateLinesTimerCtr = 0; + result = DG_DRAIN_STATE_RINSE; } return result; } /*********************************************************************//** * @brief - * The getCurrentDrainState function returns the current state of the drain mode. - * @details Inputs: drainState - * @details Outputs: none - * @return the current state of drain mode. + * The handleRinseState function handles the tare state of the drain mode + * state machine. + * @details Inputs: drainEmptyTareTimerCtr + * @details Outputs: drainEmptyTareTimerCtr + * @return the next state *************************************************************************/ -DG_DRAIN_STATE_T getCurrentDrainState( void ) +static DG_DRAIN_STATE_T handleRinseState( void ) { - return drainState; + DG_DRAIN_STATE_T result = DG_DRAIN_STATE_RINSE; + + if ( TRUE == rinseConcentrateLines ) + { + if ( ++rinseConcentrateLinesTimerCtr > RINSE_CONCENTRATE_LINES_WAIT ) + { + rinseConcentrateLinesTimerCtr = 0; + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); + requestNewOperationMode( DG_MODE_GENE ); + } + } + else + { + requestNewOperationMode( DG_MODE_GENE ); + } + + return result; } /**@}*/ Index: firmware/App/Modes/ModeDrain.h =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeDrain.h (.../ModeDrain.h) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeDrain.h (.../ModeDrain.h) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -38,6 +38,7 @@ U32 execDrainMode( void ); // execute the drain mode state machine DG_DRAIN_STATE_T getCurrentDrainState( void ); // get the current state of the drain mode. +void signalDrainModeRinseConcentrateLines( BOOL rinse ); // Signal drain mode to rinse concentrate lines. /**@}*/ Index: firmware/App/Modes/ModeFault.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -84,6 +84,8 @@ *************************************************************************/ U32 execFaultMode( void ) { + deenergizeActuators(); + // execute current fault state switch ( faultState ) { Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -47,7 +47,6 @@ #define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. #define EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ( 5 * MS_PER_SECOND ) ///< Persistent period for empty bottle detect. - #define CONCENTRATE_PUMP_PRIME_INTERVAL ( 3 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Persistent time interval for concentrate pumps prime. #define ACID_BICARB_CONCENTRATE_ADDITION_MULTIPLER 1.06 ///< Acid and bicarbonate concentrates make up around 6% to total volume. @@ -324,15 +323,16 @@ DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_BICARB_PUMP_CHECK; DG_BICARB_CONCENTRATES_RECORD_T bicarb = getBicarbConcentrateCalRecord(); F32 const measuredROFlowRate_mL_min = getMeasuredROFlowRate() * ML_PER_LITER; - F32 const bicarbPumpFlowRate_mL_min = measuredROFlowRate_mL_min * bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio + + F32 bicarbPumpFlowRate_mL_min = measuredROFlowRate_mL_min * bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio + CONCENTRATE_PUMP_PRIME_EXTRA_SPEED_ML_MIN; - #ifndef DISABLE_DIALYSATE_CHECK F32 const bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); #else - F32 const bicarbConductivity = MIN_BICARB_CONCENTRATE_CONDUCTIVITY; + F32 const bicarbConductivity = MAX_BICARB_CONCENTRATE_CONDUCTIVITY; #endif + bicarbPumpFlowRate_mL_min = MIN( bicarbPumpFlowRate_mL_min, CONCENTRATE_PUMP_MAX_SPEED ); + if ( MIN_BICARB_CONCENTRATE_CONDUCTIVITY <= bicarbConductivity ) { // Reduce acid pump speed after reaching minimum conductivity @@ -385,9 +385,11 @@ #ifndef DISABLE_DIALYSATE_CHECK F32 const acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); #else - F32 const acidConductivity = MIN_ACID_CONCENTRATE_CONDUCTIVITY; + F32 const acidConductivity = MAX_ACID_CONCENTRATE_CONDUCTIVITY; #endif + acidPumpFlowRate_mL_min = MIN( acidPumpFlowRate_mL_min, CONCENTRATE_PUMP_MAX_SPEED ); + if ( MIN_ACID_CONCENTRATE_CONDUCTIVITY <= acidConductivity ) { // Reduce acid pump speed after reaching minimum conductivity @@ -437,10 +439,12 @@ { // Prime mixing before deliver result to reservoir handleDialysateMixing( measuredROFlowRate_mL_min ); +#ifndef DISABLE_MIXING requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); if ( concentratePumpPrimeCount++ > CONCENTRATE_PUMP_PRIME_INTERVAL ) +#endif { setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; @@ -520,7 +524,7 @@ result = DG_FILL_MODE_STATE_PAUSED; } #endif - +#ifndef DISABLE_MIXING if ( ( ACID_CONCENTRATION_BOTTLE_VOLUME_ML - getF32OverrideValue( &usedAcidVolume_mL ) ) <= CONCENTRATION_BOTTLE_LOW_VOLUME_ML ) { activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); @@ -530,18 +534,18 @@ { activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); } - +#endif // If we've reached our target fill to volume (by weight), we're done filling - go back to generation idle mode - if ( ( TRUE == hasTargetFillVolumeBeenReached( inactiveReservoir ) ) || ( ( integratedVolume_mL - reservoirBaseWeight ) >= MAX_RESERVOIR_VOLUME_ML ) ) + if ( TRUE == hasTargetFillVolumeBeenReached( inactiveReservoir ) ) { F32 const filledVolume_mL = getReservoirWeight( inactiveReservoir ) - reservoirBaseWeight; F32 const integratedVolumeToLoadCellReadingPercent = fabs( 1 - ( filledVolume_mL / integratedVolume_mL ) ); - F32 const avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; + F32 const avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; // TODO - should we be checking this below? F32 const avgDialysateConductivity = dialysateConductivityTotal / conductivitySampleCount; if ( integratedVolumeToLoadCellReadingPercent > FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE ) { -#ifndef DISABLE_MIXING +#ifndef DISABLE_FLOW_CHECK_IN_FILL SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FLOW_METER_CHECK_FAILURE, filledVolume_mL, integratedVolume_mL ); #endif } Index: firmware/App/Modes/ModeFlush.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -49,13 +49,13 @@ #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. // Flush drain path state defines -#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. TODo it was 2 minutes +#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * 60 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. // Flush dialysate state defines -#define FLUSH_DIALYSATE_WAIT_TIME_MS ( 0.5 * 60 * MS_PER_SECOND ) ///< Flush dialysate wait time in milliseconds. +#define FLUSH_DIALYSATE_WAIT_TIME_MS ( 1 * 60 * MS_PER_SECOND ) ///< Flush dialysate wait time in milliseconds. // Flush concentrate straws state defines -#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 0.5 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. todo was 3 minutes +#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 3 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. #define ACID_PUMP_SPEED_ML_PER_MIN -30.0 ///< Acid pump speed in mL/min. // The bicarb pump is 2% faster than the acid pump to create a flow from acid to bicarb line during flush #define BICARB_PUMP_SPEED_ML_PER_MIN 30.6 ///< Bicarb pump speed in mL/min. @@ -303,6 +303,7 @@ // Close VPi to prevent wasting water setValveState( VPI, VALVE_STATE_CLOSED ); + // Set the actuators to drain R1 setValveState( VRD1, VALVE_STATE_OPEN ); @@ -337,7 +338,6 @@ { if ( TRUE == isThisInitialDrain ) { - // Request a tare for reservoir 1 tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); } Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -108,7 +108,6 @@ // the new PWMs for the main and small primary heaters #ifndef DISABLE_FLOW_CONTROL_TREATMENT setROPumpTargetFlowRate( TARGET_FLUSH_LINES_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); - setHeaterTargetTemperature( DG_PRIMARY_HEATER, 39.0 ); // TODO remove this line. It comes form HD this for testing only startHeater( DG_PRIMARY_HEATER ); #endif Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -508,6 +508,9 @@ } else { + tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); + tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); + // Assume reservoir 2 is full and drain it rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -19,6 +19,7 @@ #include "ConcentratePumps.h" #include "ConductivitySensors.h" #include "CPLD.h" +#include "DialysateFlow.h" #include "DrainPump.h" #include "Fans.h" #include "FPGA.h" @@ -201,6 +202,11 @@ postState = handlePOSTStatus( testStatus ); break; + case DG_POST_STATE_DIALYSATE_FLOW_SENSOR: + testStatus = execDialysateFlowMeterSelfTest(); + postState = handlePOSTStatus( testStatus ); + break; + case DG_POST_STATE_WATCHDOG: testStatus = execWatchdogTest(); postState = handlePOSTStatus( testStatus ); @@ -291,15 +297,15 @@ { DG_POST_STATE_T result = postState; - if ( ( SELF_TEST_STATUS_PASSED == testStatus ) || ( SELF_TEST_STATUS_FAILED == testStatus ) ) + if ( ( testStatus == SELF_TEST_STATUS_PASSED ) || ( testStatus == SELF_TEST_STATUS_FAILED ) ) { - BOOL passed = ( SELF_TEST_STATUS_PASSED == testStatus ? TRUE : FALSE ); + BOOL passed = ( testStatus == SELF_TEST_STATUS_PASSED ? TRUE : FALSE ); // Broadcast passed POST result sendPOSTTestResult( (DG_POST_STATE_T)((int)postState), passed ); // Move on to next POST test result = (DG_POST_STATE_T)((int)postState + 1); - if ( SELF_TEST_STATUS_FAILED == testStatus ) + if ( testStatus == SELF_TEST_STATUS_FAILED ) { tempPOSTPassed = FALSE; } Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -20,6 +20,7 @@ #include "AlarmMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" +#include "SafetyShutdown.h" #include "SystemComm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -32,6 +33,9 @@ // ********** private definitions ********** +/// Interval (ms/task time) at which the alarm information is published on the CAN bus. +#define ALARM_INFO_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) + // *** This declaration will cause a compiler error if ALARM_TABLE does not have same # of alarms as the Alarm_List enumeration. U08 alarmTableSizeAssertion[ ( ( sizeof( ALARM_TABLE ) / sizeof( ALARM_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; @@ -40,14 +44,20 @@ const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; ///< A blank alarm data record for alarms that do not include alarm data when triggered. +#define SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. + // ********** private data ********** static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Array of current state of each alarm static BOOL alarmConditionIsActive[ NUM_OF_ALARM_IDS ]; ///< Array of flag indicates if an alarm condition is active +static U32 alarmInfoPublicationTimerCounter = 0; ///< Used to schedule alarm information publication to CAN bus. +/// Interval (in task intervals) at which to publish alarm information to CAN bus. +static OVERRIDE_U32_T alarmInfoPublishInterval = { ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, 0 }; // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); +static void publishAlarmInfo( void ); /*********************************************************************//** * @brief @@ -78,6 +88,9 @@ void execAlarmMgmt( void ) { // TODO - any alarm audio or LED/lamp management for DG? + + // Publish alarm information at interval + publishAlarmInfo(); } /*********************************************************************//** @@ -246,6 +259,26 @@ /*********************************************************************//** * @brief + * The publishAlarmInfo function publishes alarm information at the set + * interval. + * @details Inputs: + * @details Outputs: alarm information are published to CAN bus. + * @return none + *************************************************************************/ +static void publishAlarmInfo( void ) +{ + // Publish voltages monitor data on interval + if ( ++alarmInfoPublicationTimerCounter >= getU32OverrideValue( &alarmInfoPublishInterval ) ) + { + BOOL safetyActivated = isSafetyShutdownActivated(); + + broadcastData( MSG_ID_DG_ALARM_INFO, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&safetyActivated, sizeof( BOOL ) ); + alarmInfoPublicationTimerCounter = 0; + } +} + +/*********************************************************************//** + * @brief * The checkPersistentAlarm function triggers/clears an alarm if an alarm condition * has persisted/cleared over given time limit. * @details Inputs: none @@ -333,4 +366,91 @@ return result; } +/*********************************************************************//** + * @brief + * The testClearAllAlarms function clears all active alarms, even if they + * are non-recoverable or faults. The caller of this function must provide + * the correct 32-bit key. A Dialin user must also be logged into DG. + * @details Inputs: none + * @details Outputs: alarmIsActive[], alarmStartedAt[] + * @param key 32-bit supervior alarm key required to perform this function + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testClearAllAlarms( U32 key ) +{ + BOOL result = FALSE; + + // Verify key + if ( SUPERVISOR_ALARM_KEY == key ) + { + // Verify tester has logged in with HD + if ( TRUE == isTestingActivated() ) + { + ALARM_ID_T a; + + // Clear all active alarms + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { + if ( TRUE == alarmIsActive[ a ] ) + { + U32 al = (U32)a; + + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_DG_ALARM, (U08*)&al, sizeof( U32 ) ); + alarmIsActive[ a ] = FALSE; + } + } + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetAlarmInfoPublishIntervalOverride function sets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @param ms milliseconds between alarm info broadcasts + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmInfoPublishIntervalOverride( U32 ms ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = ms / TASK_GENERAL_INTERVAL; + + result = TRUE; + alarmInfoPublishInterval.ovData = intvl; + alarmInfoPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmInfoPublishIntervalOverride function resets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmInfoPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmInfoPublishInterval.override = OVERRIDE_RESET; + alarmInfoPublishInterval.ovData = alarmInfoPublishInterval.ovInitData; + } + + return result; +} + /**@}*/ Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -92,6 +92,9 @@ BOOL testSetAlarmStateOverride( U32 alarmID, BOOL value ); BOOL testResetAlarmStateOverride( U32 alarmID ); +BOOL testClearAllAlarms( U32 key ); +BOOL testSetAlarmInfoPublishIntervalOverride( U32 ms ); +BOOL testResetAlarmInfoPublishIntervalOverride( void ); /**@}*/ Index: firmware/App/Services/CommBuffers.c =================================================================== diff -u -rd45c21793bdd738fb325eb7ff4446f50c2c8526d -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision d45c21793bdd738fb325eb7ff4446f50c2c8526d) +++ firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 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 CommBuffers.c +* @file CommBuffers.c * -* @author (last) Quang Nguyen -* @date (last) 26-Aug-2020 +* @author (last) Sean Nash +* @date (last) 25-Jun-2021 * -* @author (original) Dara Navaei -* @date (original) 05-Nov-2019 +* @author (original) Dara Navaei +* @date (original) 05-Nov-2019 * ***************************************************************************/ Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -82,8 +82,8 @@ #define FPGA_FLUIDLEAK_STATE_MASK 0x0004 ///< Bit mask for fluid leak detector. #define FLUID_DOOR_SWITCH_MASK 0x08 ///< Fluid door switch bit mask. -#define CONCENTRATE_CAP_SWITCH_MASK 0x10 ///< Concentrate cap switch bit mask -#define DIALYSATE_CAP_SWITCH_MASK 0x20 ///< Dialysate cap switch bit mask.. +#define DIALYSATE_CAP_SWITCH_MASK 0x10 ///< Dialysate cap switch bit mask. +#define CONCENTRATE_CAP_SWITCH_MASK 0x1A ///< Concentrate cap switch bit mask. #define FPGA_POWER_OUT_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< FPGA power out timeout in milliseconds. #define FPGA_GPIO_POWER_STATUS_PIN 7 ///< FPGA GPIO power status pin @@ -186,16 +186,13 @@ U16 fpgaFanIn3Pulse; ///< Reg 400. Fan inlet 3 pulse time in 2.5 resolution U16 fpgaFanOut3Pulse; ///< Reg 402. Fan outlet 3 pulse time in 2.5 resolution U16 fpgaTimerCount_ms; ///< Reg 404. Internal FPGA timer count in ms. - - U16 fpgaADCVccInt; ///< Reg 406. Internal FPGA Vcc Voltage. - U16 fpgaADCVccAux; ///< Reg 408. Internal FPGA Vcc auxiliary voltage. - U16 fpgaADCVPVN; ///< Reg 410. Internal FPGA VPVN voltage. - - U16 fpgaOpenRegister; ///< Reg 412. Open register. - U16 fpgaDrainPumpSpeedFeedback; ///< Reg 414. Drain pump speed feedback. - U16 fpgaDrainPumpCurrentFeedback; ///< Reg 416. Drain pump current feedback. - - U16 fpgaFMPROFlowTemporary; ///< Reg 418. FMP flow sensor temporary register. + U16 fpgaVccIntVoltage; ///< Req 406. Internal FPGA Vcc Int voltage + U16 fpgaVccAuxVoltage; ///< Req 408. Internal FPGA Vcc Aux voltage + U16 fpgaVpvnVoltage; ///< Req 410. Internal FPGA VPVN voltage + U16 fpgaRoPumpFeedBack; ///< Req 412. Internal FPGA RO pump feedback register + U16 fpgaDrainPumpSpeedMeasure; ///< Req 414. Drain pump speed measurement + U16 fpgaDrainPumpCurrent; ///< Req 416. Drain pump electrical current measurement + U16 fpgaDialysateFlowRate; ///< Req 418. Dialysate flow rate measurement } DG_FPGA_SENSORS_T; typedef struct @@ -1190,6 +1187,18 @@ /*********************************************************************//** * @brief + * The getFPGADialysateFlowRate function gets the latest dialysate flow rate. + * @details Inputs: fpgaSensorReadings.fpgaDialysateFlowRate + * @details Outputs: none + * @return last dialysate flow rate reading + *************************************************************************/ +U16 getFPGADialysateFlowRate( void ) +{ + return fpgaSensorReadings.fpgaDialysateFlowRate; +} + +/*********************************************************************//** + * @brief * The getFPGADrainPumpSpeed function gets the latest sensed drain pump speed. * @details Inputs: fpgaSensorReadings.fpgaDrainPumpSpeed * @details Outputs: none Index: firmware/App/Services/FPGA.h =================================================================== diff -u -r1c2f96bf994157b11c0c32ddaf96fc91a9a1da1d -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision 1c2f96bf994157b11c0c32ddaf96fc91a9a1da1d) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -5,13 +5,13 @@ * 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 FPGA.h +* @file FPGA.h * -* @author (last) H. Nguyen -* @date (last) 21-Oct-2021 +* @author (last) Dara Navaei +* @date (last) 09-Nov-2021 * -* @author (original) Dara Navaei -* @date (original) 05-Nov-2019 +* @author (original) Dara Navaei +* @date (original) 05-Nov-2019 * ***************************************************************************/ Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r012ee7b4f72e47aa351eb723abca0e3104ea677b -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 012ee7b4f72e47aa351eb723abca0e3104ea677b) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -1,24 +1,25 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 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 Reservoirs.c +* @file Reservoirs.c * -* @author (last) Quang Nguyen -* @date (last) 26-Aug-2020 +* @author (last) Dara Navaei +* @date (last) 11-Nov-2021 * -* @author (original) Sean -* @date (original) 18-Mar-2020 +* @author (original) Sean +* @date (original) 18-Mar-2020 * ***************************************************************************/ #include // for memcpy() #include "LoadCell.h" #include "ModeDrain.h" +#include "MessageSupport.h" #include "ModeGenIdle.h" #include "OperationModes.h" #include "Pressures.h" @@ -90,8 +91,8 @@ /*********************************************************************//** * @brief * The execReservoirs function manages periodic tasks for the Reservoirs module. - * @details Inputs: none - * @details Outputs: Reservoir data broadcast on interval + * @details Inputs: reservoirDataPublicationTimerCounter + * @details Outputs: reservoirDataPublicationTimerCounter * @return none *************************************************************************/ void execReservoirs( void ) @@ -105,11 +106,14 @@ // publish active reservoir, fill/drain volume targets at 1 Hz. if ( ++reservoirDataPublicationTimerCounter >= RESERVOIR_DATA_PUB_INTERVAL ) - { - U32 actRes = getU32OverrideValue( &activeReservoir ); - U32 filVol = getU32OverrideValue( &fillVolumeTargetMl ); - U32 drnVol = getU32OverrideValue( &drainVolumeTargetMl ); - broadcastReservoirData( actRes, filVol, drnVol ); + { + RESERVOIR_DATA_T data; + + data.activeReservoir = getU32OverrideValue( &activeReservoir ); + data.fillToVolumeMl = getU32OverrideValue( &fillVolumeTargetMl ); + data.drainToVolumeMl = getU32OverrideValue( &drainVolumeTargetMl ); + + broadcastData( MSG_ID_DG_RESERVOIR_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( RESERVOIR_DATA_T ) ); reservoirDataPublicationTimerCounter = 0; } } Index: firmware/App/Services/Reservoirs.h =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -39,8 +39,8 @@ /// Fill command data structure. typedef struct { - U32 fillToVolumeMl; ///< Target volume to fill to (in mL) - U32 cmd; ///< General command (start/stop) + U32 fillToVolumeMl; ///< Target volume to fill to (in mL) + U32 cmd; ///< General command (start/stop) } FILL_CMD_T; /// Drain command data structure. @@ -55,17 +55,17 @@ /// DG command response data record. typedef struct { - U32 commandID; ///< The command DG is responding to - BOOL rejected; ///< Flag indicates if the command has been rejected - U32 rejectCode; ///< Reason code for rejecting the command + U32 commandID; ///< The command DG is responding to + BOOL rejected; ///< Flag indicates if the command has been rejected + U32 rejectCode; ///< Reason code for rejecting the command } DG_CMD_RESPONSE_T; /// Reservoir data struct. typedef struct { - U32 activeReservoir; ///< Active reservoir ID - U32 fillToVolumeMl; ///< Volume target to fill to - U32 drainToVolumeMl; ///< Volume target to drain to + U32 activeReservoir; ///< Active reservoir ID + U32 fillToVolumeMl; ///< Volume target to fill to + U32 drainToVolumeMl; ///< Volume target to drain to } RESERVOIR_DATA_T; #pragma pack(pop) Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -54,9 +54,9 @@ #define MAX_COMM_CRC_FAILURES 5 ///< maximum number of CRC errors within window period before alarm #define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window -#define MSG_NOT_ACKED_TIMEOUT_MS ( MS_PER_SECOND * 1 ) ///< maximum time for a Denali message that requires ACK to be ACK'd -#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm -#define PENDING_ACK_LIST_SIZE 25 ///< maximum number of Delanli messages that can be pending ACK at any given time +#define MSG_NOT_ACKED_TIMEOUT_MS 150 ///< maximum time for a Denali message that requires ACK to be ACK'd +#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm +#define PENDING_ACK_LIST_SIZE 25 ///< maximum number of Delanli messages that can be pending ACK at any given time #pragma pack(push, 1) @@ -1094,10 +1094,18 @@ handleTestROMeasuredFlowOverrideRequest( message ); break; + case MSG_ID_DIALYSATE_MEASURED_FLOW_OVERRIDE: + handleTestDialysateMeasuredFlowOverrideRequest( message ); + break; + case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: handleTestROPumpDataBroadcastIntervalOverrideRequest( message ); break; + case MSG_ID_DIALYSATE_FLOW_SEND_INTERVAL_OVERRIDE: + handleTestDialysateFlowDataBroadcastIntervalOverrideRequest( message ); + break; + case MSG_ID_DRAIN_PUMP_SET_RPM: handleTestSetDrainPumpRPM( message ); break; @@ -1275,11 +1283,11 @@ break; case MSG_ID_FILTER_FLUSH_TIME_PERIOD_OVERRIDE: - handleFilterFlushTimePeriodOverride( message ); + handleFilterFlushTimePeriodOverride(message); break; - case MSG_ID_DG_FANS_RPM_OVERRIDE: - handleFansRPMOverride( message ); + case MSG_ID_DG_BLOCK_MESSAGE_TRANSMISSION: + handleTestBlockMessagesRequest( message ); break; case MSG_ID_DG_STOP_RTC_CLOCK: @@ -1290,6 +1298,14 @@ handleSetDrainPumpMeasuredRPMOverrideRequest( message ); break; + case MSG_ID_DG_SUPER_CLEAR_ALARMS_CMD: + handleTestSuperClearAlarmsRequest( message ); + break; + + case MSG_ID_DG_ALARM_INFO_SEND_INTERVAL_OVERRIDE: + handleTestAlarmInfoSendIntervalOverrideRequest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r103d68b3ba3059d3988923fb1fb8ead0eccfd526 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 103d68b3ba3059d3988923fb1fb8ead0eccfd526) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -22,15 +22,16 @@ #include "Accel.h" #include "ConcentratePumps.h" #include "ConductivitySensors.h" -#include "Fans.h" #include "FPGA.h" #include "Heaters.h" #include "ModeFlush.h" #include "ModeGenIdle.h" +#include "ModeInitPOST.h" #include "ModeStandby.h" #include "MsgQueues.h" #include "NVDataMgmt.h" #include "OperationModes.h" +#include "DialysateFlow.h" #include "Pressures.h" #include "Reservoirs.h" #include "RTC.h" @@ -55,101 +56,136 @@ #ifdef DEBUG_ENABLED #define DEBUG_EVENT_MAX_TEXT_LEN 40 #endif - -// ********** private data ********** - -static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. + +#define MAX_MSGS_BLOCKED_FOR_XMIT 8 ///< Maximum number of messages to block transmission for. + +#pragma pack(push,1) +/// Payload record structure for block message transmission request. +typedef struct +{ + U16 blockedMessages[ MAX_MSGS_BLOCKED_FOR_XMIT ]; +} BLOCKED_MSGS_DATA_T; +#pragma pack(pop) + +// ********** private data ********** + +static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. static volatile U16 nextSeqNo = 1; ///< Next sequence number. - -// ********** private function prototypes ********** - -static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); - -/*********************************************************************//** - * @brief - * The serializeMessage function serializes a given message into a given - * array of bytes. A sequence # is added to the message here and the ACK - * bit of the sequence # is set if ACK is required per parameter. A sync byte - * is inserted at the beginning of the message and an 8-bit CRC is appended to - * the end of the message. The message is queued for transmission in the given buffer. - * @details Inputs: none - * @details Outputs: given data array populated with serialized message data and queued for transmit. - * @param msg message to serialize - * @param buffer outgoing buffer that message should be queued in - * @param ackReq is an acknowledgement from receiver required? - * @return size (in bytes) of serialized message populated in given data array. - *************************************************************************/ -U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) -{ - BOOL result = FALSE; - BOOL error = FALSE; - U32 msgSize = 0; - U32 sizeMod, sizePad; - U32 i; - U08 crc; - U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data - - // prefix data with message sync byte - data[ msgSize++ ] = MESSAGE_SYNC_BYTE; - - // set sequence # and ACK bit (unless this is an ACK to a received message) - if ( msg.hdr.msgID != MSG_ID_ACK ) - { - // thread protect next sequence # access & increment - _disable_IRQ(); - msg.hdr.seqNo = nextSeqNo; - nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); - _enable_IRQ(); - if ( TRUE == ackReq ) - { - msg.hdr.seqNo *= -1; - } - } - - // calculate message CRC - crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); - - // serialize message header data - memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); - msgSize += sizeof( MESSAGE_HEADER_T ); - - // serialize message payload (only used bytes per payloadLen field) - memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); - msgSize += msg.hdr.payloadLen; - - // add 8-bit CRC - data[ msgSize++ ] = crc; - - // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) - sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; - sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); - for ( i = 0; i < sizePad; i++ ) - { - data[ msgSize++ ] = 0; - } - - // if ACK required, add to pending ACK list - if ( TRUE == ackReq ) - { - if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) - { - error = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) - } - } - - if ( FALSE == error ) - { - // add serialized message data to appropriate out-going comm buffer - result = addToCommBuffer( buffer, data, msgSize ); - } - - return result; -} +/// List of message IDs that are requested not to be transmitted. +static BLOCKED_MSGS_DATA_T blockedMessagesForXmit = { 0, 0, 0, 0, 0, 0, 0, 0 }; +// ********** private function prototypes ********** + +static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); +static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); + /*********************************************************************//** * @brief + * The serializeMessage function serializes a given message into a given + * array of bytes. A sequence # is added to the message here and the ACK + * bit of the sequence # is set if ACK is required per parameter. A sync byte + * is inserted at the beginning of the message and an 8-bit CRC is appended to + * the end of the message. The message is queued for transmission in the given buffer. + * @details Inputs: none + * @details Outputs: given data array populated with serialized message data and queued for transmit. + * @param msg message to serialize + * @param buffer outgoing buffer that message should be queued in + * @param ackReq is an acknowledgement from receiver required? + * @return size (in bytes) of serialized message populated in given data array. + *************************************************************************/ +U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) +{ + BOOL result = FALSE; + BOOL error = FALSE; + BOOL blocked = FALSE; + U32 msgSize = 0; + U32 sizeMod, sizePad; + U32 i; + U08 crc; + U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data + + // Check to see if tester has requested this message not be transmitted + if ( TRUE == isTestingActivated() ) + { + U32 i; + + for ( i = 0; i < MAX_MSGS_BLOCKED_FOR_XMIT; i++ ) + { + if ( msg.hdr.msgID == blockedMessagesForXmit.blockedMessages[ i ] ) + { + blocked = TRUE; + break; + } + } + } + // Serialize and queue message for transmission unless this message is blocked + if ( blocked != TRUE ) + { + // prefix data with message sync byte + data[ msgSize++ ] = MESSAGE_SYNC_BYTE; + + // set sequence # and ACK bit (unless this is an ACK to a received message) + if ( msg.hdr.msgID != MSG_ID_ACK ) + { + // thread protect next sequence # access & increment + _disable_IRQ(); + msg.hdr.seqNo = nextSeqNo; + nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); + _enable_IRQ(); + if ( TRUE == ackReq ) + { + msg.hdr.seqNo *= -1; + } + } + + // calculate message CRC + crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); + + // serialize message header data + memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); + msgSize += sizeof( MESSAGE_HEADER_T ); + + // serialize message payload (only used bytes per payloadLen field) + memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); + msgSize += msg.hdr.payloadLen; + + // add 8-bit CRC + data[ msgSize++ ] = crc; + + // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) + sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; + sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); + for ( i = 0; i < sizePad; i++ ) + { + data[ msgSize++ ] = 0; + } + + // if ACK required, add to pending ACK list + if ( TRUE == ackReq ) + { + if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) + { + error = TRUE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + } + } + + if ( FALSE == error ) + { + // add serialized message data to appropriate out-going comm buffer + result = addToCommBuffer( buffer, data, msgSize ); + } + } + else + { + result = TRUE; // If message blocked, return successful transmission + } + + return result; +} + +/*********************************************************************//** + * @brief * The sendACKMsg function constructs and queues for transmit an ACK message * for a given received message. * @details Inputs: none @@ -344,7 +380,6 @@ return result; } - // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** @@ -883,17 +918,18 @@ { BOOL result = FALSE; - if ( message->hdr.payloadLen == sizeof( U32 ) ) + if ( message->hdr.payloadLen == sizeof( BOOL ) ) { BOOL startingTreatment; + DG_OP_MODE_T dgMode = getCurrentOperationMode(); - memcpy( &startingTreatment, message->payload, sizeof( U32 ) ); + memcpy( &startingTreatment, message->payload, sizeof( BOOL ) ); - if ( ( DG_MODE_STAN == getCurrentOperationMode() ) && ( TRUE == startingTreatment ) ) + if ( ( DG_MODE_STAN == dgMode ) && ( TRUE == startingTreatment ) ) { result = requestDGStart(); } - else if ( ( DG_MODE_GENE == getCurrentOperationMode() ) && ( FALSE == startingTreatment ) ) + else if ( ( dgMode >= DG_MODE_GENE ) && ( dgMode <= DG_MODE_DRAI ) && ( FALSE == startingTreatment ) ) { result = requestDGStop(); } @@ -1421,15 +1457,15 @@ } -/*********************************************************************//** - * @brief - * The handleTestROMeasuredFlowOverrideRequest function handles a request to - * override the RO flow rate. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestROMeasuredFlowOverrideRequest function handles a request to + * override the RO flow rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1455,6 +1491,38 @@ /*********************************************************************//** * @brief + * The handleTestDialysateMeasuredFlowOverrideRequest function handles a request to + * override the Dialysate flow rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDialysateMeasuredFlowOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetMeasuredDialysateFlowRateOverride( payload.state.f32 ); + } + else + { + result = testResetMeasuredDialysateFlowRateOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleTestROPumpDataBroadcastIntervalOverrideRequest function handles * a request to override the broadcast interval for RO pump data. * @details Inputs: none @@ -1487,6 +1555,38 @@ /*********************************************************************//** * @brief + * The handleTestDialysateFlowDataBroadcastIntervalOverrideRequest function handles + * a request to override the broadcast interval for dialysate flow data. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDialysateFlowDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetDialysateFlowDataPublishIntervalOverride( payload.state.u32 ); + } + else + { + result = testResetDialysateFlowDataPublishIntervalOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleTestSetDrainPumpRPM function handles a request to set the drain * pump speed set point (in RPM). * @details Inputs: none @@ -2571,7 +2671,6 @@ { BOOL status = FALSE; BOOL result = FALSE; - U08* payloadPtr = message->payload; if ( 0 == message->hdr.payloadLen ) { @@ -2896,37 +2995,6 @@ } /*********************************************************************//** - * @brief - * The handleFansRPMOverride function handles a request to override a fans RPM value. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleFansRPMOverride( MESSAGE_T *message ) -{ - TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; - BOOL result = FALSE; - - // verify payload length - if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) - { - memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); - if ( FALSE == payload.reset ) - { - result = testSetFanRPMOverride( payload.index, payload.state.f32 ); - } - else - { - result = testResetFanRPMOverride( payload.index ); - } - } - - // respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** * @brief * The handleStopDGRTCClock function handles a request to stop the RTC clock. * @details Inputs: none @@ -3014,4 +3082,88 @@ return result; } +/*********************************************************************//** + * @brief + * The handleTestBlockMessagesRequest function handles a request to + * block transmission of specific message(s). + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestBlockMessagesRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(BLOCKED_MSGS_DATA_T) == message->hdr.payloadLen ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + memcpy( &blockedMessagesForXmit.blockedMessages[0], message->payload, sizeof(BLOCKED_MSGS_DATA_T) ); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestAlarmInfoSendIntervalOverrideRequest function handles a + * request to override the HD alarm information broadcast interval. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestAlarmInfoSendIntervalOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetAlarmInfoPublishIntervalOverride( payload.state.u32 ); + } + else + { + result = testResetAlarmInfoPublishIntervalOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSuperClearAlarmsRequest function handles a request to clear + * all active alarms on DG. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSuperClearAlarmsRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(U32) ) + { + U32 key; + + memcpy( &key, message->payload, sizeof(U32) ); + result = testClearAllAlarms( key ); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -24,13 +24,15 @@ #include "Fans.h" #include "FluidLeak.h" #include "LoadCell.h" +#include "MessageSupport.h" #include "ModeChemicalDisinfect.h" #include "ModeFlush.h" #include "ModeHeatDisinfect.h" #include "MsgQueues.h" #include "NVDataMgmt.h" #include "Reservoirs.h" #include "ROPump.h" +#include "DialysateFlow.h" #include "Switches.h" #include "TemperatureSensors.h" #include "Thermistors.h" @@ -52,6 +54,8 @@ // ********** public function prototypes ********** +U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ); + // ACK MSG BOOL sendACKMsg( MESSAGE_T *message ); @@ -180,9 +184,15 @@ // MSG_ID_RO_MEASURED_FLOW_OVERRIDE: void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ); +// MSG_ID_DIALYSATE_MEASURED_FLOW_OVERRIDE: +void handleTestDialysateMeasuredFlowOverrideRequest( MESSAGE_T *message ); + // MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: void handleTestROPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); +// MSG_ID_DIALYSATE_FLOW_SEND_INTERVAL_OVERRIDE: +void handleTestDialysateFlowDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + // MSG_ID_DRAIN_PUMP_SET_RPM void handleTestSetDrainPumpRPM( MESSAGE_T *message ); @@ -270,7 +280,10 @@ // MSG_ID_DG_RO_PUMP_DUTY_CYCLE_OVERRIDE void handleTestROPumpDutyCycleOverride( MESSAGE_T *message ); -// MSG_ID_DG_RO_PUMP_TARGET_FLOW_OVERRIDE +// MSG_ID_DG_RO_FLOW_RATE_OVERRIDE +void handleTestMeasuredROFlowRateOverride( MESSAGE_T *message ); + +// MSG_ID_DG_SET_RO_PUMP_TARGET_FLOW void handleTestROPumpTargetFlowOverride( MESSAGE_T *message ); // MSG_ID_DG_RO_PUMP_TARGET_PRESSURE_OVERRIDE @@ -321,15 +334,21 @@ // MSG_ID_FILTER_FLUSH_TIME_PERIOD_OVERRIDE void handleFilterFlushTimePeriodOverride( MESSAGE_T *message ); -// MSG_ID_DG_FANS_RPM_OVERRIDE -void handleFansRPMOverride( MESSAGE_T *message ); +// MSG_ID_DG_BLOCK_MESSAGE_TRANSMISSION +void handleTestBlockMessagesRequest( MESSAGE_T *message ); // MSG_ID_DG_STOP_RTC_CLOCK void handleStopDGRTCClock( MESSAGE_T * message ); // MSG_ID_DG_DRAIN_PUMP_MEASURED_RPM_OVERRIDE void handleSetDrainPumpMeasuredRPMOverrideRequest( MESSAGE_T *message ); +// MSG_ID_DG_ALARM_INFO_SEND_INTERVAL_OVERRIDE +void handleTestAlarmInfoSendIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_DG_SUPER_CLEAR_ALARMS_CMD +void handleTestSuperClearAlarmsRequest( MESSAGE_T *message ); + /**@}*/ #endif Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -18,6 +18,7 @@ #include "gio.h" #include "lin.h" +#include "AlarmMgmt.h" #include "ConcentratePumps.h" #include "DrainPump.h" #include "Fans.h" @@ -123,7 +124,10 @@ // Run non-volatile data management state machine that sends the data record // to Dialin execNVDataMgmtProcessRecord(); - + + // Run alarm management + execAlarmMgmt(); + // manage data to be transmitted to other sub-systems execSystemCommTx(); Index: firmware/App/Tasks/TaskPriority.c =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r2b60564ac818a6692b714dfd9920d2e2fcf0937d --- firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision 2b60564ac818a6692b714dfd9920d2e2fcf0937d) @@ -27,6 +27,7 @@ #include "LoadCell.h" #include "Pressures.h" #include "ROPump.h" +#include "DialysateFlow.h" #include "TaskPriority.h" #include "TemperatureSensors.h" #include "Valves.h" @@ -71,10 +72,8 @@ // Monitor load cells execLoadCell(); -#ifndef DISABLE_HEATERS_AND_TEMPS // Temperature sensors read execTemperatureSensors(); -#endif // Conductivity sensors read execConductivitySensors(); @@ -100,6 +99,11 @@ execFluidLeak(); #endif + +#ifdef DIALYSATE_FLOW_METER_ENABLED + // Monitor dialysate flow meter + execDialysateFlowMeterMonitor(); +#endif // Second pass for FPGA execFPGAOut(); @@ -110,6 +114,7 @@ #ifdef TASK_TIMING_OUTPUT_ENABLED // SET_TASK_OFF(); // TODO - uncomment and define TASK_TIMING_OUTPUT_ENABLED to monitor this tasks timing #endif + } /**@}*/