Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rdaefaef0d2d3e13ff563f11d9721ccc1d831cf06 -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision daefaef0d2d3e13ff563f11d9721ccc1d831cf06) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -20,10 +20,6 @@ #include "can.h" #include "etpwm.h" -// TODO - Test includes - remove later -#include "DialInFlow.h" -#include "PresOccl.h" - #include "BloodFlow.h" #include "FPGA.h" #include "InternalADC.h" @@ -35,7 +31,8 @@ #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" -#include "Timers.h" +#include "Timers.h" +#include "Utilities.h" /** * @addtogroup BloodFlow @@ -63,7 +60,6 @@ #define BP_SPEED_CALC_INTERVAL ( 40 / TASK_PRIORITY_INTERVAL ) /// Number of hall sensor counts kept in buffer to hold last 1 second of count data. #define BP_SPEED_CALC_BUFFER_LEN ( 1000 / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) -#define BP_HALL_EDGE_COUNTS_PER_REV 48 ///< Number of hall sensor edge counts per motor revolution. #define BP_MAX_ROTOR_SPEED_RPM 100.0 ///< Maximum rotor speed allowed for blood pump. #define BP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured speed and speed implied by measured flow. @@ -389,7 +385,7 @@ *************************************************************************/ U32 getBloodPumpMotorCount( void ) { - return bloodPumpMotorEdgeCount / BP_HALL_EDGE_COUNTS_PER_REV; + return bloodPumpMotorEdgeCount; } /*********************************************************************//** @@ -938,25 +934,28 @@ if ( ++bpMotorSpeedCalcTimerCtr >= BP_SPEED_CALC_INTERVAL ) { U16 bpMotorHallSensorCount = getFPGABloodPumpHallSensorCount(); - U32 nextIdx = INC_WRAP( bpMotorSpeedCalcIdx, 0, BP_SPEED_CALC_BUFFER_LEN - 1 ); - U16 incDelta = ( bpMotorHallSensorCount >= bpLastMotorHallSensorCounts[ nextIdx ] ? \ - bpMotorHallSensorCount - bpLastMotorHallSensorCounts[ nextIdx ] : \ - ( HEX_64_K - bpLastMotorHallSensorCounts[ nextIdx ] ) + bpMotorHallSensorCount ); + U16 last = bpLastMotorHallSensorCounts[ bpMotorSpeedCalcIdx ]; + U32 nextIdx = INC_WRAP( bpMotorSpeedCalcIdx, 0, BP_SPEED_CALC_BUFFER_LEN - 1 ); + U16 incDelta = u16DiffWithWrap( bpLastMotorHallSensorCounts[ nextIdx ], bpMotorHallSensorCount ); U16 decDelta = HEX_64_K - incDelta; - U16 delta; - + U16 spdDelta; + S16 delta; + // Determine blood pump speed/direction from delta hall sensor count since last interval if ( incDelta < decDelta ) { - delta = incDelta; - bloodPumpSpeedRPM.data = ( (F32)delta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; + spdDelta = incDelta; + bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; } else { - delta = decDelta; - bloodPumpSpeedRPM.data = ( (F32)delta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; + spdDelta = decDelta; + bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; } - bloodPumpMotorEdgeCount += delta; + + // Keep a running 32-bit edge count used for safety check on volume in some functions + delta = u16BiDiffWithWrap( last, bpMotorHallSensorCount ); + bloodPumpMotorEdgeCount += (U16)delta; // Update last count for next time bpLastMotorHallSensorCounts[ nextIdx ] = bpMotorHallSensorCount; Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r85a680de4306aa033b1dc1f386fa5fa0a25cf73b -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 85a680de4306aa033b1dc1f386fa5fa0a25cf73b) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -1226,15 +1226,17 @@ *************************************************************************/ SELF_TEST_STATUS_T execDialInFlowTest( void ) { - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; - CALIBRATION_DATA_T cal; + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; + + // Get the flow sensors calibration record + HD_FLOW_SENSORS_CAL_RECORD_T cal = getHDFlowSensorsCalibrationRecord(); #ifndef SKIP_CALIBRATION_TESTS // Retrieve dialysate flow sensor calibration data - if ( ( TRUE == getCalibrationData( &cal ) ) && ( DFM_SENSOR_PARAM_CORRUPT_STATUS != getFPGADialysateFlowMeterStatus() ) ) + if ( DFM_SENSOR_PARAM_CORRUPT_STATUS != getFPGADialysateFlowMeterStatus() ) { - dialInFlowCalGain = cal.dialysateFlowGain; - dialInFlowCalOffset = cal.dialysateFlowOffset_mL_min; + dialInFlowCalGain = cal.hdFlowSensors[ CAL_DATA_HD_DIALYZER_FLOW_SENSOR ].gain; + dialInFlowCalOffset = cal.hdFlowSensors[ CAL_DATA_HD_DIALYZER_FLOW_SENSOR ].offset; result = SELF_TEST_STATUS_PASSED; } #else @@ -1249,57 +1251,6 @@ * TEST SUPPORT FUNCTIONS *************************************************************************/ - -/*********************************************************************//** - * @brief - * The setDialInFlowCalibration function sets the dialysate flow calibration - * factors and has them stored in non-volatile memory. - * @details Inputs: none - * @details Outputs: dialInFlowCalGain, dialInFlowCalOffset - * @param gain gain calibration factor for dialysate flow sensor - * @param offset offset calibration factor for dialysate flow sensor - * @return TRUE if calibration factors successfully set/stored, FALSE if not - *************************************************************************/ -BOOL setDialInFlowCalibration( F32 gain, F32 offset ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - CALIBRATION_DATA_T cal; - - getCalibrationData( &cal ); - // Keep locally and apply immediately - dialInFlowCalGain = gain; - dialInFlowCalOffset = offset; - // Also update calibration record in non-volatile memory - cal.dialysateFlowGain = gain; - cal.dialysateFlowOffset_mL_min = offset; - if ( TRUE == setCalibrationData( cal ) ) - { - result = TRUE; - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The getDialInFlowCalibration function retrieves the current dialysate flow - * calibration factors. - * @details Inputs: dialInFlowCalGain, dialInFlowCalOffset - * @details Outputs: none - * @param gain value to populate with gain calibration factor for dialysate flow sensor - * @param offset value to populate with offset calibration factor for dialysate flow sensor - * @return none - *************************************************************************/ -void getDialInFlowCalibration( F32 *gain, F32 *offset ) -{ - *gain = dialInFlowCalGain; - *offset = dialInFlowCalOffset; -} - /*********************************************************************//** * @brief * The testSetDialInFlowDataPublishIntervalOverride function overrides the Index: firmware/App/HDCommon.h =================================================================== diff -u -rdb22e9d530c5c9d62b02e6dcc72ed96fb67c165a -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision db22e9d530c5c9d62b02e6dcc72ed96fb67c165a) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -32,13 +32,15 @@ // 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_CAL_CHECK // #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 @@ -52,6 +54,7 @@ #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 Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r2bdd010a62ea113058640fc1e9c763dcf885c93c -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 2bdd010a62ea113058640fc1e9c763dcf885c93c) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -103,8 +103,12 @@ case POST_STATE_START: postState = POST_STATE_WATCHDOG; #ifdef SKIP_POST - postState = POST_STATE_VALVES; + postState = POST_STATE_COMPLETED; #endif +#ifdef DONT_SKIP_NV_POST + // Only run NVDataMgmt POST + postState = POST_STATE_NVDATAMGMT; +#endif break; case POST_STATE_WATCHDOG: @@ -128,8 +132,13 @@ break; case POST_STATE_BLOOD_FLOW: +#ifdef DONT_SKIP_NV_POST + // Skip the rest of the POSTs + postState = POST_STATE_COMPLETED; +#else testStatus = execBloodFlowTest(); postState = handlePOSTStatus( testStatus ); +#endif break; case POST_STATE_DIALYSATE_FLOW: Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r7665e7b142961a50c5e77c44877247366a374526 -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 7665e7b142961a50c5e77c44877247366a374526) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -226,6 +226,21 @@ /*********************************************************************//** * @brief + * The getTreatmentTimeRemainingSecs function determines the number of seconds + * remaining in the treatment. + * @details Inputs: presTreatmentTimeSecs, treatmentTimeMS + * @details Outputs: none + * @return The number of seconds remaining in the treatment. + *************************************************************************/ +U32 getTreatmentTimeRemainingSecs( void ) +{ + U32 result = CALC_TREAT_TIME_REMAINING_IN_SECS(); + + return result; +} + +/*********************************************************************//** + * @brief * The getRinsebackCompleted function determines whether a rinseback has been * completed (indicating blood-side circuit should be primarily saline). * @details Inputs: rinsebackDone @@ -743,7 +758,7 @@ U32 dialVolume = presDialysateFlowRate * treatmentTime; // In mL // Always adjust UF volume to accommodate treatment time change (not UF rate) - uFVolume = ( (F32)( treatmentTime - CALC_ELAPSED_TREAT_TIME_IN_MIN() ) * presUFRate ) + getUltrafiltrationVolumeCollected(); + uFVolume = ( (F32)( treatmentTime - CALC_ELAPSED_TREAT_TIME_IN_MIN() ) * presUFRate ) + getUltrafiltrationReferenceVolume(); if ( ( treatmentTime <= MAX_TREATMENT_TIME_MINUTES ) && ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) && ( uFVolume <= MAX_UF_VOLUME_ML ) ) @@ -1156,7 +1171,7 @@ payload.rinsebackState = getCurrentRinsebackState(); payload.txStopState = getCurrentTreatmentRecircState(); payload.txEndState = getCurrentTreatmentEndState(); - payload.heparinState = HEPARIN_STATE_OFF; // TODO - get Heparin state when implemented + payload.heparinState = getHeparinState(); broadcastTreatmentState( payload ); treatmentStateBroadcastTimerCtr = 0; @@ -1182,12 +1197,12 @@ U32 elapseTime = CALC_ELAPSED_TREAT_TIME_IN_MIN(); U32 minTime = MAX( (elapseTime + 2), MIN_TREATMENT_TIME_MINUTES ); // Treatment duration cannot be < 1 hour. add two minutes to cover rounding and ensure it is valid for next minute // Compute maximum treatment duration (from both UF and dialysate volume perspectives) - U32 maxTimeRem = ( MAX_UF_VOLUME_ML - (U32)getUltrafiltrationVolumeCollected() ) / ( presUFRate > 0.0 ? (U32)presUFRate : 1 ); + U32 maxTimeRem = ( MAX_UF_VOLUME_ML - (U32)getUltrafiltrationReferenceVolume() ) / ( presUFRate > 0.0 ? (U32)presUFRate : 1 ); U32 maxTime1 = minTime + maxTimeRem; U32 maxTime2 = MAX_DIALYSATE_VOLUME_ML / presDialysateFlowRate; U32 maxTime = MAX( maxTime1, maxTime2 ); // Compute minimum UF volume - F32 minUFVol = getUltrafiltrationVolumeCollected() + presUFRate; + F32 minUFVol = getUltrafiltrationReferenceVolume() + presUFRate; // Compute maximum UF volume (considering from adjustment of UF rate and time perspectives) F32 maxUFVol1 = minUFVol + ( (F32)( presTime - elapseTime ) * MAX_UF_RATE_ML_MIN ); F32 maxUFVol2 = ( presUFRate > 0.0 ? minUFVol + ( (F32)( MAX_TREATMENT_TIME_MINUTES - elapseTime - 1 ) * presUFRate ) : minUFVol ); Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r9798f57bc288270fe058fe098a76088cbb34d50c -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 9798f57bc288270fe058fe098a76088cbb34d50c) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -245,10 +245,11 @@ SW_FAULT_ID_TREATMENT_RECIRC_INVALID_STATE, SW_FAULT_ID_TREATMENT_STOP_INVALID_STATE, // 100 SW_FAULT_ID_MODE_PRIME_INVALID_ALARM_ACTION, + SW_FAULT_ID_INVALID_NVDATAMGMT_EXEC_CAL_STATE, SW_FAULT_ID_HD_INVALID_NO_CARTRIDGE_SELF_TEST_STATE, SW_FAULT_ID_HD_INVALID_DRY_SELF_TEST_STATE, - SW_FAULT_ID_HD_INVALID_WET_SELF_TEST_STATE, - SW_FAULT_ID_HD_INVALID_PRE_TREATMENT_RECIRC_STATE, // 105 + SW_FAULT_ID_HD_INVALID_WET_SELF_TEST_STATE, // 105 + SW_FAULT_ID_HD_INVALID_PRE_TREATMENT_RECIRC_STATE, SW_FAULT_ID_HD_INVALID_COMMAND_RESPONSE_ID, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, SW_FAULT_ID_HD_INVALID_VALVE_SETTING_ID, Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -rdaefaef0d2d3e13ff563f11d9721ccc1d831cf06 -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision daefaef0d2d3e13ff563f11d9721ccc1d831cf06) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -204,6 +204,10 @@ *************************************************************************/ void checkInFromUI( void ) { + if ( FALSE == uiDidCommunicate ) + { // Start DG check-in timer when UI first communicates + timeOfLastDGCheckIn = getMSTimerCount(); + } uiIsCommunicating = TRUE; timeOfLastUICheckIn = getMSTimerCount(); uiDidCommunicate = TRUE; @@ -930,11 +934,12 @@ { activateAlarmNoData( ALARM_ID_UI_COMM_TIMEOUT ); } + if ( TRUE == didTimeout( timeOfLastDGCheckIn, DG_COMM_TIMEOUT_IN_MS ) ) + { + activateAlarmNoData( ALARM_ID_DG_COMM_TIMEOUT ); + dgIsCommunicating = FALSE; + } } - if ( TRUE == didTimeout( timeOfLastDGCheckIn, DG_COMM_TIMEOUT_IN_MS ) ) - { - dgIsCommunicating = FALSE; - } } /*********************************************************************//** @@ -1179,6 +1184,14 @@ handleTreatmentParametersFromUI( message ); break; + case MSG_ID_UI_INITIATE_TREATMENT_REQUEST: + handleInitiateTreatmentRequest( message ); + break; + + case MSG_ID_UI_START_TREATMENT_REQUEST: + handleStartTreatmentRequest( message ); + break; + case MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS: handleUIUserConfirmTreatmentParameters( message ); break; @@ -1187,6 +1200,10 @@ handleChangePressureLimitsRequest( message ); break; + case MSG_ID_UI_HEPARIN_PAUSE_RESUME_REQUEST: + handleHeparinCommandRequest( message ); + break; + case MSG_ID_UI_SET_UF_VOLUME_PARAMETER: handleUFVolumeSetRequest( message ); break; @@ -1236,7 +1253,7 @@ break; default: - // TODO - unrecognized message ID received - ignore + // Unrecognized message ID received - ignore break; } @@ -1482,8 +1499,40 @@ handleTestSuperClearAlarmsRequest( message ); break; + case MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE: + handleTestSyringePumpDataBroadcastIntervalOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_OPERATION_REQUEST: + handleTestSyringePumpOperationRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_RATE_OVERRIDE: + handleTestSyringePumpMeasuredRateOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_FORCE_OVERRIDE: + handleTestSyringePumpMeasuredForceOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_SYRINGE_DETECT_OVERRIDE: + handleTestSyringePumpMeasuredSyringeDetectOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_HOME_OVERRIDE: + handleTestSyringePumpMeasuredHomeOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_POSITION_OVERRIDE: + handleTestSyringePumpMeasuredPositionOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_VOLUME_OVERRIDE: + handleTestSyringePumpMeasuredVolumeOverrideRequest( message ); + break; + default: - // TODO - unrecognized message ID received - ignore + // Unrecognized message ID received - ignore break; } } Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r7665e7b142961a50c5e77c44877247366a374526 -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 7665e7b142961a50c5e77c44877247366a374526) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -433,6 +433,38 @@ return result; } +/*********************************************************************//** + * @brief + * The sendHeparinCommandResponse function constructs a Heparin command response + * to the UI and queues the msg for transmit on the + * appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Heparin command response msg constructed and queued. + * @param accepted flag indicating whether request was accepted + * @param rejReason rejection reason code + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +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_HEPARIN_PAUSE_RESUME_RESPONSE; + msg.hdr.payloadLen = sizeof( U32 ) * 2; + + memcpy( payloadPtr, &accepted, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &rejReason, 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 ); + + return result; +} + /*********************************************************************//** * @brief * The sendTreatmentParamsRangesToUI function constructs a treatment parameter @@ -1021,6 +1053,62 @@ result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; +} + +/*********************************************************************//** + * @brief + * The broadcastSyringePumpData function constructs a syringe pump data + * msg to be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: syringe pump data msg constructed and queued. + * @param data syringe pump data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastSyringePumpData( SYRINGE_PUMP_DATA_PAYLOAD_T data ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SYRINGE_PUMP_DATA; + msg.hdr.payloadLen = sizeof( SYRINGE_PUMP_DATA_PAYLOAD_T ); + + memcpy( payloadPtr, &data, sizeof( SYRINGE_PUMP_DATA_PAYLOAD_T ) ); + + // 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 broadcastHeparinData function constructs a Heparin data message + * to be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Heparin data msg constructed and queued. + * @param data Heparin data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastHeparinData( F32 volume ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_HEPARIN_DATA_BROADCAST; + msg.hdr.payloadLen = sizeof( F32 ); + + memcpy( payloadPtr, &volume, sizeof( F32 ) ); + + // 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; } /*********************************************************************//** @@ -1778,8 +1866,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? } /*********************************************************************//** @@ -1822,7 +1908,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? } /*********************************************************************//** @@ -1843,7 +1928,6 @@ memcpy( &payload, message->payload, sizeof(DG_DRAIN_PUMP_DATA_PAYLOAD_T) ); setDGDrainPumpData( payload.setPtRPM ); } - // TODO - what to do if invalid payload length? } /*********************************************************************//** @@ -1864,7 +1948,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? } /*********************************************************************//** @@ -1885,7 +1968,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? } /*********************************************************************//** @@ -1956,14 +2038,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; @@ -1973,17 +2055,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(); } } @@ -1992,6 +2070,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. @@ -2084,12 +2183,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; @@ -2100,7 +2199,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 ); @@ -2300,6 +2399,31 @@ /*********************************************************************//** * @brief + * The handleHeparinCommandRequest function handles a Heparin command + * request message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleHeparinCommandRequest( MESSAGE_T *message ) +{ + if ( sizeof( U32 ) == message->hdr.payloadLen ) + { + U32 payload; + + memcpy( &payload, &message->payload[0], sizeof( U32 ) ); + + userHeparinRequest( (HEPARIN_CMD_T)payload ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief * The handleSalineBolusRequest function handles a saline bolus request * message from the UI. * @details Inputs: none @@ -3490,7 +3614,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 { @@ -3522,7 +3646,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 { @@ -3554,7 +3678,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 { @@ -4553,6 +4677,95 @@ } /*********************************************************************//** + * @brief + * The handleTestSyringePumpDataBroadcastIntervalOverrideRequest function handles a + * request to override the syringe pump data broadcast interval. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpDataBroadcastIntervalOverrideRequest( 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 = testSetSyringePumpDataPublishIntervalOverride( (U32)(payload.state.u32) ); + } + else + { + result = testResetSyringePumpDataPublishIntervalOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpOperationRequest function handles a + * request to initiate a syringe pump operation. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpOperationRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(SYRINGE_PUMP_OP_PAYLOAD_T) ) + { + SYRINGE_PUMP_OP_PAYLOAD_T payload; + + memcpy( &payload, message->payload, sizeof(SYRINGE_PUMP_OP_PAYLOAD_T) ); + result = testSyringePumpOperationRequest( payload ); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredRateOverrideRequest function handles a + * request to override the syringe pump measured rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredRateOverrideRequest( 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 = testSetSyringePumpMeasuredRateOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredRateOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleSetHDSystemRecord function handles a request to set the HD * system data record. @@ -4612,6 +4825,70 @@ } /*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredForceOverrideRequest function handles a + * request to override the syringe pump measured force analog signal. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredForceOverrideRequest( 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 = testSetSyringePumpMeasuredForceOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredForceOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredSyringeDetectOverrideRequest function handles a + * request to override the syringe pump syringe detected analog signal. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredSyringeDetectOverrideRequest( 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 = testSetSyringePumpMeasuredSyringeDetectOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredSyringeDetectOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleGetHDServiceRecord function handles a request to get the HD * service data record. @@ -4639,6 +4916,38 @@ } /*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredHomeOverrideRequest function handles a + * request to override the syringe pump measured home analog signal. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredHomeOverrideRequest( 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 = testSetSyringePumpMeasuredHomeOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredHomeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleSetHDServiceRecord function handles a request to set the HD * service data record. @@ -4670,4 +4979,68 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); } +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredPositionOverrideRequest function handles a + * request to override the syringe pump measured position. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredPositionOverrideRequest( 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 = testSetSyringePumpMeasuredPositionOverride( (S32)(payload.state.u32) ); + } + else + { + result = testResetSyringePumpMeasuredPositionOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredVolumeOverrideRequest function handles a + * request to override the syringe pump measured volume delivered. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredVolumeOverrideRequest( 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 = testSetSyringePumpMeasuredVolumeOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredVolumeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r7665e7b142961a50c5e77c44877247366a374526 -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 7665e7b142961a50c5e77c44877247366a374526) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -33,6 +33,7 @@ #include "NVDataMgmt.h" #include "PresOccl.h" #include "Rinseback.h" +#include "SyringePump.h" #include "Valves.h" /** @@ -94,17 +95,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 ); @@ -163,6 +167,12 @@ // MSG_ID_HD_PRESSURE_LIMITS_CHANGE_RESPONSE BOOL sendPressureLimitsChangeResponse( PRESSURE_LIMIT_CHANGE_RESPONSE_T *data ); +// MSG_ID_UI_HEPARIN_PAUSE_RESUME_REQUEST +void handleHeparinCommandRequest( MESSAGE_T *message ); + +// MSG_ID_HD_HEPARIN_PAUSE_RESUME_RESPONSE +BOOL sendHeparinCommandResponse( U32 accepted, U32 rejReason ); + // MSG_ID_UI_RINSEBACK_CMD void handlRinsebackCmd( MESSAGE_T *message ); @@ -236,7 +246,13 @@ BOOL broadcastDialInFlowData( DIALIN_PUMP_STATUS_PAYLOAD_T *dialInData ); // MSG_ID_DIALYSATE_OUT_FLOW_DATA -BOOL broadcastDialOutFlowData( DIAL_OUT_FLOW_DATA_T *dialOutFlowData ); +BOOL broadcastDialOutFlowData( DIAL_OUT_FLOW_DATA_T *dialOutFlowData ); + +// MSG_ID_HD_SYRINGE_PUMP_DATA +BOOL broadcastSyringePumpData( SYRINGE_PUMP_DATA_PAYLOAD_T data ); + +// MSG_ID_HD_HEPARIN_DATA_BROADCAST +BOOL broadcastHeparinData( F32 volume ); // MSG_ID_PRESSURE_OCCLUSION_DATA BOOL broadcastPresOcclData( PRESSURE_OCCLUSION_DATA_T data ); @@ -511,6 +527,30 @@ // MSG_ID_HD_SET_OP_MODE_REQUEST void handleTestSetOpModeRequest( MESSAGE_T *message ); +// MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE: +void handleTestSyringePumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_OPERATION_REQUEST: +void handleTestSyringePumpOperationRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_RATE_OVERRIDE: +void handleTestSyringePumpMeasuredRateOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_FORCE_OVERRIDE: +void handleTestSyringePumpMeasuredForceOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_SYRINGE_DETECT_OVERRIDE: +void handleTestSyringePumpMeasuredSyringeDetectOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_HOME_OVERRIDE: +void handleTestSyringePumpMeasuredHomeOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_POSITION_OVERRIDE: +void handleTestSyringePumpMeasuredPositionOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_VOLUME_OVERRIDE: +void handleTestSyringePumpMeasuredVolumeOverrideRequest( MESSAGE_T *message ); + /**@}*/ #endif Index: firmware/App/Tasks/TaskPriority.c =================================================================== diff -u -ra95967003ef6168c6cb3c0d35b9219936645eae6 -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision a95967003ef6168c6cb3c0d35b9219936645eae6) +++ firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -25,6 +25,7 @@ #include "FluidLeak.h" #include "FPGA.h" #include "InternalADC.h" +#include "SyringePump.h" #include "SystemComm.h" #include "Valves.h" #include "WatchdogMgmt.h" @@ -67,7 +68,12 @@ execInternalADC(); // Monitor air trap level sensors - execAirTrapMonitor(); + execAirTrapMonitor(); + +#ifndef DISABLE_SYRINGE_PUMP + // Control/Monitor syringe pump + execSyringePump(); +#endif // Monitor blood pump and flow execBloodFlowMonitor(); Index: firmware/source/sys_main.c =================================================================== diff -u -r3c5e31fbbcb7639c868894e9560cf68433f7d30a -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/source/sys_main.c (.../sys_main.c) (revision 3c5e31fbbcb7639c868894e9560cf68433f7d30a) +++ firmware/source/sys_main.c (.../sys_main.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -81,6 +81,7 @@ #include "PresOccl.h" #include "RTC.h" #include "SafetyShutdown.h" +#include "SyringePump.h" #include "SystemComm.h" #include "TaskBG.h" #include "Timers.h" @@ -149,7 +150,6 @@ etpwmSetCmpA( etpwmREG7, etpwmREG7->TBPRD / 3 ); etpwmStartTBCLK(); canInit(); // CAN1 = CAN, re-purposing CAN2 and CAN3 Rx and Tx pins as GPIO - //canEnableloopback( canREG1, External_Lbk ); // TODO - debug code sciInit(); // SCI1 used for PC serial interface, SCI2 used for FPGA serial interface dmaEnable(); // Enable DMA } @@ -190,6 +190,7 @@ initBloodFlow(); initDialInFlow(); initDialOutFlow(); + initSyringePump(); initValves(); initFluidLeak(); // Initialize modes