Tiny storage(file) system on MCU internal flash memory for Nucleo F4xx. The purpose of SOFBlock class is to provide a way to write data on flash memory in the same way of file handling class in the file system.
Revision 5:f81b553e0ff4, committed 23 months ago
- Comitter:
- masaaki_makabe
- Date:
- Wed Nov 16 04:49:19 2022 +0000
- Parent:
- 4:a59b917583c9
- Commit message:
- add STM32L4xx
Changed in this revision
| SOF_dev_stm32_f4xx.cpp | Show diff for this revision Revisions of this file |
| SOF_dev_stm32_l4xx.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/SOF_dev_stm32_f4xx.cpp Fri Nov 05 04:30:56 2021 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/**
-* @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
-
-/* debug mak STM32F412xx 1MBytes --------------------------------------------*/
-#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F412Zx) ||\
- defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx)
-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},
- {FLASH_SECTOR_8, 0x08080000, 128*1024},
- {FLASH_SECTOR_9, 0x080A0000, 128*1024},
- {FLASH_SECTOR_10, 0x080C0000, 128*1024},
- {FLASH_SECTOR_11, 0x080E0000, 128*1024},
-};
-#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;
-}
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SOF_dev_stm32_l4xx.cpp Wed Nov 16 04:49:19 2022 +0000
@@ -0,0 +1,311 @@
+/**
+* @file SOF_dev_stm32_l4xx.c
+*
+* @brief Flash device access interface for STM32 L4xx series
+*
+*
+* History:
+*/
+
+#include <stdio.h>
+#include "SOF_dev.h"
+#include <string.h>
+
+#include "mbed.h"
+
+#include "stm32l4xx_hal_flash.h"
+
+#define DCRLF "\r\n"
+
+#if 0
+extern Serial pc;
+#define DPRINTF pc.printf
+#define DASSERT(cond) \
+ if (!(cond)) { \
+ pc.printf("%s:%d assertion failed! '%s\r\n"\
+ , __FILE__, __LINE__, #cond); \
+ }
+#else
+#define DPRINTF(...)
+#define DASSERT(...)
+#endif
+
+// 1024*4*sizeof(byte) = 4Kbyte flash must (application)
+//
+// STM32L4xx flash area
+// bank address size page (virtual_sector)
+// 1 0x08000000 2k 0
+// 1 0x08000800 2k 1
+// 1 0x08001000 2k 2
+//
+// 1 0x0803C000 2k 120 11
+// 1 0x0803C800 2k 121 11
+// 1 0x0803D000 2k 122 11
+// 1 0x0803D800 2k 123 11
+// 1 0x0803E000 2k 124 11 <-- ここを11セクタの先頭とする
+// 1 0x0803E800 2k 125 11
+// 1 0x0803F000 2k 126 11
+// 1 0x0803F800 2k 127 11 <-- STM32L432KC ここまで (256KB)
+//
+// 1 0x0807C000 2k 248 11
+// 1 0x0807C800 2k 249 11
+// 1 0x0807D000 2k 250 11
+// 1 0x0807D800 2k 251 11
+// 1 0x0807E000 2k 252 11
+// 1 0x0807E800 2k 253 11
+// 1 0x0807F000 2k 254 11
+// 1 0x0807F800 2k 255 11 <-- 512KB
+#define REQ_SECTOR 11
+#define PAGE_SIZE 2048
+#define START_ADDRESS 0x0803E000 //11セクタの先頭アドレス
+
+/*--- sector11 table ---*/
+#if defined(STM32L431xx) || defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L442xx) || defined(STM32L443xx)
+static const SOF_SectorSpec_t _sec11_spec[] = {
+// page address size
+ {124, START_ADDRESS+0x0000, PAGE_SIZE},
+ {125, START_ADDRESS+0x0800, PAGE_SIZE},
+ {126, START_ADDRESS+0x1000, PAGE_SIZE},
+ {127, START_ADDRESS+0x1800, PAGE_SIZE},//last page
+};
+#elif defined(STM32L451xx) || defined(STM32L452xx) || defined(STM32L462xx)
+static const SOF_SectorSpec_t _sec11_spec_example[] = {
+ {255, START_ADDRESS+0x0000, PAGE_SIZE},//last page
+};
+#else
+ #error "Not supported device"
+#endif
+
+#define N_PAGE_SPEC (sizeof(_sec11_spec)/sizeof(_sec11_spec[0]))
+#define PAGE_NO(page) _sec11_spec[0].sec_no //top page
+#define PAGE_ADDR(page) _sec11_spec[0].sec_addr //top address
+
+static const SOF_SectorSpec_t _sec11_dummy = {
+ // ここ重要。ページの最後をセットすること
+ REQ_SECTOR, START_ADDRESS, PAGE_SIZE*N_PAGE_SPEC
+};
+
+static uint64_t _data64w = 0;
+static uint64_t _data64b = 0;
+static int32_t _offset_addr_w = -1;
+static int32_t _offset_addr_b = -1;
+
+static inline size_t handle_to_sector_index(SOF_DevHandle_t hdev)
+{
+ DASSERT(hdev == REQ_SECTOR);
+ return hdev;
+}
+
+int SOF_dev_is_valid_sector(uint8_t sector_index)
+{
+ return sector_index == REQ_SECTOR;
+}
+
+const SOF_SectorSpec_t *SOF_dev_info_by_index(uint8_t sector_index)
+{
+ DASSERT(SOF_dev_is_valid_sector(sector_index));
+ return &_sec11_dummy;
+}
+
+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)
+{
+ DPRINTF("SOF_dev_open %d\r\n", sector_index);
+ _data64w = _data64b = 0;
+ _offset_addr_w = -1;
+ _offset_addr_b = -1;
+
+ DASSERT(sector_index == REQ_SECTOR);
+ return (SOF_DevHandle_t)sector_index;
+}
+
+void SOF_dev_close(SOF_DevHandle_t hdev)
+{
+ uint8_t sector_index = handle_to_sector_index(hdev);
+ DPRINTF("SOF_dev_close %d\r\n", sector_index);
+
+ //if write pending, must write
+ //
+ if(_offset_addr_w >= 0){
+ SOF_dev_write_word(sector_index, _offset_addr_w + 4, 0);//+4:write finish
+ }
+ if(_offset_addr_b >= 0){
+ SOF_dev_write_byte(sector_index, _offset_addr_b + 7, 0);//+7:write finish
+ }
+}
+
+uint8_t *SOF_dev_get_hw_addr(SOF_DevHandle_t hdev)
+{
+ uint8_t sector_index = handle_to_sector_index(hdev);
+ return (uint8_t *)PAGE_ADDR(sector_index);
+}
+
+/*--- hdev is sector (11 only by application) ---*/
+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_Page %d"DCRLF, PAGE_NO(sector_index));
+ HAL_FLASH_Unlock();
+
+ ei.TypeErase = FLASH_TYPEERASE_PAGES;
+#if defined(STM32L431xx) || defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L442xx) || defined(STM32L443xx) ||\
+ defined(STM32L451xx) || defined(STM32L452xx) || defined(STM32L462xx)
+ ei.Banks = FLASH_BANK_1;//bank1 only
+#else
+ ei.Banks = FLASH_BANK_2;
+#endif
+ ei.Page = PAGE_NO(secotr_index); //top page
+ ei.NbPages = N_PAGE_SPEC; //number of page
+ HAL_StatusTypeDef ret = HAL_FLASHEx_Erase(&ei, &error);
+
+ HAL_FLASH_Lock();
+ DPRINTF("FLASH_Erase_Page ret=%d, page=%d, n=%d\r\n", ret, ei.Page, ei.NbPages);
+}
+
+uint64_t SOF_dev_read_dword(SOF_DevHandle_t hdev, uint32_t offset_addr)
+{
+ uint8_t sector_index = handle_to_sector_index(hdev);
+ uint32_t src = PAGE_ADDR(sector_index) + offset_addr;
+ uint64_t ret = *(volatile uint64_t*)src;
+ return ret;
+}
+
+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 = PAGE_ADDR(sector_index) + offset_addr;
+ DPRINTF("SOF_dev_write_word dst=%08X ofs=%d, ", dst, offset_addr);
+ // +0 +4 +8
+ // +------+------+
+ // |DWORDH|DWORDL|
+ // +------+------+
+ if(offset_addr % 8 == 0){//address 8 multiple
+ _data64w |= data;
+ _offset_addr_w = offset_addr;
+ DPRINTF("data=%08X\r\n", data);
+ return 0;//next waiting
+ } else if(offset_addr % 4 == 0){//address 4 multiple
+ _data64w |= ((uint64_t)data << 32);
+ dst = PAGE_ADDR(sector_index) + _offset_addr_w;
+ DPRINTF("data=%08X\r\n", data);
+ }
+
+ DASSERT((offset_addr % sizeof(uint32_t)) == 0);//required address 4 multiple
+ HAL_FLASH_Unlock();
+
+ if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, dst, _data64w) != HAL_OK) {
+ DPRINTF("FLASH_ProgramWord failed: %#x"DCRLF, dst);
+ HAL_FLASH_Lock();
+ return -1;
+ }
+
+ HAL_FLASH_Lock();
+
+/*--- read back ---*/
+ if (_data64w != SOF_dev_read_dword(hdev, _offset_addr_w)) {
+ DPRINTF("addr=%X %#04X %#04X"DCRLF, dst, data, SOF_dev_read_dword(hdev, _offset_addr_w));
+ return -1;
+ }
+
+ _data64w = 0;//finish
+ _offset_addr_w = -1;//finish
+
+ 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 = PAGE_ADDR(sector_index) + offset_addr;
+ DASSERT((offset_addr % sizeof(uint32_t)) == 0);//required address 4 multiple
+
+ uint32_t ret = *(volatile uint32_t*)src;
+ DPRINTF("SOF_dev_read_word src=%08X, ret=%08X\r\n", src, ret);
+ return ret;
+}
+
+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 = PAGE_ADDR(sector_index) + offset_addr;
+ DPRINTF("SOF_dev_write_byte dst=%08X ofs=%d, ", dst, offset_addr);
+ // +0 +1 +2 +3 +4 +8
+ // +------+------+------+------+---- +------+
+ // |BYTE1 |BYTE2 |BYTE3 |BYTE4 | |BYTE8 |
+ // +------+------+------+------+---- +------+
+ if(offset_addr % 8 == 0){//address 4 multiple
+ _data64b |= ((uint64_t)data << (64-64));
+ _offset_addr_b = offset_addr;
+ DPRINTF("data=%02X\r\n", data);
+ return 0;//next waiting
+ } else if(offset_addr % 8 == 1){
+ _data64b |= ((uint64_t)data << (64-56));
+ DPRINTF("data=%02X\r\n", data);
+ return 0;
+ } else if(offset_addr % 8 == 2){
+ _data64b |= ((uint64_t)data << (64-48));
+ DPRINTF("data=%02X\r\n", data);
+ return 0;
+ } else if(offset_addr % 8 == 3){
+ _data64b |= ((uint64_t)data << (64-40));
+ DPRINTF("data=%02X\r\n", data);
+ return 0;
+ } else if(offset_addr % 8 == 4){
+ _data64b |= ((uint64_t)data << (64-32));
+ DPRINTF("data=%02X\r\n", data);
+ return 0;
+ } else if(offset_addr % 8 == 5){
+ _data64b |= ((uint64_t)data << (64-24));
+ DPRINTF("data=%02X\r\n", data);
+ return 0;
+ } else if(offset_addr % 8 == 6){
+ _data64b |= ((uint64_t)data << (64-16));
+ DPRINTF("data=%02X\r\n", data);
+ return 0;
+ } else if(offset_addr % 8 == 7){
+ _data64b |= ((uint64_t)data << (64-8));
+ dst = PAGE_ADDR(sector_index) + _offset_addr_b;
+ DPRINTF("data=%02X\r\n", data);
+ }
+
+ HAL_FLASH_Unlock();
+
+ if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, dst, _data64b) != HAL_OK) {
+ DPRINTF("FLASH_ProgramByte failed: %#x"DCRLF, dst);
+ HAL_FLASH_Lock();
+ return -1;
+ }
+
+ HAL_FLASH_Lock();
+
+/*--- read back ---*/
+ if (_data64b != SOF_dev_read_dword(hdev, _offset_addr_b)) {
+ DPRINTF("addr=%X %#04X %#04X"DCRLF, dst, data, SOF_dev_read_dword(hdev, _offset_addr_b));
+ return -1;
+ }
+
+ _data64b = 0;//finish
+ _offset_addr_b = -1;//finish
+
+ 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 = PAGE_ADDR(sector_index) + offset_addr;
+ uint8_t ret = *(volatile uint8_t*)src;
+ DPRINTF("SOF_dev_read_byte src=%08X, ret=%02X\r\n", src, ret);
+ return ret;
+}
+
+
+