fome-fw/firmware/controllers/flash_main.cpp

148 lines
4.6 KiB
C++
Raw Normal View History

2014-08-29 07:52:33 -07:00
/**
* @file flash_main.cpp
* @brief Higher-level logic of saving data into internal flash memory
*
*
* @date Sep 19, 2013
2015-01-12 15:04:10 -08:00
* @author Andrey Belomutskiy, (c) 2012-2015
2014-08-29 07:52:33 -07:00
*/
2014-12-24 11:05:19 -08:00
#include <main.h>
2014-08-29 07:52:33 -07:00
#include "flash_main.h"
#include "eficonsole.h"
#include "flash.h"
#include "rusefi.h"
2015-02-19 06:04:18 -08:00
#if EFI_TUNER_STUDIO || defined(__DOXYGEN__)
#include "tunerstudio.h"
#endif
2015-02-24 20:04:21 -08:00
#if EFI_INTERNAL_FLASH || defined(__DOXYGEN__)
2014-12-24 11:05:19 -08:00
2014-08-29 07:52:33 -07:00
#include "engine_controller.h"
#include "datalogging.h"
2014-10-31 13:03:07 -07:00
#include "engine.h"
2014-08-29 07:52:33 -07:00
static bool needToWriteConfiguration = false;
2014-11-07 19:04:45 -08:00
EXTERN_ENGINE;
2015-01-14 16:03:39 -08:00
static Logging* logger;
2014-08-29 07:52:33 -07:00
extern persistent_config_container_s persistentState;
extern engine_configuration_s *engineConfiguration;
#define FLASH_ADDR 0x08060000
#define PERSISTENT_SIZE sizeof(persistent_config_container_s)
crc_t flashStateCrc(persistent_config_container_s *state) {
return calc_crc((const crc_t*) &state->persistentConfiguration, sizeof(persistent_config_s));
}
void setNeedToWriteConfiguration(void) {
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, "Scheduling configuration write");
2014-08-29 07:52:33 -07:00
needToWriteConfiguration = true;
}
bool getNeedToWriteConfiguration(void) {
return needToWriteConfiguration;
}
void writeToFlashIfPending() {
if (!getNeedToWriteConfiguration()) {
return;
}
// todo: technically we need a lock here, realistically we should be fine.
needToWriteConfiguration = false;
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, "Writing pending configuration");
2015-02-19 06:04:18 -08:00
writeToFlashNow();
2014-08-29 07:52:33 -07:00
}
2014-11-21 15:03:02 -08:00
extern uint32_t maxLockTime;
2015-02-19 06:04:18 -08:00
void writeToFlashNow(void) {
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, " !!!!!!!!!!!!!!!!!!!! BE SURE NOT WRITE WITH IGNITION ON !!!!!!!!!!!!!!!!!!!!");
2014-08-29 07:52:33 -07:00
persistentState.size = PERSISTENT_SIZE;
persistentState.version = FLASH_DATA_VERSION;
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, "flash compatible with %d", persistentState.version);
2014-08-29 07:52:33 -07:00
crc_t result = flashStateCrc(&persistentState);
persistentState.value = result;
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, "Reseting flash: size=%d", PERSISTENT_SIZE);
2014-08-29 07:52:33 -07:00
flashErase(FLASH_ADDR, PERSISTENT_SIZE);
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, "Flashing with CRC=%d", result);
2014-08-29 07:52:33 -07:00
efitimems_t nowMs = currentTimeMillis();
result = flashWrite(FLASH_ADDR, (const char *) &persistentState, PERSISTENT_SIZE);
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, "Flash programmed in (ms): %d", currentTimeMillis() - nowMs);
scheduleMsg(logger, "Flashing result: %d", result);
2014-11-21 15:03:02 -08:00
maxLockTime = 0;
2014-08-29 07:52:33 -07:00
}
2014-09-12 17:05:16 -07:00
static bool isValidCrc(persistent_config_container_s *state) {
2014-08-29 07:52:33 -07:00
crc_t result = flashStateCrc(state);
int isValidCrc_b = result == state->value;
if (!isValidCrc_b) {
2015-01-14 16:03:39 -08:00
scheduleMsg(logger, "CRC got %d while %d expected", result, state->value);
2014-08-29 07:52:33 -07:00
}
return isValidCrc_b;
}
static void doResetConfiguration(void) {
2015-02-27 14:07:50 -08:00
resetConfigurationExt(logger, engineConfiguration->engineType PASS_ENGINE_PARAMETER);
2014-08-29 07:52:33 -07:00
}
2014-09-12 18:05:24 -07:00
static bool hasValidEngineType(engine_configuration_s *engineConfiguration) {
uint32_t ordinal = (uint32_t)engineConfiguration->engineType;
return ordinal < ET_UNUSED && engineConfiguration->headerMagicValue == HEADER_MAGIC_NUMBER;
}
2014-08-29 07:52:33 -07:00
void readFromFlash(void) {
2015-01-14 16:03:39 -08:00
printMsg(logger, "readFromFlash()");
2014-08-29 07:52:33 -07:00
flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE);
2014-09-12 18:05:24 -07:00
if (!isValidCrc(&persistentState)) {
2015-01-14 16:03:39 -08:00
printMsg(logger, "Need to reset flash to default due to CRC");
2015-02-27 14:07:50 -08:00
resetConfigurationExt(logger, DEFAULT_ENGINE_TYPE PASS_ENGINE_PARAMETER);
2014-09-12 18:05:24 -07:00
} else if (persistentState.version == FLASH_DATA_VERSION && persistentState.size == PERSISTENT_SIZE) {
2015-01-14 16:03:39 -08:00
printMsg(logger, "Got valid configuration from flash!");
2015-02-27 15:08:55 -08:00
applyNonPersistentConfiguration(logger PASS_ENGINE_PARAMETER);
2014-09-12 18:05:24 -07:00
} else if (hasValidEngineType(engineConfiguration)) {
2015-01-14 16:03:39 -08:00
printMsg(logger, "Resetting but saving engine type [%d]", engineConfiguration->engineType);
2015-02-27 14:07:50 -08:00
resetConfigurationExt(logger, engineConfiguration->engineType PASS_ENGINE_PARAMETER);
2014-09-12 18:05:24 -07:00
} else {
2015-01-14 16:03:39 -08:00
printMsg(logger, "Need to reset flash to default due to version change");
2015-02-27 14:07:50 -08:00
resetConfigurationExt(logger, DEFAULT_ENGINE_TYPE PASS_ENGINE_PARAMETER);
2014-08-29 07:52:33 -07:00
}
// we can only change the state after the CRC check
engineConfiguration->firmwareVersion = getRusEfiVersion();
}
2014-11-02 10:03:07 -08:00
static void rewriteConfig(Engine *engine) {
doResetConfiguration();
2015-02-19 06:04:18 -08:00
writeToFlashNow();
2014-11-02 10:03:07 -08:00
}
2015-01-14 16:03:39 -08:00
void initFlash(Logging *sharedLogger, Engine *engine) {
logger = sharedLogger;
2014-08-29 07:52:33 -07:00
addConsoleAction("readconfig", readFromFlash);
2015-02-19 06:04:18 -08:00
/**
* This would write NOW (you should not be doing this while connected to real engine)
*/
addConsoleAction("writeconfig", writeToFlashNow);
#if EFI_TUNER_STUDIO || defined(__DOXYGEN__)
/**
* This would schedule write to flash once the engine is stopped
*/
addConsoleAction("burnconfig", requestBurn);
#endif
2014-08-29 07:52:33 -07:00
addConsoleAction("resetconfig", doResetConfiguration);
2014-11-02 10:03:07 -08:00
addConsoleActionP("rewriteconfig", (VoidPtr)rewriteConfig, engine);
2014-08-29 07:52:33 -07:00
}
2014-12-24 11:05:19 -08:00
#endif /* EFI_INTERNAL_FLASH */