Stores data on the flash memory of stm32f4xx
Diff: SOF_dev_stm32_f4xx.cpp
- Revision:
- 0:4cb438b58dc2
diff -r 000000000000 -r 4cb438b58dc2 SOF_dev_stm32_f4xx.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SOF_dev_stm32_f4xx.cpp Fri Nov 18 14:37:15 2016 +0000 @@ -0,0 +1,186 @@ +/** +* @file SOF_dev_stm32.c +* +* @brief Flash device access interface for STM32 F4xx series +* +* +* History: +*/ + +#include <stdio.h> +#include "SOF_dev.h" +#include <string.h> + +#include "mbed.h" +#include "stm32f4xx_hal_flash.h" + +#define DCRLF "\r\n" + +#if 0 +#define DPRINTF printf +#define DASSERT(cond) \ + if (!(cond)) { \ + printf("%s:%d assertion failed! '%s\r\n"\ + , __FILE__, __LINE__, #cond); \ + } +#else +#define DPRINTF(...) +#define DASSERT(...) +#endif + + +#if defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F407xx) +static const SOF_SectorSpec_t _sec_spec[] = { + {FLASH_SECTOR_0, 0x08000000, 16*1024}, + {FLASH_SECTOR_1, 0x08004000, 16*1024}, + {FLASH_SECTOR_2, 0x08008000, 16*1024}, + {FLASH_SECTOR_3, 0x0800C000, 16*1024}, + {FLASH_SECTOR_4, 0x08010000, 64*1024}, + {FLASH_SECTOR_5, 0x08020000, 128*1024}, + {FLASH_SECTOR_6, 0x08040000, 128*1024}, + {FLASH_SECTOR_7, 0x08060000, 128*1024}, +}; +#else +#error "Not supported device" +#endif + +#define N_SECTOR_SPEC (sizeof(_sec_spec)/sizeof(_sec_spec[0])) + +#define SECTOR_NO(sector) _sec_spec[sector].sec_no +#define SECTOR_ADDR(sector) _sec_spec[sector].sec_addr +#define SECTOR_SIZE(sector) _sec_spec[sector].sec_size + + +static inline size_t handle_to_sector_index(SOF_DevHandle_t hdev) +{ + DASSERT(hdev < N_SECTOR_SPEC); + return hdev; +} + +const SOF_SectorSpec_t *SOF_dev_info(uint8_t sector_index) +{ + DASSERT(sector_index < N_SECTOR_SPEC); + return &_sec_spec[sector_index]; +} + +int SOF_dev_is_valid_sector(uint8_t sector_index) +{ + return sector_index < N_SECTOR_SPEC; +} + +const SOF_SectorSpec_t *SOF_dev_info_by_index(uint8_t sector_index) +{ + DASSERT(SOF_dev_is_valid_sector(sector_index)); + return &_sec_spec[sector_index]; +} + +const SOF_SectorSpec_t *SOF_dev_info(SOF_DevHandle_t hdev) +{ + uint8_t sector_index = handle_to_sector_index(hdev); + + return SOF_dev_info_by_index(sector_index); +} + +SOF_DevHandle_t SOF_dev_open(uint8_t sector_index) +{ + DASSERT(sector_index < N_SECTOR_SPEC); + return (SOF_DevHandle_t)sector_index; +} + +void SOF_dev_close(SOF_DevHandle_t hdev) +{ +} + +uint8_t *SOF_dev_get_hw_addr(SOF_DevHandle_t hdev) +{ + uint8_t sector_index = handle_to_sector_index(hdev); + + return (uint8_t *)SECTOR_ADDR(sector_index); +} + + +void SOF_dev_erase(SOF_DevHandle_t hdev) +{ + uint8_t sector_index = handle_to_sector_index(hdev); + FLASH_EraseInitTypeDef ei; + uint32_t error = 0; + + DPRINTF("FLASH_Erase_Sector %d"DCRLF, SECTOR_NO(sector_index)); + HAL_FLASH_Unlock(); + + ei.TypeErase = TYPEERASE_SECTORS; + ei.Sector = SECTOR_NO(sector_index); + ei.NbSectors = 1; + ei.Banks = 0; + ei.VoltageRange = VOLTAGE_RANGE_3; + HAL_FLASHEx_Erase(&ei, &error); + HAL_FLASH_Lock(); + DPRINTF("FLASH_Erase_Sector ok"DCRLF); +} + + +int SOF_dev_write_word(SOF_DevHandle_t hdev, uint32_t offset_addr, uint32_t data) +{ + uint8_t sector_index = handle_to_sector_index(hdev); + uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr; + + DASSERT((offset_addr%sizeof(uint32_t)) == 0); + HAL_FLASH_Unlock(); + if (HAL_FLASH_Program(TYPEPROGRAM_WORD, dst, data) != HAL_OK) { + DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst); + HAL_FLASH_Lock(); + return -1; + } + + HAL_FLASH_Lock(); + + if (data != SOF_dev_read_word(hdev, offset_addr)) { + DPRINTF("addr=%x %#04x %#04x"DCRLF, dst, data, SOF_dev_read_word(hdev, offset_addr)); + return -1; + } + + return 0; +} + +uint32_t SOF_dev_read_word(SOF_DevHandle_t hdev, uint32_t offset_addr) +{ + uint8_t sector_index = handle_to_sector_index(hdev); + uint32_t src = SECTOR_ADDR(sector_index) + offset_addr; + + DASSERT((offset_addr%sizeof(uint32_t)) == 0); + + return *(volatile uint32_t*)src; +} + +int SOF_dev_write_byte(SOF_DevHandle_t hdev, uint32_t offset_addr, uint8_t data) +{ + uint8_t sector_index = handle_to_sector_index(hdev); + uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr; + + HAL_FLASH_Unlock(); + if (HAL_FLASH_Program(TYPEPROGRAM_BYTE, dst, data) != HAL_OK) { + DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst); + HAL_FLASH_Lock(); + return -1; + } + + HAL_FLASH_Lock(); + + if (data != SOF_dev_read_byte(hdev, offset_addr)) { + DPRINTF("addr=%x %#02x %#02x"DCRLF, dst, data, SOF_dev_read_byte(hdev, offset_addr)); + return -1; + } + + return 0; +} + +uint8_t SOF_dev_read_byte(SOF_DevHandle_t hdev, uint32_t offset_addr) +{ + uint8_t sector_index = handle_to_sector_index(hdev); + uint32_t src = SECTOR_ADDR(sector_index) + offset_addr; + + return *(volatile uint8_t*)src; +} + + +