Index: firmware/App/Controllers/BloodLeak.h =================================================================== diff -u -r4e4ab946c0bc4b668cf5b197c7f841355814ccf5 -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision 4e4ab946c0bc4b668cf5b197c7f841355814ccf5) +++ firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -68,7 +68,7 @@ SELF_TEST_STATUS_T execBloodLeakSelfTest( void ); BLOOD_LEAK_STATUS_T getBloodLeakStatus( void ); -SELF_TEST_STATUS_T getBloodLeakSelfTestStatus( void ); +SELF_TEST_STATUS_T getBloodLeakSelfTestStatus( void ); BOOL testSetBloodLeakDataPublishIntervalOverride( U32 value ); BOOL testResetBloodLeakDataPublishIntervalOverride( void ); Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r93383819b0f9b7bb0be3acb95f368ee6b8d8080a -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 93383819b0f9b7bb0be3acb95f368ee6b8d8080a) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -92,6 +92,7 @@ /// Expected position of empty in relation to home position. #define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84F ) + /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5F ) /// Minimum retract position. @@ -2002,6 +2003,7 @@ + /*********************************************************************//** * @brief * The testSetSyringePumpDataPublishIntervalOverride function overrides the Index: firmware/App/HDCommon.h =================================================================== diff -u -r173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0 -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -10,8 +10,8 @@ * @author (last) Dara Navaei * @date (last) 23-May-2022 * -* @author (original) Sean -* @date (original) 27-Feb-2020 +* @author (original) Sean +* @date (original) 27-Feb-2020 * ***************************************************************************/ @@ -25,7 +25,7 @@ #define HD_VERSION_MAJOR 0 #define HD_VERSION_MINOR 6 #define HD_VERSION_MICRO 0 -#define HD_VERSION_BUILD 49 +#define HD_VERSION_BUILD 327 // ********** development build switches ********** @@ -42,13 +42,13 @@ // #define READ_FPGA_ASYNC_DATA 1 // Test build reads non-priority register page every other time // #define DISABLE_FPGA_COUNTER_CHECKS 1 // Disable alarms associated with FPGA read/error counters // #define EMC_TEST_BUILD 1 // EMC test build - HD/DG run separately but connected, HD pumps toggle on/off w/ stop button - #define DISABLE_WD_AND_SFTY_POST_TESTS 1 // Disable watchdog and safety shutdown POST tests -// #define DISABLE_UI_POST_TEST 1 // Disable the UI POST +// #define DISABLE_WD_AND_SFTY_POST_TESTS 1 // Disable watchdog and safety shutdown POST tests + #define DISABLE_UI_POST_TEST 1 // Disable the UI POST // TODO stays as a build switch until the calibration structure is updated with the build - #define SKIP_CAL_CHECK 1 // Implement software configuration + #define SKIP_CAL_CHECK 1 // Implement software configuration once the build switch is done - #include +#include #include #endif #endif Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0 -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -52,7 +52,7 @@ #define DIALYZER_VOLUME_SCALE_FACTOR 0.5F ///< Half of the dialyzer total volume. #define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. -#define PURGE_AIR_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for purge air time out. +#define PURGE_AIR_TIME_OUT_COUNT ( 120 * MS_PER_SECOND ) ///< Time period count for purge air time out. #define LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ( 1 * MS_PER_SECOND ) ///< Time load cell reading steady state detection sampling time in seconds. #define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 15 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. #define STEADY_VOLUME_COUNT_SEC ( 10000 / LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ) ///< Counter must be greater than 10 seconds before steady volume is true. Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0 -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -41,7 +41,7 @@ #define PUMP_RUN_SELF_TEST_TIME_MS ( 15 * MS_PER_SECOND ) ///< Self-test time to run pumps in ms. #define PUMP_SELF_TEST_FLOW_RATE_ML_MIN 100 ///< Self-test pump flow rate in mL/min. -#define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 3 * MS_PER_SECOND ) ///< Delay 3 seconds then check for syringe pump prime occlusion. +#define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 1 * MS_PER_SECOND ) ///< Delay 3 seconds then check for syringe pump prime occlusion. #define BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ( 5 * MS_PER_SECOND ) ///< Pressure self-test time to run blood pump in ms. #define NORMALIZED_PRESSURE_SELF_TEST_TIME ( 4 * MS_PER_SECOND ) ///< Time to wait for pressure to normalize in ms. @@ -70,6 +70,9 @@ #define SELF_TEST_TIME_DATA_PUB_INTERVAL ( MS_PER_SECOND ) ///< Interval (ms/task time) at which self-test time data is published on the CAN bus. +#define NORMAL_PRESSURE_LOWER_BOUNDARY -10.0F ///< Lower boundary (mmHg) for pressure check before dry self tests +#define NORMAL_PRESSURE_UPPER_BOUNDARY 10.0F ///< Upper boundary (mmHg) for pressure check before dry self tests + /// Multiplier to conver flow (mL/min) into volume (mL) for period of general task interval. static const F32 SELF_TEST_FLOW_INTEGRATOR = ( ( 1.0F * TASK_GENERAL_INTERVAL ) / ( SEC_PER_MIN * MS_PER_SECOND ) ); @@ -326,7 +329,7 @@ } else { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_NO_CART_SELF_TEST_TIMEOUT, currentNoCartSelfTestsState ); +// SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_NO_CART_SELF_TEST_TIMEOUT, currentNoCartSelfTestsState ); } } } @@ -878,16 +881,19 @@ DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; BUBBLE_STATUS_T const ADVBubbleStatus = getBubbleStatus( ADV ); + + SEND_EVENT_WITH_2_U32_DATA(HD_EVENT_DRY_SELF_TEST_CARTRIDGE_RESULT,(U32)ADVBubbleStatus,(U32)BUBBLE_DETECTED) + if ( ( BUBBLE_DETECTED == ADVBubbleStatus ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) ) { state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; } - else - { - activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); - } +// else +// { +// activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); +// } if ( TRUE == doesAlarmStatusIndicateStop() ) { @@ -915,11 +921,23 @@ state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } + else { // TODO - wait 1 sec before taking pressure readings and beginning pressure check previousNormalArterialPressure = getFilteredArterialPressure(); previousNormalVenousPressure = getFilteredVenousPressure(); + // Check to see if sensor is within normal ranges before we execute pressure sensor tests + if ( previousNormalArterialPressure <= NORMAL_PRESSURE_LOWER_BOUNDARY || previousNormalArterialPressure >= NORMAL_PRESSURE_UPPER_BOUNDARY ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, previousNormalArterialPressure ); + } + + if ( previousNormalVenousPressure <= NORMAL_PRESSURE_LOWER_BOUNDARY || previousNormalVenousPressure >= NORMAL_PRESSURE_UPPER_BOUNDARY ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, previousNormalVenousPressure ); + } + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_B_OPEN ); @@ -948,7 +966,7 @@ // End the test when reaching target pressure or time out if ( ( TRUE == didTimeout( pressureSelfTestBloodPumpRunStartTime, BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ) ) || - ( ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG >= arterialPressure ) || ( VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG <= venousPressure ) ) + ( ( ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG >= arterialPressure ) && ( VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG <= venousPressure ) ) ) { signalBloodPumpHardStop(); // Test pass when reading positive arterial pressure and negative venous pressure @@ -1030,8 +1048,8 @@ { if ( TRUE == isSyringePumpPrimed() ) { + syringeOcclusionDelayStartTime = getMSTimerCount(); // Get the current time to check for occlusion after 1 second has elapsed state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE; - syringeOcclusionDelayStartTime = getMSTimerCount(); // Get the current time to check for occlusion after 3 seconds has elapsed } else { @@ -1425,6 +1443,9 @@ } #endif + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement,resOneDiffAfterDisplacement ) + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, integratedVolumeDiff,WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE ) + if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) ) @@ -1560,6 +1581,10 @@ integrateVolumeToleranceG = 50.0F; } #endif + + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement, resOneDiffAfterDisplacement ) + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, integratedVolumeToTargetPercent, WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE ) + if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) ) Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r4e4ab946c0bc4b668cf5b197c7f841355814ccf5 -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 4e4ab946c0bc4b668cf5b197c7f841355814ccf5) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -1610,10 +1610,6 @@ handleTestSyringePumpHeprinBolusTargetRateOverrideRequest( message ); break; - case MSG_ID_HD_REQ_CURRENT_TREATMENT_PARAMETERS: - handleTestCurrentTreamtmentParametersRequest( message ); - break; - case MSG_ID_HD_FANS_DUTY_CYCLE_OVERRIDE: handleSetFansDutyCycleOverrideRequest( message ); break; @@ -1650,6 +1646,11 @@ handleResendAllAlarmsCommand( message ); break; + case MSG_ID_HD_REQ_CURRENT_TREATMENT_PARAMETERS: + handleTestCurrentTreamtmentParametersRequest( message ); + break; + + // The default cannot be reached in VectorCAST since the cases are run in a for loop default: // Unrecognized message ID received - ignore Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0 -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 173e4fbf9bd750bccb2e758eb1c7ef36ed8db5a0) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -2330,13 +2330,13 @@ { TEMPERATURE_SENSORS_DATA_T payload; - memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); - setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); - } - // TODO - what to do if invalid payload length? - // TODO - how to know if DG stops sending these? -} - + memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); + setDialysateTemperatureReadings( payload.TDi, payload.TRo ); + } + // TODO - what to do if invalid payload length? + // TODO - how to know if DG stops sending these? +} + /*********************************************************************//** * @brief * The handleDialysateFlowData function handles dialysate flow data broadcast @@ -5126,6 +5126,7 @@ if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) { result = testSetBatteryRemainingPercentOverride( payload.state.u32 ); @@ -7001,15 +7002,26 @@ { BOOL status = FALSE; HD_OP_MODE_T currentMode = getCurrentOperationMode(); + DG_OP_MODE_T currentDGMode = getDGOpMode(); REQUEST_REJECT_REASON_CODE_T reject; if ( 0 == message->hdr.payloadLen ) { if ( ( MODE_STAN == currentMode ) || ( MODE_FAUL == currentMode ) ) { - status = TRUE; + requestNewOperationMode( MODE_SERV ); - reject = REQUEST_REJECT_REASON_NONE; + + if ( (DG_MODE_STAN == currentDGMode) || (DG_MODE_FAUL == currentDGMode) ) + { + status = TRUE; + cmdSetDGToServiceMode(); + reject = REQUEST_REJECT_REASON_NONE; + } + else + { + reject = REQUEST_REJECT_REASON_DG_NOT_IN_STANDBY_IDLE_STATE; + } } else { @@ -7287,4 +7299,28 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** + * @brief + * The sendDGServiceModeRequest function constructs a service mode request msg + * to the DG and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG Service mode request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGServiceModeRequest() +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_SERVICE_MODE; + msg.hdr.payloadLen = 0; + + // 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_DG, ACK_REQUIRED ); + + return result; +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r4e4ab946c0bc4b668cf5b197c7f841355814ccf5 -r647f8950c1a9f936e16a7b51e36f582c3d03a40e --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 4e4ab946c0bc4b668cf5b197c7f841355814ccf5) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 647f8950c1a9f936e16a7b51e36f582c3d03a40e) @@ -395,6 +395,15 @@ // MSG_ID_DG_START_STOP_CHEM_DISINFECT BOOL sendDGStartChemicalDisinfectModeCommand( BOOL start ); +// MSG_ID_HD_RESPONSE_SERVICE_MODE_REQUEST +void sendUIServiceModeResponse( BOOL accepted, U32 rejCode ); + +// MSG_ID_HD_REQUEST_DG_SERVICE_MODE +BOOL sendDGServiceModeRequest( void ); + +// MSG_ID_UI_REQUEST_SERVICE_MODE +void handleUIServiceModeRequest( MESSAGE_T *message ); + // MSG_ID_ALARM_STATUS BOOL broadcastAlarmStatus( COMP_ALARM_STATUS_T almStatus ); @@ -422,9 +431,6 @@ // MSG_ID_HD_SET_SW_CONFIG_RECORD void handleSetHDSoftwareConfigRecord( MESSAGE_T *message ); -// MSG_ID_UI_REQUEST_SERVICE_MODE -void handleUIServiceModeRequest( MESSAGE_T *message ); -void sendUIServiceModeResponse( BOOL accepted, U32 rejCode ); // MSG_ID_HD_REQUEST_DG_ALARMS BOOL sendRequestForDGResendAlarms( void );