Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -re8f30ca933a7c373c1a4a749ad84adb2f63b7722 -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision e8f30ca933a7c373c1a4a749ad84adb2f63b7722) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -36,7 +36,6 @@ #define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). -#define SIZE_OF_SMALL_LOAD_CELL_AVG 8 ///< Small load cell moving average has 8 samples. #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. /// States of the treatment reservoir management state machine. @@ -79,16 +78,10 @@ /// Measured weight from load cells. static OVERRIDE_F32_T loadCellWeightInGrams[ NUM_OF_LOAD_CELLS ]; -/// Filtered (8 sample) weight of reservoirs. -static F32 smFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; /// Filtered (32 sample) weight of reservoirs. static F32 lgFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; // Load cell filtering data -/// Holds load cell samples for small load cell moving average. -static F32 smLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_SMALL_LOAD_CELL_AVG ]; -static U32 smLoadCellReadingsIdx = 0; ///< Index for next sample in small load cell rolling average sample array. -static F32 smLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< Rolling total - used to calc small load cell moving average. /// Holds load cell samples for large load cell moving average. static F32 lgLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_LARGE_LOAD_CELL_AVG ]; static U32 lgLoadCellReadingsIdx = 0; ///< Index for next sample in large load cell rolling average sample array. @@ -146,12 +139,7 @@ // initialize reservoirs weights for ( i = 0; i < NUM_OF_DG_RESERVOIRS; i++ ) { - smFilteredReservoirWeightInGrams[ i ] = 0.0; lgFilteredReservoirWeightInGrams[ i ] = 0.0; - for ( j = 0; j < SIZE_OF_SMALL_LOAD_CELL_AVG; j++ ) - { - smLoadCellReadings[ i ][ j ] = 0.0; - } for ( j = 0; j < SIZE_OF_LARGE_LOAD_CELL_AVG; j++ ) { lgLoadCellReadings[ i ][ j ] = 0.0; @@ -166,9 +154,6 @@ dgCmdResp[ i ].rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; } - smLoadCellReadingsIdx = 0; - smLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; - smLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; lgLoadCellReadingsIdx = 0; lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; @@ -235,7 +220,7 @@ // Calculate volume used from active reservoir - do not accumulate if saline bolus in progress if ( SALINE_BOLUS_STATE_IN_PROGRESS != getSalineBolusState() ) { - resUseVolumeMl += ( flowRateMlPerMs * msSinceLastVolumeCalc ); // TODO - should this calc be done and kept by Dialysis sub-mode? + resUseVolumeMl += ( flowRateMlPerMs * msSinceLastVolumeCalc ); } resUseTimer = getMSTimerCount(); @@ -395,6 +380,19 @@ return inactiveRes; } + +/*********************************************************************//** + * @brief + * The hasDGCompletedReservoirSwitch function checks if DG has completed a + * switch reservoir command. + * @details Inputs: dgActiveReservoir, dgActiveReservoirSet + * @details Outputs: none + * @return TRUE if reported active reservoir is the same as set id, otherwise FALSE + *************************************************************************/ +BOOL hasDGCompletedReservoirSwitch( void ) +{ + return ( dgActiveReservoir == dgActiveReservoirSet ); +} /*********************************************************************//** * @brief @@ -468,13 +466,13 @@ /*********************************************************************//** * @brief - * The getLoadCellWeightInGrams function gets the load cell weight. + * The getLoadCellWeight function gets the current load cell weight. * @details Inputs: loadCellWeightInGrams * @details Outputs: none * @param loadCellID ID of load cell to get * @return the current load cell weight in grams *************************************************************************/ -F32 getLoadCellWeightInGrams( LOAD_CELL_ID_T loadCellID ) +F32 getLoadCellWeight( LOAD_CELL_ID_T loadCellID ) { F32 result = 0.0; @@ -499,27 +497,6 @@ /*********************************************************************//** * @brief - * The getReservoirWeightSmallFilter function gets the load cell weight - * of the given reservoir after small (8 sample) filter applied. - * @details Inputs: lgFilteredReservoirWeightInGrams[] - * @details Outputs: none - * @param resID ID of reservoir to get filtered weight for - * @return the current filtered weight of the given reservoir in grams - *************************************************************************/ -F32 getReservoirWeightSmallFilter( DG_RESERVOIR_ID_T resID ) -{ - F32 result = 0.0; - - if ( resID < NUM_OF_DG_RESERVOIRS ) - { - result = smFilteredReservoirWeightInGrams[ resID ]; - } - - return result; -} - -/*********************************************************************//** - * @brief * The getReservoirWeightLargeFilter function gets the load cell weight * of the given reservoir after large (32 sample) filter applied. * @details Inputs: lgFilteredReservoirWeightInGrams[] @@ -558,7 +535,7 @@ } else { - // TODO + // TODO - s/w fault } } @@ -615,7 +592,7 @@ } else { - // TODO + // TODO - s/w fault } } @@ -695,16 +672,11 @@ for ( res = DG_RESERVOIR_1; res < NUM_OF_DG_RESERVOIRS; res++ ) { F32 wt = ( res == DG_RESERVOIR_1 ? res1Primary : res2Primary ); - smLoadCellReadingsTotal[ res ] -= smLoadCellReadings[ res ][ smLoadCellReadingsIdx ]; lgLoadCellReadingsTotal[ res ] -= lgLoadCellReadings[ res ][ lgLoadCellReadingsIdx ]; - smLoadCellReadings[ res ][ smLoadCellReadingsIdx ] = wt; lgLoadCellReadings[ res ][ lgLoadCellReadingsIdx ] = wt; - smLoadCellReadingsTotal[ res ] += wt; lgLoadCellReadingsTotal[ res ] += wt; - smFilteredReservoirWeightInGrams[ res ] = smLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_SMALL_LOAD_CELL_AVG; lgFilteredReservoirWeightInGrams[ res ] = lgLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_LARGE_LOAD_CELL_AVG; } - smLoadCellReadingsIdx = INC_WRAP( smLoadCellReadingsIdx, 0, SIZE_OF_SMALL_LOAD_CELL_AVG - 1 ); lgLoadCellReadingsIdx = INC_WRAP( lgLoadCellReadingsIdx, 0, SIZE_OF_LARGE_LOAD_CELL_AVG - 1 ); } Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -r174c9ba02da6790f01ea9141ab1cc1d28388f2f8 -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 174c9ba02da6790f01ea9141ab1cc1d28388f2f8) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -32,7 +32,7 @@ // ********** public definitions ********** -#define DRAIN_RESERVOIR_TO_VOLUME_ML 200 ///< Drain reservoir to this volume (in mL) during treatment. +#define DRAIN_RESERVOIR_TO_VOLUME_ML 0 ///< Drain reservoir to this volume (in mL) during treatment. #ifndef V1_5_SYSTEM #define FILL_RESERVOIR_TO_VOLUME_ML 1700 ///< Fill reservoir to this volume (in mL) during treatment. #else @@ -127,6 +127,7 @@ U32 getDGSubMode( void ); DG_RESERVOIR_ID_T getDGActiveReservoir( void ); DG_RESERVOIR_ID_T getDGInactiveReservoir( void ); +BOOL hasDGCompletedReservoirSwitch( void ); F32 getDGPressure( DG_PRESSURE_SENSORS_T sensorID ); U32 getDGROPumpPressureSetPt( void ); F32 getDGROPumpFlowRateMlMin( void ); @@ -148,7 +149,8 @@ void cmdStopDG( void ); void cmdSetDGActiveReservoir( DG_RESERVOIR_ID_T resID ); void cmdChangeDGValveSetting( DG_VALVE_SETTING_ID_T valveSettingID ); -void cmdStartDGFill( U32 fillToVolMl ); +void cmdStartDGFill( U32 fillToVolMl ); +void cmdStopDGFill( void ); void cmdStartDGDrain( U32 drainToVolMl, BOOL tareLoadCell ); void cmdStartDGTrimmerHeater( void ); void cmdStopDGTrimmerHeater( void ); Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r7010cc605d12e424828fabb567102e4494901e70 -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 7010cc605d12e424828fabb567102e4494901e70) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -63,7 +63,7 @@ #define CARTRIDGE_LOADED_THRESHOLD 5000 ///< Threshold above which a cartridge is considered loaded. #define EMPTY_SALINE_BAG_THRESHOLD_MMHG -300.0 ///< Threshold below which the saline bag is considered empty (in mmHg). TODO - get real threshold from Systems -static const U32 EMPTY_SALINE_BAG_PERSISTENCE = ( 250 / TASK_GENERAL_INTERVAL ); ///< Time that saline bag looks empty before saying it is empty. TODO - use persistent alarm when updated +static const U32 EMPTY_SALINE_BAG_PERSISTENCE = ( 250 / TASK_GENERAL_INTERVAL ); ///< Time that saline bag looks empty before saying it is empty. /// Occlusion sensors minimum pressure reading limit when no cartridge is loaded. #define OCCLUSION_NO_CARTRIDGE_PRESSURE_READING_MIN 2000 /// Occlusion sensors maximum pressure reading limit when cartridge is considered loaded. @@ -118,9 +118,9 @@ /*********************************************************************//** * @brief - * The initPresOccl function initializes the initPresOccl module. + * The initPresOccl function initializes the PresOccl module. * @details Inputs: none - * @details Outputs: initPresOccl module initialized. + * @details Outputs: PresOccl module initialized. * @return none *************************************************************************/ void initPresOccl( void ) @@ -233,7 +233,7 @@ /*********************************************************************//** * @brief - * The handlePresOcclInitState function handles the pres/occl initialize state + * The handlePresOcclInitState function handles the initialize state * of the pressure/occlusion monitor state machine. * @details Inputs: TBD * @details Outputs: TBD @@ -343,8 +343,6 @@ *************************************************************************/ static void convertOcclusionPressures( void ) { - // TODO - any filtering required??? - // Occlusion sensor values have no unit - take as is bloodPumpOcclusion.data = (U32)getFPGABloodPumpOcclusion(); dialInPumpOcclusion.data = (U32)getFPGADialInPumpOcclusion(); @@ -449,7 +447,6 @@ U32 diOccl = getMeasuredDialInPumpOcclusion(); U32 doOccl = getMeasuredDialOutPumpOcclusion(); - // TODO - add persistence #ifndef DISABLE_PRESSURE_CHECKS if ( bpOccl > OCCLUSION_THRESHOLD ) { @@ -477,7 +474,7 @@ * @details Outputs: none * @return the current pressure/occlusion data publication interval (in task intervals). *************************************************************************/ -U32 getPublishPresOcclDataInterval( void ) +static U32 getPublishPresOcclDataInterval( void ) { U32 result = presOcclDataPublishInterval.data; Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r2346a0cb59957d90fe61cb3bff4ec7ffc3df10a4 -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 2346a0cb59957d90fe61cb3bff4ec7ffc3df10a4) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -82,8 +82,8 @@ #define SYRINGE_PUMP_PRIME_VOLUME_ML 0.353 ///< Target syringe prime volume (in mL). #define SYRINGE_PUMP_MAX_VOL_ERROR_ML 0.1 ///< Maximum Heparin volume error (in mL). #define SYRINGE_PUMP_MAX_RATE_ERROR_ML_HR 0.1 ///< Maximum Heparin delivery rate error (in mL/hr). -#define TEN_PCT_OVER_ALLOWANCE 1.1 ///< Allow ten percent over target before alarming on over travel. -#define FIVE_PCT_OVER_ALLOWANCE 1.05 ///< Allow five percent over target before alarming on over travel. +#define TEN_PCT_OVER_ALLOWANCE 1.1 ///< Allow 10 percent over target before alarming on over travel. +#define FIVE_PCT_OVER_ALLOWANCE 1.05 ///< Allow 5 percent over target before alarming on over travel. /// Expected position of empty in relation to home postion. #define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 11.0 ) @@ -132,6 +132,10 @@ SYRINGE_PUMP_CONTROL_FORWARD_DIR | SYRINGE_PUMP_CONTROL_32TH_STEP; +#define SYRINGE_PUMP_DAC_WRITE_ERROR_BIT 0x40 ///< Syringe pump DAC write error bit flag in FPGA register. +#define SYRINGE_PUMP_ENCODER_DIRECTION_ERROR_BITS 0x3F ///< Syringe pump encoder direction error counter bits in FPGA register. +#define SYRINGE_PUMP_ENCODER_DIRECTION_BIT 0x80 ///< Syringe pump encoder direction bit in FPGA register. + /// Defined states for the syringe pump control state machine. typedef enum SyringePump_States { @@ -179,7 +183,8 @@ static S32 syringePumpVolumeStartPosition; ///< Start position for the current volume calculation. static S32 syringePumpHomePositionOffset; ///< FPGA reported position when at home postion. static S32 syringePumpPosition1SecAgo; ///< Position recorded at last 1 Hz speed check. -static MOTOR_DIR_T syringePumpMeasuredDirection; ///< Measured direction of syringe pump. +static MOTOR_DIR_T syringePumpControllerMeasuredDirection; ///< Measured direction of syringe pump per controller. +static MOTOR_DIR_T syringePumpEncoderMeasuredDirection; ///< Measured direction of syringe pump per encoder position relative to previous. static BOOL syringePumpRetractRequested; ///< Flag indicates a retract operation is requested. static BOOL syringePumpSeekRequested; ///< Flag indicates a plunger seek operation is requested. @@ -225,7 +230,7 @@ static BOOL checkOcclusionOrEmpty( BOOL stopPump ); static BOOL checkSyringeRemoved( BOOL stopPump ); static BOOL checkMaxTravel( BOOL stopPump, S32 maxPos ); -static BOOL checkMaxMeasRate( BOOL stopPump, F32 pctMargin ); +static BOOL checkMeasRate( BOOL stopPump, F32 pctMargin ); static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ); static void publishSyringePumpData( void ); @@ -248,7 +253,8 @@ syringePumpVolumeStartPosition = 0; syringePumpHomePositionOffset = 0; syringePumpPosition1SecAgo = 0; - syringePumpMeasuredDirection = MOTOR_DIR_FORWARD; + syringePumpControllerMeasuredDirection = MOTOR_DIR_FORWARD; + syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; syringePumpDataPublicationTimerCounter = 0; syringePumpSelfTestTimerCount = 0; @@ -340,7 +346,7 @@ rejReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; } - sendHeparinCommandResponse( (U32)accepted, (U32)rejReason, (U32)heparinDeliveryState ); + sendHeparinCommandResponse( (U32)accepted, (U32)rejReason ); return accepted; } @@ -751,7 +757,7 @@ { BOOL result = FALSE; - if ( ( syringePumpState > SYRINGE_PUMP_OFF_STATE ) || ( syringePumpState < SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE ) ) + if ( ( syringePumpState <= SYRINGE_PUMP_OFF_STATE ) || ( syringePumpState >= SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE ) ) { result = TRUE; } @@ -798,7 +804,6 @@ U08 pmpStatus = getFPGASyringePumpStatus(); U08 encStatus = getFPGASyringePumpEncoderStatus(); U08 adcReadCtr = getFPGASyringePumpADCReadCounter(); - U08 adcDACStatus= getFPGASyringePumpADCandDACStatus(); // Get latest ADC data and convert to V syringePumpMeasHome.data = ( (F32)getFPGASyringePumpADCChannel2() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; @@ -812,8 +817,12 @@ // Calculate measured rate (mL/hr) calcMeasRate(); // Get measured direction - syringePumpMeasuredDirection = ( ( encStatus & 0x80 ) != 0 ? MOTOR_DIR_REVERSE : MOTOR_DIR_FORWARD ); + syringePumpControllerMeasuredDirection = ( ( encStatus & SYRINGE_PUMP_ENCODER_DIRECTION_BIT ) != 0 ? MOTOR_DIR_REVERSE : MOTOR_DIR_FORWARD ); + // TODO - calc direction from encoder pos relative to last + // syringePumpEncoderMeasuredDirection = TBD; + // TODO - check if syringe pump is on while BP is off (w/ a little persistence). + if ( syringePumpDACVrefWriteInProgress != TRUE ) { // Check ADC read is fresh @@ -824,7 +833,7 @@ lastSyringePumpADCReadCtr = adcReadCtr; // Check encoder direction error. // TODO check direction in states - if ( ( encStatus & 0x3F ) != 0) + if ( ( encStatus & SYRINGE_PUMP_ENCODER_DIRECTION_ERROR_BITS ) != 0) { // TODO - alarm? } @@ -1022,11 +1031,15 @@ syringePumpPrimeCompleted = FALSE; result = SYRINGE_PUMP_OFF_STATE; } - else if ( syringePumpMeasuredDirection != MOTOR_DIR_REVERSE ) + else if ( syringePumpControllerMeasuredDirection != MOTOR_DIR_REVERSE ) { // TODO - alarm w/ some persistence } - // TODO - if position know from prior retract, ensure we don't go lower than -TBD position + else if ( syringePumpEncoderMeasuredDirection != MOTOR_DIR_REVERSE ) + { + // TODO - alarm w/ some persistence + } + // TODO - if position known from prior retract, ensure we don't go lower than -TBD position return result; } @@ -1154,7 +1167,7 @@ stopPump = checkOcclusionOrEmpty( stopPump ); // Check for commanded vs. meas. rate - stopPump = checkMaxMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); + stopPump = checkMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); // Check position > max travel stopPump = checkMaxTravel( stopPump, syringePumpVolumeStartPosition + ( bolusVol * FIVE_PCT_OVER_ALLOWANCE * SYRINGE_ENCODER_COUNTS_PER_ML ) ); @@ -1195,7 +1208,7 @@ stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); // Check for commanded vs. meas. rate - stopPump = checkMaxMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); + stopPump = checkMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); // Check volume vs. safety volume stopPump = checkVolumeVsSafetyVolume( stopPump, SYRINGE_PUMP_VOLUME_CHECK_MARGIN ); @@ -1222,6 +1235,7 @@ static SYRINGE_PUMP_STATE_T handleSyringePumpCalibrateForceSensorState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE; + U08 adcDACStatus= getFPGASyringePumpADCandDACStatus(); // Wait for DAC setting write to EEPROM to complete if ( ( getFPGASyringePumpADCandDACStatus() & SYRINGE_PUMP_ADC_DAC_ERROR_COUNT_DAC_WR_DONE ) != 0 ) @@ -1232,6 +1246,11 @@ // Back to off state result = SYRINGE_PUMP_OFF_STATE; } + // Check DAC write error + else if ( ( adcDACStatus & SYRINGE_PUMP_DAC_WRITE_ERROR_BIT ) != 0 ) + { + // TODO - alarm + } return result; } @@ -1324,16 +1343,15 @@ /*********************************************************************//** * @brief - * The checkMaxMeasRate function checks whether the measured rate is exceeding - * a maximum rate (in mL/hr). This threshold is state dependent so the calling - * function must provide the maximum rate to apply. + * The checkMeasRate function checks whether the measured rate is within a + * given margin of the set rate (in mL/hr). * @details Inputs: syringePumpMeasRate.data, syringePumpSetRate * @details Outputs: alarm triggered if measured and set rates deviate too much * @param stopPump flag passed in by caller indicating whether pump should be stopped * @param pctMargin percent tolerance allowed between set and measured rate * @return TRUE if pump should be stopped, FALSE if not *************************************************************************/ -static BOOL checkMaxMeasRate( BOOL stopPump, F32 pctMargin ) +static BOOL checkMeasRate( BOOL stopPump, F32 pctMargin ) { BOOL result = stopPump; F32 rate = getSyringePumpMeasRate(); Index: firmware/App/HDCommon.h =================================================================== diff -u -r94a95302c5d48c3632a7c2136d35c257fe64a0bf -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 94a95302c5d48c3632a7c2136d35c257fe64a0bf) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -23,42 +23,45 @@ // ********** version ********** #define HD_VERSION_MAJOR 0 -#define HD_VERSION_MINOR 4 -#define HD_VERSION_MICRO 5 +#define HD_VERSION_MINOR 5 +#define HD_VERSION_MICRO 0 #define HD_VERSION_BUILD 0 // ********** development build switches ********** // TODO - remove build switches before release #ifndef _RELEASE_ #ifndef _VECTORCAST_ + #define BOARD_WITH_NO_HARDWARE 1 // #define RUN_WITHOUT_DG 1 // Run HD w/o DG // #define SIMULATE_UI 1 // Build w/o requirement that UI be there // #define TASK_TIMING_OUTPUT_ENABLED 1 // Re-purposes alarm lamp pins for task timing // #define DISABLE_ALARM_AUDIO 1 // Disable alarm audio #define SKIP_POST 1 // Skip POST tests - all pass -// #define LIMITED_NVDATA_CRC_CHECKS 1 // Only perform POST CRC checks on nv-data records that are implemented so far + #define DONT_SKIP_NV_POST 1 #define DISABLE_AIR_TRAP_LEVELING 1 // Disable air trap level control // #define DISABLE_3WAY_VALVES 1 // Disable 3-way valves // #define TST_3WAY_VALVES_ALWAYS_OPEN 1 // After POST and homing, open all 4 valves -// #define DISABLE_ACCELS 1 // Disable accelerometer POST and monitoring + #define DISABLE_ACCELS 1 // Disable accelerometer POST and monitoring // #define DISABLE_CRC_ERROR 1 // Do not error on bad CRC for CAN messages // #define DISABLE_ACK_ERRORS 1 // Do not error on failure of other node(s) to ACK a message -// #define DISABLE_MOTOR_CURRENT_CHECKS 1 // Do not error on HD pump current checks -// #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks -// #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks -// #define DISABLE_PUMP_DIRECTION_CHECKS 1 // Do not error on HD pump direction checks -// #define DISABLE_SALINE_BOLUS_CHECKS 1 // Do not error on HD saline bolus checks + #define DISABLE_MOTOR_CURRENT_CHECKS 1 // Do not error on HD pump current checks + #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks + #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks + #define DISABLE_PUMP_DIRECTION_CHECKS 1 // Do not error on HD pump direction checks + #define DISABLE_SYRINGE_PUMP 1 // Disable syringe pump functionality #define DISABLE_PRESSURE_CHECKS 1 // Do not error on HD pressure checks // #define DISABLE_UF_ALARMS 1 // Do not error on HD ultrafiltration checks #define DISABLE_VALVE_ALARMS 1 // Do not error on HD valve position +// #define DISABLE_CAL_CHECK 1 // #define RUN_PUMPS_OPEN_LOOP 1 // BP and DPi pumps will be run open loop (no flow sensor feedback) // #define RAW_FLOW_SENSOR_DATA 1 // Test build will not filter flow sensor data // #define READ_FPGA_ASYNC_DATA 1 // Test build reads non-priority register page every other time // #define EMC_TEST_BUILD 1 // EMC test build - HD/DG run separately but connected, HD pumps toggle on/off w/ stop button #define ALARMS_DEBUG 1 // Triggered alarms sent to debug UART #define SKIP_SELF_TESTS 1 // Skip Pre-treatment Self-tests #define SKIP_PRIMING 1 // Skip Pre-treatment Prime + #define SKIP_CALIBRATION_TESTS 1 // Skip calibration tests // #define V1_5_SYSTEM 1 // Build for v1.5 system #define SKIP_UI_INTERACTION 1 // Skip UI interaction #define SKIP_CARTRIDGE_REMOVAL 1 // Skip cartridge removal check Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -ra97ade33cb05958a645306392f61b1182f6a1fe1 -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision a97ade33cb05958a645306392f61b1182f6a1fe1) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -79,7 +79,7 @@ static F32 totalSalineVolumeDelivered; ///< Volume (mL) in total of saline delivered so far (cumulative for all boluses including current one). static F32 bolusSalineVolumeDelivered; ///< Volume (mL) of current bolus delivered so far. static F32 bolusSalineVolumeDelivered_Safety; ///< Volume (mL) of current bolus delivered so far according to safety monitor. -static U32 bolusSalineMotorCount; ///< Blood pump motor rev count during saline bolus to calculate saline bolus volume independently for safety. +static S32 bolusSalineMotorCount; ///< Blood pump motor rev count during saline bolus to calculate saline bolus volume independently for safety. static U32 bolusSalineLastMotorCount; ///< Last blood pump count from last saline bolus volume update. static U32 bolusSalineLastVolumeTimeStamp; ///< Time stamp for last saline volume update. @@ -94,14 +94,14 @@ static UF_STATE_T handleUFStartState( DIALYSIS_STATE_T *dialysisState ); static UF_STATE_T handleUFPausedState( DIALYSIS_STATE_T *dialysisState ); static UF_STATE_T handleUFRunningState( DIALYSIS_STATE_T *dialysisState ); -static UF_STATE_T handleUFOffState( DIALYSIS_STATE_T *dialysisState ); -static UF_STATE_T handleUFCompletedState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusIdleState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusWait4Pumps2Stop( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusInProgressState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusMaxDeliveredState( DIALYSIS_STATE_T *dialysisState ); +static void startHeparinPump( void ); + static void checkUFAccuracyAndVolume( void ); static void updateUFVolumes( void ); @@ -201,7 +201,8 @@ setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); #endif setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - // TODO - Heparin pump + // Start Heparin pump as appropriate + startHeparinPump(); // Tell DG to start heating dialysate cmdStartDGTrimmerHeater(); @@ -215,6 +216,42 @@ /*********************************************************************//** * @brief + * The startHeparinPump function sets the syringe pump running as appropriate + * when starting/resuming dialysis sub-mode. + * @details Inputs: Heparin treatment parameters, treatment time remaining + * @details Outputs: Syringe pump started/stopped as appropriate + * @return none + *************************************************************************/ +static void startHeparinPump( void ) +{ + HEPARIN_STATE_T currentHeparinState = getHeparinState(); + U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); + U32 minRem = getTreatmentTimeRemainingSecs() / SEC_PER_MIN; + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + F32 hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + + // Do not run syringe pump if no Heparin included in prescription or it was paused or if Heparin should be stopped at this stage of treatment + if ( ( minRem > preStop ) && ( HEPARIN_STATE_STOPPED == currentHeparinState ) ) + { + // If not done with bolus, start/resume bolus + if ( ( bolusVol > 0.0 ) && ( getSyringePumpVolumeDelivered() < bolusVol ) ) + { + startHeparinBolus(); // TODO - check return status + } + // Otherwise, start/resume continuous delivery + else + { + startHeparinContinuous(); // TODO - check return status + } + } + else + { + stopSyringePump(); + } +} + +/*********************************************************************//** + * @brief * The setDialysisParams function sets the dialysis treatment parameters. * This function should be called prior to beginning dialysis treatment * and when the user changes one or more parameters during treatment. @@ -261,7 +298,7 @@ setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - // TODO - stop Heparin pump + stopSyringePump(); // Tell DG to stop heating dialysate cmdStopDGTrimmerHeater(); } @@ -392,7 +429,7 @@ * volume collected so far for current treatment. * @details Inputs: measUFVolume, measUFVolumeFromPriorReservoirs * @details Outputs: none - * @return currentUFState + * @return measUFVolume *************************************************************************/ F32 getUltrafiltrationVolumeCollected( void ) { @@ -403,6 +440,19 @@ /*********************************************************************//** * @brief + * The getUltrafiltrationReferenceVolume function gets the current ultrafiltration + * reference volume. + * @details Inputs: measUFVolume, measUFVolumeFromPriorReservoirs + * @details Outputs: none + * @return refUFVolume + *************************************************************************/ +F32 getUltrafiltrationReferenceVolume( void ) +{ + return refUFVolume; +} + +/*********************************************************************//** + * @brief * The pauseUF function pauses ultrafiltration. * @details Inputs: currentDialysisState, currentUFState * @details Outputs: currentUFState, outlet pump set point @@ -446,8 +496,6 @@ // Send response w/ reason code if rejected sendUFPauseResumeResponse( result, rejectReason, currentUFState ); - // Send state data immediately for UI update - broadcastTreatmentTimeAndState(); return result; } @@ -474,7 +522,7 @@ setDialOutPumpTargetRate( setDialysateFlowRate + FLOAT_TO_INT_WITH_ROUND( setUFRate ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); // Restart UF time accumulation for reference volume calculation lastUFTimeStamp = getMSTimerCount(); - // Go to UF paused state + // Go to UF running state currentUFState = UF_RUNNING_STATE; } else @@ -552,7 +600,22 @@ static DIALYSIS_STATE_T handleDialysisUltrafiltrationState( void ) { DIALYSIS_STATE_T result = DIALYSIS_UF_STATE; + U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); + U32 minRem = getTreatmentTimeRemainingSecs() / SEC_PER_MIN; + // Stop Heparin delivery if we have reached Heparin pre-stop point + if ( getTreatmentTimeRemainingSecs() < preStop ) + { + stopSyringePump(); + setHeparinCompleted(); + } + // TODO - find a better way to start continuous delivery after bolus completes + if ( HEPARIN_STATE_STOPPED == getHeparinState() ) + { + startHeparinPump(); + } + + // Handle current ultrafiltration state switch ( currentUFState ) { case UF_START_STATE: @@ -663,17 +726,6 @@ salineBolusStartRequested = FALSE; } } - // Handle auto-resume after saline bolus - else if ( TRUE == salineBolusAutoResumeUF ) - { - salineBolusAutoResumeUF = FALSE; - // Set outlet pump to dialysate rate + set UF rate - setDialOutPumpTargetRate( setDialysateFlowRate + FLOAT_TO_INT_WITH_ROUND( setUFRate ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - // Restart UF time accumulation for reference volume calculation - lastUFTimeStamp = getMSTimerCount(); - // Resume UF - result = UF_RUNNING_STATE; - } return result; } @@ -701,16 +753,17 @@ // Update UF ref volume in UF running state only refUFVolume += ( ( (F32)msSinceLast / MS_PER_SECOND ) / SEC_PER_MIN ) * setUFRate; - // Calculate UF volumes and provide to dialysate outlet pump controller - updateUFVolumes(); - - // If we have reached target UF volume, UF is complete + // If we have reached target UF volume, UF is complete - set UF rate to zero for remainder of treatment if ( refUFVolume >= maxUFVolumeML ) { setUFRate = 0.0; } + + // Calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + // Handle saline bolus start request from user - else if ( TRUE == salineBolusStartRequested ) + if ( TRUE == salineBolusStartRequested ) { if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) { @@ -748,15 +801,10 @@ { salineBolusStartRequested = FALSE; // Cmd all pumps to stop -#ifndef RUN_PUMPS_OPEN_LOOP setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); -#else - setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); -#endif + stopSyringePump(); // Begin saline bolus result = SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP; } @@ -827,26 +875,21 @@ F32 bolusTargetVolume = (F32)getTreatmentParameterU32( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); F32 bldFlowRate = getMeasuredBloodFlowRate(); // TODO - should I use raw flow instead of filtered here??? F32 volSinceLastUpdateMl = bldFlowRate * timeSinceLastVolumeUpdateMin; - U32 bldPumpMotorCount = getBloodPumpMotorCount(); - U32 bldPumpMotorDelta = u32DiffWithWrap( bolusSalineLastMotorCount, bldPumpMotorCount ); // Update saline bolus volumes bolusSalineLastVolumeTimeStamp = getMSTimerCount(); bolusSalineVolumeDelivered += volSinceLastUpdateMl; totalSalineVolumeDelivered += volSinceLastUpdateMl; - bolusSalineMotorCount += bldPumpMotorDelta; - bolusSalineLastMotorCount = bldPumpMotorCount; - bolusSalineVolumeDelivered_Safety = ( (F32)bolusSalineMotorCount * VOLUME_PER_BP_MOTOR_REV_ML ); // TODO - include upstream pressure compensation to this calc + bolusSalineMotorCount = u32BiDiffWithWrap( bolusSalineLastMotorCount, getBloodPumpMotorCount() ) / BP_HALL_EDGE_COUNTS_PER_REV; + bolusSalineVolumeDelivered_Safety = ( (F32)bolusSalineMotorCount * VOLUME_PER_BP_MOTOR_REV_ML ); // TODO - include upstream pressure compensation to this calc (from PBA). -#ifndef DISABLE_SALINE_BOLUS_CHECKS - // TODO - check for empty saline bag - if ( 0 ) + // Check for empty saline bag per arterial line pressure + if ( TRUE == isSalineBagEmpty() ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_EMPTY_SALINE_BAG, 0.0 ); // TODO - give data supporting empty bag detection + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_EMPTY_SALINE_BAG, getMeasuredArterialPressure() ); errorFound = TRUE; result = SALINE_BOLUS_STATE_IDLE; } -#endif // Determine if we have reached maximum saline delivery volume if ( ( totalSalineVolumeDelivered >= (F32)MAX_SALINE_VOLUME_DELIVERED ) ) @@ -861,7 +904,7 @@ // If safety thinks we have under-delivered the bolus, throw a fault if ( bolusSalineVolumeDelivered_Safety < ( bolusTargetVolume * MIN_SALINE_BOLUS_VOLUME_PCT ) ) { -#ifndef DISABLE_SALINE_BOLUS_CHECKS +#ifndef DISABLE_PUMP_FLOW_CHECKS SET_ALARM_WITH_2_F32_DATA( ALARM_ID_SALINE_BOLUS_VOLUME_CHECK_FAILURE, bolusTargetVolume, bolusSalineVolumeDelivered_Safety ); errorFound = TRUE; #endif @@ -877,7 +920,7 @@ // Determine if safety thinks we have over-delivered the bolus else if ( bolusSalineVolumeDelivered_Safety > ( bolusTargetVolume * MAX_SALINE_BOLUS_VOLUME_PCT ) ) { -#ifndef DISABLE_SALINE_BOLUS_CHECKS +#ifndef DISABLE_PUMP_FLOW_CHECKS SET_ALARM_WITH_2_F32_DATA( ALARM_ID_SALINE_BOLUS_VOLUME_CHECK_FAILURE, bolusTargetVolume, bolusSalineVolumeDelivered_Safety ); errorFound = TRUE; result = SALINE_BOLUS_STATE_IDLE; @@ -903,6 +946,7 @@ // Resume UF if appropriate if ( TRUE == salineBolusAutoResumeUF ) { + salineBolusAutoResumeUF = FALSE; currentUFState = UF_RUNNING_STATE; } // Resume dialysis @@ -948,7 +992,7 @@ { SALINE_BOLUS_DATA_PAYLOAD_T data; - data.maxSalineVolumeMl = MAX_SALINE_VOLUME_DELIVERED; + data.tgtSalineVolumeMl = getTreatmentParameterU32( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); data.cumSalineVolumeMl = totalSalineVolumeDelivered; data.bolSalineVolumeMl = bolusSalineVolumeDelivered; broadcastSalineBolusData( data ); @@ -1005,7 +1049,8 @@ static void updateUFVolumes( void ) { DG_RESERVOIR_ID_T activeRes = getDGActiveReservoir(); - F32 latestResVolume = getReservoirWeightSmallFilter( activeRes ); + LOAD_CELL_ID_T loadCell = ( activeRes == DG_RESERVOIR_1 ? LOAD_CELL_RESERVOIR_1_PRIMARY : LOAD_CELL_RESERVOIR_2_PRIMARY ); + F32 latestResVolume = getLoadCellWeight( loadCell ); #ifndef DISABLE_UF_ALARMS F32 deltaVolume = latestResVolume - resFinalVolume[ activeRes ]; Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r368e2fde80a5cc108f61c021830c684e05fb62d5 -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 368e2fde80a5cc108f61c021830c684e05fb62d5) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -1186,9 +1186,13 @@ break; case MSG_ID_UI_INITIATE_TREATMENT_REQUEST: - handleUIStartTreatmentMsg( message ); + handleInitiateTreatmentRequest( message ); break; + case MSG_ID_UI_START_TREATMENT_REQUEST: + handleStartTreatmentRequest( message ); + break; + case MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS: handleUIUserConfirmTreatmentParameters( message ); break; @@ -1237,8 +1241,32 @@ handleTesterLogInRequest( message ); break; + case MSG_ID_HD_SET_CALIBRATION_RECORD: + handleSetHDCalibrationRecord( message ); + break; + + case MSG_ID_HD_GET_CALIBRATION_RECORD: + handleGetHDCalibrationRecord( message ); + break; + + case MSG_ID_HD_SET_SYSTEM_RECORD: + handleSetHDSystemRecord( message ); + break; + + case MSG_ID_HD_GET_SYSTEM_RECORD: + handleGetHDSystemRecord( message ); + break; + + case MSG_ID_HD_GET_SERVICE_RECORD: + handleGetHDServiceRecord( message ); + break; + + case MSG_ID_HD_SET_SERVICE_RECORD: + handleSetHDServiceRecord( message ); + break; + default: - // TODO - unrecognized message ID received - ignore + // Unrecognized message ID received - ignore break; } @@ -1469,6 +1497,13 @@ handleTestDialOutPumpHomeRequest( message ); break; + case MSG_ID_HD_FLUID_LEAK_SEND_INTERVAL_OVERRIDE: + handleSetFluidLeakBroadcastIntervalOverrideRequest( message ); + break; + + case MSG_ID_HD_FLUID_LEAK_STATE_DETECTOR_OVERRIDE: + handleSetFluidLeakStateDetectorOverrideRequest( message ); + case MSG_ID_HD_SET_OP_MODE_REQUEST: handleTestSetOpModeRequest( message ); break; @@ -1510,7 +1545,7 @@ break; default: - // TODO - unrecognized message ID received - ignore + // Unrecognized message ID received - ignore break; } } Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r38e8e85e6add1c4f798af6ada4a45cc7db547f3e -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 38e8e85e6add1c4f798af6ada4a45cc7db547f3e) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -38,7 +38,7 @@ #include "TreatmentEnd.h" #include "TreatmentRecirc.h" #include "Utilities.h" -#include "Valves.h" +#include "Valves.h" #include "WatchdogMgmt.h" /** @@ -476,25 +476,22 @@ * @details Outputs: Heparin command response msg constructed and queued. * @param accepted flag indicating whether request was accepted * @param rejReason rejection reason code - * @param heparinDeliveryState current Heparin delivery state * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendHeparinCommandResponse( U32 accepted, U32 rejReason, U32 heparinDeliveryState ) +BOOL sendHeparinCommandResponse( U32 accepted, U32 rejReason ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // Create a message record blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_HD_PRESSURE_LIMITS_CHANGE_RESPONSE; - msg.hdr.payloadLen = sizeof( U32 ) * 3; + msg.hdr.msgID = MSG_ID_HD_HEPARIN_PAUSE_RESUME_RESPONSE; + msg.hdr.payloadLen = sizeof( U32 ) * 2; memcpy( payloadPtr, &accepted, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); - payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, &heparinDeliveryState, sizeof( U32 ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); @@ -1658,10 +1655,39 @@ /***********************************************************************//** * @brief - * The broadcastAirTrapData function constructs an HD air trap data msg to \n + * The broadcastFluidLeakState function constructs an HD fluid leak state msg to \n + * be broadcasted and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: fluid leak state msg constructed and queued + * @param state fluid leak state + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastFluidLeakState( FLUID_LEAK_STATES_T state ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + U32 leakState = (U32)state; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_FLUID_LEAK_STATE; + msg.hdr.payloadLen = sizeof( U32 ); + + memcpy( payloadPtr, &leakState, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/***********************************************************************//** + * @brief + * The broadcastPrimeData function constructs a prime data msg to \n * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none - * @details Outputs: air trap data msg constructed and queued + * @details Outputs: prime data msg constructed and queued * @param primeDataPtr prime data record pointer * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ @@ -1684,6 +1710,124 @@ return result; } +/*********************************************************************//** + * @brief + * The sendHDCalibrationRecord function sends out the HD calibration + * record. + * @details Inputs: none + * @details Outputs: HD calibration record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param calRcrdAddress: start address of the calibration record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendHDCalibrationRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SEND_CALIBRATION_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, calRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendHDSystemRecord function sends out the HD system record. + * @details Inputs: none + * @details Outputs: HD system record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param sysRcrdAddress: start address of the system record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendHDSystemRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* sysRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SEND_SYSTEM_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, sysRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendHDServiceRecord function sends out the HD service record. + * @details Inputs: none + * @details Outputs: HD system record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param srvcRcrdAddress: start address of the service record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendHDServiceRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* srvcRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SEND_SERVICE_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, srvcRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + #ifdef EMC_TEST_BUILD BOOL broadcastCANErrorCount( U32 count ) { @@ -1884,8 +2028,6 @@ memcpy( &payload, message->payload, sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ); setNewLoadCellReadings( payload.res1PrimaryLoadCell, payload.res1BackupLoadCell, payload.res2PrimaryLoadCell, payload.res2BackupLoadCell ); } - // TODO - what to do if invalid payload length? - // TODO - how to know if DG stops sending these? } /*********************************************************************//** @@ -1928,7 +2070,6 @@ memcpy( &payload, message->payload, sizeof(DG_RO_PUMP_DATA_PAYLOAD_T) ); setDGROPumpData( payload.setPtPSI, payload.measFlowRateMlMin ); } - // TODO - what to do if invalid payload length? } /*********************************************************************//** @@ -1949,7 +2090,6 @@ memcpy( &payload, message->payload, sizeof(DG_DRAIN_PUMP_DATA_PAYLOAD_T) ); setDGDrainPumpData( payload.setPtRPM ); } - // TODO - what to do if invalid payload length? } /*********************************************************************//** @@ -1970,7 +2110,6 @@ memcpy( &payload, message->payload, sizeof(DG_PRESSURES_DATA_PAYLOAD_T) ); setDGPressures( payload.roInPSI, payload.roOutPSI, payload.drainInPSI, payload.drainOutPSI ); } - // TODO - what to do if invalid payload length? } /*********************************************************************//** @@ -1991,7 +2130,6 @@ memcpy( &payload, message->payload, sizeof(DG_RESERVOIRS_DATA_PAYLOAD_T) ); setDGReservoirsData( (DG_RESERVOIR_ID_T)payload.resID, payload.setFillToVolumeMl, payload.setDrainToVolumeMl ); } - // TODO - what to do if invalid payload length? } /*********************************************************************//** @@ -2062,14 +2200,14 @@ /*********************************************************************//** * @brief - * The handleUIStartTreatmentMsg function handles a treatment start/cancel + * The handleInitiateTreatmentRequest function handles a treatment initiate/cancel * message from the UI. * @details Inputs: none * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ -void handleUIStartTreatmentMsg( MESSAGE_T *message ) +void handleInitiateTreatmentRequest( MESSAGE_T *message ) { BOOL result = FALSE; @@ -2079,17 +2217,13 @@ memcpy( &cmd, message->payload, sizeof(U32) ); - if ( 0 == cmd ) // Initiate treatment (go to treatment params mode) + if ( 0 == cmd ) // Cancel treatment (return from aborted treatment params mode) { - result = signalUserStartingTreatment(); - } - else if ( 1 == cmd ) // Cancel treatment (return from aborted treatment params mode) - { result = signalUserCancelTreatment(); } - else if ( 2 == cmd ) // Start treatment + else if ( 1 == cmd ) // Initiate treatment (go to treatment params mode) { - result = signalUserBeginningTreatment(); + result = signalUserStartingTreatment(); } } @@ -2098,6 +2232,27 @@ /*********************************************************************//** * @brief + * The handleStartTreatmentRequest function handles a treatment start + * message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleStartTreatmentRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( 0 == message->hdr.payloadLen ) + { + result = signalUserBeginningTreatment(); + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); +} + +/*********************************************************************//** + * @brief * The sendTreatmentStartResponseMsg function constructs a treatment start * request response message to the UI and queues the msg for transmit on * the appropriate CAN channel. @@ -2190,12 +2345,12 @@ * response to the UI and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none * @details Outputs: Treatment parameters response msg constructed and queued. - * @param rejected T/F - are settings rejected? + * @param accepted T/F - are settings accepted? * @param rejectReasons reasons each parameter was rejected (if not accepted) * @param byteLength number of bytes that array of reject reasons takes * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendTreatmentParametersResponseMsg( BOOL rejected, U08 *rejectReasons, U32 byteLength ) +BOOL sendTreatmentParametersResponseMsg( BOOL accepted, U08 *rejectReasons, U32 byteLength ) { BOOL result; MESSAGE_T msg; @@ -2206,7 +2361,7 @@ msg.hdr.msgID = MSG_ID_HD_NEW_TREATMENT_PARAMS_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ) + byteLength; - memcpy( payloadPtr, &rejected, sizeof( BOOL ) ); + memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, rejectReasons, byteLength ); @@ -3620,7 +3775,7 @@ memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); if ( FALSE == payload.reset ) { - result = testSetBloodPumpOcclusionOverride( payload.state.f32 ); + result = testSetBloodPumpOcclusionOverride( payload.state.u32 ); } else { @@ -3652,7 +3807,7 @@ memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); if ( FALSE == payload.reset ) { - result = testSetDialInPumpOcclusionOverride( payload.state.f32 ); + result = testSetDialInPumpOcclusionOverride( payload.state.u32 ); } else { @@ -3684,7 +3839,7 @@ memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); if ( FALSE == payload.reset ) { - result = testSetDialOutPumpOcclusionOverride( payload.state.f32 ); + result = testSetDialOutPumpOcclusionOverride( payload.state.u32 ); } else { @@ -4396,12 +4551,12 @@ BOOL result = FALSE; // Verify payload length - if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) + if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) { - memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); if ( FALSE == payload.reset ) { - result = testSetAirTrapLevelOverride( (AIR_TRAP_LEVEL_SENSORS_T)payload.index, (AIR_TRAP_LEVELS_T)(payload.state.u32) ); + result = testSetAirTrapLevelOverride( (AIR_TRAP_LEVEL_SENSORS_T)payload.index, (AIR_TRAP_LEVELS_T)( payload.state.u32 ) ); } else { @@ -4415,6 +4570,70 @@ /*********************************************************************//** * @brief + * The handleSetFluidLeakBroadcastIntervalOverrideRequest function handles a + * request to override the fluid leak state broadcast interval. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetFluidLeakBroadcastIntervalOverrideRequest( 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 = testSetFluidLeakStatePublishIntervalOverride( (U32)( payload.state.u32 ) ); + } + else + { + result = testResetFluidLeakStatePublishIntervalOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleSetFluidLeakStateDetectorOverrideRequest function handles a request to + * override the fluid leak detector state. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetFluidLeakStateDetectorOverrideRequest( 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 = testSetFluidLeakStateOverride( ( FLUID_LEAK_STATES_T)( payload.state.u32 ) ); + } + else + { + result = testResetFluidLeakStateOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleHDSoftwareResetRequest function handles a request to reset the * HD firmware processor. * @details Inputs: none @@ -4560,6 +4779,65 @@ } /*********************************************************************//** +* @brief +* The handleSetHDCalibrationRecord function handles a request to set the HD +* calibration data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetHDCalibrationRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = setCalibrationRecord( currentMessage, totalMessages, payloadLength, payloadPtr ); + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** +* @brief +* The handleGetHDCalibrationRecord function handles a request to get the HD +* calibration data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetHDCalibrationRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = getCalibrationRecord(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleTestSyringePumpDataBroadcastIntervalOverrideRequest function handles a * request to override the syringe pump data broadcast interval. @@ -4649,6 +4927,65 @@ } /*********************************************************************//** +* @brief +* The handleSetHDSystemRecord function handles a request to set the HD +* system data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetHDSystemRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = setSystemRecord( currentMessage, totalMessages, payloadLength, payloadPtr ); + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** +* @brief +* The handleGetHDSystemRecord function handles a request to get the HD +* system data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetHDSystemRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = getSystemRecord(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleTestSyringePumpMeasuredForceOverrideRequest function handles a * request to override the syringe pump measured force analog signal. @@ -4713,6 +5050,33 @@ } /*********************************************************************//** +* @brief +* The handleGetHDServiceRecord function handles a request to get the HD +* service data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetHDServiceRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = getServiceRecord(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleTestSyringePumpMeasuredHomeOverrideRequest function handles a * request to override the syringe pump measured home analog signal. @@ -4745,6 +5109,38 @@ } /*********************************************************************//** +* @brief +* The handleSetHDServiceRecord function handles a request to set the HD +* service data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetHDServiceRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = setServiceRecord( currentMessage, totalMessages, payloadLength, payloadPtr ); + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** * @brief * The handleTestSyringePumpMeasuredPositionOverrideRequest function handles a * request to override the syringe pump measured position. Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r38e8e85e6add1c4f798af6ada4a45cc7db547f3e -rc14a0220256e92a6339a444a3e1bc85e159ccce3 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 38e8e85e6add1c4f798af6ada4a45cc7db547f3e) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) @@ -26,7 +26,8 @@ #include "DialInFlow.h" #include "DialOutFlow.h" #include "Dialysis.h" -#include "Prime.h" +#include "FluidLeak.h" +#include "Prime.h" #include "ModePostTreat.h" #include "ModeTreatment.h" #include "MsgQueues.h" @@ -95,17 +96,20 @@ // MSG_ID_DG_RESERVOIR_DATA: void handleDGReservoirData( MESSAGE_T *message ); -// MSG_ID_UI_START_TREATMENT -void handleUIStartTreatmentMsg( MESSAGE_T *message ); +// MSG_ID_UI_START_TREATMENT_REQUEST +void handleStartTreatmentRequest( MESSAGE_T *message ); +// MSG_ID_UI_INITIATE_TREATMENT_REQUEST +void handleInitiateTreatmentRequest( MESSAGE_T *message ); + // MSG_ID_HD_START_TREATMENT_RESPONSE BOOL sendTreatmentStartResponseMsg( BOOL accepted, U32 reason ); // MSG_ID_UI_NEW_TREATMENT_PARAMS void handleTreatmentParametersFromUI( MESSAGE_T *message ); // MSG_ID_HD_NEW_TREATMENT_PARAMS_RESPONSE -BOOL sendTreatmentParametersResponseMsg( BOOL rejected, U08 *rejectReasons, U32 byteLength ); +BOOL sendTreatmentParametersResponseMsg( BOOL accepted, U08 *rejectReasons, U32 byteLength ); // MSG_ID_UI_SET_UF_VOLUME_PARAMETER void handleUFVolumeSetRequest( MESSAGE_T *message ); @@ -168,7 +172,7 @@ void handleHeparinCommandRequest( MESSAGE_T *message ); // MSG_ID_HD_HEPARIN_PAUSE_RESUME_RESPONSE -BOOL sendHeparinCommandResponse( U32 accepted, U32 rejReason, U32 heparinDeliveryState ); +BOOL sendHeparinCommandResponse( U32 accepted, U32 rejReason ); // MSG_ID_UI_RINSEBACK_CMD void handlRinsebackCmd( MESSAGE_T *message ); @@ -308,9 +312,21 @@ // MSG_ID_HD_AIR_TRAP_DATA BOOL broadcastAirTrapData( AIR_TRAP_LEVELS_T lowerLevel, AIR_TRAP_LEVELS_T upperLevel ); +// MSG_ID_HD_FLUID_LEAK_STATE +BOOL broadcastFluidLeakState( FLUID_LEAK_STATES_T state ); + // MSG_ID_HD_PRIMING_STATUS_DATA BOOL broadcastPrimeData( PRIMING_DATA_PAYLOAD_T *primeDataPtr ); +// MSG_ID_HD_SEND_CALIBRATION_RECORD +BOOL sendHDCalibrationRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress ); + +// MSG_ID_HD_SEND_SYSTEM_RECORD +BOOL sendHDSystemRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* sysRcrdAddress ); + +// MSG_ID_Hd_SEND_SERVICE_RECORD +BOOL sendHDServiceRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* srvcRcrdAddress ); + #ifdef EMC_TEST_BUILD // MSG_ID_CAN_ERROR_COUNT BOOL broadcastCANErrorCount( U32 count ); @@ -497,9 +513,36 @@ // MSG_ID_HD_AIR_TRAP_LEVEL_SENSOR_OVERRIDE void handleSetAirTrapLevelSensorOverrideRequest( MESSAGE_T *message ); +// MSG_ID_HD_FLUID_LEAK_SEND_INTERVAL_OVERRIDE +void handleSetFluidLeakBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_FLUID_LEAK_STATE_DETECTOR_OVERRIDE +void handleSetFluidLeakStateDetectorOverrideRequest( MESSAGE_T *message ); + // MSG_ID_SUPER_CLEAR_ALARMS_CMD void handleTestSuperClearAlarmsRequest( MESSAGE_T *message ); +// MSG_ID_HD_REQUEST_CALIBRATION_DATA +void handleTestHDCalibrationDataRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SET_CALIBRATION_RECORD +void handleSetHDCalibrationRecord( MESSAGE_T *message ); + +// MSG_ID_HD_GET_CALIBRATION_RECORD +void handleGetHDCalibrationRecord( MESSAGE_T *message ); + +// MSG_ID_HD_SET_SYSTEM_RECORD +void handleSetHDSystemRecord( MESSAGE_T *message ); + +// MSG_ID_HD_GET_SYSTEM_RECORD +void handleGetHDSystemRecord( MESSAGE_T *message ); + +// MSG_ID_HD_GET_SERVICE_RECORD +void handleGetHDServiceRecord( MESSAGE_T *message ); + +// MSG_ID_HD_SET_SERVICE_RECORD +void handleSetHDServiceRecord( MESSAGE_T *message ); + // MSG_ID_HD_SET_OP_MODE_REQUEST void handleTestSetOpModeRequest( MESSAGE_T *message );