/************************************************************************** * * 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 NVJobQ.c * * @author (original) Arpita Srivastava * @date (original) 31-Mar-2026 * ***************************************************************************/ #include // For memcpy #include "Common.h" #include "MsgDefs.h" #include "NVJobQ.h" #include "NVRecordsDD.h" /** * @addtogroup NVJobQ * @{ */ // ********** private definitions ********** // Once a new calibration data is available the driver, sets a signal for the defined time. Once the time is out, it turns the signal off. #define QUEUE_MAX_SIZE 20U ///< Max queue size. #define QUEUE_START_INDEX 0U ///< Queue start index. #define MAX_JOB_DATA_SIZE_BYTES 32U ///< Max bytes per job (32 bytes). /// DD institutional values structure. typedef struct { U32 minRORejectionRatioPCT; ///< Min RO rejection ratio in percent. F32 minInletWaterCondAlarmLimitUSPCM; ///< Min inlet water conductivity alarm limit in uS/cm. } DD_INSTITUTIONAL_VALUES_T; // ********** private data ********** static PROCESS_RECORD_JOB_T recordJobQueue[ QUEUE_MAX_SIZE ]; ///< Record queue jobs. static U08 recordQueueRearIndex; ///< Record queue rear index. static U08 recordQueueFrontIndex; ///< Record queue front index. static U08 recordQueueCount; ///< Record queue count. static PROCESS_RECORD_JOB_T recordCurrentJob; ///< Record queue current job. static NVM_RECORDS_READ_STATUS_T recordsReadStatus; ///< NVM records read status. // ********** private function prototypes ********** /*********************************************************************//** * @brief * The initNVJobQ function initializes the NV message queue and related * state variables. * @details \b Inputs: none * @details \b Outputs: recordQueueRearIndex, * recordQueueFrontIndex, recordQueueCount, recordsReadStatus, * @return none *************************************************************************/ void initNVJobQ ( void ) { recordQueueRearIndex = QUEUE_START_INDEX; recordQueueFrontIndex = QUEUE_START_INDEX; recordQueueCount = 0; recordsReadStatus = NVM_RECORDS_NOT_STARTED; } /*********************************************************************//** * @brief * The enqueueRecordJob function enqueues a new record job into the * record queue. It updates the queue with the new job and advances * the rear index. * @details \b Inputs: recordQueueRearIndex, recordQueueCount * @details \b Outputs: recordJobQueue, recordQueueRearIndex, * recordQueueCount * @param ops memory operation (i.e write, read) * @param job type of job (i.e write calibration data) * @return none *************************************************************************/ void enqueueRecordJob( NVM_OPERATION_T ops, NVM_RECORD_TYPE_T job ) { PROCESS_RECORD_JOB_T currentJob; currentJob.memoryOperation = ops; currentJob.recordJob = job; recordJobQueue[ recordQueueRearIndex ] = currentJob; recordQueueCount++; recordQueueRearIndex = INC_WRAP( recordQueueRearIndex, 0, QUEUE_MAX_SIZE - 1 ); } /*********************************************************************//** * @brief * The dequeueRecordJob function removes a record job from the queue. * It updates the front index, retrieves the job, and updates the * queue count. * @details \b Inputs: recordQueueFrontIndex, recordQueueCount, * recordJobQueue * @details \b Outputs: recordQueueFrontIndex, recordQueueCount, * recordCurrentJob * @return none *************************************************************************/ void dequeueRecordJob( void ) { U32 tempIndex; _disable_IRQ(); tempIndex = recordQueueFrontIndex; if ( FALSE == isRecordQueueEmpty() ) { recordQueueFrontIndex = INC_WRAP( recordQueueFrontIndex, 0, QUEUE_MAX_SIZE - 1 ); recordCurrentJob = recordJobQueue[ tempIndex ]; } if ( recordQueueCount > 0 ) { recordQueueCount--; } _enable_IRQ(); } /*********************************************************************//** * @brief * The isRecordQueueEmpty function checks whether the record queue is * empty. It returns the status based on the queue count. * @details \b Inputs: recordQueueCount * @details \b Outputs: none * @return TRUE if queue is empty otherwise FALSE *************************************************************************/ BOOL isRecordQueueEmpty( void ) { BOOL isEmpty = TRUE; if ( recordQueueCount > 0 ) { isEmpty = FALSE; } return isEmpty; } /*********************************************************************//** * @brief * The isRecordQueueFull function checks whether the record queue is * full based on the maximum queue size. * @details \b Inputs: recordQueueCount * @details \b Outputs: none * @return TRUE if queue is full otherwise FALSE *************************************************************************/ BOOL isRecordQueueFull( void ) { BOOL isFull = FALSE; if ( recordQueueCount >= ( QUEUE_MAX_SIZE - 1 ) ) { isFull = TRUE; } return isFull; } /*********************************************************************//** * @brief * The getAvailableRecordQueueCount function returns the number of * available record queue slots based on the current queue count. * @details \b Inputs: recordQueueCount * @details \b Outputs: none * @return available record queues *************************************************************************/ U32 getAvailableRecordQueueCount( void ) { return QUEUE_MAX_SIZE - recordQueueCount; } /*********************************************************************//** * @brief * The enqueueEraseAndWriteSector function enqueues erase and write * operations for the given record type. * @details \b Inputs: none * @details \b Outputs: none * @param job Record type for which erase and write operations are scheduled * @return TRUE if the operations were successfully enqueued otherwise FALSE *************************************************************************/ BOOL enqueueEraseAndWriteSector( NVM_RECORD_TYPE_T job ) { BOOL status = FALSE; if ( getAvailableRecordQueueCount() >= MIN_JOBS_NEEDED_TO_WRITE_A_RECORD ) { // Service and Calibration record are stored in the same sector. if ( ( job == NVM_SERVICE_RECORD ) || ( job == NVM_CALIBRATION_RECORD ) ) { enqueueRecordJob( NVM_OPERATION_ERASE, NVM_SERVICE_RECORD ); enqueueRecordJob( NVM_OPERATION_WRITE, NVM_SERVICE_RECORD ); enqueueRecordJob( NVM_OPERATION_WRITE, NVM_CALIBRATION_RECORD ); } else { enqueueRecordJob( NVM_OPERATION_ERASE, job ); enqueueRecordJob( NVM_OPERATION_WRITE, job ); } status = TRUE; } return status; } /*********************************************************************//** * @brief * The enqueuewriteAllRecords function enqueues erase and write * operations for all records. It schedules jobs for all record types * if sufficient queue space is available. * @details \b Inputs: none * @details \b Outputs: none * @return TRUE if all operations were successfully enqueued otherwise FALSE *************************************************************************/ BOOL enqueuewriteAllRecords( void ) { BOOL status = FALSE; if ( getAvailableRecordQueueCount() >= MIN_JOBS_NEEDED_TO_WRITE_ALL_RECORDS ) { NVM_RECORD_TYPE_T record; // Erase all the sectors for ( record = NVM_SYSTEM_RECORD; record < NUM_OF_NVM_RECORD_TYPES; record++ ) { enqueueRecordJob( NVM_OPERATION_ERASE, record ); } // Write all the records for ( record = NVM_SYSTEM_RECORD; record < NUM_OF_NVM_RECORD_TYPES; record++ ) { enqueueRecordJob( NVM_OPERATION_WRITE, record ); } status = TRUE; } return status; } /*********************************************************************//** * @brief * The enqueueReadAllRecords function enqueues all NV records to be read * during POST. It schedules read jobs for all record types if sufficient * queue space is available. * @details \b Inputs: none * @details \b Outputs: recordsReadStatus * @return TRUE if records were successfully enqueued otherwise FALSE *************************************************************************/ BOOL enqueueReadAllRecords( void ) { BOOL status = FALSE; NVM_RECORD_TYPE_T record; if ( getAvailableRecordQueueCount() >= MIN_JOBS_NEEDED_TO_READ_ALL_RECORDS ) { for ( record = NVM_SYSTEM_RECORD; record < NUM_OF_NVM_RECORD_TYPES; record++ ) { enqueueRecordJob( NVM_OPERATION_READ, record ); } status = TRUE; } // Set the status to records were queued successfully recordsReadStatus = NVM_RECORDS_QUEUED; return status; } /*********************************************************************//** * @brief * The getNVRecordsReadStatus function returns the current NV records * read status of the POST process. * @details \b Inputs: recordsReadStatus * @details \b Outputs: none * @return recordsReadStatus *************************************************************************/ NVM_RECORDS_READ_STATUS_T getNVRecordsReadStatus( void ) { return recordsReadStatus; } /*********************************************************************//** * @brief * The updateRecordReadStatus function updates the NV records read * status with the provided value. * @details \b Inputs: none * @details \b Outputs: recordsReadStatus * @param status Record read status to be updated * @return none *************************************************************************/ void updateRecordReadStatus( NVM_RECORDS_READ_STATUS_T status ) { recordsReadStatus = status; } /*********************************************************************//** * @brief * The getCurrentProcessRecordJob function gets the current record job * from the processing queue. * @details \b Inputs: recordCurrentJob * @details \b Outputs: none * @return recordCurrentJob *************************************************************************/ PROCESS_RECORD_JOB_T getCurrentProcessRecordJob ( void ) { return recordCurrentJob; } /**@}*/