Index: NVDataMgmt.c =================================================================== diff -u -rf853004049bc4701d911701e48768cd17189faea -r5ed781a9474910ff9db65e4ef0ab995e03e312fa --- NVDataMgmt.c (.../NVDataMgmt.c) (revision f853004049bc4701d911701e48768cd17189faea) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision 5ed781a9474910ff9db65e4ef0ab995e03e312fa) @@ -79,6 +79,7 @@ #define SERVICE_RECORD_START_ADDRESS 0x00000030 // 48 ///< Service date record start address in RTC RAM (HD/DG) (48). #define DG_SCHEDULED_RUNS_START_ADDRESS (SERVICE_RECORD_START_ADDRESS + sizeof(DG_SERVICE_GROUP_T)) ///< DG scheduled runs start address in RTC RAM. #define DG_HEATERS_INFO_START_ADDRESS (DG_SCHEDULED_RUNS_START_ADDRESS + sizeof(DG_HEATERS_INFO_GROUP_T))///< DG heaters info start address in RTC RAM. +#define SW_CONFIGS_START_ADDRESS 0x00000100 // 256 ///< Software configurations 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 divided by 4. @@ -120,14 +121,17 @@ // 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. -#define PRES_SENSORS_RESERVED_SPACE_COUNT 6 ///< Pressure sensors reserved space count. -#define FLOW_SENSROS_RESERVED_SPACE_COUNT 3 ///< Flow sensors reserved space count. -#define TEMP_SENSORS_RESERVED_SPACE_COUNT 5 ///< Temperature sensors reserved space count. -#define COND_SENSORS_RESERVED_SPACE_COUNT 2 ///< Conductivity sensors reserved space count. -#define GENERIC_VOL_RESERVED_SPACE_COUNT 4 ///< Generic volumes reserved space count. +#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. +#define PRES_SENSORS_RESERVED_SPACE_COUNT 6 ///< Pressure sensors reserved space count. +#define FLOW_SENSROS_RESERVED_SPACE_COUNT 3 ///< Flow sensors reserved space count. +#define TEMP_SENSORS_RESERVED_SPACE_COUNT 5 ///< Temperature sensors reserved space count. +#define COND_SENSORS_RESERVED_SPACE_COUNT 2 ///< Conductivity sensors reserved space count. +#define GENERIC_VOL_RESERVED_SPACE_COUNT 4 ///< Generic volumes reserved space count. +#define RESERVOIR_TEMPERATURE_TAU_C_PER_MIN -0.512 ///< Reservoir temperature time constant C/min. +#define ULTRAFILTER_TEMPERATURE_TAU_C_PER_MIN -4.565 ///< Ultrafilter temperature time constant C/min. +#define ULTRAFILTER_VOLUME_ML 700 ///< Ultrafilter volume in milliliters. #endif /// NVDataMgmt self-test states enumeration. @@ -142,6 +146,7 @@ NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME, ///< Self test read treatment time. TODO combine with water consumption NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION, ///< Self test read water consumption. TODO combine with tx time NVDATAMGMT_SELF_TEST_STATE_READ_DG_HEATERS_INFO, ///< Self test read DG heaters information. + NVDATAMGMT_SELF_TEST_STATE_READ_SW_CONFIG_RECORD, ///< Self test read software configuration record. 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. @@ -196,19 +201,6 @@ NUM_OF_NVDATAMGMT_RECEIVE_RECORD_STATES ///< Number of NVDataMgmt receive record. } RECEIVE_RECORD_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. -#ifdef _DG_ - NVDATAMGMT_SCHEDULED_RUNS_RECORD, ///< NVDataMgmt process scheduled runs record. - NVDATAMGMT_HEATERS_INFO_RECORD, ///< NVDataMgmt process heaters info record. -#endif - NUM_OF_NVDATMGMT_RECORDS_JOBS ///< Number of NVDataMgmt records jobs. -} RECORD_JOBS_STATE_T; - /// NVDataMgmt write record validity check states typedef enum NVDataMgmt_Write_Record_Validity_Check { @@ -237,6 +229,7 @@ U32 maxReadBufferSize; ///< Jobs max read allowed processing buffer size. U08* structAddressPtr; ///< Jobs structure address pointer. U08* structCRCPtr; ///< Jobs structure CRC pointer. + NVDATAMGMT_LOCATION_STATE_T dataLoc; ///< Jobs location (i.e. EEPROM, RTC RAM). } PROCESS_RECORD_SPECS_T; /// Process records job structure @@ -253,7 +246,7 @@ NVDATAMGMT_OPERATION_STATE_T memoryOperation; ///< Memory operation. NVDATAMGMT_LOCATION_STATE_T memoryLocation; ///< Memory location. U32 startAddress; ///< Operation start address. - U08 buffer [ MAX_JOB_DATA_SIZE_BYTES ]; ///< Buffer. + U08 buffer[ MAX_JOB_DATA_SIZE_BYTES ]; ///< Buffer. READ_DATA_T* externalAddress; ///< External address of a buffer. U32 length; ///< Length of a buffer. } MEMORY_LOG_OPS_T; @@ -274,6 +267,15 @@ U16 crc; ///< Log header CRC. } LOG_RECORD_T; +typedef struct +{ + U08 swConfigs[ NUM_OF_SW_CONFIGS ]; ///< 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(NUM_OF_SW_CONFIGS, MAX_RTC_RAM_OPS_BUFFER_BYTES) - + RECORD_BYTE_SIZE(NUM_OF_SW_CONFIGS) ]; ///< Software configurations group padding. + U16 crc; ///< Software configurations CRC. +} SW_CONFIGS_RECORD_T; + // ********** HD/DG record structures ********** #ifdef _DG_ @@ -297,6 +299,7 @@ DG_FILTERS_CAL_RECORD_T filtersRecord; ///< DG filters. DG_FANS_CAL_RECORD_T fansRecord; ///< DG fans. DG_ACCEL_SENSOR_CAL_RECORD_T accelerometerSensorCalRecord; ///< DG accelerometer sensor. + DG_HEATING_CAL_RECORD_T heatingCalRecord; ///< DG heating calibration record. } DG_CALIBRATION_GROUPS_T; /// DG calibration records structure @@ -407,6 +410,8 @@ #endif #pragma pack(pop) +static SW_CONFIGS_RECORD_T swConfigsRecord; ///< Software configurations record. + // Calibration variables #ifdef _DG_ static DG_CALIBRATION_RECORD_T dgCalibrationRecord; ///< DG calibration record structure (including padding and final CRC). @@ -417,11 +422,12 @@ static DG_HEATERS_INFO_GROUP_T dgHeatersInfoGroup; ///< DG heaters info structure (including padding and final CRC). // Process records specifications const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { - {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_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_SYSTEM_RECORD - {SERVICE_RECORD_START_ADDRESS, sizeof(DG_SERVICE_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgServiceGroup, (U08*)&dgServiceGroup.crc}, // NVDATAMGMT_SERVICE_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_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_HEATERS_INFO_RECORD + {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_START_ADDRESS, sizeof(DG_SERVICE_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgServiceGroup, (U08*)&dgServiceGroup.crc, NVDATAMGMT_RTC}, // NVDATAMGMT_SERVICE_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}, // 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 + {SW_CONFIGS_START_ADDRESS, sizeof(SW_CONFIGS_RECORD_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&swConfigsRecord, (U08*)&swConfigsRecord.crc, NVDATAMGMT_RTC} // NVDATAMGMT_SW_CONFIG_RECORD }; #endif @@ -488,6 +494,7 @@ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGHeatersInfo( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGWaterConsumption( void ); #endif +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadSWConfigRecord( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadLogRecord( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestCheckCRC( void ); @@ -531,6 +538,7 @@ // Record check helper functions static BOOL areRecordsValid( void ); static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ); +static BOOL isSWConfigRecordValid( void ); #ifdef _DG_ static BOOL isDGSystemRecordValid( void ); @@ -548,6 +556,7 @@ static BOOL isDGFilterRecordValid( DG_FILTER_CAL_RECORD_T* record ); static BOOL isDGFanRecordValid( DG_FAN_CAL_RECORD_T* record ); static BOOL isDGAccelerometerSensorRecordValid( DG_ACCEL_SENSOR_CAL_RECORD_T* record ); +static BOOL isDGHeatingCalRecordValid( DG_HEATING_CAL_RECORD_T* record ); #endif #ifdef _HD_ @@ -723,6 +732,9 @@ nvDataMgmtSelfTestState = handleSelfTestReadDGHeatersInfo(); break; #endif + case NVDATAMGMT_SELF_TEST_STATE_READ_SW_CONFIG_RECORD: + nvDataMgmtSelfTestState = handleSelfTestReadSWConfigRecord(); + break; case NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC: nvDataMgmtSelfTestState = handleSelfTestCheckCRC(); @@ -1122,6 +1134,119 @@ return status; } +/*********************************************************************//** + * @brief + * The sendRecordToDialin function prepares the process record state machine + * to send a record to Dialin. + * @details Inputs: nvDataMgmtExecProcessRecordState + * @details Outputs: hasPublishRecordBeenRequested, recordToPublish + * @param job type of job that is requested (i.e. get calibration record, ...) + * @return TRUE if the request was successfully registered + *************************************************************************/ +BOOL sendRecordToDialin( RECORD_JOBS_STATE_T job ) +{ + BOOL status = FALSE; + + // Check if the state machine is in idle state and then set the request + if ( NVDATAMGMT_PROCESS_RECORD_STATE_IDLE == nvDataMgmtExecProcessRecordState ) + { + hasPublishRecordBeenRequested = TRUE; + recordToPublish = job; + status = TRUE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The receiveRecordFromDialin function receives the record that has been sent + * from Dialin and if the CRCs passed, it schedules a write to the NV data. + * @details Inputs: currentMessage, nvDataMgmtExecReceiveRecordState, + * previousCalMessageNum, totalMessages, previousCalMessageNum, + * @details Outputs: nvDataMgmtExecReceiveRecordState, recordReceiveStartTime, + * previousCalMessageNum, recordUpdateAddress, recordUpdateAddress + * @param job: the job that has to be received and written (i.e. service record) + * @param currentMessage: current message number that is received from 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 + * @return TRUE if the request was successfully registered + *************************************************************************/ +BOOL receiveRecordFromDialin( RECORD_JOBS_STATE_T job, 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 ) && ( NVDATAMGMT_RECEIVE_RECORD_IDLE == nvDataMgmtExecReceiveRecordState ) ) + { + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; + recordReceiveStartTime = getMSTimerCount(); + previousCalMessageNum = 0; + recordUpdateAddress = 0; + } + + // Check if there is still a message left to be received + 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 ) ) + { + // Define a pointer that points to the DG calibration record + PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS[ job ]; + U08* ptr = recordSpec.structAddressPtr; + + // Offset the pointer to length that we should start writing from + ptr += recordUpdateAddress; + + memcpy(ptr, addressPtr, length); + + // Check if the current message is total messages + // and 0 everything out since we are done writing + if ( currentMessage == totalMessages ) + { + U16 calcCRC = crc16 ( recordSpec.structAddressPtr, recordSpec.sizeofJob - sizeof(U16) ); + // Get the CRC of the structure without the last 16 bits which is the CRC as well as the padding values + U16 recordCRC = *(U16*)recordSpec.structCRCPtr; + + if ( calcCRC != recordCRC ) + { + // CRC failed, request a read to read the data back from NV memory and update the structure + enqueueRecordJob( NVDATAMGMT_READ, recordSpec.dataLoc, job ); + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + status = FALSE; + } + else + { + if ( NVDATAMGMT_EEPROM == recordSpec.dataLoc ) + { + // CRC passed, enqueue an erase, a write of calibration data and a write of service record + BOOL scheduleStatus = enqueueSector0Records(); + } + else + { + // CRC passed write the last service record to the RTC RAM + enqueueRecordJob( NVDATAMGMT_WRITE, recordSpec.dataLoc, job ); + } + + // Done with receiving data, go back to idle + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + } + } + else + { + // Update the length as it has successfully been written + recordUpdateAddress += length; + + // Now the current message is the previous message + previousCalMessageNum = currentMessage; + } + } + } + + return status; +} + #ifdef _DG_ /*********************************************************************//** * @brief @@ -1352,6 +1477,16 @@ isNVDataValid |= ( 0 == dgCalibrationRecord.dgCalibrationGroups.reservoirVolumesRecord.reservoir[ i ].calibrationTime ? FALSE : TRUE ); break; + case GET_CAL_HEATING_RECORD: + nvDataStartPtr = (U08*)&dgCalibrationRecord.dgCalibrationGroups.heatingCalRecord; + isNVDataValid = ( 0 == dgCalibrationRecord.dgCalibrationGroups.heatingCalRecord.calibrationTime ? FALSE : TRUE ); + break; + + case GET_CAL_DRAIN_LINE_VOLUME_RECORD: + nvDataStartPtr = (U08*)&dgCalibrationRecord.dgCalibrationGroups.drainLineVolumeRecord; + isNVDataValid = ( 0 == dgCalibrationRecord.dgCalibrationGroups.drainLineVolumeRecord.calibrationTime ? FALSE : TRUE ); + break; + case GET_INF_HEATERS_RECORD: nvDataStartPtr = (U08*)&dgHeatersInfoGroup.dgHeatersInfo; nvDataLength = sizeof( dgHeatersInfoGroup.dgHeatersInfo ); @@ -1398,6 +1533,29 @@ return isNVDataValid; } +/*********************************************************************//** + * @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 +#ifndef _RELEASE_ + value = swConfigsRecord.swConfigs[ config ]; +#endif + + return value; +} + #ifdef _DG_ /*********************************************************************//** * @brief @@ -1439,32 +1597,6 @@ /*********************************************************************//** * @brief - * The getDGDrainLineVolumeRecord function returns the DG drain volume - * record. - * @details Inputs: none - * @details Outputs: none - * @return DG drain volume record - *************************************************************************/ -DG_DRAIN_LINE_VOLUME_T getDGDrainLineVolumeRecord( void ) -{ - return dgCalibrationRecord.dgCalibrationGroups.drainLineVolumeRecord; -} - -/*********************************************************************//** - * @brief - * The getDGReservoirsVolumeRecord function returns the DG reservoirs - * volume record. - * @details Inputs: none - * @details Outputs: none - * @return DG reservoirs volume record - *************************************************************************/ -DG_RESERVOIR_VOLUME_RECORD_T getDGReservoirsVolumeRecord( void ) -{ - return dgCalibrationRecord.dgCalibrationGroups.reservoirVolumesRecord; -} - -/*********************************************************************//** - * @brief * The getDGFiltersRecord function returns the DG filters record. * @details Inputs: none * @details Outputs: none @@ -1748,20 +1880,28 @@ * @details Outputs: dgHeatersInfoGroup * @param addressPrt which is an address to the structure that is holding the * heaters information. + * @param infoLength which is the lenght of the heaters info to be written to + * the NV RAM. * @return TRUE if queue is not full otherwise, FALSE *************************************************************************/ -BOOL setHeatersInfoRecord( U08 *addressPtr ) +BOOL setHeatersInfoRecord( U08 *addressPtr, U32 infoLength ) { BOOL status = FALSE; - memcpy( &dgHeatersInfoGroup.dgHeatersInfo, addressPtr, sizeof( DG_HEATERS_RECORD_T ) ); - // The crc is the DG heaters info and padding - the CRC U16 variable - dgHeatersInfoGroup.crc = crc16 ( (U08*)&dgHeatersInfoGroup.dgHeatersInfo, sizeof( dgHeatersInfoGroup ) - sizeof( U16 ) ); - if ( FALSE == isQueueFull() ) + // Check if the provided length of the heaters info structure matches the size of the heaters record in NV data. + if ( sizeof( DG_HEATERS_RECORD_T ) >= infoLength ) { - // Queue is not full, schedule a write to RTC RAM the write the heaters information record - enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, NVDATAMGMT_HEATERS_INFO_RECORD ); - status = TRUE; + memcpy( &dgHeatersInfoGroup.dgHeatersInfo, addressPtr, sizeof( DG_HEATERS_RECORD_T ) ); + // The crc is the DG heaters info and padding - the CRC U16 variable + dgHeatersInfoGroup.crc = crc16 ( (U08*)&dgHeatersInfoGroup.dgHeatersInfo, sizeof( dgHeatersInfoGroup ) - sizeof( U16 ) ); + + if ( FALSE == isQueueFull() ) + { + // Queue is not full, schedule a write to RTC RAM the write the heaters information record + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, NVDATAMGMT_HEATERS_INFO_RECORD ); + status = TRUE; + } + } return status; @@ -1886,7 +2026,7 @@ } #endif #ifdef _HD_ - state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; + state = NVDATAMGMT_SELF_TEST_STATE_READ_SW_CONFIG_RECORD; #endif } @@ -1989,8 +2129,41 @@ memcpy( &dgHeatersInfoGroup, bufferAddress, sizeof( DG_HEATERS_INFO_GROUP_T ) ); } + state = NVDATAMGMT_SELF_TEST_STATE_READ_SW_CONFIG_RECORD; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleSelfTestReadSWConfigRecord reads the software configurations + * record from RTC RAM. + * @details Inputs: none + * @details Outputs: none + * @return next state + *************************************************************************/ +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadSWConfigRecord( void ) +{ + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_SW_CONFIG_RECORD; + BOOL timeoutStatus = didCommandTimeout( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + +#ifndef _RELEASE_ + if ( ( RTC_RAM_STATUS_IDLE == getRTCRAMStatus() ) || ( TRUE == timeoutStatus ) ) + { + PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS[ NVDATAMGMT_SW_CONFIG_RECORD ]; + U08* bufferAddress = specs.structAddressPtr; + U32 maxBufferLength = specs.maxReadBufferSize; + + getDataFromRAM( bufferAddress, maxBufferLength ); + state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; } +#else + // It is a release so set all the software configurations to 0 to be considered as disable + memset( specs.structAddressPtr, 0, specs.sizeofJob ); + state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; +#endif return state; } @@ -2023,6 +2196,7 @@ return state; } #endif + /*********************************************************************//** * @brief * The handleSelfTestReadLogRecord reads the log record from RTC RAM. @@ -2065,10 +2239,11 @@ 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 hasSystemRecordPassed = TRUE; - BOOL hasServiceRecordPassed = TRUE; + BOOL haveCalGroupsPassed = TRUE; + BOOL haveRecordsPassed = TRUE; + BOOL hasSystemRecordPassed = TRUE; + BOOL hasServiceRecordPassed = TRUE; + BOOL hasSWConfigRecordPassed = TRUE; // Check the integrity of the records as a whole. Check the upper layer CRC haveRecordsPassed = areRecordsValid(); @@ -2085,6 +2260,8 @@ hasServiceRecordPassed = isHDServiceRecordValid(); #endif + hasSWConfigRecordPassed = isSWConfigRecordValid(); + // 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 @@ -2143,6 +2320,7 @@ U32 startAddress; U08* bufferAddress; U32 maxBufferLength; + BOOL areQueuesNotEmpty = FALSE; // If power off command has been issued, do not process any new jobs @@ -3120,7 +3298,42 @@ return status; } +/*********************************************************************//** + * @brief + * The isSWConfigRecordValid function checks the validity of the software + * configuration record. + * @details Inputs: dgSystemGroup.dgSystemRecord + * @details Outputs: none + * @return TRUE if the DG system record is valid otherwise FALSE + *************************************************************************/ +static BOOL isSWConfigRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&swConfigsRecord, sizeof(SW_CONFIGS_RECORD_T) - sizeof(U16) ); + U16 recordCRC = swConfigsRecord.crc; + + if ( calcCRC != recordCRC ) + { + memset( swConfigsRecord.swConfigs, 0, sizeof( swConfigsRecord.swConfigs ) ); + + // Recalculate the CRC with the default values + swConfigsRecord.crc = crc16 ( (U08*)&swConfigsRecord.swConfigs, sizeof(SW_CONFIGS_RECORD_T) - sizeof(U16) ); + #ifdef _DG_ + //activateAlarmNoData( ALARM_ID_DG_SW_CONFIG_RECORD_INVALID_CRC ); // TODO remove +#endif +#ifdef _HD_ + //activateAlarmNoData( ALARM_ID_HD_SW_CONFIG_RECORD_INVALID_CRC ); // TODO remove +#endif + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +#ifdef _DG_ /*********************************************************************//** * @brief * The isDGSystemRecordValid function checks the validity of the DG system @@ -3360,6 +3573,10 @@ isHardwareRecordValid = isDGAccelerometerSensorRecordValid( accelerometer ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + DG_HEATING_CAL_RECORD_T* heating = &dgCalibrationRecord.dgCalibrationGroups.heatingCalRecord; + isHardwareRecordValid = isDGHeatingCalRecordValid( heating ); + 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 ) @@ -3733,6 +3950,37 @@ return status; } + +/*********************************************************************//** + * @brief + * The isDGHeatingCalRecordValid function checks whether the calibration record + * of heating parameters is valid or not. + * @details Inputs: none + * @details Outputs: none + * @param record: DG_HEATING_CAL_RECORD_T pointer + * @return TRUE if the record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGHeatingCalRecordValid( DG_HEATING_CAL_RECORD_T* record ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16 ( (U08*)record, sizeof(DG_HEATING_CAL_RECORD_T) - sizeof(U16) ); + U16 recordCRC = record->crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + record->reservoirTempTauCPerMin = RESERVOIR_TEMPERATURE_TAU_C_PER_MIN; + record->ultrafilterTempTauCPerMin = ULTRAFILTER_TEMPERATURE_TAU_C_PER_MIN; + record->ultrafilterVolmL = ULTRAFILTER_VOLUME_ML; + record->calibrationTime = RECORD_DEFAULT_TIME; + record->crc = crc16 ( (U08*)record, sizeof(DG_HEATING_CAL_RECORD_T) - sizeof(U16) ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} #endif #ifdef _HD_ /*********************************************************************//** Index: NVDataMgmt.h =================================================================== diff -u -rf853004049bc4701d911701e48768cd17189faea -r5ed781a9474910ff9db65e4ef0ab995e03e312fa --- NVDataMgmt.h (.../NVDataMgmt.h) (revision f853004049bc4701d911701e48768cd17189faea) +++ NVDataMgmt.h (.../NVDataMgmt.h) (revision 5ed781a9474910ff9db65e4ef0ab995e03e312fa) @@ -58,6 +58,20 @@ NVDATAMGMT_READ_COMPLETE ///< Read status complete. } NVDATAMGMT_READ_STATUS_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_SW_CONFIG_RECORD, ///< NVDataMgmt process software record. +#ifdef _DG_ + NVDATAMGMT_SCHEDULED_RUNS_RECORD, ///< NVDataMgmt process scheduled runs record. + NVDATAMGMT_HEATERS_INFO_RECORD, ///< NVDataMgmt process heaters info record. +#endif + NUM_OF_NVDATMGMT_RECORDS_JOBS ///< Number of NVDataMgmt records jobs. +} RECORD_JOBS_STATE_T; + #pragma pack(push, 1) /// Read data status structure. typedef struct get_data @@ -94,19 +108,20 @@ BOOL getNVRecord2Driver( NV_DATA_T nvData, U08* bufferAddress, U32 bufferLength, U08 numOfSnsrs2Check, ALARM_ID_T nvAlarm ); +U08 getSoftwareConfigStatus( SOFTWARE_CONFIG_T config ); + #ifdef _DG_ DG_TEMP_SENSORS_CAL_RECORD_T getDGTemperatureSensorsCalibrationRecord( void ); DG_RO_PUMP_CAL_RECORD_T getDGROPumpRecord( void ); DG_CONC_PUMPS_CAL_RECORD_T getDGConcetnratePumpsRecord( void ); DG_DRAIN_PUMP_CAL_RECORD_T getDGDrainPumpRecord( void ); -DG_DRAIN_LINE_VOLUME_T getDGDrainLineVolumeRecord( void ); DG_PRE_RO_PURGE_VOLUME_T getDGPreROPurgeVolumeRecord( void ); DG_FILTERS_CAL_RECORD_T getDGFiltersRecord( void ); DG_FANS_CAL_RECORD_T getDGFansRecord( void ); DG_SCHEDULED_RUN_RECORD_T getDGScheduledRunsRecord( void ); BOOL setWaterConsumption ( U32 liters ); U32 getWaterConsumption ( void ); -BOOL setHeatersInfoRecord( U08 *addressPtr ); +BOOL setHeatersInfoRecord( U08 *addressPtr, U32 infoLength ); #endif #ifdef _HD_ HD_PUMPS_CAL_RECORD_T getHDPumpsCalibrationRecord( void ); @@ -143,6 +158,10 @@ BOOL setScheduledRunsRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); #endif +// TODO the below functions are written in a way that they can generally send and receive data to Dialin +BOOL sendRecordToDialin( RECORD_JOBS_STATE_T job ); +BOOL receiveRecordFromDialin( RECORD_JOBS_STATE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); + /**@}*/ #endif Index: NVDataMgmtDGRecords.h =================================================================== diff -u -r0f6a7299b2382daf3a3dd62446b0e8467f17bddb -r5ed781a9474910ff9db65e4ef0ab995e03e312fa --- NVDataMgmtDGRecords.h (.../NVDataMgmtDGRecords.h) (revision 0f6a7299b2382daf3a3dd62446b0e8467f17bddb) +++ NVDataMgmtDGRecords.h (.../NVDataMgmtDGRecords.h) (revision 5ed781a9474910ff9db65e4ef0ab995e03e312fa) @@ -34,26 +34,19 @@ #define MAX_TOP_LEVEL_PN_CHARS 10U ///< Max number of characters for top level part number. #define MAX_TOP_LEVEL_SN_CHARS 15U ///< Max number of characters for top level serial number. -// TODO this might need to be removed -typedef enum build_switches +/// Software configuration enums +typedef enum software_configurations { - // Anything else other than build switches name? - BUILD_SWITCH_IGNORE_HEATERS_MONITOR = 0, - BUILD_SWITCH_THD_USING_TRO_CONNECTOR, - BUILD_SWITCH_DISABLE_ALL_SWITHCES, - NUM_OF_BUILD_SWITCHES -} BUILD_SWITHCES_T; + SW_CONFIG_DISABLE_HEATERS_MONITOR = 0, ///< Software configuration disable heaters monitor. + SW_CONFIG_THD_USING_TRO_CONNECTOR, ///< Software configuration THD using TRO temperature sensor. + SW_CONFIG_DISABLE_CAL_CHECK, ///< Software configuration disable calibration check. + SW_CONFIG_ALARMS_DEBUG, ///< Software configuration alarms debug. + SW_CONFIG_DISABLE_RO_PUMP_MONITOR, ///< Software configuration disable RO pump monitor. + SW_CONFIG_DISABLE_RO_RATIO_CHECK, ///< Software configuration disable RO ratio check + SW_CONFIG_DISABLE_COND_SENSOR_CHECK, ///< Software configuration disable conductivity sensor check. + NUM_OF_SW_CONFIGS ///< Number of software configurations. +} SOFTWARE_CONFIG_T; -// This function only returns a 1 or a 0. -//U08 getSwitchStatus( BUILD_SWITHCES_T switchName ); - -typedef struct -{ - U08 switchesList[ NUM_OF_BUILD_SWITCHES ]; - U16 crc; -} STUFF_STUFF_T; -// TODO this might need to be removed - /// DG available NV data to get typedef enum dg_nv_commands { @@ -66,6 +59,8 @@ GET_CAL_CONDUCTIVITY_SENSORS, ///< Get conductivity sensors 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_INF_HEATERS_RECORD, ///< Get heaters information form the the last run. GET_SYS_RECORD, ///< Get system record. GET_SRV_RECORD, ///< Get service record.