Index: NVDataMgmt.c =================================================================== diff -u -r192c8f1aa79ad0ef4a50be44a6ba37a8939ac823 -refdbe5815e423124fdfa1a1efba8b61dacf170e8 --- NVDataMgmt.c (.../NVDataMgmt.c) (revision 192c8f1aa79ad0ef4a50be44a6ba37a8939ac823) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision efdbe5815e423124fdfa1a1efba8b61dacf170e8) @@ -44,6 +44,7 @@ #define QUEUE_START_INDEX 0U ///< Queue start index. #define MIN_JOBS_NEEDED_FOR_DATA_LOG 3U ///< Min queue required for data log (3). #define MIN_JOBS_NEEDED_FOR_SECTOR_0 4U ///< Min queue count needed to write all (4) records back in sector 0. +#define MAX_NUM_OF_WRITE_TRIES 3U ///< Max number of write tries. // The clock frequency comes from HCLK_FREQ and it has to be rounded up to the nearest number #define ROUNDED_HCLK_FREQ FLOAT_TO_INT_WITH_ROUND(HCLK_FREQ) ///< Rounded HCLK for EERPOM clock. @@ -228,6 +229,12 @@ U08* structAddressPtr; ///< Jobs structure address pointer. U08* structCRCPtr; ///< Jobs structure CRC pointer. NVDATAMGMT_LOCATION_STATE_T dataLoc; ///< Jobs location (i.e. EEPROM, RTC RAM). +#ifdef _DG_ + DG_EVENT_ID_T nvEvent; ///< Jobs non-volatile DG event (i.e calibration, system). +#endif +#ifdef _HD_ + HD_EVENT_ID_T nvEvent; ///< Jobs non-volatile HD event (i.e calibration, system). +#endif } PROCESS_RECORD_SPECS_T; /// Process records job structure @@ -426,16 +433,16 @@ // 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 Memory location - {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DG_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_CALIBRATION_RECORD_T), (U08*)&dgCalibrationRecord, (U08*)&dgCalibrationRecord.crc, NVDATAMGMT_EEPROM}, // NVDATAMGMT_CALIBRATION_RECORD - {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DG_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_SYSTEM_GROUP_T), (U08*)&dgSystemGroup, (U08*)&dgSystemGroup.crc, NVDATAMGMT_EEPROM}, // NVDATAMGMT_SYSTEM_RECORD - {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DG_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_SERVICE_GROUP_T), (U08*)&dgServiceGroup, (U08*)&dgServiceGroup.crc, NVDATAMGMT_EEPROM}, // NVDATAMGMT_SERVICE_RECORD + // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Memory location Event calibration record update + {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DG_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_CALIBRATION_RECORD_T), (U08*)&dgCalibrationRecord, (U08*)&dgCalibrationRecord.crc, NVDATAMGMT_EEPROM, DG_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD + {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DG_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_SYSTEM_GROUP_T), (U08*)&dgSystemGroup, (U08*)&dgSystemGroup.crc, NVDATAMGMT_EEPROM, DG_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD + {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DG_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_SERVICE_GROUP_T), (U08*)&dgServiceGroup, (U08*)&dgServiceGroup.crc, NVDATAMGMT_EEPROM, DG_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD #ifndef _RELEASE_ - {SW_CONFIGS_START_ADDRESS, sizeof(DG_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgSWConfigGroup, (U08*)&dgSWConfigGroup.crc, NVDATAMGMT_RTC}, // NVDATAMGMT_SW_CONFIG_RECORD + {SW_CONFIGS_START_ADDRESS, sizeof(DG_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgSWConfigGroup, (U08*)&dgSWConfigGroup.crc, NVDATAMGMT_RTC, DG_EVENT_SW_CONFIG_UPDATE }, // NVDATAMGMT_SW_CONFIG_RECORD #endif - {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_RTC}, // NVDATAMGMT_SCHEDULER_RECORD - {DG_HEATERS_INFO_START_ADDRESS, sizeof(DG_HEATERS_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgHeatersInfoGroup, (U08*)&dgHeatersInfoGroup.crc, NVDATAMGMT_RTC}, // NVDATAMGMT_HEATERS_INFO_RECORD - {DG_USAGE_INFO_START_ADDRESS, sizeof(DG_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgUsageInfoGroup, (U08*)&dgUsageInfoGroup.crc, NVDATAMGMT_RTC} // NVDATAMGMT_USAGE_INFO_RECORD + {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_RTC, DG_EVENT_NO_EVENT }, // NVDATAMGMT_SCHEDULER_RECORD + {DG_HEATERS_INFO_START_ADDRESS, sizeof(DG_HEATERS_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgHeatersInfoGroup, (U08*)&dgHeatersInfoGroup.crc, NVDATAMGMT_RTC, DG_EVENT_NO_EVENT }, // NVDATAMGMT_HEATERS_INFO_RECORD + {DG_USAGE_INFO_START_ADDRESS, sizeof(DG_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgUsageInfoGroup, (U08*)&dgUsageInfoGroup.crc, NVDATAMGMT_RTC, DG_EVENT_USAGE_INFO_UPDATE } // NVDATAMGMT_USAGE_INFO_RECORD }; #endif @@ -449,13 +456,14 @@ #endif // Process records specifications const PROCESS_RECORD_SPECS_T RECORDS_SPECS [ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { - {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_CALIBRATION_RECORD_T), (U08*)&hdCalibrationRecord, (U08*)&hdCalibrationRecord.crc, NVDATAMGMT_EEPROM}, // NVDATAMGMT_CALIBRATION_RECORD - {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SYSTEM_GROUP_T), (U08*)&hdSystemGroup, (U08*)&hdSystemGroup.crc, NVDATAMGMT_EEPROM}, // NVDATAMGMT_SYSTEM_RECORD - {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SERVICE_GROUP_T), (U08*)&hdServiceGroup, (U08*)&hdServiceGroup.crc, NVDATAMGMT_EEPROM}, // NVDATAMGMT_PROCESS_LAST_SERVICE_RECORD + // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Memory location Event calibration record update + {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_CALIBRATION_RECORD_T), (U08*)&hdCalibrationRecord, (U08*)&hdCalibrationRecord.crc, NVDATAMGMT_EEPROM, HD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD + {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SYSTEM_GROUP_T), (U08*)&hdSystemGroup, (U08*)&hdSystemGroup.crc, NVDATAMGMT_EEPROM, HD_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD + {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SERVICE_GROUP_T), (U08*)&hdServiceGroup, (U08*)&hdServiceGroup.crc, NVDATAMGMT_EEPROM, HD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_PROCESS_LAST_SERVICE_RECORD #ifndef _RELEASE_ - {SW_CONFIGS_START_ADDRESS, sizeof(HD_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdSWConfigGroup, (U08*)&hdSWConfigGroup.crc, NVDATAMGMT_RTC}, // NVDATAMGMT_SW_CONFIG_RECORD + {SW_CONFIGS_START_ADDRESS, sizeof(HD_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdSWConfigGroup, (U08*)&hdSWConfigGroup.crc, NVDATAMGMT_RTC, HD_EVENT_SW_CONFIG_UPDATE }, // NVDATAMGMT_SW_CONFIG_RECORD #endif - {HD_USAGE_INFO_START_ADDRESS, sizeof(HD_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdUsageInfoGroup, (U08*)&hdUsageInfoGroup.crc, NVDATAMGMT_RTC}, // NVDATAMGMT_USAGE_INFO + {HD_USAGE_INFO_START_ADDRESS, sizeof(HD_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdUsageInfoGroup, (U08*)&hdUsageInfoGroup.crc, NVDATAMGMT_RTC, HD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO }; #endif @@ -492,8 +500,8 @@ static volatile BOOL powerOffIsImminent; ///< Power off warning has been signaled. Non-volatile memory operations should be completed ASAP and then ceased. static BOOL isNewCalAvailable; ///< Signal to indicate whether a new calibration data is available. static U32 newCalStartTimer; ///< New calibration availability start timer. -static BOOL hasServiceRecordBeenUpdated; ///< Flag that indicates the service record has been updated once the calibration record has been updated. -static NVDATAMGMT_RECORDS_READ_STATUS recordsReadStatus; ///< NVDataMgmt records read status. +static NVDATAMGMT_RECORDS_READ_STATUS_T recordsReadStatus; ///< NVDataMgmt records read status. +static U32 usageWriteTries; ///< Usage write tries. // Self test functions static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadRecords( void ); @@ -529,7 +537,6 @@ static BOOL didCommandTimeout( ALARM_ID_T alarm, U08* state ); static BOOL eraseDataLogSectors( void ); static void monitorNewCalSignal( void ); -static void updateServiceRecord( void ); // Record operations queue functions static void enqueueRecordJob( NVDATAMGMT_OPERATION_STATE_T ops, NVDATAMGMT_LOCATION_STATE_T location, RECORD_JOBS_STATE_T job ); @@ -570,6 +577,7 @@ #ifdef _HD_ static BOOL isHDSystemRecordValid( void ); static BOOL isHDServiceRecordValid( void ); +static BOOL isHDUsageRecordValid( void ); static BOOL isHDCalibrationRecordValid( void ); static BOOL isHDValveRecordValid( HD_VALVE_CAL_PAYLOAD_T* record ); static BOOL isHDPumpRecordValid( HD_PUMP_CAL_PAYLOAD_T* record ); @@ -588,7 +596,7 @@ * queueFrontIndex, queueCount, recordUpdateAddress, recordQueueRearIndex, * recordQueueFrontIndex, recordQueueCount, recordAddressOffset, * writtenRecordStatus, hasPublishRecordBeenRequested, isNewCalAvailable, - * newCalStartTimer, hasServiceRecordBeenUpdated + * newCalStartTimer, hasServiceRecordBeenUpdated, usageWriteTries * @return none *************************************************************************/ void initNVDataMgmt( void ) @@ -611,7 +619,6 @@ hasPublishRecordBeenRequested = FALSE; isNewCalAvailable = FALSE; newCalStartTimer = 0; - hasServiceRecordBeenUpdated = FALSE; currentTime = 0; powerOffIsImminent = FALSE; calPublishMessageCount = 1; @@ -620,6 +627,7 @@ previousCalMessageNum = 0; recordReceiveStartTime = 0; recordsReadStatus = NVDATAMGMT_RECORDS_NOT_STARTED; + usageWriteTries = 0; enqueuePOSTReadRecords(); @@ -845,12 +853,12 @@ { // Define a pointer that points to the DG calibration record PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS[ job ]; - U08* ptr = recordSpec.structAddressPtr; + U08* ptr = recordSpec.structAddressPtr; // Offset the pointer to length that we should start writing from ptr += recordUpdateAddress; - memcpy(ptr, addressPtr, length); + memcpy( ptr, addressPtr, length ); // Check if the current message is total messages // and 0 everything out since we are done writing @@ -886,6 +894,9 @@ enqueueRecordJob( NVDATAMGMT_WRITE, recordSpec.dataLoc, job ); } + // Update the event of the received record that has been accepted + SEND_EVENT_WITH_2_U32_DATA( recordSpec.nvEvent, 0, 0 ) + // Done with receiving data, go back to idle nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; } @@ -1029,7 +1040,7 @@ break; default: - // TODO software fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_NV_RECORD_SELECTED, nvData ) break; #endif @@ -1165,12 +1176,17 @@ break; case GET_SRR_RECORD: - nvDataStartPtr = (U08*)&dgScheduledRunsGroup; + nvDataStartPtr = (U08*)&dgScheduledRunsGroup.dgScheduledRun; nvDataLength = sizeof( dgScheduledRunsGroup.dgScheduledRun ); break; + case GET_USAGE_RECORD: + nvDataStartPtr = (U08*)&dgUsageInfoGroup.dgUsageInfo; + nvDataLength = sizeof( dgUsageInfoGroup.dgUsageInfo ); + break; + default: - // TODO software fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_NV_RECORD_SELECTED, nvData ); break; #endif } @@ -1240,20 +1256,55 @@ } #endif -#ifdef _DG_ /*********************************************************************//** * @brief - * The getDGFiltersRecord function returns the DG filters record. + * The setServiceTime function sets the latest service time in epoch and updates + * the usage information after the service. * @details Inputs: none - * @details Outputs: none - * @return DG filters record + * @details Outputs: hdServiceGroup, hdUsageInfoGroup + * @return TRUE if the queue has sufficient space to enqueue all the changed + * records *************************************************************************/ -DG_FILTERS_CAL_RECORD_T getDGFiltersRecord( void ) +BOOL setServiceTime( void ) { - return dgCalibrationRecord.dgCalibrationGroups.filtersRecord; -} + BOOL status = FALSE; + + if ( getAvailableRecordQueueCount() >= ( MIN_JOBS_NEEDED_FOR_SECTOR_0 + 1 ) ) + { + // When the service record is changed, all the sector 0 must be re-written plus the stack's usage information must be updated. + // Therefore, at least 4 queues are needed to be able to update all the records. The usage records are changed: + // 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 +#ifdef _HD_ + hdServiceGroup.hdServiceRecord.lastServiceEpochDate = getRTCTimestamp(); + hdServiceGroup.hdServiceRecord.crc = crc16( (U08*)&hdServiceGroup.hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + hdServiceGroup.crc = crc16( (U08*)&hdServiceGroup, sizeof( HD_SERVICE_GROUP_T ) - sizeof( U16 ) ); + // Update the HD usage info + hdUsageInfoGroup.hdUsageInfo.txTimeSinceLastSrvcHrs = 0; + hdUsageInfoGroup.hdUsageInfo.crc = crc16( (U08*)&hdUsageInfoGroup.hdUsageInfo, sizeof( HD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + hdUsageInfoGroup.crc = crc16( (U08*)&hdUsageInfoGroup, sizeof( HD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); #endif +#ifdef _DG_ + dgServiceGroup.dgServiceRecord.lastServiceEpochDate = getRTCTimestamp(); + dgServiceGroup.dgServiceRecord.crc = crc16( (U08*)&dgServiceGroup.dgServiceRecord, sizeof( DG_SERVICE_RECORD_T ) - sizeof( U16 ) ); + dgServiceGroup.crc = crc16( (U08*)&dgServiceGroup, sizeof( DG_SERVICE_GROUP_T ) - sizeof( U16 ) ); + // Update the DG usage info + dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL = 0; + 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 ) ); +#endif + // Service record has been touched so the entire sector 0 of the EEPROM must be rewritten + enqueueSector0Records(); + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + // Both the usage and service records have been updated + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ) + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ].nvEvent, 0, 0 ) + } + + return status; +} + /*********************************************************************//** * @brief * The writeLogData checks if the queue is not full and if it is not, it calls @@ -1307,31 +1358,27 @@ * @details Inputs: none * @details Outputs: hdUsageInfoGroup * @param hours treatment time in hours - * @param isServiceDone flag to indicate the service has been done * @return TRUE if the queue was not full so the job was scheduled successfully *************************************************************************/ -BOOL setTxTimeHours( F32 hours, BOOL isServiceDone ) +BOOL setTxTimeHours( F32 hours ) { BOOL status = FALSE; - if ( TRUE == isServiceDone ) + if ( FALSE == isQueueFull() ) { - hdUsageInfoGroup.hdUsageInfo.txTimeTotalHrs += hdUsageInfoGroup.hdUsageInfo.txTimeSinceLastSrvcHrs; - hdUsageInfoGroup.hdUsageInfo.txTimeSinceLastSrvcHrs = hours; - } - else - { hdUsageInfoGroup.hdUsageInfo.txTimeSinceLastSrvcHrs += hours; hdUsageInfoGroup.hdUsageInfo.txTimeTotalHrs += hdUsageInfoGroup.hdUsageInfo.txTimeSinceLastSrvcHrs; - } + hdUsageInfoGroup.hdUsageInfo.crc = crc16( (U08*)&hdUsageInfoGroup.hdUsageInfo, sizeof( HD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + hdUsageInfoGroup.crc = crc16( (U08*)&hdUsageInfoGroup, sizeof( HD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); + usageWriteTries = 0; + status = TRUE; - hdUsageInfoGroup.hdUsageInfo.crc = crc16( (U08*)&hdUsageInfoGroup.hdUsageInfo, sizeof( HD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); - hdUsageInfoGroup.crc = crc16( (U08*)&hdUsageInfoGroup, sizeof( HD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); - - if ( FALSE == isQueueFull() ) + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ) + } + else if ( ++usageWriteTries > MAX_NUM_OF_WRITE_TRIES ) { - enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, HD_USAGE_INFO_START_ADDRESS, (U08*)&hdUsageInfoGroup, 0, sizeof( HD_USAGE_INFO_GROUP_T ) ); - status = TRUE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_WRITE_USAGE_INFO_TO_NV_FAILURE, USAGE_INFO_TX_HOURS_SINCE_LAST_SRVC ); } return status; @@ -1346,16 +1393,23 @@ *************************************************************************/ BOOL setTxLastStartTimeEpoch( U32 epoch ) { - BOOL status = FALSE; - hdUsageInfoGroup.hdUsageInfo.txLastStartTimeEpoch = epoch; - hdUsageInfoGroup.hdUsageInfo.crc = crc16 ( (U08*)&hdUsageInfoGroup.hdUsageInfo, sizeof( HD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); - hdUsageInfoGroup.crc = crc16 ( (U08*)&hdUsageInfoGroup, sizeof( HD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); + BOOL status = FALSE; if ( FALSE == isQueueFull() ) { - enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, HD_USAGE_INFO_START_ADDRESS, (U08*)&hdUsageInfoGroup, 0, sizeof( HD_USAGE_INFO_GROUP_T ) ); - status = TRUE; + hdUsageInfoGroup.hdUsageInfo.txLastStartTimeEpoch = epoch; + hdUsageInfoGroup.hdUsageInfo.crc = crc16 ( (U08*)&hdUsageInfoGroup.hdUsageInfo, sizeof( HD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + hdUsageInfoGroup.crc = crc16 ( (U08*)&hdUsageInfoGroup, sizeof( HD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); + usageWriteTries = 0; + status = TRUE; + + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ) } + else if ( ++usageWriteTries > MAX_NUM_OF_WRITE_TRIES ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_WRITE_USAGE_INFO_TO_NV_FAILURE, USAGE_INFO_START_TX_TIME ); + } return status; } @@ -1380,29 +1434,22 @@ 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 ) ); + usageWriteTries = 0; + status = TRUE; - enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, NVDATAMGMT_USAGE_INFO_RECORD ); - status = TRUE; + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ) } + else if ( ++usageWriteTries > MAX_NUM_OF_WRITE_TRIES ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_WRITE_USAGE_INFO_TO_NV_FAILURE, USAGE_INFO_RO_GEN_WATER ); + } return status; } /*********************************************************************//** * @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 @@ -1411,28 +1458,34 @@ * @param epochTime last disinfect time in epoch * @return TRUE if queue is not full *************************************************************************/ -BOOL setLastDisinfectDate( DG_DISINFECT_T disinfect, U32 epochTime ) +BOOL setLastDisinfectDate( DG_USAGE_INFO_ITEMS_T disinfect, U32 epochTime ) { BOOL status = FALSE; - switch ( disinfect ) + if ( FALSE == isQueueFull() ) { - case USAGE_INFO_HEAT_DISINFECT: - dgUsageInfoGroup.dgUsageInfo.lastHeatDisDateEpoch = epochTime; - break; + switch ( disinfect ) + { + case USAGE_INFO_HEAT_DISINFECT: + dgUsageInfoGroup.dgUsageInfo.lastHeatDisDateEpoch = epochTime; + break; - case USAGE_INFO_CHEMICAL_DISINFECT: - dgUsageInfoGroup.dgUsageInfo.lastChemicalDisDateEpoch = 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 ) ); + 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 ) ); + usageWriteTries = 0; + status = TRUE; - if ( FALSE == isQueueFull() ) + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ) + } + else if ( ++usageWriteTries > MAX_NUM_OF_WRITE_TRIES ) { - enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, DG_USAGE_INFO_START_ADDRESS, (U08*)&dgUsageInfoGroup, 0, sizeof( DG_USAGE_INFO_GROUP_T ) ); - status = TRUE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_WRITE_USAGE_INFO_TO_NV_FAILURE, disinfect ); } return status; @@ -1449,16 +1502,23 @@ *************************************************************************/ BOOL setDisinfectStatus( BOOL disinfectStatus ) { - BOOL status = FALSE; - dgUsageInfoGroup.dgUsageInfo.isDisinfected = disinfectStatus; - 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; if ( FALSE == isQueueFull() ) { - enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, DG_USAGE_INFO_START_ADDRESS, (U08*)&dgUsageInfoGroup, 0, sizeof( DG_USAGE_INFO_GROUP_T ) ); - status = TRUE; + dgUsageInfoGroup.dgUsageInfo.isDisinfected = disinfectStatus; + 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 ) ); + usageWriteTries = 0; + status = TRUE; + + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ) } + else if ( ++usageWriteTries > MAX_NUM_OF_WRITE_TRIES ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_WRITE_USAGE_INFO_TO_NV_FAILURE, USAGE_INFO_DISIFNECT_STATUS ); + } return status; } @@ -1505,7 +1565,7 @@ * @details Outputs: none * @return recordsReadStatus *************************************************************************/ -NVDATAMGMT_RECORDS_READ_STATUS getNVRecordsReadStatus( void ) +NVDATAMGMT_RECORDS_READ_STATUS_T getNVRecordsReadStatus( void ) { return recordsReadStatus; } @@ -1580,7 +1640,7 @@ haveCalGroupsPassed = isDGCalibrationRecordValid(); hasSystemRecordPassed = isDGSystemRecordValid(); hasServiceRecordPassed = isDGServiceRecordValid(); - hasUsageRecordPassed = isDGUsageRecordValid(); // TODO add an alarm once dialin is completed in DEN-13834 + hasUsageRecordPassed = isDGUsageRecordValid(); #ifndef _RELEASE_ hasSWConfigRecordPassed = isSWConfigRecordValid(); #endif @@ -1589,6 +1649,7 @@ haveCalGroupsPassed = isHDCalibrationRecordValid(); hasSystemRecordPassed = isHDSystemRecordValid(); hasServiceRecordPassed = isHDServiceRecordValid(); + hasUsageRecordPassed = isHDUsageRecordValid(); #ifndef _RELEASE_ hasSWConfigRecordPassed = isSWConfigRecordValid(); #endif @@ -1600,22 +1661,22 @@ if ( ( FALSE == hasServiceRecordPassed ) || ( FALSE == haveCalGroupsPassed ) || ( FALSE == hasSystemRecordPassed ) ) { enqueueSector0Records(); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_CALIBRATION_RECORD ].nvEvent, 0, 0 ) + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SYSTEM_RECORD ].nvEvent, 0, 0 ) + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ].nvEvent, 0, 0 ) } if ( FALSE == hasSWConfigRecordPassed ) { enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_SW_CONFIG_RECORD ].dataLoc, NVDATAMGMT_SW_CONFIG_RECORD ); - } + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SW_CONFIG_RECORD ].nvEvent, 0, 0 ) - if ( FALSE == hasServiceRecordPassed ) - { - enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ].dataLoc, NVDATAMGMT_SERVICE_RECORD ); } if ( FALSE == hasUsageRecordPassed ) { - // TODO un-comment in DEN-13834 - //enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + enqueueRecordJob( NVDATAMGMT_WRITE, RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].dataLoc, NVDATAMGMT_USAGE_INFO_RECORD ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ) } // Check if the records' entire CRCs as well as the individual CRCs passed @@ -1654,9 +1715,6 @@ // If power off command has been issued, do not process any new jobs if ( powerOffIsImminent != TRUE ) { - // Check if the service record has to be updated - //updateServiceRecord(); // TODO what is this doing here? un-comment in DEN-13834 - // If the record processing queue is not empty, process the queues if ( ( FALSE == isRecordQueueEmpty() ) && ( TRUE == areResourcesAvailableForNextJob() ) ) { @@ -1689,7 +1747,7 @@ } } } - // TODO add the log queue later in Phase 1B. + // Add the log queue later in Phase 1B. } // Check if a queue job is available @@ -1725,7 +1783,7 @@ else if ( ( NVDATAMGMT_READ == ops ) && ( NVDATAMGMT_RTC == location ) ) { readFromRAM( startAddress, maxBufferLength ); - //currentJob.externalAddress->status = NVDATAMGMT_READ_IN_PROGRESS; // TODO Phase 1B for logging + //currentJob.externalAddress->status = NVDATAMGMT_READ_IN_PROGRESS; // Phase 1B for logging currentTime = getMSTimerCount(); state = NVDATAMGMT_EXEC_STATE_READ_FROM_RTC; @@ -1795,7 +1853,6 @@ // If timed out, get back to Idle else if ( timeoutStatus == TRUE ) { - // TODO schedule another write? recordAddressOffset = 0; state = NVDATAMGMT_EXEC_STATE_IDLE; } @@ -1974,7 +2031,6 @@ // If timed out, get back to Idle else if ( timeoutStatus == TRUE ) { - // TODO schedule another write? recordAddressOffset = 0; state = NVDATAMGMT_EXEC_STATE_IDLE; } @@ -2571,35 +2627,6 @@ /*********************************************************************//** * @brief - * The updateServiceRecord function updates the service record once there is - * a new calibration record received. - * @details Inputs: isNewCalAvailable - * @details Outputs: isNewCalAvailable, hasServiceRecordBeenUpdated - * @return none - *************************************************************************/ -static void updateServiceRecord( void ) -{ - // If a new calibration is available and the service record has not been updated, updated the service record - // Right now, the last service date is updated once a new calibration record is received by the service personnel - if ( ( TRUE == isNewCalAvailable ) && ( FALSE == hasServiceRecordBeenUpdated ) ) - { -#ifdef _HD_ - hdServiceGroup.hdServiceRecord.lastServiceEpochDate = getRTCTimestamp(); - hdServiceGroup.hdServiceRecord.serviceLoc = 0; - hdServiceGroup.hdServiceRecord.crc = crc16( (U08*)&hdServiceGroup.hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ) - sizeof( U16 ) ); - hdServiceGroup.crc = crc16( (U08*)&hdServiceGroup, sizeof( HD_SERVICE_GROUP_T ) - sizeof( U16 ) ); - - if ( FALSE == isQueueFull() ) - { - enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, SERVICE_RECORD_NV_MEM_START_ADDRESS, (U08*)&hdServiceGroup, 0, sizeof( HD_SERVICE_RECORD_T ) ); - hasServiceRecordBeenUpdated = TRUE; - } -#endif - } -} - -/*********************************************************************//** - * @brief * The isPolynomialRecordValid function checks whether the records are * still valid by calculating the CRCs and comparing it to the strucutre's * CRC. @@ -2642,31 +2669,31 @@ BOOL status = TRUE; #ifdef _DG_ - U16 calcCRC = crc16( (U08*)&dgSWConfigGroup, sizeof( DG_SW_CONFIG_GROUP_T ) - sizeof(U16) ); + U16 calcCRC = crc16( (U08*)&dgSWConfigGroup, sizeof( DG_SW_CONFIG_GROUP_T ) - sizeof( U16 ) ); U16 recordCRC = dgSWConfigGroup.crc; if ( calcCRC != recordCRC ) { memset( (U08*)&dgSWConfigGroup, 0, sizeof( DG_SW_CONFIG_GROUP_T ) ); // Recalculate the CRC with the default values - dgSWConfigGroup.crc = crc16( (U08*)&dgSWConfigGroup, sizeof( DG_SW_CONFIG_GROUP_T ) - sizeof(U16) ); + dgSWConfigGroup.crc = crc16( (U08*)&dgSWConfigGroup, sizeof( DG_SW_CONFIG_GROUP_T ) - sizeof( U16 ) ); // Set the to FALSE since the record is not valid status = FALSE; } #endif #ifdef _HD_ - U16 calcCRC = crc16( (U08*)&hdSWConfigGroup, sizeof( HD_SW_CONFIG_GROUP_T ) - sizeof(U16) ); + U16 calcCRC = crc16( (U08*)&hdSWConfigGroup, sizeof( HD_SW_CONFIG_GROUP_T ) - sizeof( U16 ) ); U16 recordCRC = hdSWConfigGroup.crc; if ( calcCRC != recordCRC ) { memset( (U08*)&hdSWConfigGroup, SW_CONFIG_DISABLE_VALUE, sizeof( HD_SW_CONFIG_GROUP_T ) ); // Recalculate the CRC with the default values - hdSWConfigGroup.crc = crc16( (U08*)&hdSWConfigGroup, sizeof( HD_SW_CONFIG_GROUP_T ) - sizeof(U16) ); + hdSWConfigGroup.crc = crc16( (U08*)&hdSWConfigGroup, sizeof( HD_SW_CONFIG_GROUP_T ) - sizeof( U16 ) ); // Set the to FALSE since the record is not valid status = FALSE; @@ -2699,14 +2726,21 @@ dgSystemGroup.dgSystemRecord.mfgLocation = 0; memset( dgSystemGroup.dgSystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( dgSystemGroup.dgSystemRecord.topLevelPN ) ); memset( dgSystemGroup.dgSystemRecord.topLevelSN, RECORD_DEFAULT_CHARACTER, sizeof( dgSystemGroup.dgSystemRecord.topLevelSN ) ); + // 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 ) ); + dgSystemGroup.crc = crc16 ( (U08*)&dgSystemGroup, sizeof( DG_SYSTEM_GROUP_T ) - sizeof( U16 ) ); + status = FALSE; activateAlarmNoData( ALARM_ID_DG_INVALID_SYSTEM_RECORD_CRC ); - - // Set the to FALSE since the record is not valid - status = FALSE; } + else + { + if ( RECORD_DEFAULT_CHARACTER == dgSystemGroup.dgSystemRecord.topLevelSN[ 0 ] ) + { + activateAlarmNoData( ALARM_ID_DG_INVALID_SERIAL_NUMBER ); + } + } return status; } @@ -2722,22 +2756,21 @@ static BOOL isDGServiceRecordValid( void ) { BOOL status = TRUE; - U16 calcCRC = crc16( (U08*)&dgServiceGroup.dgServiceRecord, sizeof(DG_SERVICE_RECORD_T) - sizeof(U16) ); + 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 ) ); + dgServiceGroup.dgServiceRecord.lastResetTimeEpoch = getRTCTimestamp(); // TODO un-comment with the next calibration table roll out + dgServiceGroup.dgServiceRecord.crc = crc16 ( (U08*)&dgServiceGroup.dgServiceRecord, sizeof( DG_SERVICE_RECORD_T ) - sizeof( U16 ) ); + dgServiceGroup.crc = crc16 ( (U08*)&dgServiceGroup, sizeof( DG_SERVICE_GROUP_T ) - sizeof( U16 ) ); + status = FALSE; // Service record failure is also considered as RTC RAM failure activateAlarmNoData( ALARM_ID_DG_INVALID_SERVICE_RECORD_CRC ); - - // Set the to FALSE since the record is not valid - status = FALSE; } return status; @@ -2754,8 +2787,8 @@ static BOOL isDGUsageRecordValid( void ) { BOOL status = TRUE; - U16 calcCRC = crc16( (U08*)&dgUsageInfoGroup, sizeof( DG_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); - U16 recordCRC = dgUsageInfoGroup.crc; + U16 calcCRC = crc16( (U08*)&dgUsageInfoGroup.dgUsageInfo, sizeof( DG_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = dgUsageInfoGroup.dgUsageInfo.crc; if ( calcCRC != recordCRC ) { @@ -2765,9 +2798,11 @@ dgUsageInfoGroup.dgUsageInfo.roWaterGenSinceLastServiceL = 0.0; dgUsageInfoGroup.dgUsageInfo.roWaterGenTotalL = 0.0; dgUsageInfoGroup.dgUsageInfo.lastResetTimeEpoch = getRTCTimestamp(); + 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 ) ); status = FALSE; - //activateAlarmNoData( ALARM_ID_DG_INVALID_USAGE_RECORD ); // TODO remove when dialin is implemented + activateAlarmNoData( ALARM_ID_DG_INVALID_USAGE_RECORD_CRC ); } return status; @@ -3381,13 +3416,20 @@ memset( hdSystemGroup.hdsystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( hdSystemGroup.hdsystemRecord.topLevelPN ) ); memset( hdSystemGroup.hdsystemRecord.topLevelSN, RECORD_DEFAULT_CHARACTER, sizeof( hdSystemGroup.hdsystemRecord.topLevelSN ) ); // Recalculate the CRC with the default values - hdSystemGroup.hdsystemRecord.crc = crc16 ( (U08*)&hdSystemGroup.hdsystemRecord, sizeof( HD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); + hdSystemGroup.hdsystemRecord.crc = crc16 ( (U08*)&hdSystemGroup.hdsystemRecord, sizeof( HD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); + hdSystemGroup.crc = crc16 ( (U08*)&hdSystemGroup, sizeof( HD_SYSTEM_GROUP_T ) - sizeof( U16 ) ); + status = FALSE; activateAlarmNoData( ALARM_ID_HD_INVALID_SYSTEM_RECORD_CRC ); - - // Set the to FALSE since the record is not valid - status = FALSE; } + else + { + // Check if the first character of the serial number is not empty space. If it is, trigger the alarm + if ( RECORD_DEFAULT_CHARACTER == hdSystemGroup.hdsystemRecord.topLevelSN[ 0 ] ) + { + activateAlarmNoData( ALARM_ID_HD_INVALID_SERIAL_NUMBER ); + } + } return status; } @@ -3411,14 +3453,43 @@ // 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 ) ); + hdServiceGroup.hdServiceRecord.lastServiceEpochDate = getRTCTimestamp(); + hdServiceGroup.hdServiceRecord.crc = crc16 ( (U08*)&hdServiceGroup.hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + hdServiceGroup.crc = crc16 ( (U08*)&hdServiceGroup, sizeof( HD_SERVICE_GROUP_T ) - sizeof( U16 ) ); + status = FALSE; // Service record failure is also considered as RTC RAM failure activateAlarmNoData( ALARM_ID_HD_INVALID_SERVICE_RECORD_CRC ); + } - // Set the to FALSE since the record is not valid - status = FALSE; + return status; +} + +/*********************************************************************//** + * @brief + * The isHDUsageRecordValid function checks whether the HD 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 isHDUsageRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&hdUsageInfoGroup.hdUsageInfo, sizeof( HD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = hdUsageInfoGroup.hdUsageInfo.crc; + + if ( calcCRC != recordCRC ) + { + hdUsageInfoGroup.hdUsageInfo.txLastStartTimeEpoch = 0; + hdUsageInfoGroup.hdUsageInfo.txTimeSinceLastSrvcHrs = 0; + hdUsageInfoGroup.hdUsageInfo.txTimeTotalHrs = 0; + hdUsageInfoGroup.hdUsageInfo.lastResetTimeEpoch = getRTCTimestamp(); + hdUsageInfoGroup.hdUsageInfo.crc = crc16( (U08*)&hdUsageInfoGroup.hdUsageInfo, sizeof( HD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + hdUsageInfoGroup.crc = crc16( (U08*)&hdUsageInfoGroup, sizeof( HD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); + status = FALSE; + + activateAlarmNoData( ALARM_ID_HD_INVALID_USAGE_RECORD_CRC ); } return status;