// ----------------------------------------------------------------------------- /// @file CalibrationParameters.c /// @brief Description // ----------------------------------------------------------------------------- // Micro-Key bv // Industrieweg 28, 9804 TG Noordhorn // Postbus 92, 9800 AB Zuidhorn // The Netherlands // Tel: +31 594 503020 // Fax: +31 594 505825 // Email: support@microkey.nl // Web: www.microkey.nl // ----------------------------------------------------------------------------- /// $Revision$ /// $Author$ /// $Date$ // (c) 2018 Micro-Key bv // ----------------------------------------------------------------------------- /// @file CalibrationParameters.c /// @ingroup {group_name} // ----------------------------------------------------------------------------- // Include files // ----------------------------------------------------------------------------- #include #include "hsb-mrts.h" #include "Error.h" #include "CalibrationParameters.h" #include "CalibrationSetpoint.h" #include "CalibrationSetpoints.h" #include "CachedStorage.h" #include "crc32.h" #include "Logger.h" // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- struct CalibrationParameters { bool initialized; struct CachedStorage cache; struct MemoryDevice* memoryDevice; unsigned int CalibrationSetpointsOffset; }; struct CalibrationSetpointsStorageClass { uint32_t crc; struct CalibrationSetpoints setpoints; }; // ----------------------------------------------------------------------------- // File-scope variables // ----------------------------------------------------------------------------- static struct CalibrationParameters _self = {.initialized = false, .cache.initialized = false}; struct CalibrationParameters* const cpSelf = &_self; // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- static void CalibrationParameters_verifyCRCs(void); // ----------------------------------------------------------------------------- // Function definitions // ----------------------------------------------------------------------------- ErrorStatus CalibrationParameters_construct(struct MemoryDevice* memoryDevice) { ErrorStatus returnValue = SUCCESS; if (!cpSelf->initialized) { if (returnValue == SUCCESS) { if (memoryDevice != NULL) { if (memoryDevice->initialized) { cpSelf->memoryDevice = memoryDevice; } else { returnValue = ERROR; } } else { returnValue = ERROR; } } if (returnValue == SUCCESS) { // Create new cachedStorage with preset page number returnValue = CachedStorage_construct(&cpSelf->cache, cpSelf->memoryDevice, APP_FLASH_CALIBRATION_PAGE, sizeof(struct CalibrationSetpointsStorageClass) / 4); } if (returnValue == SUCCESS) { cpSelf->initialized = 0; cpSelf->initialized = true; } // Check the CRC on the loaded parameters // If a CRC fails, corrupted data will automatically be replaced with defaults if (returnValue == SUCCESS) { CalibrationParameters_verifyCRCs(); } } else { returnValue = ERROR; } return returnValue; } void CalibrationParameters_destruct(void) { if (cpSelf->initialized) { cpSelf->cache.initialized = false; cpSelf->initialized = false; } } struct CalibrationSetpoints* CalibrationParameters_getCalibrationSetpoints(void) { struct CalibrationSetpoints* returnValue = NULL; if (cpSelf->initialized) { struct CalibrationSetpointsStorageClass* tempValue; tempValue = (struct CalibrationSetpointsStorageClass*)CachedStorage_readBlob(&cpSelf->cache, cpSelf->CalibrationSetpointsOffset); returnValue = &tempValue->setpoints; } return returnValue; } ErrorStatus CalibrationParameters_setCalibrationSetpoints(struct CalibrationSetpoints* setpoints) { ErrorStatus returnValue = SUCCESS; if (cpSelf->initialized) { struct CalibrationSetpointsStorageClass tempStorage; tempStorage.setpoints = *setpoints; // Calculate CRC over preset tempStorage.crc = crc32_calculate(0, &tempStorage.setpoints, sizeof(struct CalibrationSetpoints)); // Put default preset on Cache CachedStorage_writeBlob(&cpSelf->cache, cpSelf->CalibrationSetpointsOffset, &tempStorage, sizeof(struct CalibrationSetpointsStorageClass) / 4); } else { returnValue = ERROR; } return returnValue; } void CalibrationParameters_saveParameters(void) { if (cpSelf->initialized) { // Commit cache to memory - will not write if no changes have been made CachedStorage_commit(&cpSelf->cache); } } static void CalibrationParameters_verifyCRCs(void) { uint32_t tempCRC; if (cpSelf->initialized) { // PID PARAMETERS CHECK struct CalibrationSetpointsStorageClass _tempParameters; struct CalibrationSetpointsStorageClass* tempParameters = &_tempParameters; tempParameters = (struct CalibrationSetpointsStorageClass*)CachedStorage_readBlob(&cpSelf->cache, cpSelf->CalibrationSetpointsOffset); // Calculate the CRC of the parameters tempCRC = crc32_calculate(0, &tempParameters->setpoints, sizeof(struct CalibrationSetpoints)); // Compare CRC if (tempCRC != tempParameters->crc) { Error_postError(ERROR_CRC_CALIBRATION); // CRC do not match LOGGER_ERROR(mainLog, "CRC ERROR at Calibration Parameters (calculated %X but loaded %X)", (unsigned int)tempCRC, (unsigned int)tempParameters->crc); // Replace corrupt Device parameters with defaults CalibrationSetpoints_generateDefaultParameters(&tempParameters->setpoints); // Write parameters to cache including the CRC (calculated inside write function) CalibrationParameters_setCalibrationSetpoints(&tempParameters->setpoints); } CalibrationParameters_saveParameters(); } }