Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r8a916f65cd66ab85f6f220c4e9e9c8a1bc6b0616 -rd6b09c549d14f5f7fe08484bf0e882cadf2a892b --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 8a916f65cd66ab85f6f220c4e9e9c8a1bc6b0616) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision d6b09c549d14f5f7fe08484bf0e882cadf2a892b) @@ -553,7 +553,7 @@ *************************************************************************/ static DRAIN_PUMP_STATE_T handleDrainPumpControlToTargetState( void ) { - DRAIN_PUMP_STATE_T result = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; + DRAIN_PUMP_STATE_T state = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; // control at set interval if ( ++drainControlTimerCounter >= DRP_CONTROL_INTERVAL ) @@ -568,7 +568,14 @@ drainControlTimerCounter = 0; } - return result; + // Check if the RPM is 0, and if it is turn off the pump + if ( 0 == getTargetDrainPumpRPM() ) + { + state = DRAIN_PUMP_OFF_STATE; + signalDrainPumpHardStop(); + } + + return state; } /*********************************************************************//** Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r752defbb739ea0756a8bf060f00bc6b9429c2764 -rd6b09c549d14f5f7fe08484bf0e882cadf2a892b --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 752defbb739ea0756a8bf060f00bc6b9429c2764) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision d6b09c549d14f5f7fe08484bf0e882cadf2a892b) @@ -72,8 +72,6 @@ /// Initial conversion factor from target flow rate to PWM duty cycle estimate. #define ROP_FLOW_TO_PWM_DC(flow) ( ROP_FLOW_TO_PWM_SLOPE * flow + ROP_FLOW_TO_PWM_INTERCEPT ) -#define FLOW_SENSOR_ZERO_READING 0xFFFF ///< Flow sensor reading indicates zero flow (or flow lower than can be detected by sensor). - #define MAX_ALLOWED_FLOW_DEVIATION 0.1 ///< Max allowed deviation from target flow. #define FLOW_OUT_OF_RANGE_PERSISTENT_INTERVAL ( 12 * MS_PER_SECOND ) ///< Flow out of range time out in counts. #define MAX_PRESSURE_TARGET_TOLERANCE 5 ///< Pressure tolerance from maximum set pressure by user in psi. @@ -307,12 +305,16 @@ roControlTimerCounter = 0; isROPumpOn = FALSE; targetROPumpMaxPressure = 0; + pendingROPumpCmdMaxPressure = 0.0; + pendingROPumpCmdTargetFlow = 0.0; + pendingROPumpCmdCountDown = 0; resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, MIN_RO_PUMP_DUTY_CYCLE ); } /*********************************************************************//** * @brief - * The execROPumpMonitor function executes the RO pump monitor. + * The execROPumpMonitor function executes the RO pump monitor. The RO flow + * sensor is read, filtered, converted to L/min and calibrated. * @details Inputs: measuredFlowReadingsSum, flowFilterCounter, * measuredROFlowRateLPM, measuredROFlowRateLPM, roPumpState, * flowOutOfRangeCounter, roPumpControlMode @@ -343,20 +345,20 @@ // Read flow at the control set if ( ++flowFilterCounter >= FLOW_SAMPLES_TO_AVERAGE ) { - F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER ); + F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER ); // Convert flow sensor period to L/min + // Apply calibration to flow sensor reading measuredROFlowRateLPM.data = pow(flow, 4) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].fourthOrderCoeff + pow(flow, 3) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].thirdOrderCoeff + pow(flow, 2) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].secondOrderCoeff + - flow * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].gain + + flow * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].gain + flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].offset; - // If the flow is less than a certain value, FPGA will return 0xFFFF meaning that - // the flow is 0. - if ( FLOW_SENSOR_ZERO_READING == roFlowReading ) - { - measuredROFlowRateLPM.data = 0.0; - } + // If the flow is less than a certain value, FPGA will return 0xFFFF meaning that the flow is 0. + if ( FLOW_SENSOR_ZERO_READING == roFlowReading ) + { + measuredROFlowRateLPM.data = 0.0; + } measuredFlowReadingsSum = 0; flowFilterCounter = 0; Index: firmware/App/Services/FPGA.h =================================================================== diff -u -r752defbb739ea0756a8bf060f00bc6b9429c2764 -rd6b09c549d14f5f7fe08484bf0e882cadf2a892b --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision 752defbb739ea0756a8bf060f00bc6b9429c2764) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision d6b09c549d14f5f7fe08484bf0e882cadf2a892b) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file FPGA.h * -* @author (last) Quang Nguyen -* @date (last) 24-Aug-2020 +* @author (last) H. Nguyen +* @date (last) 21-Oct-2021 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -53,6 +53,7 @@ void getFPGAVersions( U08 *Id, U08 *Maj, U08 *Min, U08 *Lab ); U16 getFPGAValveStates( void ); U16 getFPGAROPumpFlowRate( void ); +U16 getFPGADialysateFlowRate( void ); U16 getFPGADrainPumpSpeed( void ); U32 getFPGALoadCellA1( void ); U32 getFPGALoadCellA2( void ); Index: firmware/App/Services/Reservoirs.h =================================================================== diff -u -r92a0a399021a2d120155b0a779855893284b8cbb -rd6b09c549d14f5f7fe08484bf0e882cadf2a892b --- firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 92a0a399021a2d120155b0a779855893284b8cbb) +++ firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision d6b09c549d14f5f7fe08484bf0e882cadf2a892b) @@ -46,9 +46,10 @@ /// Drain command data structure. typedef struct { - U32 targetVolume; ///< Target volume to drain to (in mL) - BOOL tareLoadCell; ///< Flag to tare load call - BOOL rinseConcentrateLines; ///< Flag indicates to rinse concentrate lines or not + U32 targetVolume; ///< Target volume to drain to (in mL) + BOOL tareLoadCell; ///< Flag to tare load call + BOOL rinseConcentrateLines; ///< Flag indicates to rinse concentrate lines or not + U32 cmd; ///< General command (start/stop) } DRAIN_CMD_T; /// DG command response data record. Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r8a42ba4060bf15e63d291fa23df6fcd5434beab4 -rd6b09c549d14f5f7fe08484bf0e882cadf2a892b --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 8a42ba4060bf15e63d291fa23df6fcd5434beab4) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision d6b09c549d14f5f7fe08484bf0e882cadf2a892b) @@ -54,9 +54,9 @@ #define MAX_COMM_CRC_FAILURES 5 ///< maximum number of CRC errors within window period before alarm #define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window -#define MSG_NOT_ACKED_TIMEOUT_MS ( MS_PER_SECOND * 1 ) ///< maximum time for a Denali message that requires ACK to be ACK'd -#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm -#define PENDING_ACK_LIST_SIZE 25 ///< maximum number of Delanli messages that can be pending ACK at any given time +#define MSG_NOT_ACKED_TIMEOUT_MS 150 ///< maximum time for a Denali message that requires ACK to be ACK'd +#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm +#define PENDING_ACK_LIST_SIZE 25 ///< maximum number of Delanli messages that can be pending ACK at any given time #pragma pack(push, 1) @@ -1092,10 +1092,18 @@ handleTestROMeasuredFlowOverrideRequest( message ); break; + case MSG_ID_DIALYSATE_MEASURED_FLOW_OVERRIDE: + handleTestDialysateMeasuredFlowOverrideRequest( message ); + break; + case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: handleTestROPumpDataBroadcastIntervalOverrideRequest( message ); break; + case MSG_ID_DIALYSATE_FLOW_SEND_INTERVAL_OVERRIDE: + handleTestDialysateFlowDataBroadcastIntervalOverrideRequest( message ); + break; + case MSG_ID_DRAIN_PUMP_SET_RPM_OVERRIDE: handleTestDrainPumpRPMOverrideRequest( message ); break; @@ -1273,11 +1281,11 @@ break; case MSG_ID_FILTER_FLUSH_TIME_PERIOD_OVERRIDE: - handleFilterFlushTimePeriodOverride( message ); + handleFilterFlushTimePeriodOverride(message); break; - case MSG_ID_DG_FANS_RPM_OVERRIDE: - handleFansRPMOverride( message ); + case MSG_ID_DG_BLOCK_MESSAGE_TRANSMISSION: + handleTestBlockMessagesRequest( message ); break; case MSG_ID_DG_STOP_RTC_CLOCK: Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r8a42ba4060bf15e63d291fa23df6fcd5434beab4 -rd6b09c549d14f5f7fe08484bf0e882cadf2a892b --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 8a42ba4060bf15e63d291fa23df6fcd5434beab4) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision d6b09c549d14f5f7fe08484bf0e882cadf2a892b) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file SystemCommMessages.c * -* @author (last) Quang Nguyen -* @date (last) 26-Aug-2020 +* @author (last) H. Nguyen +* @date (last) 21-Oct-2021 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -22,15 +22,16 @@ #include "Accel.h" #include "ConcentratePumps.h" #include "ConductivitySensors.h" -#include "Fans.h" #include "FPGA.h" #include "Heaters.h" #include "ModeFlush.h" #include "ModeGenIdle.h" +#include "ModeInitPOST.h" #include "ModeStandby.h" #include "MsgQueues.h" #include "NVDataMgmt.h" #include "OperationModes.h" +#include "DialysateFlow.h" #include "Pressures.h" #include "Reservoirs.h" #include "RTC.h" @@ -55,101 +56,136 @@ #ifdef DEBUG_ENABLED #define DEBUG_EVENT_MAX_TEXT_LEN 40 #endif - -// ********** private data ********** - -static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. + +#define MAX_MSGS_BLOCKED_FOR_XMIT 8 ///< Maximum number of messages to block transmission for. + +#pragma pack(push,1) +/// Payload record structure for block message transmission request. +typedef struct +{ + U16 blockedMessages[ MAX_MSGS_BLOCKED_FOR_XMIT ]; +} BLOCKED_MSGS_DATA_T; +#pragma pack(pop) + +// ********** private data ********** + +static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. static volatile U16 nextSeqNo = 1; ///< Next sequence number. - -// ********** private function prototypes ********** - -static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); - -/*********************************************************************//** - * @brief - * The serializeMessage function serializes a given message into a given - * array of bytes. A sequence # is added to the message here and the ACK - * bit of the sequence # is set if ACK is required per parameter. A sync byte - * is inserted at the beginning of the message and an 8-bit CRC is appended to - * the end of the message. The message is queued for transmission in the given buffer. - * @details Inputs: none - * @details Outputs: given data array populated with serialized message data and queued for transmit. - * @param msg message to serialize - * @param buffer outgoing buffer that message should be queued in - * @param ackReq is an acknowledgement from receiver required? - * @return size (in bytes) of serialized message populated in given data array. - *************************************************************************/ -U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) -{ - BOOL result = FALSE; - BOOL error = FALSE; - U32 msgSize = 0; - U32 sizeMod, sizePad; - U32 i; - U08 crc; - U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data - - // prefix data with message sync byte - data[ msgSize++ ] = MESSAGE_SYNC_BYTE; - - // set sequence # and ACK bit (unless this is an ACK to a received message) - if ( msg.hdr.msgID != MSG_ID_ACK ) - { - // thread protect next sequence # access & increment - _disable_IRQ(); - msg.hdr.seqNo = nextSeqNo; - nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); - _enable_IRQ(); - if ( TRUE == ackReq ) - { - msg.hdr.seqNo *= -1; - } - } - - // calculate message CRC - crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); - - // serialize message header data - memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); - msgSize += sizeof( MESSAGE_HEADER_T ); - - // serialize message payload (only used bytes per payloadLen field) - memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); - msgSize += msg.hdr.payloadLen; - - // add 8-bit CRC - data[ msgSize++ ] = crc; - - // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) - sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; - sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); - for ( i = 0; i < sizePad; i++ ) - { - data[ msgSize++ ] = 0; - } - - // if ACK required, add to pending ACK list - if ( TRUE == ackReq ) - { - if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) - { - error = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) - } - } - - if ( FALSE == error ) - { - // add serialized message data to appropriate out-going comm buffer - result = addToCommBuffer( buffer, data, msgSize ); - } - - return result; -} +/// List of message IDs that are requested not to be transmitted. +static BLOCKED_MSGS_DATA_T blockedMessagesForXmit = { 0, 0, 0, 0, 0, 0, 0, 0 }; +// ********** private function prototypes ********** + +static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); +static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); + /*********************************************************************//** * @brief + * The serializeMessage function serializes a given message into a given + * array of bytes. A sequence # is added to the message here and the ACK + * bit of the sequence # is set if ACK is required per parameter. A sync byte + * is inserted at the beginning of the message and an 8-bit CRC is appended to + * the end of the message. The message is queued for transmission in the given buffer. + * @details Inputs: none + * @details Outputs: given data array populated with serialized message data and queued for transmit. + * @param msg message to serialize + * @param buffer outgoing buffer that message should be queued in + * @param ackReq is an acknowledgement from receiver required? + * @return size (in bytes) of serialized message populated in given data array. + *************************************************************************/ +U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) +{ + BOOL result = FALSE; + BOOL error = FALSE; + BOOL blocked = FALSE; + U32 msgSize = 0; + U32 sizeMod, sizePad; + U32 i; + U08 crc; + U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data + + // Check to see if tester has requested this message not be transmitted + if ( TRUE == isTestingActivated() ) + { + U32 i; + + for ( i = 0; i < MAX_MSGS_BLOCKED_FOR_XMIT; i++ ) + { + if ( msg.hdr.msgID == blockedMessagesForXmit.blockedMessages[ i ] ) + { + blocked = TRUE; + break; + } + } + } + // Serialize and queue message for transmission unless this message is blocked + if ( blocked != TRUE ) + { + // prefix data with message sync byte + data[ msgSize++ ] = MESSAGE_SYNC_BYTE; + + // set sequence # and ACK bit (unless this is an ACK to a received message) + if ( msg.hdr.msgID != MSG_ID_ACK ) + { + // thread protect next sequence # access & increment + _disable_IRQ(); + msg.hdr.seqNo = nextSeqNo; + nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); + _enable_IRQ(); + if ( TRUE == ackReq ) + { + msg.hdr.seqNo *= -1; + } + } + + // calculate message CRC + crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); + + // serialize message header data + memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); + msgSize += sizeof( MESSAGE_HEADER_T ); + + // serialize message payload (only used bytes per payloadLen field) + memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); + msgSize += msg.hdr.payloadLen; + + // add 8-bit CRC + data[ msgSize++ ] = crc; + + // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) + sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; + sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); + for ( i = 0; i < sizePad; i++ ) + { + data[ msgSize++ ] = 0; + } + + // if ACK required, add to pending ACK list + if ( TRUE == ackReq ) + { + if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) + { + error = TRUE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + } + } + + if ( FALSE == error ) + { + // add serialized message data to appropriate out-going comm buffer + result = addToCommBuffer( buffer, data, msgSize ); + } + } + else + { + result = TRUE; // If message blocked, return successful transmission + } + + return result; +} + +/*********************************************************************//** + * @brief * The sendACKMsg function constructs and queues for transmit an ACK message * for a given received message. * @details Inputs: none @@ -393,86 +429,86 @@ /*********************************************************************//** * @brief * The broadcastRTCEpoch function constructs an epoch msg to be broadcast - * and queues the msg for transmit on the appropriate CAN channel. - * @details Inputs: none - * @details Outputs: RTC time and date in epoch - * @param epoch Current time and date in epoch - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastRTCEpoch( U32 epoch ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_RTC_EPOCH; - msg.hdr.payloadLen = sizeof( U32 ); - - memcpy( payloadPtr, &epoch, 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_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; + * and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: RTC time and date in epoch + * @param epoch Current time and date in epoch + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastRTCEpoch( U32 epoch ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_RTC_EPOCH; + msg.hdr.payloadLen = sizeof( U32 ); + + memcpy( payloadPtr, &epoch, 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_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; } -/*********************************************************************//** - * @brief - * The broadcastLoadCellData function sends out load cell data. - * @details Inputs: none - * @details Outputs: load cell data msg constructed and queued - * @param loadCell which is the loadcells data structure pointer - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastLoadCellData( LOAD_CELL_DATA_T *loadCell ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_LOAD_CELL_READINGS; - msg.hdr.payloadLen = sizeof( LOAD_CELL_DATA_T ); - - memcpy( payloadPtr, loadCell, sizeof( LOAD_CELL_DATA_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_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; +/*********************************************************************//** + * @brief + * The broadcastLoadCellData function sends out load cell data. + * @details Inputs: none + * @details Outputs: load cell data msg constructed and queued + * @param loadCell which is the loadcells data structure pointer + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastLoadCellData( LOAD_CELL_DATA_T *loadCell ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_LOAD_CELL_READINGS; + msg.hdr.payloadLen = sizeof( LOAD_CELL_DATA_T ); + + memcpy( payloadPtr, loadCell, sizeof( LOAD_CELL_DATA_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_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; } -/*********************************************************************//** - * @brief - * The broadcastValvesStates function sends out DG valves states. - * @details Inputs: none - * @details Outputs: Valves states msg constructed and queued - * @param valvesStates valves states - * refer to setFPGAValveStates function in FPGA.c for details - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastValvesStates( U16 valvesStates ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_VALVES_STATES; - msg.hdr.payloadLen = sizeof( U16 ); - - memcpy( payloadPtr, &valvesStates, sizeof( U16 ) ); - - // 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_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} +/*********************************************************************//** + * @brief + * The broadcastValvesStates function sends out DG valves states. + * @details Inputs: none + * @details Outputs: Valves states msg constructed and queued + * @param valvesStates valves states + * refer to setFPGAValveStates function in FPGA.c for details + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastValvesStates( U16 valvesStates ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_VALVES_STATES; + msg.hdr.payloadLen = sizeof( U16 ); + + memcpy( payloadPtr, &valvesStates, sizeof( U16 ) ); + + // 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_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + /*********************************************************************//** * @brief * The broadcastDrainPumpData function sends out the drain pump data. @@ -562,6 +598,61 @@ /*********************************************************************//** * @brief + * The broadcastDialysateFlowData function sends out dialysate flow data. + * @details Inputs: measuredDialysateFlowRate + * @details Outputs: dialysate flow data message constructed and queued + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastDialysateFlowData( const DIALYSATE_FLOW_METER_DATA_T * const flowData ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_DIALYSATE_FLOW_METER_DATA; + msg.hdr.payloadLen = sizeof( DIALYSATE_FLOW_METER_DATA_T ); + + memcpy( payloadPtr, flowData, sizeof( DIALYSATE_FLOW_METER_DATA_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_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The broadcastConcentratePumpData function sends out concentrate pumps' data. + * @details Inputs: none + * @details Outputs: concentrate pump data msg constructed and queued + * @param cp1TgtSpeed target speed for concentrate pump CP1 + * @param measuredCP1Speed measured speed for concentrate pump CP1 using hall sense + * @param cp2TgtSpeed target speed for concentrate pump CP2 + * @param measuredCP2Speed measured speed for concentrate pump CP2 using hall sense + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastConcentratePumpData( void * concentratePumpDataPtr ) +{ + BOOL result; + MESSAGE_T msg; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_CONCENTRATE_PUMP_DATA; + msg.hdr.payloadLen = sizeof( CONCENTRATE_PUMP_DATA_T ); + + memcpy( &msg.payload, concentratePumpDataPtr, sizeof( CONCENTRATE_PUMP_DATA_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_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The broadcastPressureSensorsData function sends out DG pressure data. * @details Inputs: none * @details Outputs: Pressure data msg constructed and queued @@ -1557,17 +1648,18 @@ { BOOL result = FALSE; - if ( message->hdr.payloadLen == sizeof( U32 ) ) + if ( message->hdr.payloadLen == sizeof( BOOL ) ) { BOOL startingTreatment; + DG_OP_MODE_T dgMode = getCurrentOperationMode(); - memcpy( &startingTreatment, message->payload, sizeof( U32 ) ); + memcpy( &startingTreatment, message->payload, sizeof( BOOL ) ); - if ( ( DG_MODE_STAN == getCurrentOperationMode() ) && ( TRUE == startingTreatment ) ) + if ( ( DG_MODE_STAN == dgMode ) && ( TRUE == startingTreatment ) ) { result = requestDGStart(); } - else if ( ( DG_MODE_GENE == getCurrentOperationMode() ) && ( FALSE == startingTreatment ) ) + else if ( ( dgMode >= DG_MODE_GENE ) && ( dgMode <= DG_MODE_DRAI ) && ( FALSE == startingTreatment ) ) { result = requestDGStop(); } @@ -2095,15 +2187,15 @@ } -/*********************************************************************//** - * @brief - * The handleTestROMeasuredFlowOverrideRequest function handles a request to - * override the RO flow rate. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestROMeasuredFlowOverrideRequest function handles a request to + * override the RO flow rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -2129,6 +2221,38 @@ /*********************************************************************//** * @brief + * The handleTestDialysateMeasuredFlowOverrideRequest function handles a request to + * override the Dialysate flow rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDialysateMeasuredFlowOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetMeasuredDialysateFlowRateOverride( payload.state.f32 ); + } + else + { + result = testResetMeasuredDialysateFlowRateOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleTestROPumpDataBroadcastIntervalOverrideRequest function handles * a request to override the broadcast interval for RO pump data. * @details Inputs: none @@ -2161,6 +2285,38 @@ /*********************************************************************//** * @brief + * The handleTestDialysateFlowDataBroadcastIntervalOverrideRequest function handles + * a request to override the broadcast interval for dialysate flow data. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestDialysateFlowDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetDialysateFlowDataPublishIntervalOverride( payload.state.u32 ); + } + else + { + result = testResetDialysateFlowDataPublishIntervalOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleTestDrainPumpRPMOverrideRequest function handles a request to * override the drain pump speed set point (in RPM). * @details Inputs: none @@ -3237,7 +3393,6 @@ { BOOL status = FALSE; BOOL result = FALSE; - U08* payloadPtr = message->payload; if ( 0 == message->hdr.payloadLen ) { @@ -3562,37 +3717,6 @@ } /*********************************************************************//** - * @brief - * The handleFansRPMOverride function handles a request to override a fans RPM value. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleFansRPMOverride( MESSAGE_T *message ) -{ - TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; - BOOL result = FALSE; - - // verify payload length - if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) - { - memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); - if ( FALSE == payload.reset ) - { - result = testSetFanRPMOverride( payload.index, payload.state.f32 ); - } - else - { - result = testResetFanRPMOverride( payload.index ); - } - } - - // respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** * @brief * The handleStopDGRTCClock function handles a request to stop the RTC clock. * @details Inputs: none @@ -3648,4 +3772,31 @@ return result; } +/*********************************************************************//** + * @brief + * The handleTestBlockMessagesRequest function handles a request to + * block transmission of specific message(s). + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestBlockMessagesRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(BLOCKED_MSGS_DATA_T) == message->hdr.payloadLen ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + memcpy( &blockedMessagesForXmit.blockedMessages[0], message->payload, sizeof(BLOCKED_MSGS_DATA_T) ); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r8a42ba4060bf15e63d291fa23df6fcd5434beab4 -rd6b09c549d14f5f7fe08484bf0e882cadf2a892b --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 8a42ba4060bf15e63d291fa23df6fcd5434beab4) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision d6b09c549d14f5f7fe08484bf0e882cadf2a892b) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file SystemCommMessages.h * -* @author (last) Quang Nguyen -* @date (last) 24-Aug-2020 +* @author (last) H. Nguyen +* @date (last) 22-Oct-2021 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -24,13 +24,15 @@ #include "Fans.h" #include "FluidLeak.h" #include "LoadCell.h" +#include "MessageSupport.h" #include "ModeChemicalDisinfect.h" #include "ModeFlush.h" #include "ModeHeatDisinfect.h" #include "MsgQueues.h" #include "NVDataMgmt.h" #include "Reservoirs.h" #include "ROPump.h" +#include "DialysateFlow.h" #include "Switches.h" #include "TemperatureSensors.h" #include "Thermistors.h" @@ -52,6 +54,8 @@ // ********** public function prototypes ********** +U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ); + // ACK MSG BOOL sendACKMsg( MESSAGE_T *message ); @@ -85,6 +89,9 @@ // MSG_ID_DG_VALVES_STATES BOOL broadcastValvesStates( U16 valvesStates ); +// MSG_ID_DG_DIALYSATE_FLOW_METER_DATA +BOOL broadcastDialysateFlowData( const DIALYSATE_FLOW_METER_DATA_T * const flowData ); + // MSG_ID_RO_PUMP_DATA BOOL broadcastROPumpData( RO_PUMP_DATA_T *pumpData ); @@ -249,9 +256,15 @@ // MSG_ID_RO_MEASURED_FLOW_OVERRIDE: void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ); +// MSG_ID_DIALYSATE_MEASURED_FLOW_OVERRIDE: +void handleTestDialysateMeasuredFlowOverrideRequest( MESSAGE_T *message ); + // MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: void handleTestROPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); +// MSG_ID_DIALYSATE_FLOW_SEND_INTERVAL_OVERRIDE: +void handleTestDialysateFlowDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + // MSG_ID_DRAIN_PUMP_SET_RPM_OVERRIDE void handleTestDrainPumpRPMOverrideRequest( MESSAGE_T *message ); @@ -339,7 +352,10 @@ // MSG_ID_DG_RO_PUMP_DUTY_CYCLE_OVERRIDE void handleTestROPumpDutyCycleOverride( MESSAGE_T *message ); -// MSG_ID_DG_RO_PUMP_TARGET_FLOW_OVERRIDE +// MSG_ID_DG_RO_FLOW_RATE_OVERRIDE +void handleTestMeasuredROFlowRateOverride( MESSAGE_T *message ); + +// MSG_ID_DG_SET_RO_PUMP_TARGET_FLOW void handleTestROPumpTargetFlowOverride( MESSAGE_T *message ); // MSG_ID_DG_RO_PUMP_TARGET_PRESSURE_OVERRIDE @@ -390,8 +406,8 @@ // MSG_ID_FILTER_FLUSH_TIME_PERIOD_OVERRIDE void handleFilterFlushTimePeriodOverride( MESSAGE_T *message ); -// MSG_ID_DG_FANS_RPM_OVERRIDE -void handleFansRPMOverride( MESSAGE_T *message ); +// MSG_ID_DG_BLOCK_MESSAGE_TRANSMISSION +void handleTestBlockMessagesRequest( MESSAGE_T *message ); // MSG_ID_DG_STOP_RTC_CLOCK void handleStopDGRTCClock( MESSAGE_T * message );