/************************************************************************** * * 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 NVMessaging.c * * @author (original) Arpita Srivastava * @date (original) 31-Mar-2026 * ***************************************************************************/ #include // For ceilf function #include "NVJobQ.h" #include "NVMessaging.h" #include "NVRecordsDD.h" #include "OperationModes.h" #include "TaskGeneral.h" #include "Timers.h" #include "Utilities.h" // For crc calculation /** * @addtogroup NVMessaging * @{ */ // ********** 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 ) * 3 ) ) ///< 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. /// 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 { U32 payloadCurrNum; ///< Current Chunk number out of total number number of chunks U32 payloadTotalNum; ///< Total number of chunks in which data is broken be sent U32 length; ///< Length of data in the current chunk U08 data[NUM_OF_BYTES_PER_RECORD_PAYLOAD]; ///< Data to be sent } DD_NVM_SEND_RECORD_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 recordPublishMsgCount; ///< Record data publish message counter. static U32 recordPublishTotalMsgs; ///< Record data total number of messages to be sent. static U32 recordSendDataIntervalCounter; ///< Record data send to CAN bust interval counter. static U32 previousRecordMessageNum; ///< Record previous message number. static U32 recordUpdateAddress; ///< DD record update address for all the write operations. static U32 recordReceiveStartTime; ///< Time stamp the calibration/service was received. 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 BOOL sendDDRecord( MSG_ID_T msgId, U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress ); static BOOL receiveDDRecord( MESSAGE_T *message ); static BOOL verifyAndSaveReceivedRecord( NVM_RECORD_TYPE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); static NVM_RECORD_TYPE_T getNVMRecordJobState( MSG_ID_T msgID ); static MSG_ID_T getNVMRecordResponseMsgId (NVM_RECORD_TYPE_T job ); static void monitorNewCalSignal( void ); /*********************************************************************//** * @brief * The initNVMessaging 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 initNVMessaging( 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; recordPublishMsgCount = 1; recordPublishTotalMsgs = 1; recordSendDataIntervalCounter = 0; previousRecordMessageNum = 0; recordReceiveStartTime = 0; } /*********************************************************************//** * @brief * The execNVMPSendReceiveRecord 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; } // Check if the exec receive records is not idle // This section checks the status of the asynchronous state machine that receives // data from Dialin. if ( nvmExecReceiveRecordState != NVM_RECEIVE_RECORD_STATE_IDLE ) { // Check if the data receiving process has timed out. The exec receive record // state machine is asynchronous so it is checked in this state machine if ( TRUE == didTimeout( recordReceiveStartTime, RECORD_DATA_RECEIVE_TIMEOUT_MS ) ) { // Exec receive state machine timed out. Schedule a read to update the structure enqueueRecordJob( NVM_OPERATION_READ, currentRxRecordType ); 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; // Get the record specifications to find the size of the job PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( recordToPublish ); // Calculate the total number of messages required to be sent using ceilf function. This function rounds up the // value and its result is converted to U32. recordPublishTotalMsgs = (U32)ceilf( (F32)recordSpec.sizeofRecord / (F32)NUM_OF_BYTES_PER_RECORD_PAYLOAD ); recordPublishMsgCount = 0; // 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; MSG_ID_T msgId; // If the current message number is less than the total, keep sending if ( recordPublishMsgCount < recordPublishTotalMsgs ) { // If it is time to send data if ( ++recordSendDataIntervalCounter >= RECORD_DATA_SEND_INTERVAL_COUNT ) { // Set to default cal data payload length U32 length = NUM_OF_BYTES_PER_RECORD_PAYLOAD; PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( recordToPublish ); U08* startPtr = recordSpec.structAddressPtr; // If this is the last calibration data payload, calculate the remainder of the bytes to send if ( ( recordPublishMsgCount + 1 ) == recordPublishTotalMsgs ) { length = recordSpec.sizeofRecord - ( recordPublishMsgCount * NUM_OF_BYTES_PER_RECORD_PAYLOAD ); } // Find the new location of the pointer which is the start of the calibration payload to be sent startPtr += recordPublishMsgCount * NUM_OF_BYTES_PER_RECORD_PAYLOAD; // Get th message id of the NVM record response msgId = getNVMRecordResponseMsgId( recordToPublish ); // Send the NVM record sendDDRecord( msgId, recordPublishMsgCount + 1, recordPublishTotalMsgs, length, startPtr ); recordPublishMsgCount++; recordSendDataIntervalCounter = 0; } } else { state = NVM_SEND_RECORD_STATE_IDLE; } return state; } /*********************************************************************//** * @brief * The sendDDRecord function sends a DD record payload over communication. * It prepares the payload and queues it for transmission. * @details \b Inputs: none * @details \b Outputs: none * @param msgId Message Id for response record * @param payloadCurrNum Current payload number * @param payloadTotalNum Total number of payloads * @param length Buffer length to be written * @param recordAddress Start address of the record data * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ static BOOL sendDDRecord( MSG_ID_T msgId, U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* recordAddress ) { BOOL result = FALSE; U08 payloadLen = 0; DD_NVM_SEND_RECORD_PAYLOAD_T payload; payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; payload.payloadCurrNum = payloadCurrNum; payload.payloadTotalNum = payloadTotalNum; payload.length = length; memcpy( payload.data, recordAddress, length ); result = sendMessage( msgId, COMM_BUFFER_OUT_DD_CAN_PC, (U08 *)&payload, payloadLen ); return result; } /*********************************************************************//** * @brief * The receiveDDRecord function processes a received DD record message. * It extracts payload information and verifies the received data before * saving it. * @details \b Inputs: none * @details \b Outputs: none * @param message Pointer to received message structure * @return TRUE if the record is successfully verified and saved, * otherwise FALSE *************************************************************************/ static BOOL receiveDDRecord( MESSAGE_T *message ) { BOOL status = FALSE; U32 currentMessage; U32 totalMessages; U32 payloadLength; U08* payloadPtr = message->payload; U08 minPayloadLen = ( sizeof(currentMessage) + sizeof(totalMessages) + sizeof(payloadLength) ); MSG_ID_T msgID = (MSG_ID_T)message->hdr.msgID; NVM_RECORD_TYPE_T job = getNVMRecordJobState( msgID ); // To proceed, the payload length should be valid. And, if it is a service job, then DD mode should also be in service. if ( message->hdr.payloadLen >= minPayloadLen ) { memcpy(¤tMessage, payloadPtr, sizeof(U32)); payloadPtr += sizeof(U32); memcpy(&totalMessages, payloadPtr, sizeof(U32)); payloadPtr += sizeof(U32); memcpy(&payloadLength, payloadPtr, sizeof(U32)); payloadPtr += sizeof(U32); status = verifyAndSaveReceivedRecord( job, currentMessage, totalMessages, payloadLength, payloadPtr ); } return status; } /*********************************************************************//** * @brief * The verifyAndSaveReceivedRecord function receives the record sent * from Dialin, assembles it, validates it using CRC, and schedules a * write to NV memory if valid. * @details \b Inputs: nvmExecReceiveRecordState, * @details \b Outputs: nvmExecReceiveRecordState, * recordReceiveStartTime, previousRecordMessageNum, * recordUpdateAddress, currentRxRecordType, * @param job The job that has to be received and written * @param currentMessage Current message number received from Dialin * @param totalMessages Total number of messages from Dialin * @param length Message length in bytes * @param addressPtr Address to the beginning of received data from Dialin * @return TRUE if the request was successfully registered *************************************************************************/ static BOOL verifyAndSaveReceivedRecord( NVM_RECORD_TYPE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ) { BOOL status = TRUE; // If the calibration message number is the first message number and receive exec state is idle, switch to idle if ( ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage ) && ( NVM_RECEIVE_RECORD_STATE_IDLE == nvmExecReceiveRecordState ) ) { nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_RECEIVE; currentRxRecordType = job; recordReceiveStartTime = getMSTimerCount(); previousRecordMessageNum = 0; recordUpdateAddress = 0; } // Check if there is still a message left to be received if ( ( NVM_RECEIVE_RECORD_STATE_RECEIVE == nvmExecReceiveRecordState ) && ( currentMessage <= totalMessages ) ) { // Check if the current message is different from the previous message by 1 if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousRecordMessageNum ) ) { // Define a pointer that points to the temporary receive record PROCESS_RECORD_SPECS_T tempRxSpec = getTemporaryRxRecord( job ); U08* tempRxPtr = tempRxSpec.structAddressPtr; // Get the DD main nvm record PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( job ); // Offset the pointer to length that we should start writing from tempRxPtr += recordUpdateAddress; memcpy( tempRxPtr, addressPtr, length ); // Check if the current message is total messages // and 0 everything out since we are done writing if ( currentMessage == totalMessages ) { U16 calcCRC = crc16 ( tempRxSpec.structAddressPtr, tempRxSpec.sizeofRecord - sizeof(U16) ); // Get the CRC of the structure without the last 16 bits which is the CRC as well as the padding values U16 recordCRC = *(U16*)tempRxSpec.structCRCPtr; // Check if calculated CRC matches the Stored CRC if ( ( calcCRC == recordCRC ) ) { _disable_IRQ(); // Copy the valid temporary record into the main record spec memcpy(recordSpec.structAddressPtr, tempRxSpec.structAddressPtr, tempRxSpec.sizeofRecord); _enable_IRQ(); // Enqueue an erase and write of the nvm record status = enqueueEraseAndWriteSector( job ); if( NVM_CALIBRATION_RECORD == job ) { // Signal that there is a new calibration record available. // NOTE: as of now, this signal will be sent even after the system record is sent startNewCalRecordAvailableTimer(); setNewCalibrationRecordAvailable( TRUE ); } // Update the event of the received record that has been accepted SEND_EVENT_WITH_2_U32_DATA( recordSpec.nvEvent, 0, 0 ); // Done with receiving data, go back to idle nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; } else { // CRC match failed, go to idle nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; status = FALSE; } } else { // Update the length as it has successfully been written recordUpdateAddress += length; // Now the current message is the previous message previousRecordMessageNum = currentMessage; } } } return status; } /*********************************************************************//** * @brief * The getNVMRecordJobState function maps the received message ID to * the corresponding NV record job type. * @details \b Inputs: none * @details \b Outputs: none * @param msgID Message ID received * @return job corresponding NV record type *************************************************************************/ static NVM_RECORD_TYPE_T getNVMRecordJobState( MSG_ID_T msgID ) { NVM_RECORD_TYPE_T job; switch ( msgID ) { case MSG_ID_DD_NVM_SET_CALIBRATION_RECORD: job = NVM_CALIBRATION_RECORD; break; case MSG_ID_DD_NVM_SET_SYSTEM_RECORD: job = NVM_SYSTEM_RECORD; break; case MSG_ID_DD_NVM_SET_SERVICE_RECORD: job = NVM_SERVICE_RECORD; break; case MSG_ID_DD_NVM_SET_INSTITUTIONAL_RECORD: job = NVM_INSTITUTIONAL_RECORD; break; case MSG_ID_DD_NVM_SET_USAGE_INFO_RECORD: job = NVM_USAGE_INFO_RECORD; break; default: // Do nothing for Invalid Input from Dialin break; } return job; } /*********************************************************************//** * @brief * The getNVMRecordResponseMsgId function maps the NV record type to * the corresponding response message ID. * provided * @details \b Inputs: none * @details \b Outputs: none * @param job NV record type * @return msgID corresponding response message ID *************************************************************************/ static MSG_ID_T getNVMRecordResponseMsgId( NVM_RECORD_TYPE_T job ) { MSG_ID_T msgID; switch( job ) { case NVM_CALIBRATION_RECORD: msgID = MSG_ID_DD_NVM_SEND_CALIBRATION_RECORD; break; case NVM_SYSTEM_RECORD: msgID = MSG_ID_DD_NVM_SEND_SYSTEM_RECORD; break; case NVM_SERVICE_RECORD: msgID = MSG_ID_DD_NVM_SEND_SERVICE_RECORD; break; case NVM_INSTITUTIONAL_RECORD: msgID = MSG_ID_DD_NVM_SEND_INSTITUTIONAL_RECORD; break; case NVM_USAGE_INFO_RECORD: msgID = MSG_ID_DD_NVM_SEND_USAGE_INFO_RECORD; break; default: // Do nothing for Invalid Input from Dialin 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; // 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; } } 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; // System record can be updated only in service mode if ( DD_MODE_SERV == getCurrentOperationMode() ) { result = receiveDDRecord( message ); } 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; // Service record can be updated only in service mode if ( DD_MODE_SERV == getCurrentOperationMode() ) { result = receiveDDRecord( message ); } return result; } /*********************************************************************//** * @brief * The testDDSetNVCalibrationRecord function processes a request to * update the calibration 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 testDDSetNVCalibrationRecord( MESSAGE_T *message ) { BOOL result = FALSE; // Calibration record can be updated only in service mode if ( DD_MODE_SERV == getCurrentOperationMode() ) { result = receiveDDRecord( message ); } 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; result = receiveDDRecord( message ); 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; result = receiveDDRecord( message ); 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; } /**@}*/