Index: NVDataMgmt.c =================================================================== diff -u -rd8454083670704629941c95c1c57dee1a198784e -rc62f2826ae0e201841ea17b426c62c7e3d8b1a2a --- NVDataMgmt.c (.../NVDataMgmt.c) (revision d8454083670704629941c95c1c57dee1a198784e) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision c62f2826ae0e201841ea17b426c62c7e3d8b1a2a) @@ -80,7 +80,7 @@ #define DG_SCHEDULED_RUNS_START_ADDRESS (SERVICE_RECORD_START_ADDRESS + sizeof(DG_SERVICE_GROUP_T)) ///< DG scheduled runs start address in RTC RAM. #define COMMAND_TIME_OUT 500U ///< 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 divide by 4. +/// 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 // ********** Calibration data defines ********** @@ -105,11 +105,24 @@ #define RECORD_DEFAULT_OFFSET 0.0 ///< Record default offset. #define RECORD_DEFAULT_CONST 0.0 ///< Record default constant. #define RECORD_DEFAULT_RATIO 1.0 ///< Record default ratio. +// The service record interval is equivalent to 6 months +#define RECORD_DEFAULT_SERVICE_INTERVAL_S 15768000U ///< Record default service interval in seconds. +#define RECORD_DEFAULT_CHARACTER ' ' ///< Record default character. -/// 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 NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS (1 * MS_PER_SECOND) +// 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 NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS (1 * MS_PER_SECOND) ///< New calibration available signal timeout in milliseconds. +// HD specific defines +#ifdef _HD_ +#endif + +// DG specific defines +#ifdef _DG_ +#define FLUSH_LINES_DEFAULT_VOLUME_L 0.01 ///< Water volume to flush when starting re-circulate mode in liters. +#define ACID_CONC_DEFAULT_MIXING_RATIO ( 2.35618 / FRACTION_TO_PERCENT_FACTOR ) ///< Ratio between RO water and acid concentrate mixing ratio. +#define BICARB_CONC_DEFAULT_MIXING_RATIO ( 4.06812 / FRACTION_TO_PERCENT_FACTOR ) ///< Ratio between RO water and bicarbonate concentrate mixing ratio. +#endif + /// NVDataMgmt self-test states enumeration. typedef enum NVDataMgmt_Self_Test_States { @@ -181,7 +194,9 @@ NVDATAMGMT_CALIBRATION_RECORD = 0, ///< NVDataMgmt process write calibration record. NVDATAMGMT_SYSTEM_RECORD, ///< NVDataMgmt process write system record. NVDATAMGMT_SERVICE_RECORD, ///< NVDATAMgmt process service record. +#ifdef _DG_ NVDATAMGMT_SCHEDULED_RUNS_RECORD, ///< NVDataMgmt process scheduled runs record. +#endif NUM_OF_NVDATMGMT_RECORDS_JOBS ///< Number of NVDataMgmt records jobs. } RECORD_JOBS_STATE_T; @@ -387,6 +402,7 @@ {DG_SCHEDULED_RUNS_START_ADDRESS, sizeof(DG_SCHEDULED_RUNS_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgScheduledRunsGroup, (U08*)&dgScheduledRunsGroup.crc} // NVDATAMGMT_SCHEDULER_RECORD }; #endif + #ifdef _HD_ static HD_CALIBRATION_RECORD_T hdCalibrationRecord; ///< HD calibration record structure. static HD_SYSTEM_GROUP_T hdSystemGroup; ///< HD system group structure (including padding and final CRC). @@ -399,6 +415,7 @@ {SERVICE_RECORD_START_ADDRESS, sizeof(HD_SERVICE_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdServiceGroup, (U08*)&hdServiceGroup.crc}, // NVDATAMGMT_PROCESS_LAST_SERVICE_RECORD }; #endif + static RECORD_JOBS_STATE_T recordToPublish; ///< Record to publish (i.e. calibration, system) static PROCESS_RECORD_STATE_T nvDataMgmtExecProcessRecordState = NVDATAMGMT_PROCESS_RECORD_STATE_IDLE; ///< NVDataMgmt exec process record state. static RECEIVE_RECORD_STATE_T nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; ///< NVDataMgmt exec receive record state. @@ -439,7 +456,9 @@ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadCalibrationRecord( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadSystemRecord( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadServiceRecord( void ); +#ifdef _DG_ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadScheduledRunsRecord( void ); +#endif #ifdef _HD_ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadHDTreatmentTime( void ); #endif @@ -489,12 +508,18 @@ // Record check helper functions static BOOL areRecordsValid( void ); static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ); +#ifdef _DG +static void setRsrvdCalibrationRecordsToZero( void ); +#endif #ifdef _DG_ +static BOOL isDGSystemRecordValid( void ); +static BOOL isDGServiceRecordValid( void ); static BOOL isDGCalibrationRecordValid( void ); static BOOL isDGConcPumpRecordValid( DG_CONC_PUMPS_CAL_DATA_T* record ); static BOOL isDGDrainPumpRecordValid( DG_DRAIN_PUMP_CAL_RECORD_T* record ); static BOOL isDGROPumpRecordValid( DG_RO_PUMP_CAL_RECORD_T* record ); +static BOOL isDGPreROPurgeVolumeRecordValid( DG_PRE_RO_PURGE_VOLUME_T* record ); static BOOL isDGDrainLineVolRecordValid( DG_DRAIN_LINE_VOLUME_T* record ); static BOOL isDGReservoirVolRecordValid( DG_RESERVOIR_VOLUME_DATA_T* record ); static BOOL isDGGenericVolRecordValid( DG_GENERIC_VOLUME_DATA_T* record ); @@ -504,7 +529,10 @@ static BOOL isDGFanRecordValid( DG_FAN_CAL_RECORD_T* record ); static BOOL isDGAccelerometerSensorRecordValid( DG_ACCELEROMETER_SENSOR_CAL_RECORD_T* record ); #endif + #ifdef _HD_ +static BOOL isHDSystemRecordValid( void ); +static BOOL isHDServiceRecordValid( void ); static BOOL isHDCalibrationRecordValid( void ); static BOOL isHDValveRecordValid( HD_VALVE_CAL_PAYLOAD_T* record ); static BOOL isHDPumpRecordValid( HD_PUMP_CAL_PAYLOAD_T* record ); @@ -651,12 +679,15 @@ break; case NVDATAMGMT_SELF_TEST_STATE_READ_SCHEDULED_RUNS_RECORD: +#ifdef _DG_ nvDataMgmtSelfTestState = handleSelfTestReadScheduledRunsRecord(); +#endif break; case NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD: nvDataMgmtSelfTestState = handleSelfTestReadLogRecord(); break; + #ifdef _HD_ case NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME: nvDataMgmtSelfTestState = handleSelfTestReadHDTreatmentTime(); @@ -667,6 +698,7 @@ nvDataMgmtSelfTestState = handleSelfTestReadDGWaterConsumption(); break; #endif + case NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC: nvDataMgmtSelfTestState = handleSelfTestCheckCRC(); break; @@ -776,16 +808,15 @@ * Dialin * @param totalMessages: total number of messages from Dialin * @param length: message length in bytes - * @param *addressPtr: address to the beginning of the calibration data from - * Dialin + * @param *addressPtr: address to the beginning of the calibration data from Dialin * @return TRUE if the request was successfully registered *************************************************************************/ BOOL setCalibrationRecord( 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 ) && ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) ) + if ( ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage ) && ( NVDATAMGMT_RECEIVE_RECORD_IDLE == nvDataMgmtExecReceiveRecordState ) ) { nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; recordReceiveStartTime = getMSTimerCount(); @@ -794,7 +825,7 @@ } // Check if there is still a message left to be received - if ( ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE ) && ( currentMessage <= totalMessages ) ) + if ( ( NVDATAMGMT_RECEIVE_RECORD_RECEIVE == nvDataMgmtExecReceiveRecordState ) && ( currentMessage <= totalMessages ) ) { // Check if the current message is different from the previous message by 1 if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) @@ -899,7 +930,7 @@ 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 && nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) + if ( ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage ) && ( NVDATAMGMT_RECEIVE_RECORD_IDLE == nvDataMgmtExecReceiveRecordState ) ) { nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; recordReceiveStartTime = getMSTimerCount(); @@ -908,7 +939,7 @@ } // Check if there is still a message left to be received - if ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE && currentMessage <= totalMessages ) + if ( ( NVDATAMGMT_RECEIVE_RECORD_RECEIVE == nvDataMgmtExecReceiveRecordState ) && ( currentMessage <= totalMessages ) ) { // Check if the current message is different from the previous message by 1 if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) @@ -974,7 +1005,7 @@ BOOL status = FALSE; // Check if the state machine is in idle state and then set the request - if ( nvDataMgmtExecProcessRecordState == NVDATAMGMT_PROCESS_RECORD_STATE_IDLE ) + if ( NVDATAMGMT_PROCESS_RECORD_STATE_IDLE == nvDataMgmtExecProcessRecordState ) { hasPublishRecordBeenRequested = TRUE; recordToPublish = NVDATAMGMT_SERVICE_RECORD; @@ -1066,6 +1097,7 @@ return status; } +#ifdef _DG_ /*********************************************************************//** * @brief * The getScheduledRunsRecord function sets the system state machine @@ -1171,6 +1203,7 @@ return status; } +#endif /*********************************************************************//** * @brief @@ -1324,7 +1357,7 @@ * @details Outputs: none * @return DG reservoirs volume record *************************************************************************/ -DG_RESERVOIR_VOLUME_RECORD_T getDGReservoirVolumeRecord( void ) +DG_RESERVOIR_VOLUME_RECORD_T getDGReservoirsVolumeRecord( void ) { return dgCalibrationRecord.dgCalibrationGroups.reservoirVolumesRecord; } @@ -1621,7 +1654,7 @@ hdUsageInfoGroup.hdUsageInfo.treatmentTime = hours; hdUsageInfoGroup.crc = crc16 ( (U08*)&hdUsageInfoGroup.hdUsageInfo.treatmentTime, sizeof(U32) ); - if ( !isQueueFull() ) + if ( FALSE == isQueueFull() ) { enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, HD_TREATMENT_TIME_ADDRESS, (U08*)&hdUsageInfoGroup, 0, sizeof(HD_USAGE_INFO_RECORD_T) ); @@ -1698,7 +1731,7 @@ PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_CALIBRATION_RECORD ]; U32 startAddress = specs.startAddress; U08* bufferAddress = specs.structAddressPtr; - U32 maxBufferLength = ( specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER ); + U32 maxBufferLength = specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER; Fapi_doMarginRead( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); currentTime = getMSTimerCount(); @@ -1726,7 +1759,7 @@ PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SYSTEM_RECORD ]; U32 startAddress = specs.startAddress; U08* bufferAddress = specs.structAddressPtr; - U32 maxBufferLength = ( specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER ); + U32 maxBufferLength = specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER; Fapi_doMarginRead( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); currentTime = getMSTimerCount(); @@ -1748,9 +1781,9 @@ NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_SYS_RECORD; BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); - if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) + if ( ( Fapi_Status_FsmReady == FAPI_CHECK_FSM_READY_BUSY ) || ( TRUE == timeoutStatus ) ) { - if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + if ( RTC_RAM_STATE_READY == getRTCRAMState() ) { PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SERVICE_RECORD ]; U32 startAddress = specs.startAddress; @@ -1779,7 +1812,7 @@ NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_SERVICE_RECORD; BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); - if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) + if ( ( RTC_RAM_STATUS_IDLE == getRTCRAMStatus() ) || ( TRUE == timeoutStatus ) ) { PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SERVICE_RECORD ]; U08* bufferAddress = specs.structAddressPtr; @@ -1788,7 +1821,7 @@ getDataFromRAM( bufferAddress, maxBufferLength ); #ifdef _DG_ - if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + if ( RTC_RAM_STATE_READY == getRTCRAMState() ) { PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SCHEDULED_RUNS_RECORD ]; U32 startAddress = specs.startAddress; @@ -1808,6 +1841,7 @@ return state; } +#ifdef _DG_ /*********************************************************************//** * @brief * The handleSelfTestReadScheduledRunsRecord reads the scheduled runs @@ -1834,6 +1868,7 @@ return state; } +#endif #ifdef _HD_ /*********************************************************************//** * @brief @@ -1879,10 +1914,10 @@ BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); // If the RAM is ready, request a read for water consumption - if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) + if ( ( RTC_RAM_STATUS_IDLE == getRTCRAMStatus() ) || ( TRUE == timeoutStatus ) ) { getDataFromRAM ( (U08*)&dgUsageInfoGroup, sizeof(DG_USAGE_INFO_RECORD_T) ); - if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + if ( RTC_RAM_STATE_READY == getRTCRAMState() ) { readFromRAM ( LOG_RECORD_START_ADDRESS, sizeof(LOG_RECORD_T) ); currentTime = getMSTimerCount(); @@ -1916,6 +1951,7 @@ currentTime = getMSTimerCount(); // Get ready for reading the manufacturing record + // TODO uncomment. currently not working This section is for phase 1B //Fapi_doMarginRead( (U32*)BANK7_SECTOR0_START_ADDRESS, addr, len, Fapi_NormalRead ); state = NVDATAMGMT_SELF_TEST_STATE_READ_SYS_RECORD; } @@ -1934,20 +1970,24 @@ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestCheckCRC ( void ) { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; - BOOL haveCalGroupsPassed = TRUE; - BOOL haveRecordsPassed = TRUE; + BOOL haveCalGroupsPassed = TRUE; + BOOL haveRecordsPassed = TRUE; + BOOL hasSystemRecordPassed = TRUE; + BOOL hasServiceRecordPassed = TRUE; -#ifndef DISABLE_CAL_CHECK // Check the integrity of the records as a whole. Check the upper layer CRC haveRecordsPassed = areRecordsValid(); -#endif #ifdef _DG_ // Check all the calibration groups - haveCalGroupsPassed = isDGCalibrationRecordValid(); + haveCalGroupsPassed = isDGCalibrationRecordValid(); + hasSystemRecordPassed = isDGSystemRecordValid(); + hasServiceRecordPassed = isDGServiceRecordValid(); #endif #ifdef _HD_ - haveCalGroupsPassed = isHDCalibrationRecordValid(); + haveCalGroupsPassed = isHDCalibrationRecordValid(); + hasSystemRecordPassed = isHDSystemRecordValid(); + hasServiceRecordPassed = isHDServiceRecordValid(); #endif // If any of the records did not pass, they should be filled @@ -1959,7 +1999,8 @@ } // Check if the records' entire CRCs as well as the individual CRCs passed - if ( haveCalGroupsPassed && haveRecordsPassed ) + if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == haveRecordsPassed ) && + ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) ) { nvDataMgmtSelfTestResult = SELF_TEST_STATUS_PASSED; } @@ -2013,7 +2054,7 @@ if ( powerOffIsImminent != TRUE ) { // If the record processing queue is not empty, process the queues - if ( !isRecordQueueEmpty() ) + if ( FALSE == isRecordQueueEmpty() ) { dequeueRecordJob(); @@ -2036,14 +2077,14 @@ } else if ( ops == NVDATAMGMT_READ ) { - maxBufferLength = jobSpecs.maxReadBufferSize; + maxBufferLength = jobSpecs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER; } } // TODO add the log queue later in the future phases. } // Check if a queue job is available - if ( areQueuesNotEmpty ) + if ( TRUE == areQueuesNotEmpty ) { if ( ops == NVDATAMGMT_ERASE_SECTOR ) { @@ -2115,7 +2156,7 @@ memset( writtenRecordCheckBuffer, 0, sizeof(writtenRecordCheckBuffer)); // Issue a FAPI read command but only the bytes that were written, so use maxWriteBufferSize - Fapi_doMarginRead( (U32*)startAddress, (U32*)writtenRecordCheckBuffer, maxBufferLength, Fapi_NormalRead ); + Fapi_doMarginRead ( (U32*)startAddress, (U32*)writtenRecordCheckBuffer, maxBufferLength, Fapi_NormalRead ); state = NVDATAMGMT_EXEC_STATE_VERIFY_EEPROM_WRITE; } @@ -2136,8 +2177,11 @@ writtenRecordStatus = NVDATAMGMT_RECORD_NOT_CHECKED; + // The length should be divided by 4 + U32 maxBufferLength = jobSpecs.maxWriteBufferSize; + // Issue the write command - Fapi_issueProgrammingCommand ( (U32*)memoryPtr, structPtr, jobSpecs.maxWriteBufferSize, 0x00, 0, Fapi_DataOnly ); + Fapi_issueProgrammingCommand ( (U32*)memoryPtr, structPtr, maxBufferLength, 0x00, 0, Fapi_DataOnly ); } } } @@ -2435,7 +2479,7 @@ { PROCESS_RECORD_STATE_T state = NVDATAMGMT_PROCESS_RECORD_STATE_IDLE; - if ( hasPublishRecordBeenRequested ) + if ( TRUE == hasPublishRecordBeenRequested ) { // Set the publish flag to FALSE hasPublishRecordBeenRequested = FALSE; @@ -2525,13 +2569,13 @@ #endif break; - case NVDATAMGMT_SCHEDULED_RUNS_RECORD: #ifdef _DG_ + case NVDATAMGMT_SCHEDULED_RUNS_RECORD: // Pass the information to the CAN bus sendDGScheduledRunsRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); -#endif // There are no scheduled runs for HD right now. break; +#endif default: //Ignore @@ -2904,7 +2948,7 @@ *************************************************************************/ static void monitorNewCalSignal( void ) { - if ( didTimeout( newCalStartTimer, NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS ) && ( TRUE == isNewCalAvailable ) ) + if ( ( TRUE == didTimeout( newCalStartTimer, NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS ) ) && ( TRUE == isNewCalAvailable ) ) { isNewCalAvailable = FALSE; } @@ -2925,22 +2969,30 @@ U16 recordCRC; PROCESS_RECORD_SPECS_T spec; BOOL status = TRUE; + BOOL isCheckRequired = TRUE; for ( i = 0; i < NUM_OF_NVDATMGMT_RECORDS_JOBS; i++ ) { - spec = RECORDS_SPECS [ i ]; - calcCRC = crc16 ( spec.structAddressPtr, spec.sizeofJob - sizeof(U16) ); - recordCRC = *(U16*)spec.structCRCPtr; - - // If the CRCs do not match, break out of loop since POST will be failed - // regardless of the rest of the results - if ( calcCRC != recordCRC ) - { -#ifndef DISABLE_CAL_CHECK - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_NVDATAMGMT_GROUP_RECORD_CRC_INVALID, i ); - status = FALSE; +#ifdef _DG_ + // Scheduled runs are not part this phase but it is part of the enums + // so they are ignored during checking + isCheckRequired = ( NVDATAMGMT_SCHEDULED_RUNS_RECORD == i ? FALSE : TRUE ); #endif + if ( TRUE == isCheckRequired ) + { + spec = RECORDS_SPECS [ i ]; + calcCRC = crc16 ( spec.structAddressPtr, spec.sizeofJob - sizeof(U16) ); + recordCRC = *(U16*)spec.structCRCPtr; + + // If the CRCs do not match, break out of loop since POST will be failed + // regardless of the rest of the results + if ( calcCRC != recordCRC ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_NVDATAMGMT_GROUP_RECORD_CRC_INVALID, i ); + status = FALSE; + } } + } return status; @@ -2955,8 +3007,8 @@ * @details Outputs: none * @param record: pointer to a polynomial payload. The actual calibration * data to be checked - * @param isRecordNeeded: TRUE is the calibration record is need in the firmware - * right now otherwise, FALSE + * @param isRecordNeeded: TRUE is the calibration record is need in the + * firmware right now otherwise, FALSE * @return TRUE if the records' data is valid otherwise FALSE *************************************************************************/ static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ) @@ -2983,10 +3035,122 @@ return status; } +#ifdef _DG_ +/*********************************************************************//** + * @brief + * The setRsrvdCalibrationRecordsToZero function sets the calibration + * records reserved spaces to 0. This is to make sure they are not set + * to NaN. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +static void setRsrvdCalibrationRecordsToZero( void ) +{ + U32 i; + POLYNOMIAL_CAL_PAYLOAD_T* record; + // NOTE: the size of the reserved spaces in each calibration record do not have #define + // because they are based on assumptions and they may be reduced. + // Get the calibration record of the hardware (i.e. pressure sensor) + DG_PRES_SENSORS_CAL_RECORD_T* pressure = &dgCalibrationRecord.dgCalibrationGroups.presSensorsCalRecord; + for ( i = 0; i < 6; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&pressure->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } + + DG_FLOW_SENSORS_CAL_RECORD_T* flow = &dgCalibrationRecord.dgCalibrationGroups.flowSensorsCalRecord; + for ( i = 0; i < 3; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&flow->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } + + DG_TEMP_SENSORS_CAL_RECORD_T* temperature = &dgCalibrationRecord.dgCalibrationGroups.tempSensorsCalRecord; + for ( i = 0; i < 5; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&temperature->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } + + DG_COND_SENSORS_CAL_RECORD_T* conductivity = &dgCalibrationRecord.dgCalibrationGroups.condSensorsCalRecord; + for ( i = 0; i < 2; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&conductivity->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } +} +#endif + #ifdef _DG_ /*********************************************************************//** * @brief + * The isDGSystemRecordValid function checks the validity of the DG system + * record. + * @details Inputs: dgSystemGroup.dgSystemRecord + * @details Outputs: none + * @return TRUE if the DG system record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGSystemRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&dgSystemGroup.dgSystemRecord, sizeof(DG_SYSTEM_RECORD_T) - sizeof(U16) ); + U16 recordCRC = dgSystemGroup.dgSystemRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + dgSystemGroup.dgSystemRecord.mfgDate = 0; + dgSystemGroup.dgSystemRecord.mfgLocation = 0; + memset( dgSystemGroup.dgSystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( dgSystemGroup.dgSystemRecord.topLevelPN ) ); + memset( dgSystemGroup.dgSystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( dgSystemGroup.dgSystemRecord.topLevelPN ) ); + // Recalculate the CRC with the default values + dgSystemGroup.dgSystemRecord.crc = crc16 ( (U08*)&dgSystemGroup.dgSystemRecord, sizeof(DG_SYSTEM_RECORD_T) - sizeof(U16) ); + + activateAlarmNoData( ALARM_ID_DG_INVALID_SYSTEM_RECORD ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The isDGServiceRecordValid function checks the validity of the DG service + * record. + * @details Inputs: dgServiceGroup.dgServiceRecord + * @details Outputs: none + * @return TRUE if the DG service record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGServiceRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&dgServiceGroup.dgServiceRecord, sizeof(DG_SERVICE_RECORD_T) - sizeof(U16) ); + U16 recordCRC = dgServiceGroup.dgServiceRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + dgServiceGroup.dgServiceRecord.lastServiceEpochDate = 0; + dgServiceGroup.dgServiceRecord.serviceIntervalSeconds = RECORD_DEFAULT_SERVICE_INTERVAL_S; + // Recalculate the CRC with the default values + dgServiceGroup.dgServiceRecord.crc = crc16 ( (U08*)&dgServiceGroup.dgServiceRecord, sizeof(DG_SERVICE_RECORD_T) - sizeof(U16) ); + + // Service record failure is also considered as RTC RAM failure + activateAlarmNoData( ALARM_ID_DG_INVALID_SERVICE_RECORD ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief * The isDGCalibrationRecordValid function calls other functions to check * the validity of DG calibration record. * @details Inputs: dgCalibrationRecord @@ -3060,6 +3224,10 @@ isHardwareRecordValid = isDGROPumpRecordValid( roPump ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + DG_PRE_RO_PURGE_VOLUME_T* preROPurgeVolume = &dgCalibrationRecord.dgCalibrationGroups.preROPurgeVolumeRecord; + isHardwareRecordValid = isDGPreROPurgeVolumeRecordValid( preROPurgeVolume ); + isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + DG_DRAIN_LINE_VOLUME_T* drainLineVol = &dgCalibrationRecord.dgCalibrationGroups.drainLineVolumeRecord; isHardwareRecordValid = isDGDrainLineVolRecordValid( drainLineVol ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; @@ -3123,6 +3291,14 @@ isHardwareRecordValid = isDGAccelerometerSensorRecordValid( accelerometer ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + // If the sub groups failed, they are all updated to their benign values + // so the main CRC of the calibration group is calculated again + if ( FALSE == isCalRecordValid ) + { + U16 finalCRC = crc16 ( (U08*)&dgCalibrationRecord, sizeof(DG_CALIBRATION_RECORD_T) - sizeof(U16) ); + dgCalibrationRecord.crc = finalCRC; + } + return isCalRecordValid; } @@ -3218,6 +3394,36 @@ /*********************************************************************//** * @brief + * The isDGPreROPurgeVolumeRecordValid function checks whether the + * calibration record of pre RO purge is valid or not. + * @details Inputs: none + * @details Outputs: none + * @param record: DG_PRE_RO_PURGE_VOLUME_T pointer + * @return TRUE if the record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGPreROPurgeVolumeRecordValid( DG_PRE_RO_PURGE_VOLUME_T* record ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16 ( (U08*)record, sizeof(DG_PRE_RO_PURGE_VOLUME_T) - sizeof(U16) ); + U16 recordCRC = record->crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + record->pressure2FlowRatio = RECORD_DEFAULT_RATIO; + record->volume = RECORD_DEFAULT_CONST; + record->calibrationTime = RECORD_DEFAULT_TIME; + record->crc = crc16 ( (U08*)record, sizeof(DG_PRE_RO_PURGE_VOLUME_T) - sizeof(U16) ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief * The isDGDrainLineVolRecordValid function checks whether the calibration * record of drain line volume is valid or not. * @details Inputs: none @@ -3234,7 +3440,7 @@ if ( calcCRC != recordCRC ) { // CRC did not pass so set all values to default - record->volume = RECORD_DEFAULT_CONST; + record->volume = FLUSH_LINES_DEFAULT_VOLUME_L; record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_DRAIN_LINE_VOLUME_T) - sizeof(U16) ); @@ -3297,7 +3503,6 @@ // CRC did not pass so set all values to default record->volume = RECORD_DEFAULT_CONST; record->calibrationTime = RECORD_DEFAULT_TIME; - record->crc = crc16 ( (U08*)record, sizeof(DG_GENERIC_VOLUME_DATA_T) - sizeof(U16) ); // Set the to FALSE since the record is not valid status = FALSE; @@ -3326,7 +3531,7 @@ // CRC did not pass so set all values to default record->startVolume = RECORD_DEFAULT_CONST; record->reserverdSpace = RECORD_DEFAULT_CONST; - record->acidConcMixRatio = RECORD_DEFAULT_RATIO; + record->acidConcMixRatio = ACID_CONC_DEFAULT_MIXING_RATIO; record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_ACID_CONCENTRATE_T) - sizeof(U16) ); @@ -3357,7 +3562,7 @@ // CRC did not pass so set all values to default record->startVolume = RECORD_DEFAULT_CONST; record->reservedSpace = RECORD_DEFAULT_CONST; - record->bicarbConcMixRatio = RECORD_DEFAULT_RATIO; + record->bicarbConcMixRatio = BICARB_CONC_DEFAULT_MIXING_RATIO; record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_BICARB_CONCENTRATE_T) - sizeof(U16) ); @@ -3466,6 +3671,70 @@ #ifdef _HD_ /*********************************************************************//** * @brief + * The isHDSystemRecordValid function checks the validity of the HD system + * record. + * @details Inputs: hdSystemGroup.hdsystemRecord + * @details Outputs: none + * @return TRUE if the HD system record is valid otherwise FALSE + *************************************************************************/ +static BOOL isHDSystemRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&hdSystemGroup.hdsystemRecord, sizeof( HD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = hdSystemGroup.hdsystemRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + hdSystemGroup.hdsystemRecord.mfgDate = 0; + hdSystemGroup.hdsystemRecord.mfgLocation = 0; + memset( hdSystemGroup.hdsystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( hdSystemGroup.hdsystemRecord.topLevelPN ) ); + memset( hdSystemGroup.hdsystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( hdSystemGroup.hdsystemRecord.topLevelPN ) ); + // Recalculate the CRC with the default values + hdSystemGroup.hdsystemRecord.crc = crc16 ( (U08*)&hdSystemGroup.hdsystemRecord, sizeof( HD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); + + activateAlarmNoData( ALARM_ID_HD_INVALID_SYSTEM_RECORD ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The isHDServiceRecordValid function checks the validity of the HD service + * record. + * @details Inputs: hdServiceGroup.hdServiceRecord + * @details Outputs: none + * @return TRUE if the HD service record is valid otherwise FALSE + *************************************************************************/ +static BOOL isHDServiceRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&hdServiceGroup.hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = hdServiceGroup.hdServiceRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + hdServiceGroup.hdServiceRecord.lastServiceEpochDate = 0; + hdServiceGroup.hdServiceRecord.serviceIntervalSeconds = RECORD_DEFAULT_SERVICE_INTERVAL_S; + // Recalculate the CRC with the default values + hdServiceGroup.hdServiceRecord.crc = crc16 ( (U08*)&hdServiceGroup.hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + + // Service record failure is also considered as RTC RAM failure + activateAlarmNoData( ALARM_ID_HD_INVALID_SERVICE_RECORD ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} +/*********************************************************************//** + * @brief * The isHDCalibrationRecordValid function checks whether HD calibration * record is valid or not. * @details Inputs: none @@ -3739,7 +4008,6 @@ enqueueRecordJob( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, NVDATAMGMT_CALIBRATION_RECORD ); enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, NVDATAMGMT_CALIBRATION_RECORD ); enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, NVDATAMGMT_SYSTEM_RECORD ); - status = TRUE; } Index: RTC.c =================================================================== diff -u -rd8454083670704629941c95c1c57dee1a198784e -rc62f2826ae0e201841ea17b426c62c7e3d8b1a2a --- RTC.c (.../RTC.c) (revision d8454083670704629941c95c1c57dee1a198784e) +++ RTC.c (.../RTC.c) (revision c62f2826ae0e201841ea17b426c62c7e3d8b1a2a) @@ -723,8 +723,8 @@ *************************************************************************/ static BOOL isRTCFunctional( void ) { -#ifndef DISABLE_RTC_CONFIG BOOL hasTestPassed = TRUE; +#ifndef DISABLE_RTC_CONFIG U16 controlReg1 = rxBuffer[ RTC_REG_1_INDEX ]; U16 controlReg2 = rxBuffer[ RTC_REG_2_INDEX ]; U16 controlReg3 = rxBuffer[ RTC_REG_3_INDEX ]; @@ -770,9 +770,8 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_BATTERY_LOW, controlReg3, RTC_REG_3_BLF_MASK ); hasTestPassed = FALSE; } - - return hasTestPassed; #endif + return hasTestPassed; } /*********************************************************************//** @@ -1109,14 +1108,12 @@ { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_WAIT_FOR_POST; -#ifndef DONT_SKIP_NV_POST if ( RTCSelfTestState == RTC_SELF_TEST_STATE_COMPLETE ) { - result = RTC_EXEC_STATE_IDLE; + // After POST is finished, first read the current time so there is one time stamp + // available in the memory + result = RTC_EXEC_STATE_READ; } -#else - result = RTC_EXEC_STATE_IDLE; -#endif return result; }