Stores data on the flash memory of stm32f4xx

Dependents:   DISCO-F429ZI_LCDTS_demo_richard

Fork of storage_on_flash by henning l

Committer:
pierrebizouard
Date:
Fri Mar 16 15:50:04 2018 +0000
Revision:
1:801ddc4634a5
Parent:
0:4cb438b58dc2
added support for 429ZI up to bank 11

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hendreh 0:4cb438b58dc2 1 /**
hendreh 0:4cb438b58dc2 2 * @file SOF_dev_stm32.c
hendreh 0:4cb438b58dc2 3 *
hendreh 0:4cb438b58dc2 4 * @brief Flash device access interface for STM32 F4xx series
hendreh 0:4cb438b58dc2 5 *
hendreh 0:4cb438b58dc2 6 *
hendreh 0:4cb438b58dc2 7 * History:
hendreh 0:4cb438b58dc2 8 */
hendreh 0:4cb438b58dc2 9
hendreh 0:4cb438b58dc2 10 #include <stdio.h>
hendreh 0:4cb438b58dc2 11 #include "SOF_dev.h"
hendreh 0:4cb438b58dc2 12 #include <string.h>
hendreh 0:4cb438b58dc2 13
hendreh 0:4cb438b58dc2 14 #include "mbed.h"
hendreh 0:4cb438b58dc2 15 #include "stm32f4xx_hal_flash.h"
hendreh 0:4cb438b58dc2 16
hendreh 0:4cb438b58dc2 17 #define DCRLF "\r\n"
hendreh 0:4cb438b58dc2 18
hendreh 0:4cb438b58dc2 19 #if 0
hendreh 0:4cb438b58dc2 20 #define DPRINTF printf
hendreh 0:4cb438b58dc2 21 #define DASSERT(cond) \
hendreh 0:4cb438b58dc2 22 if (!(cond)) { \
hendreh 0:4cb438b58dc2 23 printf("%s:%d assertion failed! '%s\r\n"\
hendreh 0:4cb438b58dc2 24 , __FILE__, __LINE__, #cond); \
hendreh 0:4cb438b58dc2 25 }
hendreh 0:4cb438b58dc2 26 #else
hendreh 0:4cb438b58dc2 27 #define DPRINTF(...)
hendreh 0:4cb438b58dc2 28 #define DASSERT(...)
hendreh 0:4cb438b58dc2 29 #endif
hendreh 0:4cb438b58dc2 30
hendreh 0:4cb438b58dc2 31
hendreh 0:4cb438b58dc2 32 #if defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F407xx)
hendreh 0:4cb438b58dc2 33 static const SOF_SectorSpec_t _sec_spec[] = {
hendreh 0:4cb438b58dc2 34 {FLASH_SECTOR_0, 0x08000000, 16*1024},
hendreh 0:4cb438b58dc2 35 {FLASH_SECTOR_1, 0x08004000, 16*1024},
hendreh 0:4cb438b58dc2 36 {FLASH_SECTOR_2, 0x08008000, 16*1024},
hendreh 0:4cb438b58dc2 37 {FLASH_SECTOR_3, 0x0800C000, 16*1024},
hendreh 0:4cb438b58dc2 38 {FLASH_SECTOR_4, 0x08010000, 64*1024},
hendreh 0:4cb438b58dc2 39 {FLASH_SECTOR_5, 0x08020000, 128*1024},
hendreh 0:4cb438b58dc2 40 {FLASH_SECTOR_6, 0x08040000, 128*1024},
pierrebizouard 1:801ddc4634a5 41 {FLASH_SECTOR_7, 0x08060000, 128*1024},
hendreh 0:4cb438b58dc2 42 };
pierrebizouard 1:801ddc4634a5 43 #error wrong device
hendreh 0:4cb438b58dc2 44 #else
pierrebizouard 1:801ddc4634a5 45 static const SOF_SectorSpec_t _sec_spec[] = {
pierrebizouard 1:801ddc4634a5 46 {FLASH_SECTOR_0, 0x08000000, 16*1024},
pierrebizouard 1:801ddc4634a5 47 {FLASH_SECTOR_1, 0x08004000, 16*1024},
pierrebizouard 1:801ddc4634a5 48 {FLASH_SECTOR_2, 0x08008000, 16*1024},
pierrebizouard 1:801ddc4634a5 49 {FLASH_SECTOR_3, 0x0800C000, 16*1024},
pierrebizouard 1:801ddc4634a5 50 {FLASH_SECTOR_4, 0x08010000, 64*1024},
pierrebizouard 1:801ddc4634a5 51 {FLASH_SECTOR_5, 0x08020000, 128*1024},
pierrebizouard 1:801ddc4634a5 52 {FLASH_SECTOR_6, 0x08040000, 128*1024},
pierrebizouard 1:801ddc4634a5 53 {FLASH_SECTOR_7, 0x08060000, 128*1024},
pierrebizouard 1:801ddc4634a5 54 {FLASH_SECTOR_8, 0x08080000, 128*1024},
pierrebizouard 1:801ddc4634a5 55 {FLASH_SECTOR_9, 0x080A0000, 128*1024},
pierrebizouard 1:801ddc4634a5 56 {FLASH_SECTOR_10, 0x080C0000, 128*1024},
pierrebizouard 1:801ddc4634a5 57 {FLASH_SECTOR_11, 0x080E0000, 128*1024}, //BANK2 after this limit
pierrebizouard 1:801ddc4634a5 58 {FLASH_SECTOR_12, 0x08100000, 16*1024},
pierrebizouard 1:801ddc4634a5 59 {FLASH_SECTOR_13, 0x08104000, 16*1024},
pierrebizouard 1:801ddc4634a5 60 {FLASH_SECTOR_14, 0x08108000, 16*1024},
pierrebizouard 1:801ddc4634a5 61 {FLASH_SECTOR_15, 0x0810C000, 16*1024},
pierrebizouard 1:801ddc4634a5 62 {FLASH_SECTOR_16, 0x08110000, 64*1024},
pierrebizouard 1:801ddc4634a5 63 {FLASH_SECTOR_17, 0x08120000, 128*1024},
pierrebizouard 1:801ddc4634a5 64 {FLASH_SECTOR_18, 0x08140000, 128*1024},
pierrebizouard 1:801ddc4634a5 65 {FLASH_SECTOR_19, 0x08160000, 128*1024},
pierrebizouard 1:801ddc4634a5 66 {FLASH_SECTOR_20, 0x08180000, 128*1024},
pierrebizouard 1:801ddc4634a5 67 {FLASH_SECTOR_21, 0x081A0000, 128*1024},
pierrebizouard 1:801ddc4634a5 68 {FLASH_SECTOR_22, 0x081C0000, 128*1024},
pierrebizouard 1:801ddc4634a5 69 {FLASH_SECTOR_13, 0x081E0000, 128*1024}
pierrebizouard 1:801ddc4634a5 70 };
hendreh 0:4cb438b58dc2 71 #endif
hendreh 0:4cb438b58dc2 72
hendreh 0:4cb438b58dc2 73 #define N_SECTOR_SPEC (sizeof(_sec_spec)/sizeof(_sec_spec[0]))
hendreh 0:4cb438b58dc2 74
hendreh 0:4cb438b58dc2 75 #define SECTOR_NO(sector) _sec_spec[sector].sec_no
pierrebizouard 1:801ddc4634a5 76 #define SECTOR_ADDR(sector) _sec_spec[sector].sec_addr
hendreh 0:4cb438b58dc2 77 #define SECTOR_SIZE(sector) _sec_spec[sector].sec_size
hendreh 0:4cb438b58dc2 78
hendreh 0:4cb438b58dc2 79
hendreh 0:4cb438b58dc2 80 static inline size_t handle_to_sector_index(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 81 {
hendreh 0:4cb438b58dc2 82 DASSERT(hdev < N_SECTOR_SPEC);
hendreh 0:4cb438b58dc2 83 return hdev;
hendreh 0:4cb438b58dc2 84 }
hendreh 0:4cb438b58dc2 85
hendreh 0:4cb438b58dc2 86 const SOF_SectorSpec_t *SOF_dev_info(uint8_t sector_index)
hendreh 0:4cb438b58dc2 87 {
hendreh 0:4cb438b58dc2 88 DASSERT(sector_index < N_SECTOR_SPEC);
hendreh 0:4cb438b58dc2 89 return &_sec_spec[sector_index];
hendreh 0:4cb438b58dc2 90 }
hendreh 0:4cb438b58dc2 91
hendreh 0:4cb438b58dc2 92 int SOF_dev_is_valid_sector(uint8_t sector_index)
hendreh 0:4cb438b58dc2 93 {
hendreh 0:4cb438b58dc2 94 return sector_index < N_SECTOR_SPEC;
hendreh 0:4cb438b58dc2 95 }
hendreh 0:4cb438b58dc2 96
hendreh 0:4cb438b58dc2 97 const SOF_SectorSpec_t *SOF_dev_info_by_index(uint8_t sector_index)
hendreh 0:4cb438b58dc2 98 {
hendreh 0:4cb438b58dc2 99 DASSERT(SOF_dev_is_valid_sector(sector_index));
hendreh 0:4cb438b58dc2 100 return &_sec_spec[sector_index];
hendreh 0:4cb438b58dc2 101 }
hendreh 0:4cb438b58dc2 102
hendreh 0:4cb438b58dc2 103 const SOF_SectorSpec_t *SOF_dev_info(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 104 {
hendreh 0:4cb438b58dc2 105 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 106
hendreh 0:4cb438b58dc2 107 return SOF_dev_info_by_index(sector_index);
hendreh 0:4cb438b58dc2 108 }
hendreh 0:4cb438b58dc2 109
hendreh 0:4cb438b58dc2 110 SOF_DevHandle_t SOF_dev_open(uint8_t sector_index)
hendreh 0:4cb438b58dc2 111 {
hendreh 0:4cb438b58dc2 112 DASSERT(sector_index < N_SECTOR_SPEC);
hendreh 0:4cb438b58dc2 113 return (SOF_DevHandle_t)sector_index;
hendreh 0:4cb438b58dc2 114 }
hendreh 0:4cb438b58dc2 115
hendreh 0:4cb438b58dc2 116 void SOF_dev_close(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 117 {
hendreh 0:4cb438b58dc2 118 }
hendreh 0:4cb438b58dc2 119
hendreh 0:4cb438b58dc2 120 uint8_t *SOF_dev_get_hw_addr(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 121 {
hendreh 0:4cb438b58dc2 122 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 123
hendreh 0:4cb438b58dc2 124 return (uint8_t *)SECTOR_ADDR(sector_index);
hendreh 0:4cb438b58dc2 125 }
hendreh 0:4cb438b58dc2 126
hendreh 0:4cb438b58dc2 127
hendreh 0:4cb438b58dc2 128 void SOF_dev_erase(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 129 {
hendreh 0:4cb438b58dc2 130 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 131 FLASH_EraseInitTypeDef ei;
hendreh 0:4cb438b58dc2 132 uint32_t error = 0;
hendreh 0:4cb438b58dc2 133
hendreh 0:4cb438b58dc2 134 DPRINTF("FLASH_Erase_Sector %d"DCRLF, SECTOR_NO(sector_index));
hendreh 0:4cb438b58dc2 135 HAL_FLASH_Unlock();
hendreh 0:4cb438b58dc2 136
hendreh 0:4cb438b58dc2 137 ei.TypeErase = TYPEERASE_SECTORS;
hendreh 0:4cb438b58dc2 138 ei.Sector = SECTOR_NO(sector_index);
hendreh 0:4cb438b58dc2 139 ei.NbSectors = 1;
hendreh 0:4cb438b58dc2 140 ei.Banks = 0;
hendreh 0:4cb438b58dc2 141 ei.VoltageRange = VOLTAGE_RANGE_3;
hendreh 0:4cb438b58dc2 142 HAL_FLASHEx_Erase(&ei, &error);
hendreh 0:4cb438b58dc2 143 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 144 DPRINTF("FLASH_Erase_Sector ok"DCRLF);
hendreh 0:4cb438b58dc2 145 }
hendreh 0:4cb438b58dc2 146
hendreh 0:4cb438b58dc2 147
hendreh 0:4cb438b58dc2 148 int SOF_dev_write_word(SOF_DevHandle_t hdev, uint32_t offset_addr, uint32_t data)
hendreh 0:4cb438b58dc2 149 {
hendreh 0:4cb438b58dc2 150 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 151 uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 152
hendreh 0:4cb438b58dc2 153 DASSERT((offset_addr%sizeof(uint32_t)) == 0);
hendreh 0:4cb438b58dc2 154 HAL_FLASH_Unlock();
hendreh 0:4cb438b58dc2 155 if (HAL_FLASH_Program(TYPEPROGRAM_WORD, dst, data) != HAL_OK) {
hendreh 0:4cb438b58dc2 156 DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst);
hendreh 0:4cb438b58dc2 157 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 158 return -1;
hendreh 0:4cb438b58dc2 159 }
hendreh 0:4cb438b58dc2 160
hendreh 0:4cb438b58dc2 161 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 162
hendreh 0:4cb438b58dc2 163 if (data != SOF_dev_read_word(hdev, offset_addr)) {
hendreh 0:4cb438b58dc2 164 DPRINTF("addr=%x %#04x %#04x"DCRLF, dst, data, SOF_dev_read_word(hdev, offset_addr));
hendreh 0:4cb438b58dc2 165 return -1;
hendreh 0:4cb438b58dc2 166 }
hendreh 0:4cb438b58dc2 167
hendreh 0:4cb438b58dc2 168 return 0;
hendreh 0:4cb438b58dc2 169 }
hendreh 0:4cb438b58dc2 170
hendreh 0:4cb438b58dc2 171 uint32_t SOF_dev_read_word(SOF_DevHandle_t hdev, uint32_t offset_addr)
hendreh 0:4cb438b58dc2 172 {
hendreh 0:4cb438b58dc2 173 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 174 uint32_t src = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 175
hendreh 0:4cb438b58dc2 176 DASSERT((offset_addr%sizeof(uint32_t)) == 0);
hendreh 0:4cb438b58dc2 177
hendreh 0:4cb438b58dc2 178 return *(volatile uint32_t*)src;
hendreh 0:4cb438b58dc2 179 }
hendreh 0:4cb438b58dc2 180
hendreh 0:4cb438b58dc2 181 int SOF_dev_write_byte(SOF_DevHandle_t hdev, uint32_t offset_addr, uint8_t data)
hendreh 0:4cb438b58dc2 182 {
hendreh 0:4cb438b58dc2 183 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 184 uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 185
hendreh 0:4cb438b58dc2 186 HAL_FLASH_Unlock();
hendreh 0:4cb438b58dc2 187 if (HAL_FLASH_Program(TYPEPROGRAM_BYTE, dst, data) != HAL_OK) {
hendreh 0:4cb438b58dc2 188 DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst);
hendreh 0:4cb438b58dc2 189 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 190 return -1;
hendreh 0:4cb438b58dc2 191 }
hendreh 0:4cb438b58dc2 192
hendreh 0:4cb438b58dc2 193 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 194
hendreh 0:4cb438b58dc2 195 if (data != SOF_dev_read_byte(hdev, offset_addr)) {
hendreh 0:4cb438b58dc2 196 DPRINTF("addr=%x %#02x %#02x"DCRLF, dst, data, SOF_dev_read_byte(hdev, offset_addr));
hendreh 0:4cb438b58dc2 197 return -1;
hendreh 0:4cb438b58dc2 198 }
hendreh 0:4cb438b58dc2 199
hendreh 0:4cb438b58dc2 200 return 0;
hendreh 0:4cb438b58dc2 201 }
hendreh 0:4cb438b58dc2 202
hendreh 0:4cb438b58dc2 203 uint8_t SOF_dev_read_byte(SOF_DevHandle_t hdev, uint32_t offset_addr)
hendreh 0:4cb438b58dc2 204 {
hendreh 0:4cb438b58dc2 205 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 206 uint32_t src = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 207
hendreh 0:4cb438b58dc2 208 return *(volatile uint8_t*)src;
hendreh 0:4cb438b58dc2 209 }
hendreh 0:4cb438b58dc2 210
hendreh 0:4cb438b58dc2 211
hendreh 0:4cb438b58dc2 212