Stores data on the flash memory of stm32f4xx

Dependents:   DISCO-F429ZI_LCDTS_demo_richard

Fork of storage_on_flash by henning l

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SOF_dev_stm32_f4xx.cpp Source File

SOF_dev_stm32_f4xx.cpp

00001 /**
00002 * @file SOF_dev_stm32.c
00003 *
00004 * @brief Flash device access interface for STM32 F4xx series
00005 *
00006 *
00007 * History:
00008 */
00009 
00010 #include <stdio.h>
00011 #include "SOF_dev.h"
00012 #include <string.h>
00013 
00014 #include "mbed.h"
00015 #include "stm32f4xx_hal_flash.h"
00016 
00017 #define DCRLF   "\r\n"
00018 
00019 #if 0
00020 #define DPRINTF printf
00021 #define DASSERT(cond)  \
00022     if (!(cond)) { \
00023         printf("%s:%d assertion failed! '%s\r\n"\
00024             , __FILE__, __LINE__, #cond); \
00025     }
00026 #else
00027 #define DPRINTF(...)
00028 #define DASSERT(...)
00029 #endif
00030 
00031 
00032 #if defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F407xx)
00033 static const SOF_SectorSpec_t _sec_spec[] = {
00034     {FLASH_SECTOR_0, 0x08000000, 16*1024},
00035     {FLASH_SECTOR_1, 0x08004000, 16*1024},
00036     {FLASH_SECTOR_2, 0x08008000, 16*1024},
00037     {FLASH_SECTOR_3, 0x0800C000, 16*1024},
00038     {FLASH_SECTOR_4, 0x08010000, 64*1024},
00039     {FLASH_SECTOR_5, 0x08020000, 128*1024},
00040     {FLASH_SECTOR_6, 0x08040000, 128*1024},
00041     {FLASH_SECTOR_7, 0x08060000, 128*1024}, 
00042 };
00043 #error wrong device
00044 #else
00045 static const SOF_SectorSpec_t _sec_spec[] = {
00046     {FLASH_SECTOR_0, 0x08000000, 16*1024},
00047     {FLASH_SECTOR_1, 0x08004000, 16*1024},
00048     {FLASH_SECTOR_2, 0x08008000, 16*1024},
00049     {FLASH_SECTOR_3, 0x0800C000, 16*1024},
00050     {FLASH_SECTOR_4, 0x08010000, 64*1024},
00051     {FLASH_SECTOR_5, 0x08020000, 128*1024},
00052     {FLASH_SECTOR_6, 0x08040000, 128*1024},
00053     {FLASH_SECTOR_7, 0x08060000, 128*1024},
00054     {FLASH_SECTOR_8, 0x08080000, 128*1024},
00055     {FLASH_SECTOR_9, 0x080A0000, 128*1024},
00056     {FLASH_SECTOR_10, 0x080C0000, 128*1024},
00057     {FLASH_SECTOR_11, 0x080E0000, 128*1024}, //BANK2 after this limit
00058     {FLASH_SECTOR_12, 0x08100000, 16*1024},  
00059     {FLASH_SECTOR_13, 0x08104000, 16*1024},    
00060     {FLASH_SECTOR_14, 0x08108000, 16*1024},    
00061     {FLASH_SECTOR_15, 0x0810C000, 16*1024},    
00062     {FLASH_SECTOR_16, 0x08110000, 64*1024},  
00063     {FLASH_SECTOR_17, 0x08120000, 128*1024},
00064     {FLASH_SECTOR_18, 0x08140000, 128*1024},
00065     {FLASH_SECTOR_19, 0x08160000, 128*1024},
00066     {FLASH_SECTOR_20, 0x08180000, 128*1024},
00067     {FLASH_SECTOR_21, 0x081A0000, 128*1024},
00068     {FLASH_SECTOR_22, 0x081C0000, 128*1024},
00069     {FLASH_SECTOR_13, 0x081E0000, 128*1024}
00070 };
00071 #endif
00072 
00073 #define N_SECTOR_SPEC           (sizeof(_sec_spec)/sizeof(_sec_spec[0]))
00074 
00075 #define SECTOR_NO(sector)       _sec_spec[sector].sec_no
00076 #define SECTOR_ADDR(sector)     _sec_spec[sector].sec_addr
00077 #define SECTOR_SIZE(sector)     _sec_spec[sector].sec_size
00078 
00079 
00080 static inline size_t handle_to_sector_index(SOF_DevHandle_t hdev)
00081 {
00082     DASSERT(hdev < N_SECTOR_SPEC);
00083     return hdev;
00084 }
00085 
00086 const SOF_SectorSpec_t *SOF_dev_info(uint8_t sector_index)
00087 {
00088     DASSERT(sector_index < N_SECTOR_SPEC);
00089     return &_sec_spec[sector_index];
00090 }
00091 
00092 int SOF_dev_is_valid_sector(uint8_t sector_index)
00093 {
00094     return sector_index < N_SECTOR_SPEC;
00095 }
00096 
00097 const SOF_SectorSpec_t *SOF_dev_info_by_index(uint8_t sector_index)
00098 {
00099     DASSERT(SOF_dev_is_valid_sector(sector_index));
00100     return &_sec_spec[sector_index];
00101 }
00102 
00103 const SOF_SectorSpec_t *SOF_dev_info(SOF_DevHandle_t hdev)
00104 {
00105     uint8_t sector_index = handle_to_sector_index(hdev);
00106 
00107     return SOF_dev_info_by_index(sector_index);
00108 }
00109 
00110 SOF_DevHandle_t SOF_dev_open(uint8_t sector_index)
00111 {
00112     DASSERT(sector_index < N_SECTOR_SPEC);
00113     return (SOF_DevHandle_t)sector_index;
00114 }
00115 
00116 void SOF_dev_close(SOF_DevHandle_t hdev)
00117 {
00118 }
00119 
00120 uint8_t *SOF_dev_get_hw_addr(SOF_DevHandle_t hdev)
00121 {
00122     uint8_t sector_index = handle_to_sector_index(hdev);
00123 
00124     return (uint8_t *)SECTOR_ADDR(sector_index);
00125 }
00126 
00127 
00128 void SOF_dev_erase(SOF_DevHandle_t hdev)
00129 {
00130     uint8_t sector_index = handle_to_sector_index(hdev);
00131     FLASH_EraseInitTypeDef ei;
00132     uint32_t error = 0;
00133 
00134     DPRINTF("FLASH_Erase_Sector %d"DCRLF, SECTOR_NO(sector_index));
00135     HAL_FLASH_Unlock();
00136 
00137     ei.TypeErase = TYPEERASE_SECTORS;
00138     ei.Sector = SECTOR_NO(sector_index);
00139     ei.NbSectors = 1;
00140     ei.Banks = 0;
00141     ei.VoltageRange = VOLTAGE_RANGE_3;
00142     HAL_FLASHEx_Erase(&ei, &error);
00143     HAL_FLASH_Lock();
00144     DPRINTF("FLASH_Erase_Sector ok"DCRLF);
00145 }
00146 
00147 
00148 int SOF_dev_write_word(SOF_DevHandle_t hdev, uint32_t offset_addr, uint32_t data)
00149 {
00150     uint8_t sector_index = handle_to_sector_index(hdev);
00151     uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr;
00152 
00153     DASSERT((offset_addr%sizeof(uint32_t)) == 0);
00154     HAL_FLASH_Unlock();
00155     if (HAL_FLASH_Program(TYPEPROGRAM_WORD, dst, data) != HAL_OK) {
00156         DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst);
00157         HAL_FLASH_Lock();
00158         return -1;
00159     }
00160 
00161     HAL_FLASH_Lock();
00162 
00163     if (data != SOF_dev_read_word(hdev, offset_addr)) {
00164         DPRINTF("addr=%x %#04x %#04x"DCRLF, dst, data, SOF_dev_read_word(hdev, offset_addr));
00165         return -1;
00166     }
00167 
00168     return 0;
00169 }
00170 
00171 uint32_t SOF_dev_read_word(SOF_DevHandle_t hdev, uint32_t offset_addr)
00172 {
00173     uint8_t sector_index = handle_to_sector_index(hdev);
00174     uint32_t src = SECTOR_ADDR(sector_index) + offset_addr;
00175 
00176     DASSERT((offset_addr%sizeof(uint32_t)) == 0);
00177 
00178     return *(volatile uint32_t*)src;
00179 }
00180 
00181 int SOF_dev_write_byte(SOF_DevHandle_t hdev, uint32_t offset_addr, uint8_t data)
00182 {
00183     uint8_t sector_index = handle_to_sector_index(hdev);
00184     uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr;
00185 
00186     HAL_FLASH_Unlock();
00187     if (HAL_FLASH_Program(TYPEPROGRAM_BYTE, dst, data) != HAL_OK) {
00188         DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst);
00189         HAL_FLASH_Lock();
00190         return -1;
00191     }
00192 
00193     HAL_FLASH_Lock();
00194 
00195     if (data != SOF_dev_read_byte(hdev, offset_addr)) {
00196         DPRINTF("addr=%x %#02x %#02x"DCRLF, dst, data, SOF_dev_read_byte(hdev, offset_addr));
00197         return -1;
00198     }
00199 
00200     return 0;
00201 }
00202 
00203 uint8_t SOF_dev_read_byte(SOF_DevHandle_t hdev, uint32_t offset_addr)
00204 {
00205     uint8_t sector_index = handle_to_sector_index(hdev);
00206     uint32_t src = SECTOR_ADDR(sector_index) + offset_addr;
00207 
00208     return *(volatile uint8_t*)src;
00209 }
00210 
00211 
00212