Index: NVDataMgmt.c =================================================================== diff -u -r779c7d77dada88780c86e3c77a0055dcda10ef04 -r7a8126075d566078097485bf4757f2a380a1ef98 --- NVDataMgmt.c (.../NVDataMgmt.c) (revision 779c7d77dada88780c86e3c77a0055dcda10ef04) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision 7a8126075d566078097485bf4757f2a380a1ef98) @@ -540,7 +540,6 @@ static void enqueuePOSTReadRecords( void ); // Record check helper functions -static BOOL areRecordsValid( void ); static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ); #ifndef _RELEASE_ @@ -550,6 +549,7 @@ #ifdef _DG_ static BOOL isDGSystemRecordValid( void ); static BOOL isDGServiceRecordValid( void ); +static BOOL isDGUsageRecordValid( 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 ); @@ -1364,33 +1364,23 @@ * @brief * The setROWaterGeneratedL sets a queue job to write the amount of generated * RO water that has been generated in DG. - * @details Inputs: dgUsageInfoGroup + * @details Inputs: none * @details Outputs: dgUsageInfoGroup * @param liters consumed water is liters - * @param isServiceDone TURE if service is done otherwise, FALSE * @return TRUE if queue is not full *************************************************************************/ -BOOL setROWaterGeneratedL( F32 liters, BOOL isServiceDone ) +BOOL setROWaterGeneratedL( F32 liters ) { BOOL status = FALSE; - if ( TRUE == isServiceDone ) + if ( FALSE == isQueueFull() ) { - dgUsageInfoGroup.dgUsageInfo.roWaterGenTotalL += dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL; - dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL = liters; - } - else - { dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL += liters; dgUsageInfoGroup.dgUsageInfo.roWaterGenTotalL += dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL; - } + 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 ) ); - 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 ) ); - - if ( FALSE == isQueueFull() ) - { - enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, DG_USAGE_INFO_START_ADDRESS, (U08*)&dgUsageInfoGroup, 0, sizeof( DG_USAGE_INFO_GROUP_T ) ); + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, NVDATAMGMT_USAGE_INFO_RECORD ); status = TRUE; } @@ -1399,20 +1389,45 @@ /*********************************************************************//** * @brief + * The resetROWaterGeneratedLSinceLastSrvc resets the RO water generated + * since the last service to 0. + * @details Inputs: none + * @details Outputs: dgUsageInfoGroup + * @return none + *************************************************************************/ +void resetROWaterGeneratedLSinceLastSrvc( void ) +{ + dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL = 0; +} + +/*********************************************************************//** + * @brief * The setLastDisinfectDate sets a queue job to write the last time that DG * was disinfected. * @details Inputs: dgUsageInfoGroup * @details Outputs: dgUsageInfoGroup + * @param disinfect type (i.e chemical) * @param epochTime last disinfect time in epoch * @return TRUE if queue is not full *************************************************************************/ -BOOL setLastDisinfectDate( U32 epochTime ) +BOOL setLastDisinfectDate( DG_DISINFECT_T disinfect, U32 epochTime ) { - BOOL status = FALSE; - dgUsageInfoGroup.dgUsageInfo.lastDisinfectDate = epochTime; - 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 ) ); + BOOL status = FALSE; + switch ( disinfect ) + { + case USAGE_INFO_HEAT_DISINFECT: + dgUsageInfoGroup.dgUsageInfo.lastHeatDisDateEpoch = epochTime; + break; + + case USAGE_INFO_CHEMICAL_DISINFECT: + dgUsageInfoGroup.dgUsageInfo.lastChemicalDisDateEpoch = epochTime; + 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 ) ); + if ( FALSE == isQueueFull() ) { enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, DG_USAGE_INFO_START_ADDRESS, (U08*)&dgUsageInfoGroup, 0, sizeof( DG_USAGE_INFO_GROUP_T ) ); @@ -1552,29 +1567,27 @@ { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; BOOL haveCalGroupsPassed = TRUE; - BOOL haveRecordsPassed = TRUE; BOOL hasSystemRecordPassed = TRUE; BOOL hasServiceRecordPassed = TRUE; BOOL hasSWConfigRecordPassed = TRUE; + BOOL hasUsageRecordPassed = TRUE; recordsReadStatus = NVDATAMGMT_RECORDS_CRC_CHECKED; - haveRecordsPassed = areRecordsValid(); #ifdef _DG_ // Check all the calibration groups haveCalGroupsPassed = isDGCalibrationRecordValid(); hasSystemRecordPassed = isDGSystemRecordValid(); hasServiceRecordPassed = isDGServiceRecordValid(); + hasUsageRecordPassed = isDGUsageRecordValid(); // TODO add a alarm once dialin is completed #ifndef _RELEASE_ hasSWConfigRecordPassed = isSWConfigRecordValid(); #endif #endif #ifdef _HD_ haveCalGroupsPassed = isHDCalibrationRecordValid(); hasSystemRecordPassed = isHDSystemRecordValid(); -#ifndef BOARD_WITH_NO_HARDWARE hasServiceRecordPassed = isHDServiceRecordValid(); -#endif #ifndef _RELEASE_ hasSWConfigRecordPassed = isSWConfigRecordValid(); #endif @@ -1583,7 +1596,7 @@ // If any of the records did not pass, they should be filled // with benign values. After that, schedule a write to sector 0 // to re-write the records with the benign values - if ( ( FALSE == haveRecordsPassed ) || ( FALSE == haveCalGroupsPassed ) || ( FALSE == hasSystemRecordPassed ) ) + if ( ( FALSE == hasServiceRecordPassed ) || ( FALSE == haveCalGroupsPassed ) || ( FALSE == hasSystemRecordPassed ) ) { enqueueSector0Records(); } @@ -1598,9 +1611,13 @@ enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ].dataLoc, NVDATAMGMT_SERVICE_RECORD ); } + if ( FALSE == hasUsageRecordPassed ) + { + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + } + // Check if the records' entire CRCs as well as the individual CRCs passed - if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == haveRecordsPassed ) && - ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) ) + if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) ) { newCalStartTimer = getMSTimerCount(); isNewCalAvailable = TRUE; @@ -2595,42 +2612,6 @@ /*********************************************************************//** * @brief - * The areRecordsValid function checks whether the records are still valid - * by calculating the CRCs and comparing it to the strucutre's CRC. - * @details Inputs: none - * @details Outputs: none - * @return TRUE if the records' data is valid otherwise FALSE - *************************************************************************/ -static BOOL areRecordsValid( void ) -{ - ALARM_ID_T alarm; - - BOOL status = TRUE; - PROCESS_RECORD_SPECS_T spec = RECORDS_SPECS [ NVDATAMGMT_CALIBRATION_RECORD ]; - U16 calcCRC = crc16 ( spec.structAddressPtr, spec.sizeofJob - sizeof(U16) ); - 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 ) - { -#ifdef _DG_ - alarm = ALARM_ID_DG_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID; - dgCalibrationRecord.crc = calcCRC; -#endif -#ifdef _HD_ - alarm = ALARM_ID_HD_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID; - hdCalibrationRecord.crc = calcCRC; -#endif - activateAlarmNoData( alarm ); - status = FALSE; - } - - return status; -} - -/*********************************************************************//** - * @brief * The isPolynomialRecordValid function checks whether the records are * still valid by calculating the CRCs and comparing it to the strucutre's * CRC. @@ -2645,20 +2626,12 @@ static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ) { BOOL status = TRUE; - U16 calcCRC = crc16 ( (U08*)record, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) - sizeof(U16) ); + U16 calcCRC = crc16 ( (U08*)record, sizeof( POLYNOMIAL_CAL_PAYLOAD_T ) - sizeof( U16 ) ); U16 recordCRC = record->crc; if ( calcCRC != recordCRC ) { - // CRC did not pass so set all values to default - record->fourthOrderCoeff = RECORD_FOURTH_ORDER_COEFF; - record->thirdOrderCoeff = RECORD_THIRD_ORDER_COEFF; - record->secondOrderCoeff = RECORD_SECOND_ORDER_COEFF; - record->gain = RECORD_DEFAULT_GAIN; - record->offset = RECORD_DEFAULT_OFFSET; - record->calibrationTime = RECORD_DEFAULT_TIME; - // Recalculate the CRC with the default values - record->crc = crc16 ( (U08*)record, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) - sizeof(U16) ); + benignPolynomialCalRecord( record ); // Set the to FALSE since the record is not valid status = FALSE; @@ -2728,7 +2701,7 @@ static BOOL isDGSystemRecordValid( void ) { BOOL status = TRUE; - U16 calcCRC = crc16( (U08*)&dgSystemGroup.dgSystemRecord, sizeof(DG_SYSTEM_RECORD_T) - sizeof(U16) ); + U16 calcCRC = crc16( (U08*)&dgSystemGroup.dgSystemRecord, sizeof( DG_SYSTEM_RECORD_T ) - sizeof( U16 ) ); U16 recordCRC = dgSystemGroup.dgSystemRecord.crc; if ( calcCRC != recordCRC ) @@ -2739,7 +2712,7 @@ 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) ); + dgSystemGroup.dgSystemRecord.crc = crc16 ( (U08*)&dgSystemGroup.dgSystemRecord, sizeof( DG_SYSTEM_RECORD_T ) - sizeof( U16 ) ); activateAlarmNoData( ALARM_ID_DG_INVALID_SYSTEM_RECORD_CRC ); @@ -2770,7 +2743,7 @@ 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) ); + 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_CRC ); @@ -2784,6 +2757,36 @@ /*********************************************************************//** * @brief + * The isDGUsageRecordValid function checks whether the DG usage information + * is valid or not. + * @details Inputs: dgUsageInfoGroup + * @details Outputs: dgUsageInfoGroup + * @return TRUE if the DG usage record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGUsageRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&dgUsageInfoGroup, sizeof( DG_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); + U16 recordCRC = dgUsageInfoGroup.crc; + + if ( calcCRC != recordCRC ) + { + dgUsageInfoGroup.dgUsageInfo.isDisinfected = FALSE; + dgUsageInfoGroup.dgUsageInfo.lastChemicalDisDateEpoch = 0; + dgUsageInfoGroup.dgUsageInfo.lastHeatDisDateEpoch = 0; + dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL = 0.0; + dgUsageInfoGroup.dgUsageInfo.roWaterGenTotalL = 0.0; + dgUsageInfoGroup.dgUsageInfo.lastResetTimeEpoch = getRTCTimestamp(); + status = FALSE; + + //activateAlarmNoData( ALARM_ID_DG_INVALID_USAGE_RECORD ); + } + + return status; +} + +/*********************************************************************//** + * @brief * The isDGCalibrationRecordValid function calls other functions to check * the validity of DG calibration record. * @details Inputs: dgCalibrationRecord @@ -2796,20 +2799,15 @@ POLYNOMIAL_CAL_PAYLOAD_T* record; BOOL isHardwareRecordValid = TRUE; BOOL isCalRecordValid = TRUE; + U16 recordCRC = crc16 ( (U08*)&dgCalibrationRecord, sizeof( DG_CALIBRATION_RECORD_T ) - sizeof( U16 ) ); // Create a benign polynomial calibration record. This record is used to // clear the reserved calibration record. The reserved spaces are not used // but this will prevent those records to be nan or a random number. POLYNOMIAL_CAL_PAYLOAD_T tempRecord; - tempRecord.fourthOrderCoeff = RECORD_FOURTH_ORDER_COEFF; - tempRecord.thirdOrderCoeff = RECORD_THIRD_ORDER_COEFF; - tempRecord.secondOrderCoeff = RECORD_SECOND_ORDER_COEFF; - tempRecord.gain = RECORD_DEFAULT_GAIN; - tempRecord.offset = RECORD_DEFAULT_OFFSET; - tempRecord.calibrationTime = RECORD_DEFAULT_TIME; - // Recalculate the CRC with the default values - tempRecord.crc = crc16 ( (U08*)&tempRecord, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) - sizeof(U16) ); + benignPolynomialCalRecord( &tempRecord ); + // Get the calibration record of the hardware (i.e. pressure sensor) DG_PRES_SENSORS_CAL_RECORD_T* pressure = &dgCalibrationRecord.dgCalibrationGroups.presSensorsCalRecord; // The ones that are an array, are looped through @@ -2970,10 +2968,11 @@ // 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 ) + if ( ( FALSE == isCalRecordValid ) || ( recordCRC != dgCalibrationRecord.crc ) ) { - U16 finalCRC = crc16 ( (U08*)&dgCalibrationRecord, sizeof(DG_CALIBRATION_RECORD_T) - sizeof(U16) ); - dgCalibrationRecord.crc = finalCRC; + dgCalibrationRecord.crc = recordCRC; + + activateAlarmNoData( ALARM_ID_DG_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID ); } return isCalRecordValid; @@ -2991,15 +2990,15 @@ static BOOL isDGConcPumpRecordValid( DG_CONC_PUMPS_CAL_DATA_T* record ) { BOOL status = TRUE; - U16 calcCRC = crc16 ( (U08*)record, sizeof(DG_CONC_PUMPS_CAL_DATA_T) - sizeof(U16) ); + U16 calcCRC = crc16 ( (U08*)record, sizeof( DG_CONC_PUMPS_CAL_DATA_T ) - sizeof( U16 ) ); U16 recordCRC = record->crc; if ( calcCRC != recordCRC ) { // CRC did not pass so set all values to default record->stepSpeed2FlowRatio = RECORD_DEFAULT_RATIO; record->calibrationTime = RECORD_DEFAULT_TIME; - record->crc = crc16 ( (U08*)record, sizeof(DG_CONC_PUMPS_CAL_DATA_T) - sizeof(U16) ); + record->crc = crc16 ( (U08*)record, sizeof( DG_CONC_PUMPS_CAL_DATA_T ) - sizeof( U16 ) ); // Set the to FALSE since the record is not valid status = FALSE; @@ -3450,6 +3449,7 @@ POLYNOMIAL_CAL_PAYLOAD_T* record; BOOL isHardwareRecordValid = TRUE; BOOL isCalRecordValid = TRUE; + U16 recordCRC = crc16 ( (U08*)&hdCalibrationRecord, sizeof( HD_CALIBRATION_RECORD_T ) - sizeof( U16 ) ); HD_PUMPS_CAL_RECORD_T* pump = &hdCalibrationRecord.hdCalibrationGroups.pumpsCalRecord; for ( i = 0; i < NUM_OF_CAL_DATA_HD_PUMPS; i++ ) @@ -3507,6 +3507,13 @@ isHardwareRecordValid = isHDBloodLeakSesnorValid( bloodLeak ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + if ( ( FALSE == isCalRecordValid ) || ( hdCalibrationRecord.crc != recordCRC ) ) + { + hdCalibrationRecord.crc = recordCRC; + + activateAlarmNoData( ALARM_ID_HD_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID ); + } + return isCalRecordValid; } @@ -3799,14 +3806,19 @@ if ( getAvailableRecordQueueCount() >= MIN_JOBS_NEEDED_FOR_SECTOR_0 ) { RECORD_JOBS_STATE_T record; + NVDATAMGMT_LOCATION_STATE_T location; + // It is sector 0 of bank 7 so the sector must be erased first enqueueRecordJob( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, NVDATAMGMT_CALIBRATION_RECORD ); for ( record = NVDATAMGMT_CALIBRATION_RECORD; record < NUM_OF_NVDATMGMT_RECORDS_JOBS; record++ ) { - if ( NVDATAMGMT_EEPROM == RECORDS_SPECS[ record ].dataLoc ) + location = RECORDS_SPECS[ record ].dataLoc; + + // Loop through the records and enqueue any record that is in EEPROM to be written to the bank 7 + if ( NVDATAMGMT_EEPROM == location ) { - enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ record ].dataLoc, record ); + enqueueRecordJob( NVDATAMGMT_WRITE, location, record ); } }