Stores data on the flash memory of stm32f4xx

Committer:
hendreh
Date:
Fri Nov 18 14:37:15 2016 +0000
Revision:
0:4cb438b58dc2
working

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},
hendreh 0:4cb438b58dc2 41 {FLASH_SECTOR_7, 0x08060000, 128*1024},
hendreh 0:4cb438b58dc2 42 };
hendreh 0:4cb438b58dc2 43 #else
hendreh 0:4cb438b58dc2 44 #error "Not supported device"
hendreh 0:4cb438b58dc2 45 #endif
hendreh 0:4cb438b58dc2 46
hendreh 0:4cb438b58dc2 47 #define N_SECTOR_SPEC (sizeof(_sec_spec)/sizeof(_sec_spec[0]))
hendreh 0:4cb438b58dc2 48
hendreh 0:4cb438b58dc2 49 #define SECTOR_NO(sector) _sec_spec[sector].sec_no
hendreh 0:4cb438b58dc2 50 #define SECTOR_ADDR(sector) _sec_spec[sector].sec_addr
hendreh 0:4cb438b58dc2 51 #define SECTOR_SIZE(sector) _sec_spec[sector].sec_size
hendreh 0:4cb438b58dc2 52
hendreh 0:4cb438b58dc2 53
hendreh 0:4cb438b58dc2 54 static inline size_t handle_to_sector_index(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 55 {
hendreh 0:4cb438b58dc2 56 DASSERT(hdev < N_SECTOR_SPEC);
hendreh 0:4cb438b58dc2 57 return hdev;
hendreh 0:4cb438b58dc2 58 }
hendreh 0:4cb438b58dc2 59
hendreh 0:4cb438b58dc2 60 const SOF_SectorSpec_t *SOF_dev_info(uint8_t sector_index)
hendreh 0:4cb438b58dc2 61 {
hendreh 0:4cb438b58dc2 62 DASSERT(sector_index < N_SECTOR_SPEC);
hendreh 0:4cb438b58dc2 63 return &_sec_spec[sector_index];
hendreh 0:4cb438b58dc2 64 }
hendreh 0:4cb438b58dc2 65
hendreh 0:4cb438b58dc2 66 int SOF_dev_is_valid_sector(uint8_t sector_index)
hendreh 0:4cb438b58dc2 67 {
hendreh 0:4cb438b58dc2 68 return sector_index < N_SECTOR_SPEC;
hendreh 0:4cb438b58dc2 69 }
hendreh 0:4cb438b58dc2 70
hendreh 0:4cb438b58dc2 71 const SOF_SectorSpec_t *SOF_dev_info_by_index(uint8_t sector_index)
hendreh 0:4cb438b58dc2 72 {
hendreh 0:4cb438b58dc2 73 DASSERT(SOF_dev_is_valid_sector(sector_index));
hendreh 0:4cb438b58dc2 74 return &_sec_spec[sector_index];
hendreh 0:4cb438b58dc2 75 }
hendreh 0:4cb438b58dc2 76
hendreh 0:4cb438b58dc2 77 const SOF_SectorSpec_t *SOF_dev_info(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 78 {
hendreh 0:4cb438b58dc2 79 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 80
hendreh 0:4cb438b58dc2 81 return SOF_dev_info_by_index(sector_index);
hendreh 0:4cb438b58dc2 82 }
hendreh 0:4cb438b58dc2 83
hendreh 0:4cb438b58dc2 84 SOF_DevHandle_t SOF_dev_open(uint8_t sector_index)
hendreh 0:4cb438b58dc2 85 {
hendreh 0:4cb438b58dc2 86 DASSERT(sector_index < N_SECTOR_SPEC);
hendreh 0:4cb438b58dc2 87 return (SOF_DevHandle_t)sector_index;
hendreh 0:4cb438b58dc2 88 }
hendreh 0:4cb438b58dc2 89
hendreh 0:4cb438b58dc2 90 void SOF_dev_close(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 91 {
hendreh 0:4cb438b58dc2 92 }
hendreh 0:4cb438b58dc2 93
hendreh 0:4cb438b58dc2 94 uint8_t *SOF_dev_get_hw_addr(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 95 {
hendreh 0:4cb438b58dc2 96 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 97
hendreh 0:4cb438b58dc2 98 return (uint8_t *)SECTOR_ADDR(sector_index);
hendreh 0:4cb438b58dc2 99 }
hendreh 0:4cb438b58dc2 100
hendreh 0:4cb438b58dc2 101
hendreh 0:4cb438b58dc2 102 void SOF_dev_erase(SOF_DevHandle_t hdev)
hendreh 0:4cb438b58dc2 103 {
hendreh 0:4cb438b58dc2 104 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 105 FLASH_EraseInitTypeDef ei;
hendreh 0:4cb438b58dc2 106 uint32_t error = 0;
hendreh 0:4cb438b58dc2 107
hendreh 0:4cb438b58dc2 108 DPRINTF("FLASH_Erase_Sector %d"DCRLF, SECTOR_NO(sector_index));
hendreh 0:4cb438b58dc2 109 HAL_FLASH_Unlock();
hendreh 0:4cb438b58dc2 110
hendreh 0:4cb438b58dc2 111 ei.TypeErase = TYPEERASE_SECTORS;
hendreh 0:4cb438b58dc2 112 ei.Sector = SECTOR_NO(sector_index);
hendreh 0:4cb438b58dc2 113 ei.NbSectors = 1;
hendreh 0:4cb438b58dc2 114 ei.Banks = 0;
hendreh 0:4cb438b58dc2 115 ei.VoltageRange = VOLTAGE_RANGE_3;
hendreh 0:4cb438b58dc2 116 HAL_FLASHEx_Erase(&ei, &error);
hendreh 0:4cb438b58dc2 117 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 118 DPRINTF("FLASH_Erase_Sector ok"DCRLF);
hendreh 0:4cb438b58dc2 119 }
hendreh 0:4cb438b58dc2 120
hendreh 0:4cb438b58dc2 121
hendreh 0:4cb438b58dc2 122 int SOF_dev_write_word(SOF_DevHandle_t hdev, uint32_t offset_addr, uint32_t data)
hendreh 0:4cb438b58dc2 123 {
hendreh 0:4cb438b58dc2 124 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 125 uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 126
hendreh 0:4cb438b58dc2 127 DASSERT((offset_addr%sizeof(uint32_t)) == 0);
hendreh 0:4cb438b58dc2 128 HAL_FLASH_Unlock();
hendreh 0:4cb438b58dc2 129 if (HAL_FLASH_Program(TYPEPROGRAM_WORD, dst, data) != HAL_OK) {
hendreh 0:4cb438b58dc2 130 DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst);
hendreh 0:4cb438b58dc2 131 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 132 return -1;
hendreh 0:4cb438b58dc2 133 }
hendreh 0:4cb438b58dc2 134
hendreh 0:4cb438b58dc2 135 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 136
hendreh 0:4cb438b58dc2 137 if (data != SOF_dev_read_word(hdev, offset_addr)) {
hendreh 0:4cb438b58dc2 138 DPRINTF("addr=%x %#04x %#04x"DCRLF, dst, data, SOF_dev_read_word(hdev, offset_addr));
hendreh 0:4cb438b58dc2 139 return -1;
hendreh 0:4cb438b58dc2 140 }
hendreh 0:4cb438b58dc2 141
hendreh 0:4cb438b58dc2 142 return 0;
hendreh 0:4cb438b58dc2 143 }
hendreh 0:4cb438b58dc2 144
hendreh 0:4cb438b58dc2 145 uint32_t SOF_dev_read_word(SOF_DevHandle_t hdev, uint32_t offset_addr)
hendreh 0:4cb438b58dc2 146 {
hendreh 0:4cb438b58dc2 147 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 148 uint32_t src = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 149
hendreh 0:4cb438b58dc2 150 DASSERT((offset_addr%sizeof(uint32_t)) == 0);
hendreh 0:4cb438b58dc2 151
hendreh 0:4cb438b58dc2 152 return *(volatile uint32_t*)src;
hendreh 0:4cb438b58dc2 153 }
hendreh 0:4cb438b58dc2 154
hendreh 0:4cb438b58dc2 155 int SOF_dev_write_byte(SOF_DevHandle_t hdev, uint32_t offset_addr, uint8_t data)
hendreh 0:4cb438b58dc2 156 {
hendreh 0:4cb438b58dc2 157 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 158 uint32_t dst = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 159
hendreh 0:4cb438b58dc2 160 HAL_FLASH_Unlock();
hendreh 0:4cb438b58dc2 161 if (HAL_FLASH_Program(TYPEPROGRAM_BYTE, dst, data) != HAL_OK) {
hendreh 0:4cb438b58dc2 162 DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst);
hendreh 0:4cb438b58dc2 163 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 164 return -1;
hendreh 0:4cb438b58dc2 165 }
hendreh 0:4cb438b58dc2 166
hendreh 0:4cb438b58dc2 167 HAL_FLASH_Lock();
hendreh 0:4cb438b58dc2 168
hendreh 0:4cb438b58dc2 169 if (data != SOF_dev_read_byte(hdev, offset_addr)) {
hendreh 0:4cb438b58dc2 170 DPRINTF("addr=%x %#02x %#02x"DCRLF, dst, data, SOF_dev_read_byte(hdev, offset_addr));
hendreh 0:4cb438b58dc2 171 return -1;
hendreh 0:4cb438b58dc2 172 }
hendreh 0:4cb438b58dc2 173
hendreh 0:4cb438b58dc2 174 return 0;
hendreh 0:4cb438b58dc2 175 }
hendreh 0:4cb438b58dc2 176
hendreh 0:4cb438b58dc2 177 uint8_t SOF_dev_read_byte(SOF_DevHandle_t hdev, uint32_t offset_addr)
hendreh 0:4cb438b58dc2 178 {
hendreh 0:4cb438b58dc2 179 uint8_t sector_index = handle_to_sector_index(hdev);
hendreh 0:4cb438b58dc2 180 uint32_t src = SECTOR_ADDR(sector_index) + offset_addr;
hendreh 0:4cb438b58dc2 181
hendreh 0:4cb438b58dc2 182 return *(volatile uint8_t*)src;
hendreh 0:4cb438b58dc2 183 }
hendreh 0:4cb438b58dc2 184
hendreh 0:4cb438b58dc2 185
hendreh 0:4cb438b58dc2 186