/************************************************************************** * * Copyright (c) 2019-2020 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) Sean Nash * @date (last) 04-Sep-2020 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 * ***************************************************************************/ #include // for memcpy() #include "Accel.h" #include "AlarmLamp.h" #include "BloodFlow.h" #include "Buttons.h" #include "DGInterface.h" #include "DialInFlow.h" #include "Dialysis.h" #include "FPGA.h" #include "ModeStandby.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" #include "PresOccl.h" #include "SafetyShutdown.h" #include "SystemComm.h" #include "SystemCommMessages.h" #include "Utilities.h" #include "WatchdogMgmt.h" #include "RTC.h" /** * @addtogroup SystemCommMessages * @{ */ // ********** private definitions ********** #define ACK_REQUIRED TRUE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver. #define ACK_NOT_REQUIRED FALSE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver. #ifdef DEBUG_ENABLED #define DEBUG_EVENT_MAX_TEXT_LEN 40 #endif // ********** private data ********** static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether an external tester (connected PC) has sent a valid login message. static volatile U16 nextSeqNo = 1; ///< Value of sequence number to use for next transmitted message. // ********** private function prototypes ********** static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ); 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 * 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. *************************************************************************/ static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) { BOOL result = 0; 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; } #ifndef DISABLE_ACK_ERRORS // 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_HD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) } } #endif if ( FALSE == error ) { // add serialized message data to appropriate out-going comm buffer result = addToCommBuffer( buffer, data, msgSize ); } return result; } /*********************************************************************//** * @brief * The sendACKMsg function constructs and queues for transmit an ACK message * for a given received message. * @details * Inputs : none * Outputs : ACK message queued for transmit on broadcast CAN channel. * @param message message to send an ACK for * @return TRUE if ACK message queued successfully, FALSE if not *************************************************************************/ BOOL sendACKMsg( MESSAGE_T *message ) { BOOL result; MESSAGE_T msg; // create a message record blankMessage( &msg ); // send ACK back with same seq. #, but w/o ACK bit msg.hdr.seqNo = message->hdr.seqNo * -1; // ACK messages always have this ID msg.hdr.msgID = MSG_ID_ACK; // ACK messages always have no payload msg.hdr.payloadLen = 0; // serialize and queue the message for transmit on broadcast channel result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendTestAckResponseMsg function constructs a simple response * message for a handled test message and queues it for transmit on the * appropriate UART channel. * @details * Inputs : none * Outputs : response message constructed and queued for transmit. * @param msgID ID of handled message that we are responding to * @param buffer outgoing buffer that message should be queued in * @param ack TRUE if test message was handled successfully, FALSE if not * @return TRUE if response message successfully queued for transmit, FALSE if not *************************************************************************/ static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ) { BOOL result; MESSAGE_T msg; // create a message record blankMessage( &msg ); msg.hdr.msgID = msgID; msg.hdr.payloadLen = sizeof( U08 ); msg.payload[ 0 ] = (U08)ack; // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, buffer, ACK_NOT_REQUIRED ); return result; } // *********************************************************************** // ***************** Message Sending Helper Functions ******************** // *********************************************************************** /*********************************************************************//** * @brief * The sendOffButtonMsgToUI function constructs an off button msg to the UI * and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : Off button msg constructed and queued. * @param cmd 0=prompt user to confirm, 1=cancel prompt, 2=reject user off request * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendOffButtonMsgToUI( U08 cmd ) { BOOL result; MESSAGE_T msg; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_OFF_BUTTON_PRESS; msg.hdr.payloadLen = sizeof( U08 ); msg.payload[ 0 ] = cmd; // 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_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendChangeUFSettingsResponse function constructs a UF change settings * response to the UI and queues the msg for transmit on the appropriate CAN * channel. * @details * Inputs : none * Outputs : UF change settings response msg constructed and queued. * @param accepted T/F - are settings ok? * @param reason reason rejected (if not accepted) * @param volume_mL UF volume (in mL) * @param time_min treatment duration (in minutes) * @param ufRate_mL_min UF rate (in mL/min) * @param timeDiff change in treatment duration (in minutes) * @param rateDiff change in UF rate (in mL/min) * @param oldUFRate_mL_min the UF rate prior to this change (in mL/min) * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendChangeUFSettingsResponse( BOOL accepted, U32 reason, F32 volume_mL, U32 time_min, F32 ufRate_mL_min, S32 timeDiff, F32 rateDiff, F32 oldUFRate_mL_min ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_USER_UF_SETTINGS_CHANGE_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ) + sizeof( F32 ) + sizeof( U32 ) + sizeof( S32 ) + sizeof( F32 ) + sizeof( F32 ) + sizeof( F32 ); memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, &reason, sizeof( U32) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &volume_mL, sizeof( F32 ) ); payloadPtr += sizeof( F32 ); memcpy( payloadPtr, &time_min, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &timeDiff, sizeof( S32 ) ); payloadPtr += sizeof( S32 ); memcpy( payloadPtr, &ufRate_mL_min, sizeof( F32 ) ); payloadPtr += sizeof( F32 ); memcpy( payloadPtr, &rateDiff, sizeof( F32 ) ); payloadPtr += sizeof( F32 ); memcpy( payloadPtr, &oldUFRate_mL_min, 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_UI, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendChangeUFSettingsResponse function constructs a UF change settings * option response to the UI and queues the msg for transmit on the appropriate CAN * channel. * @details * Inputs : none * Outputs : UF change settings option response msg constructed and queued. * @param accepted T/F - are settings ok? * @param reason reason rejected (if not accepted) * @param volume_mL UF volume (in mL) * @param time_min treatment duration (in minutes) * @param ufRate_mL_min UF rate (in mL/min) * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendChangeUFSettingsOptionResponse( BOOL accepted, U32 reason, F32 volume_mL, U32 time_min, F32 ufRate_mL_min ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_USER_UF_SETTINGS_CHANGE_CONFIRMATION_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ) + sizeof( F32 ) + sizeof( U32 ) + sizeof( F32 ); memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, &reason, sizeof( U32) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &volume_mL, sizeof( F32 ) ); payloadPtr += sizeof( F32 ); memcpy( payloadPtr, &time_min, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &ufRate_mL_min, 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_UI, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendChangeTreatmentDurationResponse function constructs a treatment * duration change response to the UI and queues the msg for transmit on the * appropriate CAN channel. * @details * Inputs : none * Outputs : treatment duration change settings response msg constructed and queued. * @param accepted T/F - are settings ok? * @param reason reason rejected (if not accepted) * @param time_min treatment duration (in minutes) * @param volume_mL UF volume (in mL) * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendChangeTreatmentDurationResponse( BOOL accepted, U32 reason, U32 time_min, F32 volume_mL ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_USER_TREATMENT_TIME_CHANGE_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ) + sizeof( U32 ) + sizeof( F32 ); memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, &reason, sizeof( U32) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &time_min, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &volume_mL, 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_UI, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendChangeBloodDialysateRateChangeResponse function constructs a change * blood and dialysate rate settings response to the UI and queues the msg for * transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : Blood & dialysate rate change response msg constructed and queued. * @param accepted T/F - are settings ok? * @param reason reason code for rejection or unused if accepted * @param bloodRate new blood flow rate * @param dialRate new dialysate flow rate * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendChangeBloodDialysateRateChangeResponse( BOOL accepted, U32 reason, U32 bloodRate, U32 dialRate ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ); memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, &reason, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &bloodRate, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &dialRate, 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 sendChangePressureLimitsChangeResponse function constructs a change * pressure limits response to the UI and queues the msg for transmit on the * appropriate CAN channel. * @details Inputs: none * @details Outputs: Pressure limits change response msg constructed and queued. * @param data response data record * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendChangePressureLimitsChangeResponse( PRESSURE_LIMIT_CHANGE_RESPONSE_T *data ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_PRESSURE_LIMITS_CHANGE_RESPONSE; msg.hdr.payloadLen = sizeof( PRESSURE_LIMIT_CHANGE_RESPONSE_T ); memcpy( payloadPtr, (U08*)data, sizeof( PRESSURE_LIMIT_CHANGE_RESPONSE_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_UI, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendTreatmentParamsRangesToUI function constructs a treatment parameter * ranges message to the UI and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : Treatment parameter ranges msg constructed and queued. * @param minTime Minimum treatment duration (in minutes) * @param maxTime Maximum treatment duration (in minutes) * @param minUFVol Minimum ultrafiltration volume (in mL) * @param maxUFVol Maximum ultrafiltration volume (in mL) * @param minDialRate Minimum dialysate flow rate (in mL/min) * @param maxDialRate Maximum dialysate flow rate (in mL/min) * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendTreatmentParamsRangesToUI( U32 minTime, U32 maxTime, F32 minUFVol, F32 maxUFVol, U32 minDialRate, U32 maxDialRate ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_TREATMENT_PARAM_CHANGE_RANGES; msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( F32 ) + sizeof( F32 ) + sizeof( U32 ) + sizeof( U32 ); memcpy( payloadPtr, &minTime, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &maxTime, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &minUFVol, sizeof( F32 ) ); payloadPtr += sizeof( F32 ); memcpy( payloadPtr, &maxUFVol, sizeof( F32 ) ); payloadPtr += sizeof( F32 ); memcpy( payloadPtr, &minDialRate, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &maxDialRate, 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 sendDialysateTempTargetsToDG function constructs a dialysate temperature * set points message for DG and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * 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 * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendDialysateTempTargetsToDG( F32 primary, F32 trimmer ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS; msg.hdr.payloadLen = sizeof( F32 ) + sizeof( F32 ); memcpy( payloadPtr, &primary, sizeof( F32 ) ); payloadPtr += sizeof( F32 ); memcpy( payloadPtr, &trimmer, 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 ); return result; } /*********************************************************************//** * @brief * The sendDGSwitchReservoirCommand function constructs a DG set active * reservoir message for DG and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : DG set active reservoir msg constructed and queued. * @param activeReservoir reservoir ID to set as active * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendDGSwitchReservoirCommand( U32 activeReservoir ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_SWITCH_RESERVOIR_CMD; msg.hdr.payloadLen = sizeof( U32 ); memcpy( payloadPtr, &activeReservoir, 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_DG, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendDGFillCommand function constructs a DG fill command message * and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : DG fill command msg constructed and queued. * @param fillToVolumeMl volume (in mL) to fill inactive reservoir to * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendDGFillCommand( U32 fillToVolumeMl ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_FILL_CMD; msg.hdr.payloadLen = sizeof( U32 ); memcpy( payloadPtr, &fillToVolumeMl, 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_DG, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendDGDrainCommand function constructs a DG drain command message * and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : DG drain command msg constructed and queued. * @param drainToVolumeMl volume (in mL) to drain the inactive reservoir to * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendDGDrainCommand( U32 drainToVolumeMl ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_DRAIN_CMD; msg.hdr.payloadLen = sizeof( U32 ); memcpy( payloadPtr, &drainToVolumeMl, 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_DG, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The sendDGStartStopCommand function constructs a DG start/stop command * message and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : DG start/stop command msg constructed and queued. * @param start TRUE indicates start DG, FALSE indicates stop DG * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendDGStartStopCommand( BOOL start ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_STARTING_STOPPING_TREATMENT_CMD; msg.hdr.payloadLen = sizeof( BOOL ); memcpy( payloadPtr, &start, sizeof( BOOL ) ); // 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 sendDGStartStopTrimmerHeaterCommand function constructs a DG start/stop * trimmer heater command message and queues the msg for transmit on the * appropriate CAN channel. * @details * Inputs : none * Outputs : DG start/stop trimmer heater command msg constructed and queued. * @param start TRUE indicates start heater, FALSE indicates stop heater * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendDGStartStopTrimmerHeaterCommand( BOOL start ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD; msg.hdr.payloadLen = sizeof( BOOL ); memcpy( payloadPtr, &start, sizeof( BOOL ) ); // 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 sendDGSampleWaterCommand function constructs a DG sample water command * message and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : DG sample water command msg constructed and queued. * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendDGSampleWaterCommand( void ) { BOOL result; MESSAGE_T msg; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_SAMPLE_WATER_CMD; 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 broadcastAccelData function constructs an accelerometer data msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : accelerometer data broadcast msg constructed and queued. * @param x X axis vector magnitude (in g) * @param y Y axis vector magnitude (in g) * @param z Z axis vector magnitude (in g) * @param xm max X axis vector magnitude (in g) * @param ym max Y axis vector magnitude (in g) * @param zm max Z axis vector magnitude (in g) * @param xt X axis tilt (in degrees) * @param yt Y axis tilt (in degrees) * @param zt Z axis tilt (in degrees) * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastAccelData( F32 x, F32 y, F32 z, F32 xm, F32 ym, F32 zm, F32 xt, F32 yt, F32 zt ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; ACCEL_DATA_PAYLOAD_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_ACCELEROMETER_DATA; msg.hdr.payloadLen = sizeof( ACCEL_DATA_PAYLOAD_T ); payload.x = x; payload.y = y; payload.z = z; payload.xMax = xm; payload.yMax = ym; payload.zMax = zm; payload.xTilt = xt; payload.yTilt = yt; payload.zTilt = zt; memcpy( payloadPtr, &payload, sizeof( ACCEL_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 broadcastAlarmStatus function constructs an alarm status msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : alarm status msg constructed and queued. * @param almStatus alarm status record * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastAlarmStatus( COMP_ALARM_STATUS_T almStatus ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; ALARM_COMP_STATUS_PAYLOAD_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_ALARM_STATUS; msg.hdr.payloadLen = sizeof( ALARM_COMP_STATUS_PAYLOAD_T ); payload.alarmState = (U32)almStatus.alarmsState; payload.alarmTop = (U32)almStatus.alarmTop; payload.silenceExpiresIn = almStatus.alarmsSilenceExpiresIn; payload.escalatesIn = almStatus.alarmsEscalatesIn; payload.alarmsFlags = ( almStatus.systemFault ? BIT_BY_POS(0) : 0 ); payload.alarmsFlags |= ( almStatus.stop ? BIT_BY_POS(1) : 0 ); payload.alarmsFlags |= ( almStatus.noClear ? BIT_BY_POS(2) : 0 ); payload.alarmsFlags |= ( almStatus.noResume ? BIT_BY_POS(3) : 0 ); payload.alarmsFlags |= ( almStatus.noRinseback ? BIT_BY_POS(4) : 0 ); payload.alarmsFlags |= ( almStatus.noEndTreatment ? BIT_BY_POS(5) : 0 ); payload.alarmsFlags |= ( almStatus.noNewTreatment ? BIT_BY_POS(6) : 0 ); payload.alarmsFlags |= ( almStatus.bypassDialyzer ? BIT_BY_POS(7) : 0 ); payload.alarmsFlags |= ( almStatus.alarmsToEscalate ? BIT_BY_POS(8) : 0 ); payload.alarmsFlags |= ( almStatus.alarmsSilenced ? BIT_BY_POS(9) : 0 ); memcpy( payloadPtr, &payload, sizeof( ALARM_COMP_STATUS_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_ALARM, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastAlarmTriggered function constructs an alarm triggered msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : alarm triggered msg constructed and queued. * @param alarm ID of alarm triggered * @param almData1 1st data associated with alarm * @param almData2 2nd data associated with alarm * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastAlarmTriggered( U16 alarm, ALARM_DATA_T almData1, ALARM_DATA_T almData2 ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_ALARM_TRIGGERED; msg.hdr.payloadLen = sizeof( U16 ) + sizeof( U32 ) * 2 * 2; // 2 alarm data recs w/ 2 32-bit values each memcpy( payloadPtr, &alarm, sizeof( U16 ) ); payloadPtr += sizeof( U16 ); memcpy( payloadPtr, &almData1.dataType, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &almData1.data, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &almData2.dataType, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &almData2.data, 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_ALARM, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastAlarmCleared function constructs an alarm cleared msg to be * broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : alarm cleared msg constructed and queued. * @param alarm ID of alarm cleared * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastAlarmCleared( U16 alarm ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_ALARM_CLEARED; msg.hdr.payloadLen = sizeof( U16 ); memcpy( payloadPtr, &alarm, 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_HD_ALARM, ACK_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastBloodFlowData function constructs a blood flow data msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : blood flow data msg constructed and queued. * @param flowStPt Current set point for blood flow * @param measFlow Latest measured blood flow * @param measRotorSpd Latest measured blood pump rotoro speed * @param measSpd Latest measured blood pump speed * @param measMCspd Latest measured blood pump motor controller speed * @param measSpd Latest measured blood pump motor controller current * @param pwmDC Latest PWM duty cycle % * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastBloodFlowData( U32 flowStPt, F32 measFlow, F32 measRotorSpd, F32 measSpd, F32 measMCSpd, F32 measMCCurr, F32 pwmDC ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; PERISTALTIC_PUMP_STATUS_PAYLOAD_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_BLOOD_FLOW_DATA; msg.hdr.payloadLen = sizeof( PERISTALTIC_PUMP_STATUS_PAYLOAD_T ); payload.setPoint = flowStPt; payload.measFlow = measFlow; payload.measRotorSpd = measRotorSpd; payload.measPumpSpd = measSpd; payload.measMCSpd = measMCSpd; payload.measMCCurr = measMCCurr; payload.pwmDC = pwmDC; memcpy( payloadPtr, &payload, sizeof( PERISTALTIC_PUMP_STATUS_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 broadcastDialInFlowData function constructs a dialysate flow data msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : dialysate flow data msg constructed and queued. * @param flowStPt Current set point for dialysate flow * @param measFlow Latest measured dialysate flow * @param measRotorSpd Latest measured dialysate pump rotor speed * @param measSpd Latest measured dialysate pump speed * @param measMCspd Latest measured dialysate pump motor controller speed * @param measSpd Latest measured dialysate pump motor controller current * @param pwmDC Latest PWM duty cycle % * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastDialInFlowData( U32 flowStPt, F32 measFlow, F32 measRotorSpd, F32 measSpd, F32 measMCSpd, F32 measMCCurr, F32 pwmDC ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; PERISTALTIC_PUMP_STATUS_PAYLOAD_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DIALYSATE_FLOW_DATA; msg.hdr.payloadLen = sizeof( PERISTALTIC_PUMP_STATUS_PAYLOAD_T ); payload.setPoint = flowStPt; payload.measFlow = measFlow; payload.measRotorSpd = measRotorSpd; payload.measPumpSpd = measSpd; payload.measMCSpd = measMCSpd; payload.measMCCurr = measMCCurr; payload.pwmDC = pwmDC; memcpy( payloadPtr, &payload, sizeof( PERISTALTIC_PUMP_STATUS_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 broadcastDialInFlowData function constructs a dialysate outlet flow data * msg to be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : dialysate out flow data msg constructed and queued. * @param dialOutFlowData Pointer to the dialysate out flow data record * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastDialOutFlowData( DIAL_OUT_FLOW_DATA_T *dialOutFlowData ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DIALYSATE_OUT_FLOW_DATA; msg.hdr.payloadLen = sizeof( DIAL_OUT_FLOW_DATA_T ); memcpy( payloadPtr, dialOutFlowData, sizeof( DIAL_OUT_FLOW_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_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastPresOcclData function constructs a pres/occl data msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : pressure/occlusion data msg constructed and queued. * @param artPres Latest measured arterial pressure * @param venPres Latest measured venous pressure * @param bpOccl Latest measured blood pump occlusion pressure * @param diOccl Latest measured dialysate inlet pump occlusion pressure * @param doOccl Latest measured dialysate outlet pump occlusion pressure * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastPresOcclData( PRESSURE_OCCLUSION_DATA_T data ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; PRESSURE_OCCLUSION_DATA_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_PRESSURE_OCCLUSION_DATA; msg.hdr.payloadLen = sizeof( PRESSURE_OCCLUSION_DATA_T ); memcpy( payloadPtr, &data, sizeof( PRESSURE_OCCLUSION_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_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @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 * 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_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastTreatmentTime function constructs a treatment time msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : treatment time data msg constructed and queued * @param secsTotTreatment Total treatment time prescribed (in seconds) * @param secsElapsed Treatment time elapsed (in seconds) * @param secsRemaining Treatment time remaining (in seconds) * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastTreatmentTime( U32 secsTotTreatment, U32 secsElapsed, U32 secsRemaining ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; TREATMENT_TIME_DATA_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_TREATMENT_TIME; msg.hdr.payloadLen = sizeof( TREATMENT_TIME_DATA_T ); payload.treatmentTimePrescribedinSec = secsTotTreatment; payload.treatmentTimeElapsedinSec = secsElapsed; payload.treatmentTimeRemaininginSec = secsRemaining; memcpy( payloadPtr, &payload, sizeof( TREATMENT_TIME_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_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastTreatmentState function constructs a treatment state msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : treatment state msg constructed and queued * @param subMode Current state (sub-mode) of treatment * @param uFState Current state of ultrafiltration * @param salineBolusState 1=saline bolus in progress, 0=not, 2=max bolus volume reached * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastTreatmentState( U32 subMode, U32 uFState, U32 salineBolusState ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; TREATMENT_STATE_DATA_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_TREATMENT_STATE; msg.hdr.payloadLen = sizeof( TREATMENT_STATE_DATA_T ); payload.treatmentSubMode = subMode; payload.uFState = uFState; payload.salineBolusState = salineBolusState; memcpy( payloadPtr, &payload, sizeof( TREATMENT_STATE_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_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastPowerOffWarning function constructs a power off warning msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : power off warning msg constructed and queued * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastPowerOffWarning( void ) { BOOL result; MESSAGE_T msg; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_POWER_OFF_WARNING; 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_BROADCAST, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The broadcastHDOperationMode function constructs an HD operation mode * broadcast message and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : HD operation mode msg constructed and queued * @param mode current HD operation mode * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL broadcastHDOperationMode( U32 mode, U32 subMode ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_OP_MODE; msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); memcpy( payloadPtr, &mode, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &subMode, sizeof( U32 ) ); // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } #ifdef EMC_TEST_BUILD BOOL broadcastCANErrorCount( U32 count ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_CAN_ERROR_COUNT; msg.hdr.payloadLen = sizeof( U32 ); memcpy( payloadPtr, &count, sizeof( U32 ) ); // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; } #endif // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** /*********************************************************************//** * @brief * The handleDGCheckIn function handles a check-in from the DG. * @details * Inputs : none * Outputs : check in the DG with the SystemComm module. * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleDGCheckIn( MESSAGE_T *message ) { checkInFromDG(); } /*********************************************************************//** * @brief * The handleUICheckIn function handles a check-in from the UI. * @details * Inputs : none * Outputs : check in the UI with the SystemComm module. * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleUICheckIn( MESSAGE_T *message ) { checkInFromUI(); } /*********************************************************************//** * @brief * The handleAlarmTriggered function handles a triggered alarm event message. * @details * Inputs : none * Outputs : alarm triggered. * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleAlarmTriggered( MESSAGE_T *message ) { if ( message->hdr.payloadLen == ( sizeof( U16 ) + sizeof( U32 ) * 2 * 2 ) ) // 2 data records w/ 2 U32s each { U08 *payloadPtr = message->payload; U16 alarmID; ALARM_DATA_T alm1, alm2; memcpy( &alarmID, payloadPtr, sizeof( U16 ) ); payloadPtr += sizeof( U16 ); memcpy( &alm1.dataType, payloadPtr, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( &alm1.data, payloadPtr, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( &alm2.dataType, payloadPtr, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( &alm2.data, payloadPtr, sizeof( U32 ) ); if ( (ALARM_ID_T)alarmID < NUM_OF_ALARM_IDS ) { activateAlarm2Data( (ALARM_ID_T)alarmID, alm1, alm2 ); } } } /*********************************************************************//** * @brief * The handleAlarmCleared function handles a cleared alarm event message. * @details * Inputs : none * Outputs : alarm cleared. * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleAlarmCleared( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof( U16 ) ) { U08 *payloadPtr = message->payload; U16 alarmID; memcpy( &alarmID, payloadPtr, sizeof( U16 ) ); if ( (ALARM_ID_T)alarmID < NUM_OF_ALARM_IDS ) { clearAlarm( (ALARM_ID_T)alarmID ); } } } /*********************************************************************//** * @brief * The handleOffButtonConfirmMsgFromUI function handles a response to an * off button message to the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleOffButtonConfirmMsgFromUI( MESSAGE_T *message ) { OFF_BUTTON_MESSAGE_FROM_UI_PAYLOAD_T payload; if ( message->hdr.payloadLen == sizeof(OFF_BUTTON_MESSAGE_FROM_UI_PAYLOAD_T) ) { memcpy( &payload, message->payload, sizeof(OFF_BUTTON_MESSAGE_FROM_UI_PAYLOAD_T) ); userConfirmOffButton( payload.confirmed ); } } /*********************************************************************//** * @brief * The handleLoadCellReadingsFromDG function handles a load cell readings * broadcast message from the DG. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleLoadCellReadingsFromDG( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ) { LOAD_CELL_READINGS_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ); result = 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? } /*********************************************************************//** * @brief * The handleDGTemperatureData function handles a temperature readings * broadcast message from the DG. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleDGTemperatureData( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(DG_TEMPERATURES_T) ) { DG_TEMPERATURES_T payload; memcpy( &payload, message->payload, sizeof(DG_TEMPERATURES_T) ); setDialysateTemperatureReadings( payload.TDi, payload.TRo ); } // TODO - what to do if invalid payload length? // TODO - how to know if DG stops sending these? } /*********************************************************************//** * @brief * The handleROPumpData function handles an RO pump data broadcast * message from the DG. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleROPumpData( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(DG_RO_PUMP_DATA_PAYLOAD_T) ) { DG_RO_PUMP_DATA_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(DG_RO_PUMP_DATA_PAYLOAD_T) ); setDGROPumpData( payload.setPtPSI, payload.measFlowRateMlMin ); } // TODO - what to do if invalid payload length? } /*********************************************************************//** * @brief * The handleDrainPumpData function handles a drain pump broadcast * message from the DG. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleDrainPumpData( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(DG_DRAIN_PUMP_DATA_PAYLOAD_T) ) { DG_DRAIN_PUMP_DATA_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(DG_DRAIN_PUMP_DATA_PAYLOAD_T) ); setDGDrainPumpData( payload.setPtRPM ); } // TODO - what to do if invalid payload length? } /*********************************************************************//** * @brief * The handleDGPressuresData function handles a DG pressure sensor readings * broadcast message from the DG. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleDGPressuresData( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(DG_PRESSURES_DATA_PAYLOAD_T) ) { DG_PRESSURES_DATA_PAYLOAD_T payload; 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? } /*********************************************************************//** * @brief * The handleDGReservoirData function handles a reservoir data broadcast * message from the DG. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleDGReservoirData( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(DG_RESERVOIRS_DATA_PAYLOAD_T) ) { DG_RESERVOIRS_DATA_PAYLOAD_T payload; 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? } /*********************************************************************//** * @brief * The handleUFPauseResumeRequest function handles a ultrafiltration pause * or resume request message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleUFPauseResumeRequest( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(U32) ) { U32 cmd; memcpy( &cmd, message->payload, sizeof(U32) ); if ( UF_CMD_PAUSE == cmd ) { result = pauseUF(); } else if ( UF_CMD_RESUME == cmd ) { result = resumeUF(); } } sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); } /*********************************************************************//** * @brief * The handleUIStartTreatmentMsg function handles a treatment start/cancel * message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleUIStartTreatmentMsg( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(U32) ) { U32 cmd; memcpy( &cmd, message->payload, sizeof(U32) ); if ( 0 == cmd ) // initiate treatment (go to 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 { // TODO - handle when pre-treatment mode is ready for this } } 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. * @details * Inputs : none * Outputs : Treatment start response msg constructed and queued. * @param accepted T/F - request accepted? * @param reason reason code if rejected * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendTreatmentStartResponseMsg( BOOL accepted, U32 reason ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_START_TREATMENT_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, &reason, 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 handleUIUserEndTreatmentRequest function handles a treatment end * request message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleUIUserEndTreatmentRequest( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == 0 ) { result = userRequestEndTreatment(); } sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); } /*********************************************************************//** * @brief * The sendTreatmentEndResponseMsg function constructs a treatment end * request response message to the UI and queues the msg for transmit on * the appropriate CAN channel. * @details * Inputs : none * Outputs : Treatment end response msg constructed and queued. * @param accepted T/F - request accepted? * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ BOOL sendTreatmentEndResponseMsg( BOOL accepted ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_TREATMENT_END_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ); memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); // 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 handleTreatmentParametersFromUI function handles a treatment parameters * set and validate request message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTreatmentParametersFromUI( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(TREATMENT_PARAMS_DATA_PAYLOAD_T) ) { TREATMENT_PARAMS_DATA_PAYLOAD_T treatmentParams; memcpy( &treatmentParams, message->payload, sizeof(TREATMENT_PARAMS_DATA_PAYLOAD_T) ); result = validateAndSetTreatmentParameters( treatmentParams ); } sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); } /*********************************************************************//** * @brief * The handleUIUserConfirmTreatmentParameters function handles a user confirmation * of treatment parameters message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleUIUserConfirmTreatmentParameters( MESSAGE_T *message ) { BOOL result = FALSE; if ( 0 == message->hdr.payloadLen ) { result = signalUserConfirmationOfTreatmentParameters(); } sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); } /*********************************************************************//** * @brief * The sendTreatmentParametersResponseMsg function constructs a treatment parameters * response to the UI and queues the msg for transmit on the appropriate CAN channel. * @details * Inputs : none * Outputs : Treatment parameters response msg constructed and queued. * @param accepted T/F - are settings ok? * @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 accepted, U08 *rejectReasons, U32 byteLength ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_NEW_TREATMENT_PARAMS_RESPONSE; msg.hdr.payloadLen = sizeof( BOOL ) + byteLength; memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, rejectReasons, byteLength ); // 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 handleChangeUFSettingsRequest function handles a ultrafiltration * change settings request message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleChangeUFSettingsRequest( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(F32) ) { F32 uFVolume; memcpy( &uFVolume, message->payload, sizeof(F32) ); verifyUFSettingsChange( uFVolume ); } else { sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); } } /*********************************************************************//** * @brief * The handleChangeUFSettingsConfirmation function handles a ultrafiltration * change setting confirmation message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleChangeUFSettingsConfirmation( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ) { UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ); verifyUFSettingsConfirmation( payload.volume_mL, payload.adjustType ); } else { sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); } } /*********************************************************************//** * @brief * The handleChangeTreatmentDurationRequest function handles a treatment * duration setting change message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleChangeTreatmentDurationRequest( MESSAGE_T *message ) { if ( message->hdr.payloadLen == sizeof(U32) ) { U32 timeInMin; memcpy( &timeInMin, message->payload, sizeof(U32) ); verifyTreatmentDurationSettingChange( timeInMin ); } else { sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); } } /*********************************************************************//** * @brief * The handleChangeBloodDialysateRateChangeRequest function handles a blood * and dialysate rate settings change message from the UI. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleChangeBloodDialysateRateChangeRequest( MESSAGE_T *message ) { U32 expPayloadSize = sizeof(U32) + sizeof(U32); if ( expPayloadSize == message->hdr.payloadLen ) { U32 bloodRate; U32 dialRate; memcpy( &bloodRate, &message->payload[0], sizeof(U32) ); memcpy( &dialRate, &message->payload[sizeof(U32)], sizeof(U32) ); verifyBloodAndDialysateRateSettingsChange( bloodRate, dialRate ); } else { sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); } } /*********************************************************************//** * @brief * The handleChangePressureLimitsRequest function handles a pressure limits * change message from the UI. * @details Inputs: none * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleChangePressureLimitsRequest( MESSAGE_T *message ) { if ( sizeof( PRESSURE_LIMIT_CHANGE_REQUEST_T ) == message->hdr.payloadLen ) { PRESSURE_LIMIT_CHANGE_REQUEST_T data; memcpy( &data, &message->payload[0], sizeof(PRESSURE_LIMIT_CHANGE_REQUEST_T) ); verifyPressureLimitsChange( &data ); } else { sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); } } /*********************************************************************//** * @brief * The handleDGOpMode function handles a DG broadcast of it's current mode. * @details * Inputs : none * Outputs : message handled, response constructed and queued for transmit. * @param message a pointer to the message to handle. * @return none *************************************************************************/ void handleDGOpMode( MESSAGE_T *message ) { U32 payloadSize = sizeof(U32) + sizeof(U32); if ( message->hdr.payloadLen == payloadSize ) { U32 mode, subMode; memcpy( &mode, message->payload, sizeof(U32) ); memcpy( &subMode, &message->payload[sizeof(U32)], sizeof(U32) ); setDGOpMode( mode, subMode ); checkInFromDG(); // TODO - here until we implement DG check-in w/ HD broadcast } else { sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_DG, FALSE ); } } /*********************************************************************//** * @brief * The handleFWVersionRequest function handles a request for HD f/w version. * @details * Inputs : none * Outputs : message handled, response constructed and queued for transmit. * @param message a pointer to the message to handle. * @return none *************************************************************************/ void handleFWVersionRequest( MESSAGE_T *message ) { MESSAGE_T msg; HD_VERSIONS_T payload; U08 *payloadPtr = msg.payload; // populate payload payload.major = (U08)HD_VERSION_MAJOR; payload.minor = (U08)HD_VERSION_MINOR; payload.micro = (U08)HD_VERSION_MICRO; payload.build = (U16)HD_VERSION_BUILD; getFPGAVersions( &payload.fpgaId, &payload.fpgaMajor, &payload.fpgaMinor, &payload.fpgaLab ); // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_VERSION; msg.hdr.payloadLen = sizeof( HD_VERSIONS_T ); // fill message payload memcpy( payloadPtr, &payload, sizeof( HD_VERSIONS_T ) ); // 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_REQUIRED ); } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ #ifdef DEBUG_ENABLED /*********************************************************************//** * @brief * The sendDebugData function sends debug data out to the PC port. * @details * Inputs : none * 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 * 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 * logged in to activate testing functionality. * @details * Inputs : testerLoggedIn * Outputs : none * @return TRUE if a tester has logged in to activate testing, FALSE if not *************************************************************************/ BOOL isTestingActivated( void ) { return testerLoggedIn; } /*********************************************************************//** * @brief * The sendTestAckResponseMsg function constructs a simple response * message for a handled test message and queues it for transmit on the * appropriate UART channel. * @details * Inputs : none * Outputs : response message constructed and queued for transmit. * @param msgID ID of handled message that we are responding to * @param ack TRUE if test message was handled successfully, FALSE if not * @return TRUE if response message successfully queued for transmit, FALSE if not *************************************************************************/ static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ) { BOOL result; MESSAGE_T msg; // create a message record blankMessage( &msg ); msg.hdr.msgID = msgID; msg.hdr.payloadLen = sizeof( U08 ); msg.payload[ 0 ] = (U08)ack; // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); return result; } /*********************************************************************//** * @brief * The handleTesterLogInRequest function handles a request to login as a * tester. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTesterLogInRequest( MESSAGE_T *message ) { // verify pass code // TODO - placeholder - how do we want to authenticate tester? if ( ( 3 == message->hdr.payloadLen ) && ( 0x31 == message->payload[ 0 ] ) && ( 0x32 == message->payload[ 1 ] ) && ( 0x33 == message->payload[ 2 ] ) ) { testerLoggedIn = TRUE; checkInFromUI(); // allow tasks to begin normal processing when tester has logged in } else { testerLoggedIn = FALSE; } // respond to would be tester sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, testerLoggedIn ); } /*********************************************************************//** * @brief * The handleTestOffButtonStateOverrideRequest function handles a request to * override the state of the off button. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestOffButtonStateOverrideRequest( 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 = testSetOffButtonStateOverride( payload.state.u32 ); } else { result = testResetOffButtonStateOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestStopButtonStateOverrideRequest function handles a request to * override the stop button state. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestStopButtonStateOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; BOOL result = 0; // 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 = testSetStopButtonStateOverride( payload.state.u32 ); } else { result = testResetStopButtonStateOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestAlarmLampPatternOverrideRequest function handles a request to * override the alarm lamp pattern. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestAlarmLampPatternOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; BOOL result = 0; // 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 = testSetCurrentLampPatternOverride( payload.state.u32 ); } else { result = testResetCurrentLampPatternOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestWatchdogCheckInStateOverrideRequest function handles a * request to override the check-in status of a given task. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestWatchdogCheckInStateOverrideRequest( 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 = testSetWatchdogTaskCheckInOverride( payload.index, payload.state.u32 ); } else { result = testResetWatchdogTaskCheckInOverride( payload.index ); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestAlarmStateOverrideRequest function handles a request to * override the active status of a given alarm. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestAlarmStateOverrideRequest( 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 = testSetAlarmStateOverride( payload.index, payload.state.u32 ); } else { result = testResetAlarmStateOverride( payload.index ); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestAlarmTimeOverrideRequest function handles a request to * override the time since activation of a given alarm. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestAlarmTimeOverrideRequest( 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 = testSetAlarmStartOverride( payload.index, payload.state.u32 ); } else { result = testResetAlarmStartOverride( payload.index ); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestAlarmStatusBroadcastIntervalOverrideRequest function handles a request to * override the broadcast interval for alarm status. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestAlarmStatusBroadcastIntervalOverrideRequest( 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 = testSetAlarmStatusPublishIntervalOverride( payload.state.u32 ); } else { result = testResetAlarmStatusPublishIntervalOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodFlowSetPointOverrideRequest function handles a request to * override the set point for the blood flow rate (mL/min). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodFlowSetPointOverrideRequest( MESSAGE_T *message ) { OVERRIDE_PUMP_SET_PT_PAYLOAD_T payload; BOOL result = FALSE; // verify payload length if ( sizeof(OVERRIDE_PUMP_SET_PT_PAYLOAD_T) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof(OVERRIDE_PUMP_SET_PT_PAYLOAD_T) ); result = testSetTargetBloodFlowRateOverride( payload.setPt, payload.ctrlMode ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodFlowMeasuredOverrideRequest function handles a request to * override the measured blood flow rate (mL/min). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodFlowMeasuredOverrideRequest( 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 = testSetMeasuredBloodFlowRateOverride( payload.state.f32 ); } else { result = testResetMeasuredBloodFlowRateOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodPumpRotorMeasuredSpeedOverrideRequest function handles a request to * override the measured blood pump rotor speed (RPM). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodPumpRotorMeasuredSpeedOverrideRequest( 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 = testSetMeasuredBloodPumpRotorSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredBloodPumpRotorSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodPumpMeasuredSpeedOverrideRequest function handles a request to * override the measured blood pump speed (RPM). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodPumpMeasuredSpeedOverrideRequest( 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 = testSetMeasuredBloodPumpSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredBloodPumpSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodPumpMCMeasuredSpeedOverrideRequest function handles a request to * override the measured blood pump motor controller speed (RPM). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodPumpMCMeasuredSpeedOverrideRequest( 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 = testSetMeasuredBloodPumpMCSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredBloodPumpMCSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodPumpMCMeasuredCurrentOverrideRequest function handles a request to * override the measured blood pump motor controller current (mA). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodPumpMCMeasuredCurrentOverrideRequest( 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 = testSetMeasuredBloodPumpMCCurrentOverride( payload.state.f32 ); } else { result = testResetMeasuredBloodPumpMCCurrentOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodFlowBroadcastIntervalOverrideRequest function handles a request to * override the broadcast interval for blood flow data. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodFlowBroadcastIntervalOverrideRequest( 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 = testSetBloodFlowDataPublishIntervalOverride( payload.state.u32 ); } else { result = testResetBloodFlowDataPublishIntervalOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialInFlowSetPointOverrideRequest function handles a request to * override the set point for the dialysate inlet flow rate (mL/min). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialInFlowSetPointOverrideRequest( MESSAGE_T *message ) { OVERRIDE_PUMP_SET_PT_PAYLOAD_T payload; BOOL result = FALSE; // verify payload length if ( sizeof(OVERRIDE_PUMP_SET_PT_PAYLOAD_T) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof(OVERRIDE_PUMP_SET_PT_PAYLOAD_T) ); result = testSetTargetDialInFlowRateOverride( payload.setPt, payload.ctrlMode ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutFlowSetPointOverrideRequest function handles a request to * override the set point for the dialysate outlet flow rate (mL/min). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutFlowSetPointOverrideRequest( MESSAGE_T *message ) { OVERRIDE_PUMP_SET_PT_PAYLOAD_T payload; BOOL result = FALSE; // verify payload length if ( sizeof(OVERRIDE_PUMP_SET_PT_PAYLOAD_T) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof(OVERRIDE_PUMP_SET_PT_PAYLOAD_T) ); result = testSetTargetDialOutFlowRateOverride( payload.setPt, payload.ctrlMode ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialInFlowMeasuredOverrideRequest function handles a request to * override the measured dialysate inlet flow rate (mL/min). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialInFlowMeasuredOverrideRequest( 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 = testSetMeasuredDialInFlowRateOverride( payload.state.f32 ); } else { result = testResetMeasuredDialInFlowRateOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialInPumpRotorMeasuredSpeedOverrideRequest function handles a request to * override the measured dialysate inlet pump rotor speed (RPM). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialInPumpRotorMeasuredSpeedOverrideRequest( 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 = testSetMeasuredDialInPumpRotorSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredDialInPumpRotorSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialInPumpMeasuredSpeedOverrideRequest function handles a request to * override the measured dialysate inlet pump speed (RPM). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialInPumpMeasuredSpeedOverrideRequest( 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 = testSetMeasuredDialInPumpSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredDialInPumpSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialInPumpMCMeasuredSpeedOverrideRequest function handles a request to * override the measured dialysate inlet pump motor controller speed (RPM). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialInPumpMCMeasuredSpeedOverrideRequest( 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 = testSetMeasuredDialInPumpMCSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredDialInPumpMCSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialInPumpMCMeasuredCurrentOverrideRequest function handles a request to * override the measured dialysate inlet pump motor controller current (mA). * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialInPumpMCMeasuredCurrentOverrideRequest( 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 = testSetMeasuredDialInPumpMCCurrentOverride( payload.state.f32 ); } else { result = testResetMeasuredDialInPumpMCCurrentOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialInFlowBroadcastIntervalOverrideRequest function handles a request to * override the broadcast interval for dialysate inlet flow data. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialInFlowBroadcastIntervalOverrideRequest( 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 = testSetDialInFlowDataPublishIntervalOverride( payload.state.u32 ); } else { result = testResetDialInFlowDataPublishIntervalOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestArterialPressureOverrideRequest function handles a request to * override the arterial pressure. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestArterialPressureOverrideRequest( 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 = testSetArterialPressureOverride( payload.state.f32 ); } else { result = testResetArterialPressureOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestVenousPressureOverrideRequest function handles a request to * override the venous pressure. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestVenousPressureOverrideRequest( 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 = testSetVenousPressureOverride( payload.state.f32 ); } else { result = testResetVenousPressureOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestBloodPumpOcclusionOverrideRequest function handles a request to * override the blood pump occlusion sensor. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestBloodPumpOcclusionOverrideRequest( 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 = testSetBloodPumpOcclusionOverride( payload.state.f32 ); } else { result = testResetBloodPumpOcclusionOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialysateInletPumpOcclusionOverrideRequest function handles a request to * override the dialysate inlet pump occlusion sensor. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialysateInletPumpOcclusionOverrideRequest( 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 = testSetDialInPumpOcclusionOverride( payload.state.f32 ); } else { result = testResetDialInPumpOcclusionOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialysateOutletPumpOcclusionOverrideRequest function handles a request to * override the dialysate outlet pump occlusion sensor. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialysateOutletPumpOcclusionOverrideRequest( 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 = testSetDialOutPumpOcclusionOverride( payload.state.f32 ); } else { result = testResetDialOutPumpOcclusionOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestPresOcclBroadcastIntervalOverrideRequest function handles a request to * override the broadcast interval for pressure/occlusion data. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestPresOcclBroadcastIntervalOverrideRequest( 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 = testSetPresOcclDataPublishIntervalOverride( payload.state.u32 ); } else { result = testResetPresOcclDataPublishIntervalOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleSetRTCTimestamp function handles a request to write time and * date to RTC * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleSetRTCTimestamp( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == 9 ) // TODO - add payload structure to RTC.h and use a structure to import payload. { U08 seconds = message->payload[0]; U08 minutes = message->payload[1]; U08 hours = message->payload[2]; U08 days = message->payload[3]; U08 months = message->payload[4]; U32 years; memcpy(&years, &message->payload[5], sizeof(U32)); result = setRTCTimestamp( seconds, minutes, hours, days, months, years ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutFlowBroadcastIntervalOverrideRequest function handles * a request to override the broadcast interval for dialysate outlet pump data. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutFlowBroadcastIntervalOverrideRequest( 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 = testSetDialOutPumpAndLoadCellDataPublishIntervalOverride( payload.state.u32 ); } else { result = testResetDialOutPumpAndLoadCellDataPublishIntervalOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutUFReferenceVolumeOverrideRequest function handles a * request to override the ultrafiltration reference volume for the dialysate * outlet pump. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutUFReferenceVolumeOverrideRequest( 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 = testSetDialOutUFRefVolumeOverride( payload.state.f32 ); } else { result = testResetDialOutUFRefVolumeOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutUFMeasuredVolumeOverrideRequest function handles a * request to override the ultrafiltration measured volume for the dialysate * outlet pump. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutUFMeasuredVolumeOverrideRequest( 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 = testSetDialOutUFTotVolumeOverride( payload.state.f32 ); } else { result = testResetDialOutUFTotVolumeOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutPumpMCMeasuredSpeedOverrideRequest function handles a * request to override the measured motor controller speed for the dialysate * outlet pump. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutPumpMCMeasuredSpeedOverrideRequest( 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 = testSetMeasuredDialOutPumpMCSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredDialOutPumpMCSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutPumpMCMeasuredCurrentOverrideRequest function handles a * request to override the measured motor controller current for the dialysate * outlet pump. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutPumpMCMeasuredCurrentOverrideRequest( 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 = testSetMeasuredDialOutPumpMCCurrentOverride( payload.state.f32 ); } else { result = testResetMeasuredDialOutPumpMCCurrentOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutPumpMeasuredSpeedOverrideRequest function handles a * request to override the measured speed for the dialysate outlet pump. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutPumpMeasuredSpeedOverrideRequest( 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 = testSetMeasuredDialOutPumpSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredDialOutPumpSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutPumpMeasuredRotorSpeedOverrideRequest function handles a * request to override the measured rotor speed for the dialysate outlet pump. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutPumpMeasuredRotorSpeedOverrideRequest( 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 = testSetMeasuredDialOutPumpRotorSpeedOverride( payload.state.f32 ); } else { result = testResetMeasuredDialOutPumpRotorSpeedOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestDialOutLoadCellWeightOverrideRequest function handles a * request to override the measured load cell weight for the dialysate outlet pump. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestDialOutLoadCellWeightOverrideRequest( 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 = testSetDialOutLoadCellWeightOverride( payload.index, payload.state.f32 ); } else { result = testResetDialOutLoadCellWeightOverride( payload.index ); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestHDSafetyShutdownOverrideRequest function handles a * request to override the safety shutdown signal. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestHDSafetyShutdownOverrideRequest( 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 = testSetSafetyShutdownOverride( payload.state.u32 ); } else { result = testResetSafetyShutdownOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestHDAccelOverrideRequest function handles a request to * override the measured accelerometer sensor readings. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestHDAccelOverrideRequest( 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 = testSetAccelAxisOverride( payload.index, payload.state.f32 ); } else { result = testResetAccelAxisOverride( payload.index ); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestHDAccelMaxOverrideRequest function handles a request to * override the measured accelerometer sensor maximum readings. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestHDAccelMaxOverrideRequest( 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 = testSetAccelMaxOverride( payload.index, payload.state.f32 ); } else { result = testResetAccelMaxOverride( payload.index ); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestHDAccelBroadcastIntervalOverrideRequest function handles a * request to override the broadcast interval for accelerometer data messages. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestHDAccelBroadcastIntervalOverrideRequest( 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 = testSetAccelDataPublishIntervalOverride( payload.state.u32 ); } else { result = testResetAccelDataPublishIntervalOverride(); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleSetAccelCalibration function handles a request to set * accelerometer calibration factors. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleSetAccelCalibration( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(ACCEL_CAL_PAYLOAD_T) ) { ACCEL_CAL_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(ACCEL_CAL_PAYLOAD_T) ); result = setAccelCalibration( payload.xOffset, payload.yOffset, payload.zOffset ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleSetBloodFlowCalibration function handles a request to set * blood flow calibration factors. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleSetBloodFlowCalibration( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(LINEAR_F32_CAL_PAYLOAD_T) ) { LINEAR_F32_CAL_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(LINEAR_F32_CAL_PAYLOAD_T) ); result = setBloodFlowCalibration( payload.gain, payload.offset ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleSetDialysateFlowCalibration function handles a request to set * dialysate flow calibration factors. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleSetDialysateFlowCalibration( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(LINEAR_F32_CAL_PAYLOAD_T) ) { LINEAR_F32_CAL_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(LINEAR_F32_CAL_PAYLOAD_T) ); result = setDialInFlowCalibration( payload.gain, payload.offset ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestSetTreatmentParameter function handles a request to set * a given treatment parameter. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestSetTreatmentParameter( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(CRITICAL_DATAS_T) + sizeof(CRITICAL_DATAS_T) ) { CRITICAL_DATAS_T payload[2]; memcpy( &payload[0], message->payload, sizeof(CRITICAL_DATAS_T) * 2 ); result = testSetTreatmentParameter( (TREATMENT_PARAM_T)payload[0].uInt, payload[1] ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestSuperClearAlarmsRequest function handles a request to clear * all active alarms. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestSuperClearAlarmsRequest( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(U32) ) { U32 key; memcpy( &key, message->payload, sizeof(U32) ); result = testClearAllAlarms( key ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestHDCalibrationDataRequest function handles a request for * HD calibration data. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestHDCalibrationDataRequest( MESSAGE_T *message ) { BOOL result = FALSE; if ( 0 == message->hdr.payloadLen ) { CALIBRATION_DATA_T cal; MESSAGE_T msg; U08 *payloadPtr = msg.payload; // get calibration data result = getCalibrationData( &cal ); if ( TRUE == result ) { // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_CALIBRATION_DATA; msg.hdr.payloadLen = sizeof( CALIBRATION_DATA_T ); memcpy( payloadPtr, &cal, sizeof( CALIBRATION_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_HD_BROADCAST, ACK_NOT_REQUIRED ); } } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** * @brief * The handleTestEraseHDCalibrationDataRequest function handles a request for * HD calibration data erasure. * @details * Inputs : none * Outputs : message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ void handleTestEraseHDCalibrationDataRequest( MESSAGE_T *message ) { BOOL result = FALSE; if ( message->hdr.payloadLen == sizeof(U32) ) { U32 key; memcpy( &key, message->payload, sizeof(U32) ); result = testResetCalibrationData( key ); } // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /**@}*/