Index: firmware/App/Drivers/NVDriver.c =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Drivers/NVDriver.c (.../NVDriver.c) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Drivers/NVDriver.c (.../NVDriver.c) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -21,7 +21,6 @@ #define BANK7_SECTOR_0_31_ENABLE_BIT_MASK 0x0000000F ///< Bank7 sector 0 t0 31 enable mask. #define BANK7_SECTOR_32_63_ENABLE_BIT_MASK 0x00000000 ///< Bank7 sector 32 to 63 enable mask. -#define BANK7_SECTOR0_START_ADDRESS 0xF0200000 ///< Bank7 sector 0 start address. #define BANK7_SECTOR0_END_ADDRESS 0xF0203FFF ///< Bank7 sector 0 end address. #define BANK7_SECTOR1_START_ADDRESS 0xF0204000 ///< Bank7 sector 1 start address. @@ -33,9 +32,6 @@ #define BANK7_SECTOR3_START_ADDRESS 0xF020C000 ///< Bank7 sector 3 start address. #define BANK7_SECTOR3_END_ADDRESS 0xF020FFFF ///< Bank7 sector 3 end address. -/// EEPROM functions use the buffer length as the size of U32. So before send the length to any of FAPI functions, it should be divided by 4. -#define EEPROM_OPS_SIZE_OF_CONVERTER 4 - void initNVDriver( void ) { // Initialize and activate flash bank 7 Index: firmware/App/Drivers/NVDriver.h =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Drivers/NVDriver.h (.../NVDriver.h) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Drivers/NVDriver.h (.../NVDriver.h) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -17,6 +17,40 @@ #include "Common.h" +#define BANK7_SECTOR0_START_ADDRESS 0xF0200000 ///< Bank7 sector 0 start address. + +/// NVDataMgmt memory operation modes enumeration. +typedef enum NVDataMgmt_Operation +{ + NVDATAMGMT_NONE = 0, ///< Default mode to prevent any accidental ops. + NVDATAMGMT_WRITE, ///< Operation mode write. + NVDATAMGMT_READ, ///< Operation mode read. + NVDATAMGMT_ERASE_SECTOR, ///< Operation mode erase a sector (EEPROM). + NUM_OF_NVDATAMGMT_OPS_STATES ///< Total number of operation states. +} NVDATAMGMT_OPERATION_STATE_T; + +/// NVDataMgmt records' jobs states +typedef enum NVDataMgmt_Records_Jobs +{ + NVDATAMGMT_CALIBRATION_RECORD = 0, ///< NVDataMgmt process write calibration record. + NVDATAMGMT_SYSTEM_RECORD, ///< NVDataMgmt process write system record. + NVDATAMGMT_SERVICE_RECORD, ///< NVDataMgmt process service record. + NVDATAMGMT_SCHEDULED_RUNS_RECORD, ///< NVDataMgmt process scheduled runs record. + NVDATAMGMT_HEATERS_INFO_RECORD, ///< NVDataMgmt process heaters info record. + NVDATAMGMT_USAGE_INFO_RECORD, ///< NVDataMgmt process usage info record. +#ifndef _RELEASE_ + NVDATAMGMT_SW_CONFIG_RECORD, ///< NVDataMgmt process software record. +#endif + NUM_OF_NVDATMGMT_RECORDS_JOBS ///< Number of NVDataMgmt records jobs. +} RECORD_JOBS_STATE_T; + +/// Process records job structure +typedef struct +{ + NVDATAMGMT_OPERATION_STATE_T memoryOperation; ///< Memory operation. + RECORD_JOBS_STATE_T recordJob; ///< Record job (i.e sector 0). +} PROCESS_RECORD_JOB_T; + void initNVDriver( void ); void eraseSector( U32* startAddress ); void writeSector( U32* startAddress, U08* bufferAddress, U32 bufferSize ); Index: firmware/App/Services/NVMgmtDD.c =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Services/NVMgmtDD.c (.../NVMgmtDD.c) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Services/NVMgmtDD.c (.../NVMgmtDD.c) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -12,10 +12,12 @@ * ***************************************************************************/ #include // For memcpy +#include "Common.h" #include "NVDriver.h" #include "NVMgmtDD.h" #include "NVMsgQ.h" #include "NVRecordsDD.h" +#include "Timers.h" /// NVDataMgmt Exec states enumeration. typedef enum NVDataMgmt_Exec_State @@ -38,13 +40,15 @@ } RECORD_VALIDITY_CHECK_T; #define COMMAND_TIME_OUT (1 * MS_PER_SECOND) ///< Timeout for an EEPROM or RTC command in ms. +/// EEPROM functions use the buffer length as the size of U32. So before send the length to any of FAPI functions, it should be divided by 4. +#define EEPROM_OPS_SIZE_OF_CONVERTER 4 - static NVDATAMGMT_EXEC_STATE_T nvDataMgmtExecState; ///< NVDataMgmt exec state variable. static volatile BOOL powerOffIsImminent; ///< Power off warning has been signaled. Non-volatile memory operations should be completed ASAP and then ceased. static RECORD_VALIDITY_CHECK_T writtenRecordStatus; ///< Record data write validity check. static U08 writtenRecordCheckBuffer[ MAX_EEPROM_WRITE_BUFFER_BYTES ]; ///< Written record validity check buffer. static U32 currentTime; ///< Current time. +static U32 recordAddressOffset; ///< Record address offset. // Exec functions static NVDATAMGMT_EXEC_STATE_T handleExecIdleState( void ); @@ -63,6 +67,7 @@ currentTime = 0; writtenRecordStatus = NVDATAMGMT_RECORD_NOT_CHECKED; + recordAddressOffset = 0; initNVDriver(); initNVMsgQ(); @@ -136,17 +141,20 @@ NVDATAMGMT_OPERATION_STATE_T ops; U32 startAddress; U08* bufferAddress; + PROCESS_RECORD_JOB_T recordCurrentJob; + RECORD_JOBS_STATE_T job; + PROCESS_RECORD_SPECS_T jobSpecs; // If power off command has been issued, do not process any new jobs if ( powerOffIsImminent != TRUE ) { // If the record processing queue is not empty, process the queues - if ( ( FALSE == isRecordQueueEmpty() ) && ( TRUE == areResourcesAvailableForNextJob() ) ) + if ( ( FALSE == isRecordQueueEmpty() ) && ( TRUE == isFlashReady() ) ) { dequeueRecordJob(); - - RECORD_JOBS_STATE_T job = recordCurrentJob.recordJob; - PROCESS_RECORD_SPECS_T jobSpecs = RECORDS_SPECS[ job ]; + recordCurrentJob = getCurrentProcessRecordJob(); + job = recordCurrentJob.recordJob; + jobSpecs = getProcessRecord( job ); // Set the record address offset to 0 since a job will just be started recordAddressOffset = 0; areQueuesNotEmpty = TRUE; @@ -223,8 +231,9 @@ { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_WRITE_TO_EEPROM; BOOL timeoutStatus = didCommandTimeout( state ); + PROCESS_RECORD_JOB_T recordCurrentJob = getCurrentProcessRecordJob(); RECORD_JOBS_STATE_T job = recordCurrentJob.recordJob; - PROCESS_RECORD_SPECS_T jobSpecs = RECORDS_SPECS [ job ]; + PROCESS_RECORD_SPECS_T jobSpecs = getProcessRecord ( job ); // Check if the fapi has finished if ( TRUE == isFlashReady() ) @@ -311,8 +320,9 @@ { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_VERIFY_EEPROM_WRITE; BOOL timeoutStatus = didCommandTimeout( state ); + PROCESS_RECORD_JOB_T recordCurrentJob = getCurrentProcessRecordJob(); RECORD_JOBS_STATE_T job = recordCurrentJob.recordJob; - PROCESS_RECORD_SPECS_T jobSpecs = RECORDS_SPECS [ job ]; + PROCESS_RECORD_SPECS_T jobSpecs = getProcessRecord ( job ); // Check if the write job is EEPROM or RTC RAM if ( TRUE == isFlashReady() ) @@ -361,253 +371,17 @@ *************************************************************************/ void resetNVDataMgmtPOSTState( void ) { - nvDataMgmtSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; - nvDataMgmtSelfTestState = NVDATAMGMT_SELF_TEST_STATE_READ_RECORDS; + updateNVSelfTestResult( SELF_TEST_STATUS_IN_PROGRESS ); + updateNVSelfTestState( NVDATAMGMT_SELF_TEST_STATE_READ_RECORDS ); } -/*********************************************************************//** - * @brief - * The getNVRecord2Driver function copies the requested non-volatile - * data into the provided buffer by the caller. The function then checks if - * the non-volatile data is valid. If the data is not valid, it raises the - * provided alarm by the caller. - * @details Inputs: ddCalibrationRecord - * @details Outputs: ddCalibrationRecord - * @param nvData the non-volatile data to be copied - * @param bufferAddress the address of the provided buffer by the caller - * @param bufferLength the length of the provided buffer by the caller - * @param numOfSnsrs2Check the number of sensors to check in a array of sensors called - * @param nvAlarm the corresponding alarm of the non-volatile data to be raised - * if the data is not valid - * @return TRUE if the non-volatile data is valid otherwise, FALSE - *************************************************************************/ -BOOL getNVRecord2Driver( NV_DATA_T nvData, U08* bufferAddress, U32 bufferLength, U08 numOfSnsrs2Check, ALARM_ID_T nvAlarm ) +BOOL isNVExecStateIdle ( void ) { - U08 i; - U08* nvDataStartPtr = 0; - BOOL isNVDataInvalid = FALSE; - U32 nvDataLength = 0; - - switch ( nvData ) - { - - case GET_CAL_PRESSURE_SENOSRS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord.pressureSensors[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_LOAD_CELL_SENSORS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.loadCellsCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.loadCellsCalRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.loadCellsCalRecord.loadCells[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_FLOW_SENSORS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.flowSensorsCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.flowSensorsCalRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.flowSensorsCalRecord.flowSensors[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_ACID_CONCENTREATES: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord.acidConcentrate[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_BICARB_CONCENTRATES: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord.bicarbConcentrate[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_ACCEL_SENSORS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.accelerometerSensorCalRecord; - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.accelerometerSensorCalRecord.calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_TEMP_SENSORS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord.tempSensors[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_RSRVRS_VOL_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.reservoirVolumesRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.reservoirVolumesRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.reservoirVolumesRecord.reservoir[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_HEATING_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.heatingCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.heatingCalRecord ); - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.heatingCalRecord.calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_DRAIN_LINE_VOLUME_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.drainLineVolumeRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.drainLineVolumeRecord ); - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.drainLineVolumeRecord.calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_RO_PUMP_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.roPumpRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.roPumpRecord ); - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.roPumpRecord.calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_CONCENTRATE_PUMPS_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord.concentratePumps[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_DRAIN_PUMP_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.drainPumpRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.drainPumpRecord ); - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.drainPumpRecord.calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_FANS_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.fansRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.fansRecord ); - for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.fansRecord.fans[ i ].calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_PRE_RO_PURGE_VOLUME_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.preROPurgeVolumeRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.preROPurgeVolumeRecord ); - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.preROPurgeVolumeRecord.calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_FILTERS_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.filtersRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.filtersRecord ); - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.carbonFilter.calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.carbonPolishFilter.calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.roFilter.calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.sedimentFilter.calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.ultraFilter.calibrationTime ? TRUE : FALSE ); - break; - - case GET_CAL_FILL_CONDUCTIVITIES_RECORD: - { - DG_FILL_COND_OPS_T fillOps; - - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues ); - - for ( i = 0; i < numOfSnsrs2Check; i++ ) - { - for ( fillOps = FILL_COND_NORMAL_OP; fillOps < NUM_OF_FILL_COND_TEST; fillOps++ ) - { - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues[ i ][ fillOps ].calibrationTime ? TRUE : FALSE ); - } - } - } - break; - - case GET_INF_HEATERS_RECORD: - nvDataStartPtr = (U08*)&ddHeatersInfoGroup.ddHeatersInfo; - nvDataLength = sizeof( ddHeatersInfoGroup.ddHeatersInfo ); - break; - - case GET_SYS_RECORD: - nvDataStartPtr = (U08*)&ddSystemGroup.ddSystemRecord; - nvDataLength = sizeof( ddSystemGroup.ddSystemRecord ); - break; - - case GET_SRV_RECORD: - nvDataStartPtr = (U08*)&ddServiceGroup.ddServiceRecord; - nvDataLength = sizeof( ddServiceGroup.ddServiceRecord ); - break; - - case GET_SRR_RECORD: - nvDataStartPtr = (U08*)&ddScheduledRunsGroup.ddScheduledRun; - nvDataLength = sizeof( ddScheduledRunsGroup.ddScheduledRun ); - break; - - case GET_USAGE_RECORD: - nvDataStartPtr = (U08*)&ddUsageInfoGroup.ddUsageInfo; - nvDataLength = sizeof( ddUsageInfoGroup.ddUsageInfo ); - break; - - default: -// SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_NV_RECORD_SELECTED, nvData ); - break; - } - - // Make sure the provided buffer length is >= NV Data Length in the NV data management so the memory of the other variables is not - // overridden. - if ( ( bufferLength >= nvDataLength ) && ( nvDataStartPtr != 0 ) ) - { - // Copy the data into the provided buffer - memcpy( bufferAddress, nvDataStartPtr, bufferLength ); - } - - // Check if the non-volatile data is valid and if not raise the alarm - if ( TRUE == isNVDataInvalid ) - { - // If no alarm has been provided to raise, just set the variable as TRUE - if ( ALARM_ID_NO_ALARM == nvAlarm ) - { - isNVDataInvalid = FALSE; - } - else - { -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAL_CHECK ) != SW_CONFIG_ENABLE_VALUE ) -#endif - { - activateAlarmNoData( nvAlarm ); - } -#ifndef _RELEASE_ - else - { - isNVDataInvalid = FALSE; - } -#endif - } - } - - // Reverse the polarity to signal the outside users that the calibration has passed. - return ( FALSE == isNVDataInvalid ? TRUE : FALSE ); + return ( NVDATAMGMT_EXEC_STATE_IDLE == nvDataMgmtExecState ); } -#ifndef _RELEASE_ /*********************************************************************//** * @brief - * The getSoftwareConfigStatus function returns the status of a software - * configuration. - * @details Inputs: swConfigsList - * @details Outputs: none - * @param config which is the configuration of the that its status is requested - * @return status of the software configuration (0 or 1) - *************************************************************************/ -U08 getSoftwareConfigStatus( SOFTWARE_CONFIG_T config ) -{ - U08 value = 0; - - // If the build is not a release, get the value from the software configurations list - // If the build is a release, the configuration not matter what its value is kept in - // the NV RAM, it returns a 0 which is the configuration is disabled - value = ddSWConfigGroup.ddSWConfigsRecord.swConfigs[ config ]; - - return value; -} -#endif - -/*********************************************************************//** - * @brief * The didCommandTimedout checks whether the a command whether RTC RAM or * EEPROM has timedout. If it has timedout, it sets the alarm and turns * flag to TRUE. @@ -630,48 +404,5 @@ } -/*********************************************************************//** - * @brief - * The testSetNVRecordCRCOverride overrides the non-volatile record CRC override. - * @details Inputs: none - * @details Outputs: none - * @param job the job to override its CRC (i.e. calibration record) - * @param crc the value its CRC to be overridden - * @return TRUE if the job was scheduled successfully otherwise, FALSE - *************************************************************************/ -BOOL testSetNVRecordCRCOverride( U32 job, U16 crc ) -{ - BOOL status = FALSE; - RECORD_JOBS_STATE_T nvJob = (RECORD_JOBS_STATE_T)job; - switch( nvJob ) - { - case NVDATAMGMT_CALIBRATION_RECORD: - ddCalibrationRecord.crc = crc; - status = enqueueSector0Records(); - break; - case NVDATAMGMT_SYSTEM_RECORD: - ddSystemGroup.ddSystemRecord.crc = crc; - status = enqueueSector0Records(); - break; - - case NVDATAMGMT_SERVICE_RECORD: - ddServiceGroup.ddServiceRecord.crc = crc; - status = enqueueSector0Records(); - break; - - case NVDATAMGMT_USAGE_INFO_RECORD: - ddUsageInfoGroup.ddUsageInfo.crc = crc; - if ( getAvailableRecordQueueCount() > 0 ) - { - enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_USAGE_INFO_RECORD ); - status = TRUE; - } - break; - - } - - return status; -} - Index: firmware/App/Services/NVMgmtDD.h =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Services/NVMgmtDD.h (.../NVMgmtDD.h) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Services/NVMgmtDD.h (.../NVMgmtDD.h) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -27,13 +27,6 @@ void signalPowerOffWarning( void ); void execNVDataMgmt( void ); void resetNVDataMgmtPOSTState( void ); -BOOL getNVRecord2Driver( NV_DATA_T nvData, U08* bufferAddress, U32 bufferLength, U08 numOfSnsrs2Check, ALARM_ID_T nvAlarm ); +BOOL isNVExecStateIdle ( void ); - -#ifndef _RELEASE_ -U08 getSoftwareConfigStatus( SOFTWARE_CONFIG_T config ); -#endif - -BOOL testSetNVRecordCRCOverride( U32 job, U16 crc ); - #endif /* _NV_MGMT_DD_H_ */ Index: firmware/App/Services/NVMsgQ.c =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Services/NVMsgQ.c (.../NVMsgQ.c) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Services/NVMsgQ.c (.../NVMsgQ.c) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -15,7 +15,12 @@ #include // For memcpy #include // For ceilf function +#include "Common.h" #include "NVMsgQ.h" +#include "NVRecordsDD.h" +#include "TaskGeneral.h" +#include "Timers.h" +#include "Utilities.h" // For crc calculation #define QUEUE_MAX_SIZE 20U ///< Max queue size. #define QUEUE_START_INDEX 0U ///< Queue start index. @@ -37,13 +42,6 @@ U32 length; ///< Length of a buffer. } MEMORY_OPS_T; -/// Process records job structure -typedef struct -{ - NVDATAMGMT_OPERATION_STATE_T memoryOperation; ///< Memory operation. - RECORD_JOBS_STATE_T recordJob; ///< Record job (i.e sector 0). -} PROCESS_RECORD_JOB_T; - /// NVDataMgmt process records states typedef enum NVDataMgmt_Process_Records_States { @@ -66,8 +64,6 @@ static U08 recordQueueCount; ///< Record queue count. static PROCESS_RECORD_JOB_T recordCurrentJob; ///< Record queue current job. -static U32 recordAddressOffset; ///< Record address offset. -static MEMORY_OPS_T currentJob; ///< Current job. static NVDATAMGMT_RECORDS_READ_STATUS_T recordsReadStatus; ///< NVDataMgmt records read status. static BOOL isNewCalAvailable; ///< Signal to indicate whether a new calibration data is available. @@ -95,7 +91,6 @@ recordQueueRearIndex = QUEUE_START_INDEX; recordQueueFrontIndex = QUEUE_START_INDEX; recordQueueCount = 0; - recordAddressOffset = 0; recordsReadStatus = NVDATAMGMT_RECORDS_NOT_STARTED; isNewCalAvailable = FALSE; @@ -180,7 +175,7 @@ hasPublishRecordBeenRequested = FALSE; // Get the record specifications to find the size of the job - PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS [ recordToPublish ]; + 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. @@ -218,15 +213,15 @@ if ( ++calSendDataIntervalCounter >= CAL_DATA_SEND_INTERVAL_COUNT ) { // Set to default cal data payload length - U32 length = NUM_OF_BYTES_PER_CAL_PAYLOAD; +// U32 length = NUM_OF_BYTES_PER_CAL_PAYLOAD; - PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS [ recordToPublish ]; + 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 ( ( calPublishMessageCount + 1 ) == calPublishTotalMessages ) { - length = recordSpec.sizeofJob - ( calPublishMessageCount * NUM_OF_BYTES_PER_CAL_PAYLOAD ); +// length = recordSpec.sizeofJob - ( calPublishMessageCount * NUM_OF_BYTES_PER_CAL_PAYLOAD ); } // Find the new location of the pointer which is the start of the calibration payload to be sent @@ -236,28 +231,28 @@ { case NVDATAMGMT_CALIBRATION_RECORD: // Pass the information to the CAN bus - sendDGCalibrationRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); +// sendDGCalibrationRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; case NVDATAMGMT_SYSTEM_RECORD: // Pass the information to the CAN bus - sendDGSystemRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); +// sendDGSystemRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; case NVDATAMGMT_SERVICE_RECORD: // Pass the information to the CAN bus - sendDGServiceRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); +// sendDGServiceRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; #ifndef _RELEASE_ case NVDATAMGMT_SW_CONFIG_RECORD: - sendDGSWConfigRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); +// sendDGSWConfigRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; #endif case NVDATAMGMT_USAGE_INFO_RECORD: - sendDGUsageInfoRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); +// sendDGUsageInfoRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; default: @@ -328,42 +323,6 @@ /*********************************************************************//** * @brief - * The areResourcesAvailableForNextJob checks whether the resources such as - * semaphore for RTC is available prior to dequeuing the job to be processed. - * @details Inputs: recordQueueFrontIndex - * @details Outputs: none - * @return TRUE if the resources are available otherwise, FALSE - *************************************************************************/ -BOOL areResourcesAvailableForNextJob( void ) -{ - U32 tempIndex; - PROCESS_RECORD_JOB_T tempJob; - BOOL status = FALSE; - - // Initialize the structure per CppCheck run - tempJob.memoryOperation = NVDATAMGMT_NONE; - tempJob.recordJob = NVDATAMGMT_CALIBRATION_RECORD; - - _disable_IRQ(); - tempIndex = recordQueueFrontIndex; - - if ( FALSE == isRecordQueueEmpty() ) - { - tempJob = recordJobQueue[ tempIndex ]; - } - _enable_IRQ(); - - if ( TRUE == isFlashReady() ) - { - status = TRUE; - } - - - return status; -} - -/*********************************************************************//** - * @brief * The isRecordQueueEmpty checks whether the queue is empty and if it is * empty, it will return a false. * @details Inputs: recordQueueCount @@ -382,6 +341,18 @@ return isEmpty; } +BOOL isRecordQueueFull( void ) +{ + BOOL isFull = FALSE; + + if ( recordQueueCount >= ( QUEUE_MAX_SIZE - 1 ) ) + { + isFull = TRUE; + } + + return isFull; +} + /*********************************************************************//** * @brief * The getAvailableRecordQueueCount returns the number of available record @@ -516,7 +487,7 @@ if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) { // Define a pointer that points to the DG calibration record - PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS[ job ]; + PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( job ); U08* ptr = recordSpec.structAddressPtr; // Offset the pointer to length that we should start writing from @@ -603,3 +574,23 @@ { return isNewCalAvailable; } + +void updateNewCalAvailableFlag( BOOL value ) +{ + isNewCalAvailable = value; +} + +void updateRecordReadStatus( NVDATAMGMT_RECORDS_READ_STATUS_T status ) +{ + recordsReadStatus = status; +} + +void updateCalStartTimer( U32 value ) +{ + newCalStartTimer = value; +} + +PROCESS_RECORD_JOB_T getCurrentProcessRecordJob ( void ) +{ + return recordCurrentJob; +} Index: firmware/App/Services/NVMsgQ.h =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Services/NVMsgQ.h (.../NVMsgQ.h) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Services/NVMsgQ.h (.../NVMsgQ.h) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -15,8 +15,9 @@ #ifndef _NV_MSG_Q_H_ #define _NV_MSG_Q_H_ +#include "NVDriver.h" #include "Common.h" -#indluce "DDDefs.h" +#include "DDDefs.h" #define MIN_JOBS_NEEDED_FOR_SECTOR_0 5U ///< Min queue count needed to erase and write all (5) records back in sector 0. #define DD_USAGE_INFO_START_ADDRESS 0x00000030 /* 48 */ ///< DG usage info start address in RTC RAM (48). @@ -28,31 +29,6 @@ #define SERVICE_RECORD_NV_MEM_START_ADDRESS (BANK7_SECTOR0_START_ADDRESS + BITS_12_FULL_SCALE) ///< Service record storage start address in NV memory. #define CAL_RECORD_NV_MEM_START_ADDRESS (SERVICE_RECORD_NV_MEM_START_ADDRESS + BITS_12_FULL_SCALE) ///< Calibration record storage start address in NV memory. -/// NVDataMgmt memory operation modes enumeration. -typedef enum NVDataMgmt_Operation -{ - NVDATAMGMT_NONE = 0, ///< Default mode to prevent any accidental ops. - NVDATAMGMT_WRITE, ///< Operation mode write. - NVDATAMGMT_READ, ///< Operation mode read. - NVDATAMGMT_ERASE_SECTOR, ///< Operation mode erase a sector (EEPROM). - NUM_OF_NVDATAMGMT_OPS_STATES ///< Total number of operation states. -} NVDATAMGMT_OPERATION_STATE_T; - -/// NVDataMgmt records' jobs states -typedef enum NVDataMgmt_Records_Jobs -{ - NVDATAMGMT_CALIBRATION_RECORD = 0, ///< NVDataMgmt process write calibration record. - NVDATAMGMT_SYSTEM_RECORD, ///< NVDataMgmt process write system record. - NVDATAMGMT_SERVICE_RECORD, ///< NVDataMgmt process service record. - NVDATAMGMT_SCHEDULED_RUNS_RECORD, ///< NVDataMgmt process scheduled runs record. - NVDATAMGMT_HEATERS_INFO_RECORD, ///< NVDataMgmt process heaters info record. - NVDATAMGMT_USAGE_INFO_RECORD, ///< NVDataMgmt process usage info record. -#ifndef _RELEASE_ - NVDATAMGMT_SW_CONFIG_RECORD, ///< NVDataMgmt process software record. -#endif - NUM_OF_NVDATMGMT_RECORDS_JOBS ///< Number of NVDataMgmt records jobs. -} RECORD_JOBS_STATE_T; - /// NVDataMgmt records read status typedef enum NVDataMgmt_NV_Records_Read_Status { @@ -63,41 +39,14 @@ NUM_OF_NVDATAMGMT_READ_RECORDS_STATES, ///< Number of NVDataMgmt read records states. } NVDATAMGMT_RECORDS_READ_STATUS_T; -/// Process records specifications structure -typedef struct -{ - U32 startAddress; ///< Jobs spec start address. - U32 sizeofJob; ///< Jobs spec size of job. - U32 maxWriteBufferSize; ///< Jobs max write allowed processing buffer size. - U32 maxReadBufferSize; ///< Jobs max read allowed processing buffer size. - U08* structAddressPtr; ///< Jobs structure address pointer. - U08* structCRCPtr; ///< Jobs structure CRC pointer. - DD_EVENT_ID_T nvEvent; ///< Jobs non-volatile DG event (i.e calibration, system). - -} PROCESS_RECORD_SPECS_T; - -// Process records specifications -const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { - // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Event calibration record update - {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddCalibrationRecord, (U08*)&ddCalibrationRecord.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD - {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SYSTEM_GROUP_T), (U08*)&ddSystemGroup, (U08*)&ddSystemGroup.crc, DD_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD - {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddServiceGroup, (U08*)&ddServiceGroup.crc, DD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD - {DD_SCHEDULED_RUNS_START_ADDRESS, sizeof(DD_SCHEDULED_RUNS_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SCHEDULED_RUNS_GROUP_T),(U08*)&ddScheduledRunsGroup, (U08*)&ddScheduledRunsGroup.crc, DD_EVENT_SCHEDULED_RUNS_UPDATE }, // NVDATAMGMT_SCHEDULER_RECORD - {DD_HEATERS_INFO_START_ADDRESS, sizeof(DD_HEATERS_INFO_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_HEATERS_INFO_GROUP_T), (U08*)&ddHeatersInfoGroup, (U08*)&ddHeatersInfoGroup.crc, DD_EVENT_HEATERS_INFO_UPDATE }, // NVDATAMGMT_HEATERS_INFO_RECORD - {DD_USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddUsageInfoGroup, (U08*)&ddUsageInfoGroup.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO_RECORD -#ifndef _RELEASE_ - {SW_CONFIGS_START_ADDRESS, sizeof(DD_SW_CONFIG_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SW_CONFIG_GROUP_T), (U08*)&ddSWConfigGroup, (U08*)&ddSWConfigGroup.crc, DD_EVENT_SW_CONFIG_UPDATE } // NVDATAMGMT_SW_CONFIG_RECORD -#endif -}; - void initNVMsgQ ( void ); void execNVDataMgmtProcessRecord( void ); // Record operations queue functions void enqueueRecordJob( NVDATAMGMT_OPERATION_STATE_T ops, RECORD_JOBS_STATE_T job ); void dequeueRecordJob( void ); -BOOL areResourcesAvailableForNextJob( void ); BOOL isRecordQueueEmpty( void ); +BOOL isRecordQueueFull( void ); U32 getAvailableRecordQueueCount( void ); BOOL enqueueSector0Records( void ); void enqueuePOSTReadRecords( void ); @@ -106,4 +55,10 @@ BOOL receiveRecordFromDialin( RECORD_JOBS_STATE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); BOOL isNewCalibrationRecordAvailable( void ); +void updateNewCalAvailableFlag( BOOL value ); +void updateRecordReadStatus( NVDATAMGMT_RECORDS_READ_STATUS_T status ); +void updateCalStartTimer( U32 value ); + +PROCESS_RECORD_JOB_T getCurrentProcessRecordJob ( void ); + #endif /* _NV_MSG_Q_H_ */ Index: firmware/App/Services/NVRecordsDD.c =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -13,8 +13,12 @@ ***************************************************************************/ #include // For memcpy +#include "Common.h" +#include "DDDefs.h" #include "NVMsgQ.h" #include "NVRecordsDD.h" +#include "NVMgmtDD.h" +#include "Timers.h" #include "Utilities.h" // For crc calculation // Data addresses and length in RTC RAM @@ -71,18 +75,6 @@ ((((RECORD_BYTE_SIZE(rcrd) / buf) + 1)) * buf) \ - RECORD_BYTE_SIZE(rcrd)) ///< DG padding length macro. - - - -/// NVDataMgmt self-test states enumeration. -typedef enum NVDataMgmt_Self_Test_States -{ - NVDATAMGMT_SELF_TEST_STATE_READ_RECORDS = 0, ///< Self test read records. - NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC, ///< Self test check CRC. - NVDATAMGMT_SELF_TEST_STATE_COMPLETE, ///< Self test complete. - NUM_OF_NVDATAMGMT_SELF_TEST_STATES ///< Total number of self-test states. -} NVDATAMGMT_SELF_TEST_STATE_T; - #pragma pack(push, 1) // ********** DD record structures ********** @@ -99,7 +91,6 @@ DD_RO_PUMP_CAL_RECORD_T roPumpRecord; ///< DG RO pump. DD_DRAIN_LINE_VOLUME_T drainLineVolumeRecord; ///< DG drain line volume. DD_PRE_RO_PURGE_VOLUME_T preROPurgeVolumeRecord; ///< DG RO purge volume. - DD_RESERVOIR_VOLUME_RECORD_T reservoirVolumesRecord; ///< DG reservoir volumes. DD_GENERIC_VOLUME_RECORD_T genericVolumeRecord; ///< DG generic volume (magic number because the value is unknown). DD_ACID_CONCENTRATES_RECORD_T acidConcentratesRecord; ///< DG acid concentrates. DD_BICARB_CONCENTRATES_RECORD_T bicarbConcentratesRecord; ///< DG bicarb concentrates. @@ -130,31 +121,31 @@ typedef struct { DD_SERVICE_RECORD_T ddServiceRecord; ///< DG service record. - U08 padding[ RECORD_PADDING_LENGTH(DD_SERVICE_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< DG service group padding. + U08 padding[ RECORD_PADDING_LENGTH(DD_SERVICE_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG service group padding. U16 crc; ///< CRC for the DG service structure. } DD_SERVICE_GROUP_T; /// DG scheduler record structure typedef struct { DD_SCHEDULED_RUN_RECORD_T ddScheduledRun; ///< DG scheduled runs. - U08 padding[ RECORD_PADDING_LENGTH(DD_SCHEDULED_RUN_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< DG scheduled run group padding. + U08 padding[ RECORD_PADDING_LENGTH(DD_SCHEDULED_RUN_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG scheduled run group padding. U16 crc; ///< CRC for the DG scheduled runs structure. } DD_SCHEDULED_RUNS_GROUP_T; /// DG usage record structure typedef struct { DD_USAGE_INFO_RECORD_T ddUsageInfo; ///< DG usage info record. - U08 padding[ RECORD_PADDING_LENGTH(DD_USAGE_INFO_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< DG scheduled run group padding. + U08 padding[ RECORD_PADDING_LENGTH(DD_USAGE_INFO_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG scheduled run group padding. U16 crc; ///< CRC for the DG usage info structure. } DD_USAGE_INFO_GROUP_T; /// DG heaters record typedef struct { DD_HEATERS_RECORD_T ddHeatersInfo; ///< DG heaters info record. - U08 padding[ RECORD_PADDING_LENGTH(DD_HEATERS_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< DG heater info group padding. + U08 padding[ RECORD_PADDING_LENGTH(DD_HEATERS_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG heater info group padding. U16 crc; ///< CRC for the DG heaters info structure. } DD_HEATERS_INFO_GROUP_T; @@ -165,7 +156,7 @@ DD_SW_CONFIG_RECORD_T ddSWConfigsRecord; ///< Software configurations record. // Since the software configurations are one byte, Num_of was used for the length of the lists - U08 padding[ RECORD_PADDING_LENGTH(DD_SW_CONFIG_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< Software configurations group padding. + U08 padding[ RECORD_PADDING_LENGTH(DD_SW_CONFIG_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< Software configurations group padding. U16 crc; ///< Software configurations CRC. } DD_SW_CONFIG_GROUP_T; #endif @@ -183,6 +174,20 @@ static DD_SW_CONFIG_GROUP_T ddSWConfigGroup; ///< DG Software configurations structure(including padding and final CRC). #endif +// Process records specifications +const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { + // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Event calibration record update + {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddCalibrationRecord, (U08*)&ddCalibrationRecord.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD + {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SYSTEM_GROUP_T), (U08*)&ddSystemGroup, (U08*)&ddSystemGroup.crc, DD_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD + {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddServiceGroup, (U08*)&ddServiceGroup.crc, DD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD + {DD_SCHEDULED_RUNS_START_ADDRESS, sizeof(DD_SCHEDULED_RUNS_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SCHEDULED_RUNS_GROUP_T),(U08*)&ddScheduledRunsGroup, (U08*)&ddScheduledRunsGroup.crc, DD_EVENT_SCHEDULED_RUNS_UPDATE }, // NVDATAMGMT_SCHEDULER_RECORD + {DD_HEATERS_INFO_START_ADDRESS, sizeof(DD_HEATERS_INFO_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_HEATERS_INFO_GROUP_T), (U08*)&ddHeatersInfoGroup, (U08*)&ddHeatersInfoGroup.crc, DD_EVENT_HEATERS_INFO_UPDATE }, // NVDATAMGMT_HEATERS_INFO_RECORD + {DD_USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddUsageInfoGroup, (U08*)&ddUsageInfoGroup.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO_RECORD +#ifndef _RELEASE_ + {SW_CONFIGS_START_ADDRESS, sizeof(DD_SW_CONFIG_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SW_CONFIG_GROUP_T), (U08*)&ddSWConfigGroup, (U08*)&ddSWConfigGroup.crc, DD_EVENT_SW_CONFIG_UPDATE } // NVDATAMGMT_SW_CONFIG_RECORD +#endif +}; + static NVDATAMGMT_SELF_TEST_STATE_T nvDataMgmtSelfTestState; ///< NVDataMgmt self-test state variable. static SELF_TEST_STATUS_T nvDataMgmtSelfTestResult; ///< NVDataMgmt self-test result. static U32 usageWriteTries; ///< Usage write tries. @@ -201,14 +206,14 @@ static BOOL isDDROPumpRecordValid( DD_RO_PUMP_CAL_RECORD_T* record ); static BOOL isDDPreROPurgeVolumeRecordValid( DD_PRE_RO_PURGE_VOLUME_T* record ); static BOOL isDDDrainLineVolRecordValid( DD_DRAIN_LINE_VOLUME_T* record ); -static BOOL isDDReservoirVolRecordValid( DD_RESERVOIR_VOLUME_DATA_T* record ); static BOOL isDDGenericVolRecordValid( DD_GENERIC_VOLUME_DATA_T* record ); static BOOL isDDAcidConcentrateRecordValid( DD_ACID_CONCENTRATE_T* record ); static BOOL isDDBicarbConcentrateRecordValid( DD_BICARB_CONCENTRATE_T* record ); static BOOL isDDFilterRecordValid( DD_FILTER_CAL_RECORD_T* record ); static BOOL isDDFanRecordValid( DD_FAN_CAL_RECORD_T* record ); static BOOL isDDAccelerometerSensorRecordValid( DD_ACCEL_SENSOR_CAL_RECORD_T* record ); static BOOL isDDHeatingCalRecordValid( DD_HEATING_CAL_RECORD_T* record ); +static BOOL isDDFillConductiviesRecordValid( DD_ACID_BICARB_FILL_COND_VALUES_T* record, DD_ACID_TYPES_T acidType, DD_FILL_COND_OPS_T operation ); #ifndef _RELEASE_ static BOOL isSWConfigRecordValid( void ); #endif @@ -254,6 +259,11 @@ return nvDataMgmtSelfTestResult; } +PROCESS_RECORD_SPECS_T getProcessRecord( RECORD_JOBS_STATE_T job ) +{ + return RECORDS_SPECS[ job ]; +} + /*********************************************************************//** * @brief * The handleSelfTestReadRecords waits for the records to be read @@ -267,9 +277,9 @@ // Check if the queues are empty and the exec state machine is in Idle meaning all the records have been read and the state machine // is back at Idle so even the last job in the queue has been processed - if ( ( TRUE == isRecordQueueEmpty() ) && ( NVDATAMGMT_EXEC_STATE_IDLE == nvDataMgmtExecState ) ) + if ( ( TRUE == isRecordQueueEmpty() ) && ( TRUE == isNVExecStateIdle() ) ) { - recordsReadStatus = NVDATAMGMT_RECORDS_READ; + updateRecordReadStatus( NVDATAMGMT_RECORDS_READ ); state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; } @@ -295,7 +305,7 @@ BOOL hasSWConfigRecordPassed = TRUE; BOOL hasUsageRecordPassed = TRUE; - recordsReadStatus = NVDATAMGMT_RECORDS_CRC_CHECKED; + updateRecordReadStatus( NVDATAMGMT_RECORDS_CRC_CHECKED ); // Check all the calibration groups haveCalGroupsPassed = isDDCalibrationRecordValid(); @@ -334,8 +344,8 @@ // Check if the records' entire CRCs as well as the individual CRCs passed if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) && ( TRUE == hasInstitutionalRecordPassed ) ) { - newCalStartTimer = getMSTimerCount(); - isNewCalAvailable = TRUE; + updateCalStartTimer( getMSTimerCount() ); + updateNewCalAvailableFlag( TRUE ); nvDataMgmtSelfTestResult = SELF_TEST_STATUS_PASSED; } @@ -487,7 +497,7 @@ // CRC did not pass so set all values to default ddServiceGroup.ddServiceRecord.lastServiceEpochDate = 0; ddServiceGroup.ddServiceRecord.serviceIntervalSeconds = RECORD_DEFAULT_SERVICE_INTERVAL_S; - ddServiceGroup.ddServiceRecord.lastResetTimeEpoch = getRTCTimestamp(); +// ddServiceGroup.ddServiceRecord.lastResetTimeEpoch = getRTCTimestamp(); ddServiceGroup.ddServiceRecord.crc = crc16 ( (U08*)&ddServiceGroup.ddServiceRecord, sizeof( DD_SERVICE_RECORD_T ) - sizeof( U16 ) ); ddServiceGroup.crc = crc16 ( (U08*)&ddServiceGroup, sizeof( DD_SERVICE_GROUP_T ) - sizeof( U16 ) ); status = FALSE; @@ -519,7 +529,7 @@ ddUsageInfoGroup.ddUsageInfo.lastHeatDisCompleteDateEpoch = 0; ddUsageInfoGroup.ddUsageInfo.roWaterGenSinceLastServiceL = 0.0F; ddUsageInfoGroup.ddUsageInfo.roWaterGenTotalL = 0.0F; - ddUsageInfoGroup.ddUsageInfo.lastResetTimeEpoch = getRTCTimestamp(); +// ddUsageInfoGroup.ddUsageInfo.lastResetTimeEpoch = getRTCTimestamp(); ddUsageInfoGroup.ddUsageInfo.crc = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfo, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); ddUsageInfoGroup.crc = crc16( (U08*)&ddUsageInfoGroup, sizeof( DD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); status = FALSE; @@ -635,13 +645,6 @@ isHardwareRecordValid = isDDDrainLineVolRecordValid( drainLineVol ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; - DD_RESERVOIR_VOLUME_RECORD_T* reservoirVol = &ddCalibrationRecord.ddCalibrationGroups.reservoirVolumesRecord; - for ( i = 0; i < NUM_OF_CAL_DATA_RSRVRS; i++ ) - { - isHardwareRecordValid = isDDReservoirVolRecordValid( &reservoirVol->reservoir[ i ] ); - isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; - } - DD_GENERIC_VOLUME_RECORD_T* genericVol = &ddCalibrationRecord.ddCalibrationGroups.genericVolumeRecord; for ( i = 0; i < GENERIC_VOL_RESERVED_SPACE_COUNT; i++ ) { @@ -844,38 +847,6 @@ /*********************************************************************//** * @brief - * The isDDReservoirVolRecordValid function checks whether the calibration - * record of reservoir volume is valid or not. - * @details Inputs: none - * @details Outputs: none - * @param record: DD_RESERVOIR_VOLUME_DATA_T pointer - * @return TRUE if the record is valid otherwise FALSE - *************************************************************************/ -static BOOL isDDReservoirVolRecordValid( DD_RESERVOIR_VOLUME_DATA_T* record ) -{ - BOOL status = TRUE; - U16 calcCRC = crc16 ( (U08*)record, sizeof(DD_RESERVOIR_VOLUME_DATA_T) - sizeof(U16) ); - U16 recordCRC = record->crc; - - if ( calcCRC != recordCRC ) - { - // CRC did not pass so set all values to default - record->maxResidualFluid = RECORD_DEFAULT_CONST; - record->normalFillVolume = RECORD_DEFAULT_CONST; - record->rsrvrUnfilledWeight = EMPTY_RESERVOIR_WEIGHT_GRAMS; - record->rsrvrVolume = RECORD_DEFAULT_CONST; - record->calibrationTime = RECORD_DEFAULT_TIME; - record->crc = crc16 ( (U08*)record, sizeof(DD_RESERVOIR_VOLUME_DATA_T) - sizeof(U16) ); - - // Set the to FALSE since the record is not valid - status = FALSE; - } - - return status; -} - -/*********************************************************************//** - * @brief * The isDDGenericVolRecordValid function checks whether the calibration * record of generic volume is valid or not. * @details Inputs: none @@ -1086,6 +1057,99 @@ /*********************************************************************//** * @brief + * The isDGFillConductiviesRecordValid function checks whether fill conductivity + * record is valid or not. + * @details Inputs: none + * @details Outputs: none + * @param record: DG_ACID_BICARB_FILL_COND_VALUES_T pointer containing the + * fill conductivities of acid and bicrab + * @param operation which is the type fill operation that is check (e.g. normal ops) + * @param acidType whcih is the type of acid that its values are checked (e.g. 0-1251-1) + * @return TRUE if the record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDDFillConductiviesRecordValid( DD_ACID_BICARB_FILL_COND_VALUES_T* record, DD_ACID_TYPES_T acidType, DD_FILL_COND_OPS_T operation ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16 ( (U08*)record, sizeof(DD_ACID_BICARB_FILL_COND_VALUES_T) - sizeof(U16) ); + U16 recordCRC = record->crc; + + if ( calcCRC != recordCRC ) + { + F32 acidSensorCond = 0.0F; + F32 bicarbSensorCond = 0.0F; + + switch ( operation ) + { + case FILL_COND_NORMAL_OP: + switch ( acidType ) + { + case ACID_08_1251_1: + acidSensorCond = DEFAULT_FILL_1251_1_ACID_SNSR_US_PER_CM; + bicarbSensorCond = DEFAULT_FILL_1251_1_BIC_SNSR_US_PER_CM; + break; + + case ACID_08_2251_0: + acidSensorCond = DEFAULT_FILL_2251_0_ACID_SNSR_US_PER_CM; + bicarbSensorCond = DEFAULT_FILL_2251_0_BIC_SNSR_US_PER_CM; + break; + + case ACID_08_3251_9: + acidSensorCond = DEFAULT_FILL_3251_9_ACID_SNSR_US_PER_CM; + bicarbSensorCond = DEFAULT_FILL_3251_9_BIC_SNSR_US_PER_CM; + break; + + default: + // TODO software fault + break; + } + break; + + case FILL_COND_ACID_TEST: + switch ( acidType ) + { + case ACID_08_1251_1: + acidSensorCond = DEFAULT_ACID_TEST_1251_1_US_PER_CM; + bicarbSensorCond = DEFAULT_ACID_TEST_1251_1_US_PER_CM; + break; + + case ACID_08_2251_0: + acidSensorCond = DEFAULT_ACID_TEST_2251_0_US_PER_CM; + bicarbSensorCond = DEFAULT_ACID_TEST_2251_0_US_PER_CM; + break; + + case ACID_08_3251_9: + acidSensorCond = DEFAULT_ACID_TEST_3251_9_US_PER_CM; + bicarbSensorCond = DEFAULT_ACID_TEST_3251_9_US_PER_CM; + break; + + default: + // TODO software fault + break; + } + break; + + case FILL_COND_BICARB_TEST: + acidSensorCond = DEFAULT_BIC_TEST_ACID_SNSR_US_PER_CM; + bicarbSensorCond = DEFAULT_BIC_TEST_BIC_SNSR_US_PER_CM; + break; + } + + // CRC did not pass so set all values to default + record->acidConduSPerCM = acidSensorCond; + record->bicarbConduSPerCM = bicarbSensorCond; + record->calibrationTime = RECORD_DEFAULT_TIME; + record->crc = crc16 ( (U08*)record, sizeof(DD_ACID_BICARB_FILL_COND_VALUES_T) - sizeof(U16) ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + + +/*********************************************************************//** + * @brief * The setLastDisinfectDate sets a queue job to write the last time that DG * was disinfected. * @details Inputs: dgUsageInfoGroup @@ -1094,49 +1158,49 @@ * @param epochTime last disinfect time in epoch * @return TRUE if queue is not full *************************************************************************/ -BOOL setLastDisinfectDate( DG_USAGE_INFO_ITEMS_T disinfect, U32 epochTime ) +BOOL setLastDisinfectDate( DD_USAGE_INFO_ITEMS_T disinfect, U32 epochTime ) { BOOL status = FALSE; - if ( FALSE == isQueueFull() ) + if ( FALSE == isRecordQueueFull() ) { switch ( disinfect ) { case USAGE_INFO_BASIC_FLUSH: - dgUsageInfoGroup.dgUsageInfo.lastBasicFlushCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfo.lastBasicFlushCompleteDateEpoch = epochTime; break; case USAGE_INFO_CHEM_DIS_START: - dgUsageInfoGroup.dgUsageInfo.lastChemDisStartDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfo.lastChemDisStartDateEpoch = epochTime; break; case USAGE_INFO_CHEM_DIS: - dgUsageInfoGroup.dgUsageInfo.lastChemDisCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfo.lastChemDisCompleteDateEpoch = epochTime; break; case USAGE_INFO_CHEM_FLUSH: - dgUsageInfoGroup.dgUsageInfo.lastChemDisFlushCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfo.lastChemDisFlushCompleteDateEpoch = epochTime; break; case USAGE_INFO_HEAT_DIS: - dgUsageInfoGroup.dgUsageInfo.lastHeatDisCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfo.lastHeatDisCompleteDateEpoch = epochTime; break; case USAGE_INFO_FILTER_FLUSH: - dgUsageInfoGroup.dgUsageInfo.lastFilterFlushCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfo.lastFilterFlushCompleteDateEpoch = epochTime; break; case USAGE_INFO_HEAT_DIS_ACTIVE_COOL: - dgUsageInfoGroup.dgUsageInfo.lastHeatActiveCoolCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfo.lastHeatActiveCoolCompleteDateEpoch = epochTime; break; default: // SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_USAGE_INFO_SELECTED, disinfect ); break; } - dgUsageInfoGroup.dgUsageInfo.crc = crc16( (U08*)&dgUsageInfoGroup.dgUsageInfo, sizeof( DG_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); - dgUsageInfoGroup.crc = crc16( (U08*)&dgUsageInfoGroup, sizeof( DG_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); + ddUsageInfoGroup.ddUsageInfo.crc = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfo, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + ddUsageInfoGroup.crc = crc16( (U08*)&ddUsageInfoGroup, sizeof( DD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); usageWriteTries = 0; status = TRUE; @@ -1171,7 +1235,7 @@ // In HD the treatment time since last service is reset to 0 // In DG the RO water generation since the last service in reset to 0 - ddServiceGroup.ddServiceRecord.lastServiceEpochDate = getRTCTimestamp(); +// ddServiceGroup.ddServiceRecord.lastServiceEpochDate = getRTCTimestamp(); ddServiceGroup.ddServiceRecord.crc = crc16( (U08*)&ddServiceGroup.ddServiceRecord, sizeof( DD_SERVICE_RECORD_T ) - sizeof( U16 ) ); ddServiceGroup.crc = crc16( (U08*)&ddServiceGroup, sizeof( DD_SERVICE_GROUP_T ) - sizeof( U16 ) ); // Update the DG usage info @@ -1191,3 +1255,292 @@ return status; } + +/*********************************************************************//** + * @brief + * The getNVRecord2Driver function copies the requested non-volatile + * data into the provided buffer by the caller. The function then checks if + * the non-volatile data is valid. If the data is not valid, it raises the + * provided alarm by the caller. + * @details Inputs: ddCalibrationRecord + * @details Outputs: ddCalibrationRecord + * @param nvData the non-volatile data to be copied + * @param bufferAddress the address of the provided buffer by the caller + * @param bufferLength the length of the provided buffer by the caller + * @param numOfSnsrs2Check the number of sensors to check in a array of sensors called + * @param nvAlarm the corresponding alarm of the non-volatile data to be raised + * if the data is not valid + * @return TRUE if the non-volatile data is valid otherwise, FALSE + *************************************************************************/ +BOOL getNVRecord2Driver( NV_DATA_T nvData, U08* bufferAddress, U32 bufferLength, U08 numOfSnsrs2Check, ALARM_ID_T nvAlarm ) +{ + U08 i; + U08* nvDataStartPtr = 0; + BOOL isNVDataInvalid = FALSE; + U32 nvDataLength = 0; + + switch ( nvData ) + { + + case GET_CAL_PRESSURE_SENOSRS: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord.pressureSensors[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_LOAD_CELL_SENSORS: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.loadCellsCalRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.loadCellsCalRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.loadCellsCalRecord.loadCells[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_FLOW_SENSORS: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.flowSensorsCalRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.flowSensorsCalRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.flowSensorsCalRecord.flowSensors[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_ACID_CONCENTREATES: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord.acidConcentrate[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_BICARB_CONCENTRATES: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord.bicarbConcentrate[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_ACCEL_SENSORS: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.accelerometerSensorCalRecord; + isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.accelerometerSensorCalRecord.calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_TEMP_SENSORS: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord.tempSensors[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_HEATING_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.heatingCalRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.heatingCalRecord ); + isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.heatingCalRecord.calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_DRAIN_LINE_VOLUME_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.drainLineVolumeRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.drainLineVolumeRecord ); + isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.drainLineVolumeRecord.calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_RO_PUMP_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.roPumpRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.roPumpRecord ); + isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.roPumpRecord.calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_CONCENTRATE_PUMPS_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord.concentratePumps[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_DRAIN_PUMP_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.drainPumpRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.drainPumpRecord ); + isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.drainPumpRecord.calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_FANS_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.fansRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.fansRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.fansRecord.fans[ i ].calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_PRE_RO_PURGE_VOLUME_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.preROPurgeVolumeRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.preROPurgeVolumeRecord ); + isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.preROPurgeVolumeRecord.calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_FILTERS_RECORD: + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.filtersRecord; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.filtersRecord ); + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.carbonFilter.calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.carbonPolishFilter.calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.roFilter.calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.sedimentFilter.calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.filtersRecord.ultraFilter.calibrationTime ? TRUE : FALSE ); + break; + + case GET_CAL_FILL_CONDUCTIVITIES_RECORD: + { + DD_FILL_COND_OPS_T fillOps; + + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues ); + + for ( i = 0; i < numOfSnsrs2Check; i++ ) + { + for ( fillOps = FILL_COND_NORMAL_OP; fillOps < NUM_OF_FILL_COND_TEST; fillOps++ ) + { + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues[ i ][ fillOps ].calibrationTime ? TRUE : FALSE ); + } + } + } + break; + + case GET_INF_HEATERS_RECORD: + nvDataStartPtr = (U08*)&ddHeatersInfoGroup.ddHeatersInfo; + nvDataLength = sizeof( ddHeatersInfoGroup.ddHeatersInfo ); + break; + + case GET_SYS_RECORD: + nvDataStartPtr = (U08*)&ddSystemGroup.ddSystemRecord; + nvDataLength = sizeof( ddSystemGroup.ddSystemRecord ); + break; + + case GET_SRV_RECORD: + nvDataStartPtr = (U08*)&ddServiceGroup.ddServiceRecord; + nvDataLength = sizeof( ddServiceGroup.ddServiceRecord ); + break; + + case GET_SRR_RECORD: + nvDataStartPtr = (U08*)&ddScheduledRunsGroup.ddScheduledRun; + nvDataLength = sizeof( ddScheduledRunsGroup.ddScheduledRun ); + break; + + case GET_USAGE_RECORD: + nvDataStartPtr = (U08*)&ddUsageInfoGroup.ddUsageInfo; + nvDataLength = sizeof( ddUsageInfoGroup.ddUsageInfo ); + break; + + default: +// SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_NV_RECORD_SELECTED, nvData ); + break; + } + + // Make sure the provided buffer length is >= NV Data Length in the NV data management so the memory of the other variables is not + // overridden. + if ( ( bufferLength >= nvDataLength ) && ( nvDataStartPtr != 0 ) ) + { + // Copy the data into the provided buffer + memcpy( bufferAddress, nvDataStartPtr, bufferLength ); + } + + // Check if the non-volatile data is valid and if not raise the alarm + if ( TRUE == isNVDataInvalid ) + { + // If no alarm has been provided to raise, just set the variable as TRUE + if ( ALARM_ID_NO_ALARM == nvAlarm ) + { + isNVDataInvalid = FALSE; + } + else + { +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAL_CHECK ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + activateAlarmNoData( nvAlarm ); + } +#ifndef _RELEASE_ + else + { + isNVDataInvalid = FALSE; + } +#endif + } + } + + // Reverse the polarity to signal the outside users that the calibration has passed. + return ( FALSE == isNVDataInvalid ? TRUE : FALSE ); +} + +/*********************************************************************//** + * @brief + * The testSetNVRecordCRCOverride overrides the non-volatile record CRC override. + * @details Inputs: none + * @details Outputs: none + * @param job the job to override its CRC (i.e. calibration record) + * @param crc the value its CRC to be overridden + * @return TRUE if the job was scheduled successfully otherwise, FALSE + *************************************************************************/ +BOOL testSetNVRecordCRCOverride( U32 job, U16 crc ) +{ + BOOL status = FALSE; + RECORD_JOBS_STATE_T nvJob = (RECORD_JOBS_STATE_T)job; + + switch( nvJob ) + { + case NVDATAMGMT_CALIBRATION_RECORD: + ddCalibrationRecord.crc = crc; + status = enqueueSector0Records(); + break; + + case NVDATAMGMT_SYSTEM_RECORD: + ddSystemGroup.ddSystemRecord.crc = crc; + status = enqueueSector0Records(); + break; + + case NVDATAMGMT_SERVICE_RECORD: + ddServiceGroup.ddServiceRecord.crc = crc; + status = enqueueSector0Records(); + break; + + case NVDATAMGMT_USAGE_INFO_RECORD: + ddUsageInfoGroup.ddUsageInfo.crc = crc; + if ( getAvailableRecordQueueCount() > 0 ) + { + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_USAGE_INFO_RECORD ); + status = TRUE; + } + break; + + } + + return status; +} + +void updateNVSelfTestResult( SELF_TEST_STATUS_T result ) +{ + nvDataMgmtSelfTestResult = result; +} + +void updateNVSelfTestState( NVDATAMGMT_SELF_TEST_STATE_T state ) +{ + nvDataMgmtSelfTestState = state; +} + +#ifndef _RELEASE_ +/*********************************************************************//** + * @brief + * The getSoftwareConfigStatus function returns the status of a software + * configuration. + * @details Inputs: swConfigsList + * @details Outputs: none + * @param config which is the configuration of the that its status is requested + * @return status of the software configuration (0 or 1) + *************************************************************************/ +U08 getSoftwareConfigStatus( SOFTWARE_CONFIG_T config ) +{ + U08 value = 0; + + // If the build is not a release, get the value from the software configurations list + // If the build is a release, the configuration not matter what its value is kept in + // the NV RAM, it returns a 0 which is the configuration is disabled + value = ddSWConfigGroup.ddSWConfigsRecord.swConfigs[ config ]; + + return value; +} +#endif Index: firmware/App/Services/NVRecordsDD.h =================================================================== diff -u -r1e809a81cb8831f5aa5938bd333cc374920d5b87 -r45b03b9f23005c05fc75f69416595a155e250cbe --- firmware/App/Services/NVRecordsDD.h (.../NVRecordsDD.h) (revision 1e809a81cb8831f5aa5938bd333cc374920d5b87) +++ firmware/App/Services/NVRecordsDD.h (.../NVRecordsDD.h) (revision 45b03b9f23005c05fc75f69416595a155e250cbe) @@ -15,8 +15,9 @@ #ifndef _NV_RECORDS_DD_H_ #define _NV_RECORDS_DD_H_ -#include "Common.h" #include "DDDefs.h" +#include "NVDriver.h" +#include "Common.h" // ********** public definitions ********** @@ -30,6 +31,20 @@ #define MAX_EEPROM_WRITE_BUFFER_BYTES 16U ///< Max allowed bytes for an EEPROM write (16 bytes). +/// Process records specifications structure +typedef struct +{ + U32 startAddress; ///< Jobs spec start address. + U32 sizeofJob; ///< Jobs spec size of job. + U32 maxWriteBufferSize; ///< Jobs max write allowed processing buffer size. + U32 maxReadBufferSize; ///< Jobs max read allowed processing buffer size. + U08* structAddressPtr; ///< Jobs structure address pointer. + U08* structCRCPtr; ///< Jobs structure CRC pointer. + DD_EVENT_ID_T nvEvent; ///< Jobs non-volatile DG event (i.e calibration, system). + +} PROCESS_RECORD_SPECS_T; + + #ifndef _RELEASE_ /// Software configuration enums typedef enum software_configurations @@ -72,10 +87,7 @@ GET_CAL_ACID_CONCENTREATES, ///< Get acid concentrates calibration data. GET_CAL_BICARB_CONCENTRATES, ///< Get bicarb concentrates calibration data. GET_CAL_ACCEL_SENSORS, ///< Get accelerometers calibration data. - GET_CAL_CONDUCTIVITY_SENSORS, ///< Get conductivity sensors calibration data. - GET_CAL_CONDUCTIVITY_SENSORS_TEMP_COMP, ///< Get conductivity sensors temperature compensation calibration data. GET_CAL_TEMP_SENSORS, ///< Get temperature sensors calibration data. - GET_CAL_RSRVRS_VOL_RECORD, ///< Get reservoirs volume record. GET_CAL_HEATING_RECORD, ///< Get heating calibration record. GET_CAL_DRAIN_LINE_VOLUME_RECORD, ///< Get drain line volume record. GET_CAL_RO_PUMP_RECORD, ///< Get RO pump calibration record. @@ -320,23 +332,6 @@ U16 crc; ///< CRC. } DD_PRE_RO_PURGE_VOLUME_T; -/// DG reservoir volume calibration structure -typedef struct -{ - F32 rsrvrVolume; ///< Reservoir volume. - F32 normalFillVolume; ///< Normal fill volume. - F32 maxResidualFluid; ///< Max residual fluid. - F32 rsrvrUnfilledWeight; ///< Reservoir unfilled weight. - U32 calibrationTime; ///< Calibration time. - U16 crc; ///< CRC. -} DD_RESERVOIR_VOLUME_DATA_T; - -/// DG reservoir volume record -typedef struct -{ - DD_RESERVOIR_VOLUME_DATA_T reservoir[ NUM_OF_CAL_DATA_RSRVRS ]; ///< DG reservoir volume data. -} DD_RESERVOIR_VOLUME_RECORD_T; - /// DG generic volumes (reserved space) typedef struct { @@ -493,10 +488,55 @@ #endif #pragma pack(pop) +#pragma pack(push, 1) +/// DD usage info structure. +typedef struct +{ + F32 roWaterGenTotalL; ///< Total RO water generated in liters. (Cannot be reset) + F32 roWaterGenSinceLastServiceL; ///< RO water generated since last treatment in liters. + U32 lastBasicFlushCompleteDateEpoch; ///< Last basic flush complete date in epoch. + U32 lastChemDisStartDateEpoch; ///< Last chemical disinfect start date in epoch. + U32 lastChemDisCompleteDateEpoch; ///< Last chemical disinfect complete date in epoch. + U32 lastChemDisFlushCompleteDateEpoch; ///< Last chemical disinfect flush complete date in epoch. + U32 lastHeatDisCompleteDateEpoch; ///< Last heat disinfect complete date in epoch. + U32 lastHeatActiveCoolCompleteDateEpoch; ///< Last heat disinfect active cool complete date in epoch. + U32 lastFilterFlushCompleteDateEpoch; ///< Last filter flush complete date in epoch. + U32 lastResetTimeEpoch; ///< Last time the record was reset in epoch. + U16 crc; ///< CRC for the DG usage info structure. +} DD_USAGE_INFO_RECORD_T; + +/// DD service record structure +typedef struct +{ + U08 serviceLoc; ///< DG service location. + U32 lastServiceEpochDate; ///< DG last service date in epoch. + U32 serviceIntervalSeconds; ///< DG service interval in seconds. + U32 lastResetTimeEpoch; ///< Last time the record was reset in epoch. + U16 crc; ///< CRC for the DG service record structure. +} DD_SERVICE_RECORD_T; +#pragma pack(pop) + +/// NVDataMgmt self-test states enumeration. +typedef enum NVDataMgmt_Self_Test_States +{ + NVDATAMGMT_SELF_TEST_STATE_READ_RECORDS = 0, ///< Self test read records. + NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC, ///< Self test check CRC. + NVDATAMGMT_SELF_TEST_STATE_COMPLETE, ///< Self test complete. + NUM_OF_NVDATAMGMT_SELF_TEST_STATES ///< Total number of self-test states. +} NVDATAMGMT_SELF_TEST_STATE_T; + void initNVRecordsDD( void ); SELF_TEST_STATUS_T execNVDataMgmtSelfTest ( void ); +PROCESS_RECORD_SPECS_T getProcessRecord( RECORD_JOBS_STATE_T job ); void benignPolynomialCalRecord( POLYNOMIAL_CAL_PAYLOAD_T* record ); BOOL setLastDisinfectDate( DD_USAGE_INFO_ITEMS_T disinfect, U32 epochTime ); BOOL setServiceTime( void ); +BOOL getNVRecord2Driver( NV_DATA_T nvData, U08* bufferAddress, U32 bufferLength, U08 numOfSnsrs2Check, ALARM_ID_T nvAlarm ); +BOOL testSetNVRecordCRCOverride( U32 job, U16 crc ); +void updateNVSelfTestResult( SELF_TEST_STATUS_T result ); +void updateNVSelfTestState( NVDATAMGMT_SELF_TEST_STATE_T state ); +#ifndef _RELEASE_ +U08 getSoftwareConfigStatus( SOFTWARE_CONFIG_T config ); +#endif #endif /* _NV_RECORDS_DD_H_ */