Index: firmware/App/Modes/ModeTreatmentParams.c =================================================================== diff -u -r9a45dcbdfae33fc06479d99b8d52bada8f682194 -re0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe --- firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision 9a45dcbdfae33fc06479d99b8d52bada8f682194) +++ firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision e0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe) @@ -62,6 +62,7 @@ { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=2}, {.uInt=0} }, // TREATMENT_PARAM_ACID_CONCENTRATE { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=0}, {.uInt=0} }, // TREATMENT_PARAM_BICARB_CONCENTRATE { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=4}, {.uInt=0} }, // TREATMENT_PARAM_DIALYZER_TYPE + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=0}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_TYPE { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=60}, {.uInt=30} }, // TREATMENT_PARAM_BP_MEAS_INTERVAL { CRITICAL_DATA_TYPE_U32, {.uInt=50}, {.uInt=150}, {.uInt=75} }, // TREATMENT_PARAM_RINSEBACK_FLOW_RATE { CRITICAL_DATA_TYPE_S32, {.sInt=-300}, {.sInt=-30}, {.sInt=-300} }, // TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT @@ -415,6 +416,9 @@ if ( TRUE == accepted ) { + // store the user set ultrafiltration volume in pre-treatment parameters setup, if it is validated, otherwise keep the initial 0.0 + origTreatmentParams.uFVolume_L = uFVolumeL; + U32 treatmentDuration = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); if ( treatmentDuration > 0 ) @@ -837,7 +841,36 @@ return result; } +/*********************************************************************//** + * @brief + * The getUltrafiltrationVolumeOriginal function gets the floating point value + * of the original set treatment parameter's ultrafiltration volume by user in + * Pre-Treatment mode. + * @details Inputs: none + * @details Outputs: origTreatmentParams.uFVolume_L + * @param none + * @return the original ultrafiltration volume value in liter + *************************************************************************/ +F32 getUltrafiltrationVolumeOriginal( void ) +{ + return origTreatmentParams.uFVolume_L; +} +/*********************************************************************//** + * @brief + * The getUltrafiltrationRateOriginal function gets the floating point value + * of the original ultrafiltration rate calculated by the set treatment parameter's + * ultrafiltration volume and treatment duration by user in Pre-Treatment mode. + * @details Inputs: origTreatmentParams.uFVolume_L, origTreatmentParams.treatmentDuration_min + * @details Outputs: none + * @param none + * @return the original ultrafiltration rate value in mL/min + *************************************************************************/ +F32 getUltrafiltrationRateOriginal( void ) +{ + return origTreatmentParams.uFVolume_L * ML_PER_LITER / origTreatmentParams.treatmentDuration_min; +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/ModeTreatmentParams.h =================================================================== diff -u -r09e6cf9de34acf18f6e1138bf56ac0edb4821186 -re0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe --- firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision 09e6cf9de34acf18f6e1138bf56ac0edb4821186) +++ firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision e0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe) @@ -47,6 +47,7 @@ U32 acidConcentrate; ///< User set acid concentrate option U32 bicarbConcentrate; ///< User set bicarbonate concentrate option U32 dialyzerType; ///< User set dialyzer type option + U32 heparinType; ///< User set heparin type option U32 bloodPressureMeasurementInterval_min; ///< User set blood pressure measurement interval (in min) U32 rinsebackFlowRate_mL_min; ///< User set rinseback flow rate (in mL/min) S32 arterialPressureLowLimit_mmHg; ///< User set lower alarm limit for arterial pressure (in mmHg) @@ -92,6 +93,8 @@ S32 getTreatmentParameterS32( TREATMENT_PARAM_T param ); // Get a specified signed integer treatment parameter F32 getTreatmentParameterF32( TREATMENT_PARAM_T param ); // Get a specified floating point treatment parameter BOOL isTreatmentParamInRange( TREATMENT_PARAM_T param, CRITICAL_DATAS_T value ); // Check range for a proposed treatment parameter value +F32 getUltrafiltrationVolumeOriginal( void ); // Get the original ultrafiltration volume, set in pre-treatment mode by user. +F32 getUltrafiltrationRateOriginal( void ); // Get/calculate the original ultrafiltration rate, by ultrafiltration volume and treatment duration set in pre-treatment mode by user. BOOL testSetTreatmentParameter( TREATMENT_PARAM_T param, CRITICAL_DATAS_T value ); // Set a specific treatment parameter value Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r5addd92e279ebc0871364fee70e3ac74db21001a -re0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 5addd92e279ebc0871364fee70e3ac74db21001a) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe) @@ -7,8 +7,8 @@ * * @file SystemComm.c * -* @author (last) Sean Nash -* @date (last) 12-Nov-2021 +* @author (last) Dara Navaei +* @date (last) 07-Dec-2021 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -49,12 +49,13 @@ #define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window #define MSG_NOT_ACKED_TIMEOUT_MS 150 ///< Maximum time for a Denali message that requires ACK to be ACK'd +#define MSG_NOT_ACKED_TIMEOUT_MS_INIT 5000 ///< Maximum time for a Denali message that requires ACK to be ACK'd on the INIT state for the first (UI version request) message of the POST #define MSG_NOT_ACKED_MAX_RETRIES 3 ///< Maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm #define PENDING_ACK_LIST_SIZE 25 ///< Maximum number of Denali messages that can be pending ACK at any given time #pragma pack(push, 1) -/// Record for transmitted message that is pending acknowledgement from receiver. +/// Record for transmitted message that is pending acknowledgment from receiver. typedef struct { BOOL used; @@ -871,8 +872,13 @@ // Find expired messages pending ACK for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) - { // Pending ACK expired? - if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, MSG_NOT_ACKED_TIMEOUT_MS ) ) ) + { // Pending ACK expired? + U32 timeoutPeriod = MSG_NOT_ACKED_TIMEOUT_MS; // set the timeout as default + if ( MODE_INIT == getCurrentOperationMode() ) + { // change it to longer timeout if the HD is in INIT state + timeoutPeriod = MSG_NOT_ACKED_TIMEOUT_MS_INIT; + } + if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, timeoutPeriod ) ) ) { // If retries left, reset and resend pending message if ( pendingAckList[ i ].retries > 0 ) { // Re-queue message for transmit Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r65d0f3fed34c836640f502d80a8aeb4e10ddf5ac -re0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 65d0f3fed34c836640f502d80a8aeb4e10ddf5ac) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision e0af40e2557c9f9c4fd9f97e909b3cccdc2d15fe) @@ -15,9 +15,9 @@ * ***************************************************************************/ -#include // For memcpy() +#include // For memcpy() -#include "reg_system.h" +#include "reg_system.h" // Used to access system register to reset processor on request #include "Accel.h" #include "AlarmLamp.h" @@ -49,10 +49,6 @@ // ********** private definitions ********** -#ifdef DEBUG_ENABLED - #define DEBUG_EVENT_MAX_TEXT_LEN 40 -#endif - #define MAX_MSGS_BLOCKED_FOR_XMIT 8 ///< Maximum number of messages to block transmission for. #pragma pack(push,1) @@ -1369,15 +1365,17 @@ /*********************************************************************//** * @brief - * The sendDialysateTempTargetsToDG function constructs a dialysate temperature - * set points message for DG and queues the msg for transmit on the appropriate CAN channel. + * The sendDialysateTempTargetsAndReservoirCycleTimeToDG function constructs a + * dialysate temperature set points message and the active reservoir cycle time + * for DG and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none * @details Outputs: Dialysate temperature set points msg constructed and queued. - * @param primary temperature set point for primary heater - * @param trimmer temperature set point for trimmer heater + * @param trimmer temperature set point for trimmer heater + * @param rsrvrCycleTime active reservoir cycle time in milliseconds + * @param rsrvrWait2Switch time to switch the inactive and active reservoirs in milliseconds * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendDialysateTempTargetsToDG( F32 primary, F32 trimmer ) +BOOL sendDialysateHeatingParamsToDG( DG_CMD_DIALYSATE_HEATING_PARAMS_T *params ) { BOOL result; MESSAGE_T msg; @@ -1386,11 +1384,9 @@ // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS; - msg.hdr.payloadLen = sizeof( F32 ) + sizeof( F32 ); + msg.hdr.payloadLen = sizeof( DG_CMD_DIALYSATE_HEATING_PARAMS_T ); - memcpy( payloadPtr, &primary, sizeof( F32 ) ); - payloadPtr += sizeof( F32 ); - memcpy( payloadPtr, &trimmer, sizeof( F32 ) ); + memcpy( payloadPtr, params, sizeof( DG_CMD_DIALYSATE_HEATING_PARAMS_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_2_DG, ACK_REQUIRED ); @@ -1461,10 +1457,11 @@ * @details Inputs: none * @details Outputs: DG fill command msg constructed and queued. * @param cmd start or stop fill command - * @param fillToVolumeMl volume (in mL) to fill inactive reservoir to + * @param fillToVolumeMl volume (in mL) to fill inactive reservoir to + * @param targetFlowLRatePM target fill flow rate in L/min * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendDGFillCommand( U32 cmd, U32 fillToVolumeMl ) +BOOL sendDGFillCommand( U32 cmd, U32 fillToVolumeMl, F32 targetFlowRateLPM ) { BOOL result; MESSAGE_T msg; @@ -1473,11 +1470,13 @@ // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_FILL_CMD; - msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( F32 ); memcpy( payloadPtr, &fillToVolumeMl, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, &cmd, sizeof( U32 ) ); + memcpy( payloadPtr, &cmd, sizeof( U32 ) ); + payloadPtr += sizeof( F32 ); + memcpy( payloadPtr, &targetFlowRateLPM, 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_2_DG, ACK_REQUIRED ); @@ -1935,6 +1934,52 @@ return result; } +/*********************************************************************//** + * @brief + * The sendDGConcentrateMixingRatiosRequest function constructs a request msg + * to the DG to request the concentrate ratios and queues the msg for transmit + * on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG POST result request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGConcentrateMixingRatiosRequest( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_CONCENTRATE_MIXING_RATIOS; + 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; +} + +/*********************************************************************//** + * @brief + * The handleDGMixingRatios function handles a concentrate mixing ratios and + * prepare fill time broadcast from DG. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGMixingRatios( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof( DG_MIXING_RATIOS_T ) ) + { + DG_MIXING_RATIOS_T payload; + + memcpy( &payload, message->payload, sizeof( DG_MIXING_RATIOS_T ) ); + + setDGMixingRatios( payload ); + } +} + #ifdef EMC_TEST_BUILD BOOL broadcastCANErrorCount( U32 count ) { @@ -2262,7 +2307,7 @@ TEMPERATURE_SENSORS_DATA_T payload; memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); - setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); + setDialysateTemperatureReadings( payload.TDi, payload.TRo ); } // TODO - what to do if invalid payload length? // TODO - how to know if DG stops sending these? @@ -2279,11 +2324,11 @@ *************************************************************************/ void handleDialysateFlowData( MESSAGE_T *message ) { - if ( message->hdr.payloadLen == sizeof(DIALYSATE_FLOW_METER_DATA_T) ) + if ( message->hdr.payloadLen == sizeof( DIALYSATE_FLOW_METER_DATA_T ) ) { DIALYSATE_FLOW_METER_DATA_T payload; - memcpy( &payload, message->payload, sizeof(DIALYSATE_FLOW_METER_DATA_T) ); + memcpy( &payload, message->payload, sizeof( DIALYSATE_FLOW_METER_DATA_T ) ); setDialysateFlowData( payload.measuredDialysateFlowRate ); } } @@ -3158,55 +3203,6 @@ *************************************************************************/ -#ifdef DEBUG_ENABLED - /*********************************************************************//** - * @brief - * The sendDebugData function sends debug data out to the PC port. - * @details - * @details Inputs: none - * @details Outputs: PC serial port - * @param dbgData Pointer to debug data - * @param len number of bytes of debug data - * @return TRUE if debug data was successfully queued for transmit, FALSE if not - *************************************************************************/ - BOOL sendDebugData( U08 *dbgData, U32 len ) - { - BOOL result; - - // Add serialized message data to appropriate comm buffer - result = addToCommBuffer( COMM_BUFFER_OUT_UART_PC, dbgData, len ); - - return result; - } - - /*********************************************************************//** - * @brief - * The sendDebugDataToUI function sends debug string to the UI for logging. - * @details Inputs: none - * @details Outputs: Message constructed and queued for transmit - * @param str Pointer to debug string - * @return none - *************************************************************************/ - void sendDebugDataToUI( U08 *str ) - { - MESSAGE_T msg; - U32 txtLen = strlen( (char*)str ); - U08 *payloadPtr = msg.payload; - - // Create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_HD_DEBUG_EVENT; - msg.hdr.payloadLen = DEBUG_EVENT_MAX_TEXT_LEN + 1; // Add 1 byte for null terminator - if ( txtLen <= DEBUG_EVENT_MAX_TEXT_LEN ) - { - memcpy( payloadPtr, str, txtLen + 1 ); - - // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_NOT_REQUIRED ); - } - } -#endif - /*********************************************************************//** * @brief * The isTestingActivated function determines whether a tester has successfully @@ -5127,6 +5123,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 ); @@ -6730,7 +6727,6 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } - /*********************************************************************//** * @brief * The handleStopHDRTCClock function handles a request to stop the RTC clock.