git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@417 05563f52-14a8-4384-a975-3d1654cca0fa
315 lines
9.5 KiB
C
315 lines
9.5 KiB
C
// -----------------------------------------------------------------------------
|
|
/// @file RepairPresets.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) 2017 Micro-Key bv
|
|
// -----------------------------------------------------------------------------
|
|
|
|
/// @file RepairPresets.c
|
|
/// @ingroup {group_name}
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Include files
|
|
// -----------------------------------------------------------------------------
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include "hsb-mrts.h"
|
|
#include "Error.h"
|
|
#include "RepairPresets.h"
|
|
|
|
#include "CachedStorage.h"
|
|
#include "crc32.h"
|
|
#include "MemoryDevice.h"
|
|
|
|
#include "Logger.h"
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Constant and macro definitions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Type definitions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
struct RepairPresets
|
|
{
|
|
bool initialized;
|
|
bool presetsLoaded;
|
|
REPAIR_PRESETS_ID currentPresetID;
|
|
struct CachedStorage* presetStorage;
|
|
struct MemoryDevice* memoryDevice;
|
|
};
|
|
|
|
struct RepairPresetStorageClass
|
|
{
|
|
uint32_t crc;
|
|
struct RepairPreset preset;
|
|
};
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// File-scope variables
|
|
// -----------------------------------------------------------------------------
|
|
static struct CachedStorage cache = {.initialized = false};
|
|
|
|
static struct RepairPresets _self = {.initialized = false, .presetStorage = &cache, .presetsLoaded = false};
|
|
struct RepairPresets* const self = &_self;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Function declarations
|
|
// -----------------------------------------------------------------------------
|
|
|
|
static void RepairPresets_verifyCRCs(void);
|
|
static ErrorStatus RepairPresets_verifyPresetCRC(struct RepairPresetStorageClass* repairPreset);
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Function definitions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
ErrorStatus RepairPresets_construct(struct MemoryDevice* memoryDevice)
|
|
{
|
|
ErrorStatus returnValue = SUCCESS;
|
|
if (!self->initialized)
|
|
{
|
|
if (returnValue == SUCCESS)
|
|
{
|
|
if (memoryDevice != NULL)
|
|
{
|
|
if (memoryDevice->initialized)
|
|
{
|
|
self->memoryDevice = memoryDevice;
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
}
|
|
self->initialized = true;
|
|
self->presetsLoaded = false;
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
void RepairPresets_destruct(void)
|
|
{
|
|
if (self->initialized)
|
|
{
|
|
self->initialized = false;
|
|
self->presetsLoaded = false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ErrorStatus RepairPresets_loadPresets(REPAIR_PRESETS_ID presetID)
|
|
{
|
|
ErrorStatus returnValue = SUCCESS;
|
|
|
|
if (self->initialized)
|
|
{
|
|
// Destruct the cachedStorage to remove all previous data
|
|
CachedStorage_destruct(self->presetStorage);
|
|
|
|
// Get the new preset ID
|
|
self->currentPresetID = presetID;
|
|
// Construct new cached Storage with base address defined by the preset ID
|
|
unsigned int pageNumber;
|
|
switch (self->currentPresetID)
|
|
{
|
|
case REPAIR_PRESETS_ANODE:
|
|
{
|
|
pageNumber = APP_FLASH_PRESET_ANODE_PAGE;
|
|
break;
|
|
}
|
|
case REPAIR_PRESETS_CATHODE:
|
|
{
|
|
pageNumber = APP_FLASH_PRESET_CATHODE_PAGE;
|
|
break;
|
|
}
|
|
case REPAIR_PRESETS_MCP:
|
|
{
|
|
pageNumber = APP_FLASH_PRESET_MCP_PAGE;
|
|
break;
|
|
}
|
|
case REPAIR_PRESETS_TESLA:
|
|
{
|
|
pageNumber = APP_FLASH_PRESET_TESLA_PAGE;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
LOGGER_ERROR(mainLog, "Unknown preset ID");
|
|
returnValue = ERROR;
|
|
}
|
|
}
|
|
|
|
// If Preset ID was valid, go on loading presets from memory
|
|
if (returnValue == SUCCESS)
|
|
{
|
|
// Create new cachedStorage with preset page number
|
|
returnValue = CachedStorage_construct(self->presetStorage, self->memoryDevice, pageNumber, ((sizeof(struct RepairPresetStorageClass) * REPAIR_PRESETS_NUMBER_OF_PRESETS) / 4));
|
|
}
|
|
else
|
|
{
|
|
self->presetsLoaded = false;
|
|
}
|
|
|
|
// Check the CRC on the loaded presets
|
|
if (returnValue == SUCCESS)
|
|
{
|
|
RepairPresets_verifyCRCs();
|
|
}
|
|
|
|
// CRCs are verified
|
|
// If CRCs are correct on all presets, returnValue will still be SUCCESS
|
|
if (returnValue == SUCCESS)
|
|
{
|
|
self->presetsLoaded = true;
|
|
}
|
|
// If any CRC is wrong
|
|
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
struct RepairPreset* RepairPresets_getPreset(unsigned int index)
|
|
{
|
|
struct RepairPreset* returnValue = NULL;
|
|
if (self->initialized)
|
|
{
|
|
if (self->presetsLoaded)
|
|
{
|
|
// Index is human-readable, thus starting with 1
|
|
if ((index > 0) || (index <= REPAIR_PRESETS_NUMBER_OF_PRESETS))
|
|
{
|
|
struct RepairPresetStorageClass* tempPreset;
|
|
tempPreset = (struct RepairPresetStorageClass*)CachedStorage_readBlob(self->presetStorage, (index - 1) * sizeof(struct RepairPresetStorageClass) / 4);
|
|
returnValue = (struct RepairPreset*)&tempPreset->preset;
|
|
}
|
|
}
|
|
}
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
void RepairPresets_savePresets(void)
|
|
{
|
|
// Commit cache to memory - will not write if no changes have been made
|
|
CachedStorage_commit(self->presetStorage);
|
|
}
|
|
|
|
|
|
static void RepairPresets_verifyCRCs(void)
|
|
{
|
|
ErrorStatus returnValue = SUCCESS;
|
|
if (self->initialized)
|
|
{
|
|
int loopCounter;
|
|
struct RepairPresetStorageClass _tempPresetStorage;
|
|
struct RepairPresetStorageClass* tempPresetStorage = &_tempPresetStorage;
|
|
bool crcErrorFound = false;
|
|
for (loopCounter = 0; loopCounter < REPAIR_PRESETS_NUMBER_OF_PRESETS; loopCounter++)
|
|
{
|
|
// Load next preset from cache
|
|
tempPresetStorage = (struct RepairPresetStorageClass*)CachedStorage_readBlob(self->presetStorage, loopCounter * sizeof(struct RepairPresetStorageClass) / 4);
|
|
// Verify CRC
|
|
returnValue = RepairPresets_verifyPresetCRC(tempPresetStorage);
|
|
// Check CRC verification
|
|
if (returnValue != SUCCESS)
|
|
{
|
|
crcErrorFound = true;
|
|
// CRC was not correct - replace corrupted preset with a DEFAULT preset
|
|
RepairPreset_generateDefaultPreset(&tempPresetStorage->preset, loopCounter + 1);
|
|
LOGGER_DEBUG(mainLog, "PRESET %d: Softstart: %d, Duration: %d, Voltage: %d", tempPresetStorage->preset.presetNumber, tempPresetStorage->preset.preset[0].softstartDuration, tempPresetStorage->preset.preset[0].duration, tempPresetStorage->preset.preset[0].voltage);
|
|
// Write default preset to Cache
|
|
RepairPresets_writePreset(&tempPresetStorage->preset);
|
|
}
|
|
}
|
|
if (crcErrorFound)
|
|
{
|
|
Error_postError(ERROR_CRC_PRESETS);
|
|
}
|
|
// Commit cache to memory - will not write if no changes have been made
|
|
CachedStorage_commit(self->presetStorage);
|
|
}
|
|
}
|
|
|
|
|
|
static ErrorStatus RepairPresets_verifyPresetCRC(struct RepairPresetStorageClass* repairPreset)
|
|
{
|
|
ErrorStatus returnValue = SUCCESS;
|
|
if (self->initialized)
|
|
{
|
|
// Calculate the CRC of the given repair preset
|
|
uint32_t tempCRC;
|
|
tempCRC = crc32_calculate(0, &repairPreset->preset, sizeof(struct RepairPreset));
|
|
// Compare loaded and calculated CRC values - must be equal
|
|
if (repairPreset->crc != tempCRC)
|
|
{
|
|
// CRCs do not match
|
|
returnValue = ERROR;
|
|
LOGGER_ERROR(mainLog, "CRC ERROR at repair preset %d (calculated %X but loaded %X)", repairPreset->preset.presetNumber, (unsigned int)tempCRC, (unsigned int)repairPreset->crc);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
|
|
ErrorStatus RepairPresets_writePreset(struct RepairPreset* preset)
|
|
{
|
|
ErrorStatus returnValue = SUCCESS;
|
|
if (self->initialized)
|
|
{
|
|
struct RepairPresetStorageClass tempPresetStorage;
|
|
tempPresetStorage.preset = *preset;
|
|
// Calculate CRC over preset
|
|
tempPresetStorage.crc = crc32_calculate(0, &tempPresetStorage.preset, sizeof(struct RepairPreset));
|
|
// Put default preset on Cache
|
|
CachedStorage_writeBlob(self->presetStorage, (tempPresetStorage.preset.presetNumber - 1) * sizeof(struct RepairPresetStorageClass) / 4,
|
|
&tempPresetStorage, sizeof(struct RepairPresetStorageClass) / 4);
|
|
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
return returnValue;
|
|
}
|