// // Flash: Nonvolatile storage for settings / etc // #include "stm32f3xx_hal.h" #include "flash.h" #include "config.h" // Private variables static __attribute__((__section__(".eeprom"))) uint16_t eeprom_emulation[512]; // Takes up 1 page (1k size) static therm_settings_t settings; static therm_status_t status; // Initialize flash and restore settings void flash_init(void) { flash_restoresettings(); } // Save settings to flash memory void flash_savesettings() { // Unlock flash memory HAL_FLASH_Unlock(); // Initialize eraser to erase one page of flash FLASH_EraseInitTypeDef eraser = { .TypeErase = TYPEERASE_PAGES, .PageAddress = eeprom_emulation, .NbPages = 1, }; uint32_t errvar = 0; // Erase flash page HAL_FLASHEx_Erase(&eraser, &errvar); // Write new flash data uint16_t writectr; for(writectr = 0; writectr < 128; writectr++)// 128 bytes data { HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, (uint32_t)(eeprom_emulation+writectr), settings.data[writectr]); } // Write magic value to flash HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, (uint32_t)(eeprom_emulation+FLASH_MAGIC_LOC),FLASH_MAGIC_VALUE); // Lock flash memory HAL_FLASH_Lock(); HAL_Delay(2); } // Restore configuration from flash memory, if any was previously saved void flash_restoresettings(void) { // Check for magic flash value if(eeprom_emulation[FLASH_MAGIC_LOC] == FLASH_MAGIC_VALUE) { // Read page of flash into settings structure uint16_t readctr = 0; for(readctr = 0; readctr < 128; readctr++) { settings.data[readctr] = eeprom_emulation[readctr]; } } // No data in flash! Set defaults here //TODO: Set all defaults else { settings.val.k_p = DEFAULT_K_P; settings.val.k_i = DEFAULT_K_I; settings.val.k_d = DEFAULT_K_D; settings.val.windup_guard = DEFAULT_WINDUP_GUARD; settings.val.sensor_type = 1; settings.val.setpoint_count = DEFAULT_SETPOINT_COUNT; settings.val.control_mode = DEFAULT_CONTROL_MODE; settings.val.plant_type = DEFAULT_PLANT_TYPE; } } // Accessor to retrieve settings structure inline therm_settings_t* flash_getsettings(void) { return &settings; } inline therm_status_t* runtime_status(void) { return &status; }