diff --git a/include/sta/devices/stm32/flash.hpp b/include/sta/devices/stm32/flash.hpp new file mode 100644 index 0000000..9b23934 --- /dev/null +++ b/include/sta/devices/stm32/flash.hpp @@ -0,0 +1,32 @@ +/* + * flash.hpp + * + * Created on: Jan 24, 2024 + * Author: Lars Wilko Sentse + */ + +#ifndef STA_CORE_FLASH_HPP +#define STA_CORE_FLASH_HPP + +#include + +// Only enable module on STM32 platform w/ HAL GPIO module enabled +#include +#ifdef STA_PLATFORM_STM32 +# include +#endif // STA_PLATFORM_STM32 +#include + +namespace sta +{ + class Flash{ + public: + Flash() = delete; + static uint32_t flash_write_word(uint32_t address, uint32_t data, bool erase_sector); + static uint32_t flash_read_word(uint32_t address); + static uint32_t flash_erase_sectors(uint32_t sector, uint32_t num_sectors); + static uint32_t flash_get_sector(uint32_t address); + }; +}//namespace sta + +#endif //STA_CORE_FLASH_HPP diff --git a/src/devices/stm32/flash.cpp b/src/devices/stm32/flash.cpp new file mode 100644 index 0000000..7275724 --- /dev/null +++ b/src/devices/stm32/flash.cpp @@ -0,0 +1,58 @@ +/* + * flash.cpp + * + * Created on: Jan 24, 2024 + * Author: Lars Wilko Sentse + */ + +#include + +namespace sta +{ + uint32_t Flash::flash_write_word(uint32_t address, uint32_t data, bool erase_sector){ + if(erase_sector){ + uint32_t flash_error = flash_erase_sectors(flash_get_sector(address), 1); + if(flash_error != HAL_OK) return flash_error; + } + + HAL_FLASH_Unlock(); + if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data)); + HAL_FLASH_Lock(); + + return HAL_OK; + } + + uint32_t Flash::flash_read_word(uint32_t address){ + volatile uint32_t read_data = *(volatile uint32_t*)address; + + return (uint32_t)read_data; + } + + uint32_t Flash::flash_erase_sectors(uint32_t sector, uint32_t num_sectors){ + static FLASH_EraseInitTypeDef erase_init; + erase_init.TypeErase = FLASH_TYPEERASE_SECTORS; + erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_3;//don't know what this does + erase_init.Sector = sector; + erase_init.NbSectors = num_sectors; + uint32_t sector_error; + + HAL_FLASH_Unlock(); + if(HAL_FLASHEx_Erase(&erase_init, §or_error) != HAL_OK) return HAL_FLASH_GetError(); + HAL_FLASH_Lock(); + + return HAL_OK; + } + + uint32_t Flash::flash_get_sector(uint32_t address){ + if(address < FLASH_BASE || address > FLASH_END){ + STA_DEBUG_PRINTF("[STA_FLASH] ADDRESS OUTSIDE [%#010x, %#010x]", FLASH_BASE, FLASH_END); + return std::numeric_limits::max(); + } + //TODO: assumes all sectors are the same size -> not true + // ( address without offset / flash size ) * number of sectors + return (uint32_t) ( ( (float)(address - (FLASH_BASE))/(float)(FLASH_END - FLASH_BASE) ) * FLASH_SECTOR_TOTAL ); + // (0x0807FF00 - 0x08000000 = 0x007FF00) / (0x0807FFFF - 0x08000000 = 0x0007FFFF) = 524032 / 524287 = 0.999... + // 0.999... * 8 = 7.996... (uint32_t)->FLASH_SECTOR_7 + } +}//namespace sta +