/************************************************************************** * * Copyright (c) 2026-2027 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 NVMessagingDD.c * * @author (original) Arpita Srivastava * @date (original) 31-Mar-2026 * ***************************************************************************/ #include // For ceilf function #include "Messaging.h" #include "NVJobQ.h" #include "NVMessagingDD.h" #include "NVRecordsDD.h" #include "OperationModes.h" #include "TaskGeneral.h" #include "Timers.h" #include "Utilities.h" // For crc calculation /** * @addtogroup NVMessagingDD * @{ */ // ********** private definitions ********** #define NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS (1 * MS_PER_SECOND) ///< New calibration available signal timeout in milliseconds. #define NUM_OF_BYTES_PER_RECORD_PAYLOAD ( MAX_MSG_PAYLOAD_SIZE - ( sizeof( U32 ) ) ) ///< Number of bytes per calibration payload. #define RECORD_DATA_SEND_INTERVAL_COUNT (MS_PER_SECOND / (5 * TASK_GENERAL_INTERVAL)) ///< Calibration data send time interval in counts. #define RECORD_DATA_RECEIVE_TIMEOUT_MS (4 * MS_PER_SECOND) ///< Record data receive all the data packets timeout in ms. #define RECORD_DATA_MAX_MESSAGE_DFFIRENCE 1 ///< Calibration data receive message different from the previous message. #define RECORD_DATA_FIRST_RECEIVING_MSG_NUM 1 ///< Calibration data first receiving message number. #define MAX_NUM_OF_SEND_RETRIES 5 ///< Maximum number of retries to send a record /// NVM send records states typedef enum NVM_Send_Records_States { NVM_SEND_RECORD_STATE_IDLE = 0, ///< NVM process record idle state. NVM_SEND_RECORD_STATE_SEND, ///< NVM process record send record state. NUM_OF_NVM_SEND_RECORD_STATES ///< Number of NVM process records state. } SEND_RECORD_STATE_T; /// NVM receive records states typedef enum NVM_Receive_Records_States { NVM_RECEIVE_RECORD_STATE_IDLE = 0, ///< NVM receive record idle. NVM_RECEIVE_RECORD_STATE_RECEIVE, ///< NVM receive record receive. NUM_OF_NVM_RECEIVE_RECORD_STATES ///< Number of NVM receive record. } RECEIVE_RECORD_STATE_T; /// DD NVM Record Payload typedef struct { U08 idx; ///< Index of sensor / pump / concentrates U08 data[ NUM_OF_BYTES_PER_RECORD_PAYLOAD ]; ///< Data to be sent } DD_NVM_SEND_RECORD_PAYLOAD_T; /// DD NVM Record Payload for Institutional data of type U32 typedef struct { U08 idx; ///< Index of institutional record component U32 data; ///< Data to be sent } DD_NVM_U32_INSTIT_REC_PAYLOAD_T; /// DD NVM Record Payload for Institutional data of type F32 typedef struct { U08 idx; ///< Index of institutional record component F32 data; ///< Data to be sent } DD_NVM_F32_INSTIT_REC_PAYLOAD_T; /// DD NVM Record Payload for Polynomial structures Calibration Data typedef struct { U08 idx; ///< Index of sensor / pump / concentrates POLYNOMIAL_CAL_PAYLOAD_T data; ///< Data to be sent } DD_NVM_POLYNOMIAL_CAL_REC_PAYLOAD_T; /// DD NVM Record Payload for Acid Concentrate Calibration Data typedef struct { U08 idx; ///< Index of acid concentrates DD_ACID_CONCENTRATE_T data; ///< Data to be sent } DD_NVM_ACID_CONC_CAL_REC_PAYLOAD_T; /// DD NVM Record Payload for Bicarb Concentrate Calibration Data typedef struct { U08 idx; ///< Index of bicarb concentrates DD_BICARB_CONCENTRATE_T data; ///< Data to be sent } DD_NVM_BICARB_CONC_CAL_REC_PAYLOAD_T; // ********** private data ********** static SEND_RECORD_STATE_T nvMExecSendRecordState; ///< NVM exec process record state. static RECEIVE_RECORD_STATE_T nvmExecreceiveRecordState; ///< NVM exec receive record state. static U32 newRecordStartTimer; ///< New record availability start timer. static BOOL isNewCalRecordAvailable; ///< Signal to indicate whether a new NVM data is available. static NVM_RECORD_TYPE_T recordToPublish; ///< Record type which is being processed currently for sending static NVM_RECORD_TYPE_T nvPublishRecordType; ///< Used to index over isPublishRecordRequested in the idle state static NVM_RECORD_TYPE_T currentRxRecordType; ///< Record type which is being processed currently for receiving static U32 recordSendDataIntervalCounter; ///< Record data send to CAN bust interval counter. static U32 sendRetryCount; ///< Counter for number of retries to send a record static U32 calRecordReceiveStartTime; ///< Time stamp the calibration record was received. static U32 institRecordReceiveStartTime; ///< Time stamp the institutional record was received. static DD_INSTIT_REC_TYPE sendInstitRec; ///< Current Institutional Record to be sent static DD_CAL_REC_TYPE sendCalRec; ///< Current Calibration Record to be sent static U08 sendSensorIdx; ///< Current Index of sensor calibration data to be sent static U08 maxSensorIdx; ///< Total number of sensor in current calibration data being sent static BOOL isPublishRecordRequested[ NUM_OF_NVM_RECORD_TYPES ]; ///< Record state machine publish request flag. // ********** private function prototypes ********** // Process record functions static SEND_RECORD_STATE_T handleExecSendRecordIdleState( void ); static SEND_RECORD_STATE_T handleExecSendRecordSendState( void ); static SEND_RECORD_STATE_T handleSendDDSystemRecord( void ); static SEND_RECORD_STATE_T handleSendDDServiceRecord( void ); static SEND_RECORD_STATE_T handleSendDDInstitutionalRecord( void ); static SEND_RECORD_STATE_T handleSendDDUsageInfoRecord( void ); static SEND_RECORD_STATE_T handleSendDDCalibrationRecord( void ); static BOOL sendPressureSensorCalRecord( void ); static BOOL sendTempSensorCalRecord( void ); static BOOL sendConcPumpCalRecord( void ); static BOOL sendD12PumpCalRecord( void ); static BOOL sendD48PumpCalRecord( void ); static BOOL sendAcidConcCalRecord( void ); static BOOL sendBicarbConcCalRecord( void ); static BOOL sendAccelSensorCalRecord( void ); static BOOL sendBloodLeakSensorCalRecord( void ); static BOOL receiveCalRecord( MESSAGE_T *message, BOOL isIndexed, DD_CAL_REC_TYPE calRecordType, U16 recordSize ); static MSG_ID_T getNVMCalRecordResponseMsgId(DD_CAL_REC_TYPE calRecordType ); static void monitorNewCalSignal( void ); /*********************************************************************//** * @brief * The initNVMessagingDD function initializes NV messaging related * states and variables. It resets send and receive states, flags, * counters, and timing values. * @details \b Inputs: none * @details \b Outputs: nvMExecSendRecordState, * nvmExecreceiveRecordState, newRecordStartTimer, * isNewCalRecordAvailable, nvPublishRecordType, * isPublishRecordRequested, recordPublishMsgCount, * recordPublishTotalMsgs, recordSendDataIntervalCounter, * previousRecordMessageNum, recordReceiveStartTime * @return none *************************************************************************/ void initNVMessagingDD( void ) { nvMExecSendRecordState = NVM_SEND_RECORD_STATE_IDLE; nvmExecreceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; newRecordStartTimer = 0; isNewCalRecordAvailable = FALSE; nvPublishRecordType = NVM_SYSTEM_RECORD; isPublishRecordRequested[ NVM_SYSTEM_RECORD ] = FALSE; isPublishRecordRequested[ NVM_SERVICE_RECORD ] = FALSE; isPublishRecordRequested[ NVM_CALIBRATION_RECORD ] = FALSE; isPublishRecordRequested[ NVM_INSTITUTIONAL_RECORD ] = FALSE; isPublishRecordRequested[ NVM_USAGE_INFO_RECORD ] = FALSE; recordSendDataIntervalCounter = 0; sendInstitRec = DD_INSTIT_MIN_DIALYSATE_FLOW_MLPM; sendCalRec = DD_CAL_RECORD_PRESSURE_SENSOR; } /*********************************************************************//** * @brief * The execNVMPSendreceiveDDRecord function executes the NV record processing * state machines. It handles send and receive operations and monitors * for timeouts and calibration signals. * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if invalid send state * @details \b Inputs: nvMExecSendRecordState, * nvmExecreceiveRecordState, recordReceiveStartTime * @details \b Outputs: nvMExecSendRecordState, * nvmExecreceiveRecordState * @return none *************************************************************************/ void execNVMPSendReceiveRecord( void ) { switch ( nvMExecSendRecordState ) { case NVM_SEND_RECORD_STATE_IDLE: nvMExecSendRecordState = handleExecSendRecordIdleState(); break; case NVM_SEND_RECORD_STATE_SEND: nvMExecSendRecordState = handleExecSendRecordSendState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_NVM_INVALID_EXEC_SEND_STATE, ( U32 )nvMExecSendRecordState ); nvMExecSendRecordState = NVM_SEND_RECORD_STATE_IDLE; break; } if( nvmExecreceiveRecordState == NVM_RECEIVE_RECORD_STATE_RECEIVE ) { if ( ( NVM_CALIBRATION_RECORD == currentRxRecordType ) && ( TRUE == didTimeout( calRecordReceiveStartTime, RECORD_DATA_RECEIVE_TIMEOUT_MS ) ) ) { updateRecordCRC(NVM_CALIBRATION_RECORD); enqueueEraseAndWriteSector( NVM_CALIBRATION_RECORD ); startNewCalRecordAvailableTimer(); setNewCalibrationRecordAvailable( TRUE ); PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( NVM_CALIBRATION_RECORD ); sendNVEvent( NVM_CALIBRATION_RECORD , 0, 0 ); nvmExecreceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; } if ( ( NVM_INSTITUTIONAL_RECORD == currentRxRecordType ) && ( TRUE == didTimeout( institRecordReceiveStartTime, RECORD_DATA_RECEIVE_TIMEOUT_MS ) ) ) { updateRecordCRC(NVM_INSTITUTIONAL_RECORD); enqueueEraseAndWriteSector( NVM_INSTITUTIONAL_RECORD ); PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( NVM_INSTITUTIONAL_RECORD ); sendNVEvent( NVM_INSTITUTIONAL_RECORD , 0, 0 ); nvmExecreceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; } } // Check the calibration signal monitorNewCalSignal(); } /*********************************************************************//** * @brief * The setNewCalibrationRecordAvailable function updates the flag * indicating new NV record availability. * @details \b Inputs: none * @details \b Outputs: isNewCalRecordAvailable * @param value Flag value to be updated * @return none *************************************************************************/ void setNewCalibrationRecordAvailable( BOOL isAvailable) { isNewCalRecordAvailable = isAvailable; } /*********************************************************************//** * @brief * The getNewCalRecordAvalability function gets the status of new * calibration record availability. * @details \b Inputs: isNewCalRecordAvailable * @details \b Outputs: none * @return TRUE if new calibration record is available otherwise FALSE *************************************************************************/ BOOL getNewCalRecordAvalability( void ) { return isNewCalRecordAvailable; } /*********************************************************************//** * @brief * The startNewCalRecordAvailableTimer function starts the time for * new calibration record availability. * @details \b Inputs: none * @details \b Outputs: newRecordStartTimer * @return none *************************************************************************/ void startNewCalRecordAvailableTimer( void ) { newRecordStartTimer = getMSTimerCount(); } /*********************************************************************//** * @brief * The handleExecSendRecordIdleState function handles the idle state of * the exec send record state machine. It prepares record data for * publishing when requested. * @details \b Inputs: isPublishRecordRequested, * nvPublishRecordType * @details \b Outputs: isPublishRecordRequested, * recordPublishTotalMsgs, recordPublishMsgCount, * recordSendDataIntervalCounter, nvPublishRecordType, * recordToPublish * @return state next state of the state machine *************************************************************************/ static SEND_RECORD_STATE_T handleExecSendRecordIdleState( void ) { SEND_RECORD_STATE_T state = NVM_SEND_RECORD_STATE_IDLE; if ( TRUE == isPublishRecordRequested[ nvPublishRecordType ] ) { recordToPublish = ( NVM_RECORD_TYPE_T )nvPublishRecordType; // Set the publish flag to FALSE isPublishRecordRequested[ recordToPublish ] = FALSE; // Time interval in between data to be sent. It is set to the interval count so on the first call // of the send calibration record function, the first packet of data is sent recordSendDataIntervalCounter = RECORD_DATA_SEND_INTERVAL_COUNT; state = NVM_SEND_RECORD_STATE_SEND; } nvPublishRecordType = ( NVM_RECORD_TYPE_T )( nvPublishRecordType + 1 ); if( nvPublishRecordType >= NUM_OF_NVM_RECORD_TYPES ) { nvPublishRecordType = NVM_SYSTEM_RECORD; } return state; } /*********************************************************************//** * @brief * The handleExecSendRecordSendState function handles the send state of * the exec send record state machine. It sends record data in chunks * based on timing and message count. * @details \b Inputs: recordPublishTotalMsgs, * recordPublishMsgCount, recordSendDataIntervalCounter, * recordToPublish * @details \b Outputs: recordPublishMsgCount, * recordSendDataIntervalCounter * @return state next state of the state machine *************************************************************************/ static SEND_RECORD_STATE_T handleExecSendRecordSendState( void ) { SEND_RECORD_STATE_T state = NVM_SEND_RECORD_STATE_SEND; // If it is time to send data if ( ++recordSendDataIntervalCounter >= RECORD_DATA_SEND_INTERVAL_COUNT ) { switch(recordToPublish) { case NVM_SYSTEM_RECORD: state = handleSendDDSystemRecord(); break; case NVM_SERVICE_RECORD: state = handleSendDDServiceRecord(); break; case NVM_CALIBRATION_RECORD: state = handleSendDDCalibrationRecord(); break; case NVM_INSTITUTIONAL_RECORD: state = handleSendDDInstitutionalRecord(); break; case NVM_USAGE_INFO_RECORD: state = handleSendDDUsageInfoRecord(); break; default: break; } recordSendDataIntervalCounter = 0; } return state; } /*********************************************************************//** * @brief * The handleSendDDSystemRecord function sends the DD system record. * It retries transmission on failure and returns to the idle state * after a successful send or when retries are exhausted. * @details \b Inputs: recordToPublish, sendRetryCount * @details \b Outputs: recordToPublish, sendRetryCount * @return state next state of the state machine *************************************************************************/ static SEND_RECORD_STATE_T handleSendDDSystemRecord( void ) { SEND_RECORD_STATE_T state = NVM_SEND_RECORD_STATE_SEND; BOOL sysStatus = FALSE; DD_SYSTEM_RECORD_T systemRecord; // Get the record if ( TRUE == getNVMRecord( GET_SYSTEM_RECORD, (U08*)&systemRecord, sizeof( DD_SYSTEM_RECORD_T ) , 0, ALARM_ID_DD_NVM_INVALID_SYSTEM_RECORD_CRC ) ) { // Send the record sysStatus = sendMessage( MSG_ID_DD_NVM_SYSTEM_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&systemRecord, sizeof( DD_SYSTEM_RECORD_T ) ); } // Check if record send successfully if ( TRUE == sysStatus ) { // Reset the retry count sendRetryCount = 0; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; } else { sendRetryCount ++; } // Utilized all the retries. Something is wrong. if ( sendRetryCount > MAX_NUM_OF_SEND_RETRIES ) { // Reset the retry count sendRetryCount = 0; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; } return state; } /*********************************************************************//** * @brief * The handleSendDDServiceRecord function sends the DD service record. * It retries transmission on failure and returns to the idle state * after a successful send or when retries are exhausted. * @details \b Inputs: recordToPublish, sendRetryCount * @details \b Outputs: recordToPublish, sendRetryCount * @return state next state of the state machine *************************************************************************/ static SEND_RECORD_STATE_T handleSendDDServiceRecord( void ) { SEND_RECORD_STATE_T state = NVM_SEND_RECORD_STATE_SEND; BOOL serStatus = FALSE; DD_SERVICE_RECORD_T serviceRecord; // Get the record if ( TRUE == getNVMRecord( GET_SERVICE_RECORD, (U08*)&serviceRecord, sizeof( DD_SERVICE_RECORD_T ) , 0, ALARM_ID_DD_NVM_INVALID_SERVICE_RECORD_CRC ) ) { // Send the record serStatus = sendMessage( MSG_ID_DD_NVM_SERVICE_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&serviceRecord, sizeof( DD_SERVICE_RECORD_T ) ); } // Check if record send successfully if ( TRUE == serStatus ) { // Reset the retry count sendRetryCount = 0; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; } else { sendRetryCount ++; } // Utilized all the retries. Something is wrong. if ( sendRetryCount > MAX_NUM_OF_SEND_RETRIES ) { // Reset the retry count sendRetryCount = 0; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; } return state; } /*********************************************************************//** * @brief * The handleSendDDInstitutionalRecord function sends institutional * record data one item at a time. It builds the payload based on the * data type and manages retries and record sequencing. * @details \b Inputs: sendInstitRec, recordToPublish, sendRetryCount * @details \b Outputs: sendInstitRec, recordToPublish, sendRetryCount * @return state next state of the state machine *************************************************************************/ static SEND_RECORD_STATE_T handleSendDDInstitutionalRecord( void ) { SEND_RECORD_STATE_T state = NVM_SEND_RECORD_STATE_SEND; BOOL sendStatus = FALSE; U32 valueU32 = 0; F32 valueF32 = 0.0; DD_NVM_SEND_RECORD_PAYLOAD_T payload; CRITICAL_DATA_TYPES_T dataType; // Get the data type of the institutional record dataType = getInstitRecDataType( (DD_INSTIT_REC_TYPE)sendInstitRec ); // Create the payload based on the data type if ( CRITICAL_DATA_TYPE_U32 == dataType ) { if ( TRUE == ( getNVMInstitRecord( (DD_INSTIT_REC_TYPE)sendInstitRec, (U08*)&valueU32 ) ) ) { memcpy( &payload.data, &valueU32, sizeof( U32 ) ); } } if ( CRITICAL_DATA_TYPE_F32 == dataType ) { if ( TRUE == ( getNVMInstitRecord( (DD_INSTIT_REC_TYPE)sendInstitRec, (U08*)&valueF32 ) ) ) { memcpy( &payload.data, &valueF32, sizeof( F32 ) ); } } payload.idx = (U08)sendInstitRec; // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_INSTITUTIONAL_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_NVM_SEND_RECORD_PAYLOAD_T ) ); // Check if record was sent successfully if ( TRUE == sendStatus ) { // Reset the retry count sendRetryCount = 0; // Move on to publish the next institutional record sendInstitRec = (DD_INSTIT_REC_TYPE)( (U32)sendInstitRec + 1 ); } else { sendRetryCount ++; } // If all the allowed retries has been utilized or // If all the institutional records have been published if ( ( sendRetryCount > MAX_NUM_OF_SEND_RETRIES ) || ( sendInstitRec >= NUM_OF_DD_INSTIT_RECORD_TYPE ) ) { // Reset Index tracker for next request. sendInstitRec = DD_INSTIT_MIN_DIALYSATE_FLOW_MLPM; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; // Reset the retry count sendRetryCount = 0; } return state; } /*********************************************************************//** * @brief * The handleSendDDUsageInfoRecord function sends the DD usage * information record. It retries transmission on failure and returns * to the idle state after a successful send or when retries are * exhausted. * @details \b Inputs: recordToPublish, sendRetryCount * @details \b Outputs: recordToPublish, sendRetryCount * @return state next state of the state machine *************************************************************************/ static SEND_RECORD_STATE_T handleSendDDUsageInfoRecord( void ) { SEND_RECORD_STATE_T state = NVM_SEND_RECORD_STATE_SEND; BOOL usageStatus = FALSE; DD_USAGE_INFO_RECORD_T usageInfoRecord; // Get the record if ( TRUE == getNVMRecord( GET_USAGE_RECORD, (U08*)&usageInfoRecord, sizeof( DD_USAGE_INFO_RECORD_T ), 0, ALARM_ID_DD_NVM_INVALID_USAGE_RECORD_CRC ) ) { // Send the record usageStatus = sendMessage( MSG_ID_DD_NVM_USAGE_INFO_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&usageInfoRecord, sizeof( DD_USAGE_INFO_RECORD_T ) ); } // Check if record send successfully if ( TRUE == usageStatus ) { // Reset the retry count sendRetryCount = 0; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; } else { sendRetryCount ++; } // Utilized all the retries. Something is wrong. if ( sendRetryCount > MAX_NUM_OF_SEND_RETRIES ) { // Reset the retry count sendRetryCount = 0; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; } return state; } /*********************************************************************//** * @brief * The handleSendDDCalibrationRecord function sends DD calibration * records. It manages calibration record sequencing, sensor indexing, * retries, and transitions back to the idle state when all records * have been published or retries are exhausted. * @details \b Inputs: sendCalRec, sendSensorIdx, * maxSensorIdx, recordToPublish, sendRetryCount * @details \b Outputs: sendCalRec, sendSensorIdx, * recordToPublish, sendRetryCount * @return state next state of the state machine *************************************************************************/ static SEND_RECORD_STATE_T handleSendDDCalibrationRecord( void ) { SEND_RECORD_STATE_T state = NVM_SEND_RECORD_STATE_SEND; BOOL sendStatus = FALSE; switch ( sendCalRec ) { case DD_CAL_RECORD_PRESSURE_SENSOR: sendStatus = sendPressureSensorCalRecord(); break; case DD_CAL_RECORD_TEMPERATURE_SENSOR: sendStatus = sendTempSensorCalRecord(); break; case DD_CAL_RECORD_CONCENTRATE_PUMP: sendStatus = sendConcPumpCalRecord(); break; case DD_CAL_RECORD_D12_PUMP: sendStatus = sendD12PumpCalRecord(); break; case DD_CAL_RECORD_D48_PUMP: sendStatus = sendD48PumpCalRecord(); break; case DD_CAL_RECORD_ACID_CONCENTRATE: sendStatus = sendAcidConcCalRecord(); break; case DD_CAL_RECORD_BICARB_CONCENTRATE: sendStatus = sendBicarbConcCalRecord(); break; case DD_CAL_RECORD_ACCELEROMETER_SENSOR: sendStatus = sendAccelSensorCalRecord(); break; case DD_CAL_RECORD_BLLOD_LEAK_SENSOR: sendStatus = sendBloodLeakSensorCalRecord(); break; default: break; } // Check if record was sent successfully if ( TRUE == sendStatus) { sendSensorIdx++; // Check if we sent the last record of calibration component if ( sendSensorIdx >= maxSensorIdx ) { // Reset Sensor Index for the next calibration data sendSensorIdx = 0; // Reset the retry count for the next calibration data sendRetryCount = 0; // Move on to publish the next calibration record sendCalRec = (DD_CAL_REC_TYPE)( (U32)sendCalRec + 1 ); } } else { sendRetryCount ++; } // If all the allowed retries has been utilized or // If all the calibration records have been published if ( ( sendRetryCount > MAX_NUM_OF_SEND_RETRIES ) || ( sendCalRec >= NUM_OF_CAL_RECORD_TYPE ) ) { // Reset Sensor Index for the next request sendSensorIdx = 0; // Reset Index tracker for next request. sendCalRec = DD_CAL_RECORD_PRESSURE_SENSOR; // Clear the publishing flags recordToPublish = NUM_OF_NVM_RECORD_TYPES; // Move to Send Idle State state = NVM_SEND_RECORD_STATE_IDLE; // Reset the retry count sendRetryCount = 0; } return state; } /*********************************************************************//** * @brief * The sendPressureSensorCalRecord function sends the calibration * record of the selected pressure sensor. * @details \b Inputs: sendSensorIdx * @details \b Outputs: maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendPressureSensorCalRecord( void ) { BOOL sendStatus = FALSE; DD_NVM_POLYNOMIAL_CAL_REC_PAYLOAD_T payload; maxSensorIdx = NUM_OF_PRESSURE_SENSORS; payload.idx = sendSensorIdx; payload.data = getPressureSensorCalRecord( sendSensorIdx ); // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_PRESSURE_SENSOR_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_NVM_POLYNOMIAL_CAL_REC_PAYLOAD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendTempSensorCalRecord function sends the calibration record * of the selected temperature sensor. * @details \b Inputs: sendSensorIdx * @details \b Outputs: maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendTempSensorCalRecord( void ) { BOOL sendStatus = FALSE; DD_NVM_POLYNOMIAL_CAL_REC_PAYLOAD_T payload; maxSensorIdx = NUM_OF_TEMPERATURE_SENSORS; payload.idx = sendSensorIdx; payload.data = getTemperatureSensorCalRecord( sendSensorIdx ); // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_TEMP_SENSOR_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_NVM_POLYNOMIAL_CAL_REC_PAYLOAD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendConcPumpCalRecord function sends the calibration record * of the selected concentrate pump. * @details \b Inputs: sendSensorIdx * @details \b Outputs: maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendConcPumpCalRecord( void ) { BOOL sendStatus = FALSE; DD_NVM_POLYNOMIAL_CAL_REC_PAYLOAD_T payload; maxSensorIdx = NUM_OF_CONCENTRATE_PUMPS; payload.idx = sendSensorIdx; payload.data = getConcPumpCalRecord( sendSensorIdx ); // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_CONC_PUMP_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_NVM_POLYNOMIAL_CAL_REC_PAYLOAD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendD12PumpCalRecord function sends the calibration record of * the D12 dialysate pump. * @details \b Inputs: none * @details \b Outputs: sendSensorIdx, maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendD12PumpCalRecord( void ) { BOOL sendStatus = FALSE; DD_D12_DIALYSATE_PUMP_RECORD_T payload = getD12PumpCalRecord( ); sendSensorIdx = 0; maxSensorIdx = 0; // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_D12_PUMP_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_D12_DIALYSATE_PUMP_RECORD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendD48PumpCalRecord function sends the calibration record of * the D48 dialysate pump. * @details \b Inputs: none * @details \b Outputs: sendSensorIdx, maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendD48PumpCalRecord( void ) { BOOL sendStatus = FALSE; DD_D48_DIALYSATE_PUMP_RECORD_T payload = getD48PumpCalRecord( ); sendSensorIdx = 0; maxSensorIdx = 0; // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_D48_PUMP_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_D48_DIALYSATE_PUMP_RECORD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendAcidConcCalRecord function sends the calibration record of * the selected acid concentrate. * @details \b Inputs: sendSensorIdx * @details \b Outputs: maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendAcidConcCalRecord( void ) { BOOL sendStatus = FALSE; DD_NVM_ACID_CONC_CAL_REC_PAYLOAD_T payload; maxSensorIdx = NUM_OF_ACID_TYPE; payload.idx = sendSensorIdx; payload.data = getAcidConcentrateCalRecord( sendSensorIdx ); // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_ACID_CONCENTRATE_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_NVM_ACID_CONC_CAL_REC_PAYLOAD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendAcidConcCalRecord function sends the calibration record of * the selected acid concentrate. * @details \b Inputs: sendSensorIdx * @details \b Outputs: maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendBicarbConcCalRecord( void ) { BOOL sendStatus = FALSE; DD_NVM_BICARB_CONC_CAL_REC_PAYLOAD_T payload; maxSensorIdx = NUM_OF_BICARB_TYPE; payload.idx = sendSensorIdx; payload.data = getBicarbConcentrateCalRecord( sendSensorIdx ); // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_BICARB_CONCENTRATE_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_NVM_BICARB_CONC_CAL_REC_PAYLOAD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendAccelSensorCalRecord function sends the calibration record * of the accelerometer sensor. * @details \b Inputs: none * @details \b Outputs: sendSensorIdx, maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendAccelSensorCalRecord( void ) { BOOL sendStatus = FALSE; DD_ACCEL_SENSOR_CAL_RECORD_T payload = getAccelSensorCalRecord( ); sendSensorIdx = 0; maxSensorIdx = 0; // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_ACCEL_SENSOR_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_ACCEL_SENSOR_CAL_RECORD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The sendBloodLeakSensorCalRecord function sends the calibration * record of the blood leak sensor. * @details \b Inputs: none * @details \b Outputs: sendSensorIdx, maxSensorIdx * @return TRUE if the message was successfully sent otherwise FALSE *************************************************************************/ static BOOL sendBloodLeakSensorCalRecord( void ) { BOOL sendStatus = FALSE; DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T payload = getBloodLeakSensorCalRecord( ); sendSensorIdx = 0; maxSensorIdx = 0; // Send the record sendStatus = sendMessage( MSG_ID_DD_NVM_CAL_BLOOD_LEAK_SENSOR_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&payload, sizeof( DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T ) ); return sendStatus; } /*********************************************************************//** * @brief * The receiveCalRecord function receives a calibration record, * validates its CRC, updates the calibration data, and sends a * response indicating whether the request was accepted. * @details \b Inputs: none * @details \b Outputs: nvmExecreceiveRecordState, * calRecordReceiveStartTime, currentRxRecordType * @param message Pointer to the received message * @param calRecordType Calibration record type being received * @param recordSize Size of the calibration record in bytes * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ static BOOL receiveCalRecord( MESSAGE_T* message, BOOL isIndexed, DD_CAL_REC_TYPE calRecordType, U16 recordSize ) { BOOL status = FALSE; U08* payloadPtr = message->payload; U08 expectedPayloadLen = recordSize ; MSG_ID_T msgID = getNVMCalRecordResponseMsgId( calRecordType ); UI_RESPONSE_PAYLOAD_T response; if ( TRUE == isIndexed ) { expectedPayloadLen = ( sizeof(U08) + recordSize ); } DD_NVM_SEND_RECORD_PAYLOAD_T recvdPayload; if ( DD_MODE_SERV == getCurrentOperationMode() ) { if ( message->hdr.payloadLen == expectedPayloadLen ) { // Get the index of the received calibration record if required if ( TRUE == isIndexed ) { memcpy( &recvdPayload.idx, payloadPtr, sizeof(U32)); payloadPtr += sizeof(U08); } memcpy( &recvdPayload.data, payloadPtr, recordSize ); // CRC assumed at end of record U16 *recordCRC = (U16*)( recvdPayload.data + ( recordSize - sizeof(U16) ) ); U16 calcCRC = crc16( recvdPayload.data, recordSize - sizeof(U16) ); if ( calcCRC == *recordCRC ) { nvmExecreceiveRecordState = NVM_RECEIVE_RECORD_STATE_RECEIVE; status = setNVMCalRecord( calRecordType, (U08*)&recvdPayload.data, recvdPayload.idx ); response.accepted = TRUE; response.rejectionReason = REQUEST_REJECT_REASON_NONE; // It is possible that we receive multiple packets of cal record // So we write it to flash when we finish receiving all packets or // a timeout occurs. calRecordReceiveStartTime = getMSTimerCount(); currentRxRecordType = NVM_CALIBRATION_RECORD; } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_INVALID_CRC; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_INVALID_OPERATION_MODE; } response.fwValue = recvdPayload.idx; sendMessage( msgID, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); return status; } /*********************************************************************//** * @brief * The getNVMCalRecordResponseMsgId function gets the response message * ID corresponding to the specified calibration record type. * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if invalid calibration * record type is provided * @details \b Inputs: none * @details \b Outputs: none * @param calRecordType Calibration record type * @return msgId corresponding response message ID *************************************************************************/ static MSG_ID_T getNVMCalRecordResponseMsgId( DD_CAL_REC_TYPE calRecordType ) { MSG_ID_T msgId = MSG_ID_UNUSED; switch ( calRecordType ) { case DD_CAL_RECORD_PRESSURE_SENSOR: msgId = MSG_ID_DD_NVM_SET_CAL_PRESSURE_SENSOR_RESPONSE; break; case DD_CAL_RECORD_TEMPERATURE_SENSOR: msgId = MSG_ID_DD_NVM_SET_CAL_TEMP_SENSOR_RESPONSE; break; case DD_CAL_RECORD_CONCENTRATE_PUMP: msgId = MSG_ID_DD_NVM_SET_CAL_CONC_PUMP_RESPONSE; break; case DD_CAL_RECORD_D12_PUMP: msgId = MSG_ID_DD_NVM_SET_CAL_D12_PUMP_RESPONSE; break; case DD_CAL_RECORD_D48_PUMP: msgId = MSG_ID_DD_NVM_SET_CAL_D48_PUMP_RESPONSE; break; case DD_CAL_RECORD_ACID_CONCENTRATE: msgId = MSG_ID_DD_NVM_SET_CAL_ACID_CONCENTRATE_RESPONSE; break; case DD_CAL_RECORD_BICARB_CONCENTRATE: msgId = MSG_ID_DD_NVM_SET_CAL_BICARB_CONCENTRATE_RESPONSE; break; case DD_CAL_RECORD_ACCELEROMETER_SENSOR: msgId = MSG_ID_DD_NVM_SET_CAL_ACCEL_SENSOR_RESPONSE; break; case DD_CAL_RECORD_BLLOD_LEAK_SENSOR: msgId = MSG_ID_DD_NVM_SET_CAL_BLOOD_LEAK_SENSOR_RESPONSE; break; default: // Software fault SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, ( U32 )calRecordType ); break; } return msgId; } /*********************************************************************//** * @brief * The monitorNewCalSignal function monitors the new calibration signal * and clears it when the timeout has elapsed. * @details \b Inputs: isNewCalRecordAvailable, * newRecordStartTimer * @details \b Outputs: isNewCalRecordAvailable * @return none *************************************************************************/ static void monitorNewCalSignal( void ) { // Check if new calibration record is available and // the timer has elapsed if ( ( TRUE == didTimeout( newRecordStartTimer, NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS ) ) && ( TRUE == getNewCalRecordAvalability() ) ) { // Clear the new calibration record available flag setNewCalibrationRecordAvailable( FALSE ); } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testDDGetNVRecord function processes a request to publish an NV * record. It validates the payload and sets the publish request flag * for the selected record. * @details \b Inputs: nvMExecSendRecordState * @details \b Outputs: isPublishRecordRequested, * recordToPublish * @param message Pointer to the received message * @return TRUE if the request is accepted otherwise FALSE *************************************************************************/ BOOL testDDGetNVRecord( MESSAGE_T *message ) { BOOL result = FALSE; NVM_RECORD_TYPE_T job; UI_RESPONSE_PAYLOAD_T response; // verify payload length if ( 1 == message->hdr.payloadLen ) { job = ( NVM_RECORD_TYPE_T )message->payload[ 0 ]; // Accept the request only if the send exec is in the idle state if ( ( job < NUM_OF_NVM_RECORD_TYPES ) && ( NVM_SEND_RECORD_STATE_IDLE == nvMExecSendRecordState ) ) { isPublishRecordRequested[ job ] = TRUE; recordToPublish = job; result = TRUE; response.accepted = TRUE; response.rejectionReason = REQUEST_REJECT_REASON_NONE; } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_JOB_QUEUE_BUSY; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; } sendMessage( MSG_ID_DD_NVM_GET_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetNVSystemRecord function processes a request to update * the system record. It allows updates only when the system is in * service mode. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the record is successfully processed otherwise FALSE *************************************************************************/ BOOL testDDSetNVSystemRecord( MESSAGE_T *message ) { BOOL result = FALSE; U08 tempBuffer[ sizeof( DD_SYSTEM_RECORD_T ) ]; UI_RESPONSE_PAYLOAD_T response; // System record can be updated only in service mode if ( DD_MODE_SERV == getCurrentOperationMode() ) { if (message->hdr.payloadLen == sizeof( DD_SYSTEM_RECORD_T )) { memcpy( tempBuffer, message->payload, sizeof( DD_SYSTEM_RECORD_T ) ); // CRC received at end of record U16 *recordCRC = (U16 *)( tempBuffer + ( sizeof( DD_SYSTEM_RECORD_T ) - sizeof(U16) ) ); U16 calcCRC = crc16( tempBuffer, sizeof( DD_SYSTEM_RECORD_T ) - sizeof(U16) ); if ( calcCRC == *recordCRC ) { currentRxRecordType = NVM_SYSTEM_RECORD; PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( NVM_SYSTEM_RECORD ); memcpy( recordSpec.structAddressPtr, tempBuffer, sizeof( DD_SYSTEM_RECORD_T ) ); setNVMRecord( NVM_SYSTEM_RECORD, tempBuffer ); result = enqueueEraseAndWriteSector( NVM_SYSTEM_RECORD ); sendNVEvent( NVM_SYSTEM_RECORD, 0, 0 ); response.accepted = TRUE; response.rejectionReason = REQUEST_REJECT_REASON_NONE; } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_INVALID_CRC; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_INVALID_OPERATION_MODE; } sendMessage( MSG_ID_DD_NVM_SET_SYSTEM_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetNVServiceRecord function processes a request to update * the service record. It allows updates only when the system is in * service mode. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the record is successfully processed otherwise FALSE *************************************************************************/ BOOL testDDSetNVServiceRecord( MESSAGE_T *message ) { BOOL result = FALSE; U08 tempBuffer[ sizeof( DD_SERVICE_RECORD_T ) ]; UI_RESPONSE_PAYLOAD_T response; // Service record can be updated only in service mode if ( DD_MODE_SERV == getCurrentOperationMode() ) { if (message->hdr.payloadLen == ( sizeof( DD_SERVICE_RECORD_T ) ) ) { memcpy( tempBuffer, message->payload, sizeof( DD_SERVICE_RECORD_T ) ); // CRC assumed at end of record U16 *recordCRC = (U16 *)( tempBuffer + ( sizeof( DD_SERVICE_RECORD_T ) - sizeof(U16) ) ); U16 calcCRC = crc16( tempBuffer, sizeof( DD_SERVICE_RECORD_T ) - sizeof(U16) ); if ( calcCRC == *recordCRC ) { currentRxRecordType = NVM_SERVICE_RECORD; PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( NVM_SERVICE_RECORD ); memcpy( recordSpec.structAddressPtr, tempBuffer, sizeof( DD_SERVICE_RECORD_T ) ); setNVMRecord( NVM_SERVICE_RECORD, tempBuffer ); result = enqueueEraseAndWriteSector( NVM_SERVICE_RECORD ); sendNVEvent( NVM_SERVICE_RECORD, 0, 0 ); response.accepted = TRUE; response.rejectionReason = REQUEST_REJECT_REASON_NONE; } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_INVALID_CRC; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_INVALID_OPERATION_MODE; } sendMessage( MSG_ID_DD_NVM_SET_SERVICE_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetNVUsageInfoRecord function processes a request to * update the usage information record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the record is successfully processed otherwise FALSE *************************************************************************/ BOOL testDDSetNVUsageInfoRecord( MESSAGE_T *message ) { BOOL result = FALSE; U08 tempBuffer[ sizeof( DD_USAGE_INFO_RECORD_T ) ]; UI_RESPONSE_PAYLOAD_T response; if (message->hdr.payloadLen == ( sizeof( DD_USAGE_INFO_RECORD_T ) )) { memcpy( tempBuffer, message->payload, sizeof( DD_USAGE_INFO_RECORD_T ) ); // CRC assumed at end of record U16 *recordCRC = (U16 *)( tempBuffer + ( sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof(U16) ) ); U16 calcCRC = crc16( tempBuffer, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof(U16) ); if ( calcCRC == *recordCRC ) { currentRxRecordType = NVM_USAGE_INFO_RECORD; PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( NVM_USAGE_INFO_RECORD ); memcpy( recordSpec.structAddressPtr, tempBuffer, sizeof( DD_USAGE_INFO_RECORD_T ) ); setNVMRecord( NVM_USAGE_INFO_RECORD, tempBuffer ); result = enqueueEraseAndWriteSector( NVM_USAGE_INFO_RECORD ); sendNVEvent( NVM_USAGE_INFO_RECORD, 0, 0 ); response.accepted = TRUE; response.rejectionReason = REQUEST_REJECT_REASON_NONE; } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_NVM_INVALID_CRC; } } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; } sendMessage( MSG_ID_DD_NVM_SET_USAGE_INFO_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetNVInstitutionalRecord function processes a request to * update the institutional record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the record is successfully processed otherwise FALSE *************************************************************************/ BOOL testDDSetNVInstitutionalRecord( MESSAGE_T *message ) { BOOL result = FALSE; U08 idx = 0; U08* payloadPtr = message->payload; U08 expectedPayloadLen = sizeof(U08); UI_RESPONSE_PAYLOAD_T response; if ( message->hdr.payloadLen >= expectedPayloadLen ) { nvmExecreceiveRecordState = NVM_RECEIVE_RECORD_STATE_RECEIVE; memcpy( &idx, payloadPtr, sizeof(U32) ); payloadPtr += sizeof(U08); result = setNVMInstitRecord( (DD_INSTIT_REC_TYPE)idx, payloadPtr ); response.accepted = TRUE; response.rejectionReason = REQUEST_REJECT_REASON_NONE; // It is possible that we receive multiple packets of instit record // So we write it to flash when we finish receiving all packets or // a timeout occurs. institRecordReceiveStartTime = getMSTimerCount(); currentRxRecordType = NVM_INSTITUTIONAL_RECORD; } else { response.accepted = FALSE; response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; } response.fwValue = idx; sendMessage( MSG_ID_DD_NVM_SET_INSTITUTIONAL_RECORD_RESPONSE, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetPressureSensorCalRecord function processes a request * to update a pressure sensor calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetPressureSensorCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, TRUE, DD_CAL_RECORD_PRESSURE_SENSOR, sizeof( POLYNOMIAL_CAL_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetTempSensorCalRecord function processes a request to * update a temperature sensor calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetTempSensorCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, TRUE, DD_CAL_RECORD_TEMPERATURE_SENSOR, sizeof( POLYNOMIAL_CAL_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetConcPumpCalRecord function processes a request to * update a concentrate pump calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetConcPumpCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, TRUE, DD_CAL_RECORD_CONCENTRATE_PUMP, sizeof( POLYNOMIAL_CAL_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetD12PumpCalRecord function processes a request to * update the D12 dialysate pump calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetD12PumpCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, FALSE, DD_CAL_RECORD_D12_PUMP, sizeof( DD_D12_DIALYSATE_PUMP_RECORD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetD48PumpCalRecord function processes a request to * update the D48 dialysate pump calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetD48CalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, FALSE, DD_CAL_RECORD_D48_PUMP, sizeof( POLYNOMIAL_CAL_PAYLOAD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetAcidConcCalRecord function processes a request to * update an acid concentrate calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetAcidConcCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, TRUE, DD_CAL_RECORD_ACID_CONCENTRATE, sizeof( DD_ACID_CONCENTRATE_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetBicarbConcCalRecord function processes a request to * update a bicarb concentrate calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetBicarbConcCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, TRUE, DD_CAL_RECORD_BICARB_CONCENTRATE, sizeof( DD_BICARB_CONCENTRATE_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetAccelSensorCalRecord function processes a request to * update the accelerometer sensor calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetAccelSensorCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, FALSE, DD_CAL_RECORD_ACCELEROMETER_SENSOR, sizeof( DD_ACCEL_SENSOR_CAL_RECORD_T ) ); return result; } /*********************************************************************//** * @brief * The testDDSetBloodLeakSensorCalRecord function processes a request * to update the blood leak sensor calibration record. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to the received message * @return TRUE if the calibration record was accepted and processed * successfully otherwise FALSE *************************************************************************/ BOOL testDDSetBloodLeakSensorCalRecord( MESSAGE_T *message ) { BOOL result = FALSE; result = receiveCalRecord( message, FALSE, DD_CAL_RECORD_BLLOD_LEAK_SENSOR, sizeof( DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T ) ); return result; } /*********************************************************************//** * @brief * The testSetNVRecordCRCOverride function overrides the CRC value of * the selected non-volatile record and schedules it for writing. * @details \b Inputs: none * @details \b Outputs: none * @param job The job whose CRC needs to be overridden * @param crc The CRC value to be set * @return TRUE if the job was scheduled successfully otherwise FALSE *************************************************************************/ BOOL testSetNVRecordCRCOverride( U32 job, U16 crc ) { BOOL result = FALSE; result = updateNVRecordCRC( job, crc ); return result; } /**@}*/