From 4830c7c11a2b8bd9acbb9dbe154161e1e2e42178 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 23 Jan 2024 10:39:22 +0100 Subject: [PATCH 01/15] drivers: flash: stm32 flash base address from the DTS node For the flash driver, the base address is the MCU internal flash address (usualyy 0x8000000). This PR gets the that address from the device tree node "st,stm32-nv-flash" instead of relying on the CONFIG_FLASH_BASE_ADDRESS which might differ when building for another flash memory. Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32.c | 7 ++++--- drivers/flash/flash_stm32.h | 3 +++ drivers/flash/flash_stm32f1x.c | 6 +++--- drivers/flash/flash_stm32f2x.c | 2 +- drivers/flash/flash_stm32f4x.c | 2 +- drivers/flash/flash_stm32f7x.c | 2 +- drivers/flash/flash_stm32g0x.c | 2 +- drivers/flash/flash_stm32g4x.c | 2 +- drivers/flash/flash_stm32h7x.c | 6 +++--- drivers/flash/flash_stm32l4x.c | 2 +- drivers/flash/flash_stm32l5x.c | 2 +- drivers/flash/flash_stm32wba_fm.c | 4 ++-- drivers/flash/flash_stm32wbax.c | 2 +- drivers/flash/flash_stm32wbx.c | 2 +- 14 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/flash/flash_stm32.c b/drivers/flash/flash_stm32.c index 36e3103c56d3..2dcf63f32089 100644 --- a/drivers/flash/flash_stm32.c +++ b/drivers/flash/flash_stm32.c @@ -157,7 +157,7 @@ static void flash_stm32_flush_caches(const struct device *dev, regs->ACR |= FLASH_ACR_DCEN; } #elif defined(CONFIG_SOC_SERIES_STM32F7X) - SCB_InvalidateDCache_by_Addr((uint32_t *)(CONFIG_FLASH_BASE_ADDRESS + SCB_InvalidateDCache_by_Addr((uint32_t *)(FLASH_STM32_BASE_ADDRESS + offset), len); #endif } @@ -178,7 +178,7 @@ static int flash_stm32_read(const struct device *dev, off_t offset, LOG_DBG("Read offset: %ld, len: %zu", (long int) offset, len); - memcpy(data, (uint8_t *) CONFIG_FLASH_BASE_ADDRESS + offset, len); + memcpy(data, (uint8_t *) FLASH_STM32_BASE_ADDRESS + offset, len); return 0; } @@ -562,7 +562,8 @@ static int stm32_flash_init(const struct device *dev) flash_stm32_sem_init(dev); - LOG_DBG("Flash initialized. BS: %zu", + LOG_DBG("Flash @0x%x initialized. BS: %zu", + FLASH_STM32_BASE_ADDRESS, flash_stm32_parameters.write_block_size); /* Check Flash configuration */ diff --git a/drivers/flash/flash_stm32.h b/drivers/flash/flash_stm32.h index e0fba89a5503..3583a1379c6c 100644 --- a/drivers/flash/flash_stm32.h +++ b/drivers/flash/flash_stm32.h @@ -17,6 +17,9 @@ #include #endif +/* Get the base address of the flash from the DTS node */ +#define FLASH_STM32_BASE_ADDRESS DT_REG_ADDR(DT_INST(0, st_stm32_nv_flash)) + struct flash_stm32_priv { FLASH_TypeDef *regs; #if DT_NODE_HAS_PROP(DT_INST(0, st_stm32_flash_controller), clocks) || \ diff --git a/drivers/flash/flash_stm32f1x.c b/drivers/flash/flash_stm32f1x.c index 0c54d3f69fef..9a2c0bb4a903 100644 --- a/drivers/flash/flash_stm32f1x.c +++ b/drivers/flash/flash_stm32f1x.c @@ -62,7 +62,7 @@ static void erase_page_begin(FLASH_TypeDef *regs, unsigned int page) { /* Set the PER bit and select the page you wish to erase */ regs->CR |= FLASH_CR_PER; - regs->AR = CONFIG_FLASH_BASE_ADDRESS + page * FLASH_PAGE_SIZE; + regs->AR = FLASH_STM32_BASE_ADDRESS + page * FLASH_PAGE_SIZE; barrier_dsync_fence_full(); @@ -99,7 +99,7 @@ static void write_disable(FLASH_TypeDef *regs) static void erase_page_begin(FLASH_TypeDef *regs, unsigned int page) { volatile flash_prg_t *page_base = (flash_prg_t *)( - CONFIG_FLASH_BASE_ADDRESS + page * FLASH_PAGE_SIZE); + FLASH_STM32_BASE_ADDRESS + page * FLASH_PAGE_SIZE); /* Enable programming in erase mode. An erase is triggered by * writing 0 to the first word of a page. */ @@ -123,7 +123,7 @@ static int write_value(const struct device *dev, off_t offset, flash_prg_t val) { volatile flash_prg_t *flash = (flash_prg_t *)( - offset + CONFIG_FLASH_BASE_ADDRESS); + offset + FLASH_STM32_BASE_ADDRESS); FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); int rc; diff --git a/drivers/flash/flash_stm32f2x.c b/drivers/flash/flash_stm32f2x.c index f3781855f576..a525aa8e90f0 100644 --- a/drivers/flash/flash_stm32f2x.c +++ b/drivers/flash/flash_stm32f2x.c @@ -76,7 +76,7 @@ static int write_byte(const struct device *dev, off_t offset, uint8_t val) /* flush the register write */ tmp = regs->CR; - *((uint8_t *) offset + CONFIG_FLASH_BASE_ADDRESS) = val; + *((uint8_t *) offset + FLASH_STM32_BASE_ADDRESS) = val; /* Wait until the BSY bit is cleared */ rc = flash_stm32_wait_flash_idle(dev); diff --git a/drivers/flash/flash_stm32f4x.c b/drivers/flash/flash_stm32f4x.c index 4261c26a5890..ddc882747ccb 100644 --- a/drivers/flash/flash_stm32f4x.c +++ b/drivers/flash/flash_stm32f4x.c @@ -101,7 +101,7 @@ static int write_byte(const struct device *dev, off_t offset, uint8_t val) /* flush the register write */ tmp = regs->CR; - *((uint8_t *) offset + CONFIG_FLASH_BASE_ADDRESS) = val; + *((uint8_t *) offset + FLASH_STM32_BASE_ADDRESS) = val; rc = flash_stm32_wait_flash_idle(dev); regs->CR &= (~FLASH_CR_PG); diff --git a/drivers/flash/flash_stm32f7x.c b/drivers/flash/flash_stm32f7x.c index b65bf25a0791..324b66d81979 100644 --- a/drivers/flash/flash_stm32f7x.c +++ b/drivers/flash/flash_stm32f7x.c @@ -60,7 +60,7 @@ static int write_byte(const struct device *dev, off_t offset, uint8_t val) barrier_dsync_fence_full(); /* write the data */ - *((uint8_t *) offset + CONFIG_FLASH_BASE_ADDRESS) = val; + *((uint8_t *) offset + FLASH_STM32_BASE_ADDRESS) = val; /* flush the register write */ barrier_dsync_fence_full(); diff --git a/drivers/flash/flash_stm32g0x.c b/drivers/flash/flash_stm32g0x.c index 41a0e1da3bf8..5c232dacc64c 100644 --- a/drivers/flash/flash_stm32g0x.c +++ b/drivers/flash/flash_stm32g0x.c @@ -56,7 +56,7 @@ static inline void flush_cache(FLASH_TypeDef *regs) static int write_dword(const struct device *dev, off_t offset, uint64_t val) { - volatile uint32_t *flash = (uint32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); + volatile uint32_t *flash = (uint32_t *)(offset + FLASH_STM32_BASE_ADDRESS); FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); uint32_t tmp; int rc; diff --git a/drivers/flash/flash_stm32g4x.c b/drivers/flash/flash_stm32g4x.c index 8f11e21c20e9..631268a70c6a 100644 --- a/drivers/flash/flash_stm32g4x.c +++ b/drivers/flash/flash_stm32g4x.c @@ -75,7 +75,7 @@ static inline void flush_cache(FLASH_TypeDef *regs) static int write_dword(const struct device *dev, off_t offset, uint64_t val) { - volatile uint32_t *flash = (uint32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); + volatile uint32_t *flash = (uint32_t *)(offset + FLASH_STM32_BASE_ADDRESS); FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); #if defined(FLASH_STM32_DBANK) bool dcache_enabled = false; diff --git a/drivers/flash/flash_stm32h7x.c b/drivers/flash/flash_stm32h7x.c index 61394164c1bd..271bb413194c 100644 --- a/drivers/flash/flash_stm32h7x.c +++ b/drivers/flash/flash_stm32h7x.c @@ -307,7 +307,7 @@ static int write_ndwords(const struct device *dev, uint8_t n) { volatile uint64_t *flash = (uint64_t *)(offset - + CONFIG_FLASH_BASE_ADDRESS); + + FLASH_STM32_BASE_ADDRESS); int rc; int i; struct flash_stm32_sector_t sector = get_sector(dev, offset); @@ -451,7 +451,7 @@ static void flash_stm32h7_flush_caches(const struct device *dev, return; /* Cache not enabled */ } - SCB_InvalidateDCache_by_Addr((uint32_t *)(CONFIG_FLASH_BASE_ADDRESS + SCB_InvalidateDCache_by_Addr((uint32_t *)(FLASH_STM32_BASE_ADDRESS + offset), len); } #endif /* CONFIG_CPU_CORTEX_M7 */ @@ -574,7 +574,7 @@ static int flash_stm32h7_read(const struct device *dev, off_t offset, barrier_dsync_fence_full(); barrier_isync_fence_full(); - memcpy(data, (uint8_t *) CONFIG_FLASH_BASE_ADDRESS + offset, len); + memcpy(data, (uint8_t *) FLASH_STM32_BASE_ADDRESS + offset, len); __set_FAULTMASK(0); SCB->CCR &= ~SCB_CCR_BFHFNMIGN_Msk; diff --git a/drivers/flash/flash_stm32l4x.c b/drivers/flash/flash_stm32l4x.c index e82bf1db3039..d9b0fbbcbee2 100644 --- a/drivers/flash/flash_stm32l4x.c +++ b/drivers/flash/flash_stm32l4x.c @@ -69,7 +69,7 @@ static unsigned int get_page(off_t offset) static int write_dword(const struct device *dev, off_t offset, uint64_t val) { - volatile uint32_t *flash = (uint32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); + volatile uint32_t *flash = (uint32_t *)(offset + FLASH_STM32_BASE_ADDRESS); FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); #ifdef CONTROL_DCACHE bool dcache_enabled = false; diff --git a/drivers/flash/flash_stm32l5x.c b/drivers/flash/flash_stm32l5x.c index 5e4c096dceae..59b649731e94 100644 --- a/drivers/flash/flash_stm32l5x.c +++ b/drivers/flash/flash_stm32l5x.c @@ -161,7 +161,7 @@ static int write_nwords(const struct device *dev, off_t offset, const uint32_t * { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); volatile uint32_t *flash = (uint32_t *)(offset - + CONFIG_FLASH_BASE_ADDRESS); + + FLASH_STM32_BASE_ADDRESS); bool full_zero = true; uint32_t tmp; int rc; diff --git a/drivers/flash/flash_stm32wba_fm.c b/drivers/flash/flash_stm32wba_fm.c index 2628f650dccf..ff42c2643c53 100644 --- a/drivers/flash/flash_stm32wba_fm.c +++ b/drivers/flash/flash_stm32wba_fm.c @@ -93,7 +93,7 @@ static int flash_stm32_read(const struct device *dev, off_t offset, flash_stm32_sem_take(dev); - memcpy(data, (uint8_t *) CONFIG_FLASH_BASE_ADDRESS + offset, len); + memcpy(data, (uint8_t *) FLASH_STM32_BASE_ADDRESS + offset, len); flash_stm32_sem_give(dev); @@ -153,7 +153,7 @@ static int flash_stm32_write(const struct device *dev, off_t offset, LOG_DBG("Write offset: %p, len: %zu", (void *)offset, len); rc = FM_Write((uint32_t *)data, - (uint32_t *)(CONFIG_FLASH_BASE_ADDRESS + offset), + (uint32_t *)(FLASH_STM32_BASE_ADDRESS + offset), (int32_t)len/4, &cb_ptr); if (rc == 0) { k_sem_take(&flash_busy, K_FOREVER); diff --git a/drivers/flash/flash_stm32wbax.c b/drivers/flash/flash_stm32wbax.c index 0796b9a5be40..db158f71a9a2 100644 --- a/drivers/flash/flash_stm32wbax.c +++ b/drivers/flash/flash_stm32wbax.c @@ -109,7 +109,7 @@ static int write_qword(const struct device *dev, off_t offset, const uint32_t *b { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); volatile uint32_t *flash = (uint32_t *)(offset - + CONFIG_FLASH_BASE_ADDRESS); + + FLASH_STM32_BASE_ADDRESS); uint32_t tmp; int rc; diff --git a/drivers/flash/flash_stm32wbx.c b/drivers/flash/flash_stm32wbx.c index e72fddf756f7..293d9c5a54ee 100644 --- a/drivers/flash/flash_stm32wbx.c +++ b/drivers/flash/flash_stm32wbx.c @@ -60,7 +60,7 @@ static inline void flush_cache(FLASH_TypeDef *regs) static int write_dword(const struct device *dev, off_t offset, uint64_t val) { - volatile uint32_t *flash = (uint32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); + volatile uint32_t *flash = (uint32_t *)(offset + FLASH_STM32_BASE_ADDRESS); FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); uint32_t tmp; int ret, rc; From 3291b4cb1ce4c8325d9aaa0a7f0f9241c6440db9 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 2 Aug 2023 16:57:22 +0200 Subject: [PATCH 02/15] drivers: flash: stm32 flash driver has a Kconfig STM32_MEMMAP This CONFIG_STM32_MEMMAP is for enabling the MemoryMapped mode on external octo or quad spi memory. In this case, the flash_stm32_read is done in mem map mode the flash_stm32_erase is not available. Signed-off-by: Francois Ramu --- drivers/flash/Kconfig.stm32 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index a452ab8b98d0..d431b76cbe19 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -72,4 +72,11 @@ config FLASH_STM32_BLOCK_REGISTERS registers improves system security, because flash content (or protection settings) can't be changed even when exploit was found. +config STM32_MEMMAP + bool "NOR Flash in MemoryMapped for XiP" + depends on XIP + help + This option enables the XIP mode for the external NOR flash + mounted on STM32 boards. + endif # SOC_FLASH_STM32 From 44a19342c486127b7e9f296fa90bc1204c0493bd Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 1 Jun 2023 15:39:02 +0200 Subject: [PATCH 03/15] drivers: flash: stm32 ospi drivers with Memorymapped mode Enable the MemoryMapped Mode for the stm32 octoFlash driver Configure the Flash in MemoryMapped to use in XiP mode. With this mode the erase and write are not supported. Address and size are given by the DTS register property. Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_ospi.c | 190 +++++++++++++++++- .../flash_controller/st,stm32-ospi-nor.yaml | 4 +- 2 files changed, 187 insertions(+), 7 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 9d2ed2412dc5..4fcc904746b6 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -36,6 +36,9 @@ LOG_MODULE_REGISTER(flash_stm32_ospi, CONFIG_FLASH_LOG_LEVEL); (_CONCAT(HAL_OSPIM_, DT_STRING_TOKEN(STM32_OSPI_NODE, prop))), \ ((default_value))) +/* Get the base address of the flash from the DTS node */ +#define STM32_OSPI_BASE_ADDRESS DT_REG_ADDR(DT_INST(0, st_stm32_ospi_nor)) + #define STM32_OSPI_RESET_GPIO DT_INST_NODE_HAS_PROP(0, reset_gpios) #define STM32_OSPI_DLYB_BYPASSED DT_PROP(STM32_OSPI_NODE, dlyb_bypass) @@ -955,11 +958,136 @@ static int stm32_ospi_mem_reset(const struct device *dev) return 0; } +#ifdef CONFIG_STM32_MEMMAP +/* Function to configure the octoflash in MemoryMapped mode */ +static int stm32_ospi_set_memorymap(const struct device *dev) +{ + HAL_StatusTypeDef ret; + const struct flash_stm32_ospi_config *dev_cfg = dev->config; + struct flash_stm32_ospi_data *dev_data = dev->data; + OSPI_RegularCmdTypeDef s_command; + OSPI_MemoryMappedTypeDef s_MemMappedCfg = {0}; + + /* Configure octoflash in MemoryMapped mode */ + if ((dev_cfg->data_mode == OSPI_SPI_MODE) && + (stm32_ospi_hal_address_size(dev) == HAL_OSPI_ADDRESS_24_BITS)) { + /* OPI mode and 3-bytes address size not supported by memory */ + LOG_ERR("OSPI_SPI_MODE in 3Bytes addressing is not supported"); + return -EIO; + } + + /* Initialize the read command */ + s_command.OperationType = HAL_OSPI_OPTYPE_READ_CFG; + s_command.FlashId = HAL_OSPI_FLASH_ID_1; + s_command.InstructionMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_INSTRUCTION_1_LINE + : HAL_OSPI_INSTRUCTION_8_LINES) + : HAL_OSPI_INSTRUCTION_8_LINES; + s_command.InstructionDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_INSTRUCTION_DTR_DISABLE + : HAL_OSPI_INSTRUCTION_DTR_ENABLE; + s_command.InstructionSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_INSTRUCTION_8_BITS + : HAL_OSPI_INSTRUCTION_16_BITS) + : HAL_OSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? ((stm32_ospi_hal_address_size(dev) == + HAL_OSPI_ADDRESS_24_BITS) + ? SPI_NOR_CMD_READ_FAST + : SPI_NOR_CMD_READ_FAST_4B) + : SPI_NOR_OCMD_RD) + : SPI_NOR_OCMD_DTR_RD; + s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_ADDRESS_1_LINE + : HAL_OSPI_ADDRESS_8_LINES) + : HAL_OSPI_ADDRESS_8_LINES; + s_command.AddressDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_ADDRESS_DTR_DISABLE + : HAL_OSPI_ADDRESS_DTR_ENABLE; + s_command.AddressSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? stm32_ospi_hal_address_size(dev) + : HAL_OSPI_ADDRESS_32_BITS; + s_command.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + s_command.DataMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_DATA_1_LINE + : HAL_OSPI_DATA_8_LINES) + : HAL_OSPI_DATA_8_LINES; + s_command.DataDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_DATA_DTR_DISABLE + : HAL_OSPI_DATA_DTR_ENABLE; + s_command.DummyCycles = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? SPI_NOR_DUMMY_RD + : SPI_NOR_DUMMY_RD_OCTAL) + : SPI_NOR_DUMMY_RD_OCTAL_DTR; + s_command.DQSMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_DQS_DISABLE + : HAL_OSPI_DQS_ENABLE; + + s_command.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + ret = HAL_OSPI_Command(&dev_data->hospi, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory map", ret); + return -EIO; + } + + /* Initialize the program command */ + s_command.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG; + if (dev_cfg->data_rate == OSPI_STR_TRANSFER) { + s_command.Instruction = (dev_cfg->data_mode == OSPI_SPI_MODE) + ? ((stm32_ospi_hal_address_size(dev) == + HAL_OSPI_ADDRESS_24_BITS) + ? SPI_NOR_CMD_PP + : SPI_NOR_CMD_PP_4B) + : SPI_NOR_OCMD_PAGE_PRG; + } else { + s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG; + } + s_command.DQSMode = HAL_OSPI_DQS_DISABLE; + s_command.DummyCycles = 0U; + + ret = HAL_OSPI_Command(&dev_data->hospi, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory mapped", ret); + return -EIO; + } + + /* Enable the memory-mapping */ + s_MemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE; + + ret = HAL_OSPI_MemoryMapped(&dev_data->hospi, &s_MemMappedCfg); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory mapped", ret); + return -EIO; + } + + LOG_INF("MemoryMap mode enabled"); + return 0; +} + +/* Function to return true if the octoflash is in MemoryMapped else false */ +static bool stm32_ospi_is_memorymap(const struct device *dev) +{ + struct flash_stm32_ospi_data *dev_data = dev->data; + + return ((READ_BIT(dev_data->hospi.Instance->CR, + OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ? + true : false); +} +#endif /* CONFIG_STM32_MEMMAP */ + /* * Function to erase the flash : chip or sector with possible OSPI/SPI and STR/DTR * to erase the complete chip (using dedicated command) : * set size >= flash size * set addr = 0 + * NOTE: cannot erase in MemoryMapped mode */ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, size_t size) @@ -989,6 +1117,13 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, return -ENOTSUP; } +#ifdef CONFIG_STM32_MEMMAP + if (stm32_ospi_is_memorymap(dev)) { + LOG_INF("MemoryMap : cannot erase"); + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + OSPI_RegularCmdTypeDef cmd_erase = { .OperationType = HAL_OSPI_OPTYPE_COMMON_CFG, .FlashId = HAL_OSPI_FLASH_ID_1, @@ -1003,9 +1138,9 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, if (stm32_ospi_mem_ready(&dev_data->hospi, dev_cfg->data_mode, dev_cfg->data_rate) != 0) { - ospi_unlock_thread(dev); LOG_ERR("Erase failed : flash busy"); - return -EBUSY; + ret = -EBUSY; + goto end_erase; } cmd_erase.InstructionMode = (dev_cfg->data_mode == OSPI_OPI_MODE) @@ -1115,6 +1250,7 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, } +end_erase: ospi_unlock_thread(dev); return ret; @@ -1139,6 +1275,17 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (stm32_ospi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu", + (long)(STM32_OSPI_BASE_ADDRESS + addr), + size); + memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate); if (dev_cfg->data_mode != OSPI_OPI_MODE) { @@ -1207,7 +1354,10 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr, return ret; } -/* Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR */ +/* + * Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR + * NOTE: writing in MemoryMapped mode is not guaranted + */ static int flash_stm32_ospi_write(const struct device *dev, off_t addr, const void *data, size_t size) { @@ -1227,6 +1377,16 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (stm32_ospi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu", + (long)(STM32_OSPI_BASE_ADDRESS + addr), + size); + memcpy((uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, data, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ /* page program for STR or DTR mode */ OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate); @@ -1891,6 +2051,16 @@ static int flash_stm32_ospi_init(const struct device *dev) return -ENODEV; } +#ifdef CONFIG_STM32_MEMMAP + /* If MemoryMapped then configure skip init */ + if (stm32_ospi_is_memorymap(dev)) { + LOG_INF("NOR init'd in MemMapped mode\n"); + /* Force HAL instance in correct state */ + dev_data->hospi.State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + #if STM32_OSPI_USE_DMA /* * DMA configuration @@ -2235,6 +2405,18 @@ static int flash_stm32_ospi_init(const struct device *dev) } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +#ifdef CONFIG_STM32_MEMMAP + /* Now configure the octo Flash in MemoryMapped (access by address) */ + ret = stm32_ospi_set_memorymap(dev); + if (ret != 0) { + LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret); + return -EINVAL; + } + LOG_INF("NOR in MemoryMapped mode at 0x%lx (0x%x bytes)", + (long)(STM32_OSPI_BASE_ADDRESS), + dev_cfg->flash_size); + +#endif /* CONFIG_STM32_MEMMAP */ return 0; } @@ -2300,7 +2482,7 @@ static const struct flash_stm32_ospi_config flash_stm32_ospi_cfg = { .enr = DT_CLOCKS_CELL_BY_NAME(STM32_OSPI_NODE, ospi_mgr, bits)}, #endif .irq_config = flash_stm32_ospi_irq_config_func, - .flash_size = DT_INST_PROP(0, size) / 8U, + .flash_size = DT_REG_ADDR_BY_IDX(DT_INST(0, st_stm32_ospi_nor), 1), .max_frequency = DT_INST_PROP(0, ospi_max_frequency), .data_mode = DT_INST_PROP(0, spi_bus_width), /* SPI or OPI */ .data_rate = DT_INST_PROP(0, data_rate), /* DTR or STR */ diff --git a/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml b/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml index f8f84020f6a1..25dce9c07694 100644 --- a/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml +++ b/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml @@ -25,13 +25,11 @@ on-bus: ospi properties: reg: required: true + description: Flash Memory base address and size in bytes ospi-max-frequency: type: int required: true description: Maximum clock frequency of device's OSPI interface in Hz - size: - required: true - description: Flash Memory size in bits reset-gpios: type: phandle-array description: RESETn pin From aeed3d34ee5ffd49f60ff191a03ec6cf27d5693f Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 24 Jan 2024 12:55:47 +0100 Subject: [PATCH 04/15] drivers: flash: stm32 ospi driver aborts memmap before erase/write This change is aborting the memoryMapped mode of the octo-flash before erasing or writing the NOR. Operations are performed in command mode. Reading is always performed in MemoryMapped mode (memcopy) Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_ospi.c | 48 ++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 4fcc904746b6..83d4275fd9a0 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -998,7 +998,7 @@ static int stm32_ospi_set_memorymap(const struct device *dev) HAL_OSPI_ADDRESS_24_BITS) ? SPI_NOR_CMD_READ_FAST : SPI_NOR_CMD_READ_FAST_4B) - : SPI_NOR_OCMD_RD) + : dev_data->read_opcode) : SPI_NOR_OCMD_DTR_RD; s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) ? ((dev_cfg->data_mode == OSPI_SPI_MODE) @@ -1063,11 +1063,11 @@ static int stm32_ospi_set_memorymap(const struct device *dev) ret = HAL_OSPI_MemoryMapped(&dev_data->hospi, &s_MemMappedCfg); if (ret != HAL_OK) { - LOG_ERR("%d: Failed to set memory mapped", ret); + LOG_ERR("%d: Failed to enable memory mapped", ret); return -EIO; } - LOG_INF("MemoryMap mode enabled"); + LOG_DBG("MemoryMap mode enabled"); return 0; } @@ -1080,6 +1080,20 @@ static bool stm32_ospi_is_memorymap(const struct device *dev) OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ? true : false); } + +/* Abort the Memorymapped Mode so that erasing is possible */ +static int stm32_ospi_abort_memmap(const struct device *dev) +{ + struct flash_stm32_ospi_data *dev_data = dev->data; + + if (HAL_OSPI_Abort(&dev_data->hospi) != HAL_OK) { + LOG_ERR("MemoryMap abort failed"); + return -EIO; + } + LOG_DBG("MemoryMap mode disabled"); + + return 0; +} #endif /* CONFIG_STM32_MEMMAP */ /* @@ -1119,8 +1133,12 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, #ifdef CONFIG_STM32_MEMMAP if (stm32_ospi_is_memorymap(dev)) { - LOG_INF("MemoryMap : cannot erase"); - return 0; + /* If the Flash is in MemoryMapped mode, abort it and continue */ + LOG_INF("MemoryMap : disable before erase"); + if (stm32_ospi_abort_memmap(dev) != 0) { + LOG_ERR("MemoryMap not aborted correctly"); + return -EIO; + } } #endif /* CONFIG_STM32_MEMMAP */ @@ -1276,6 +1294,14 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr, } #ifdef CONFIG_STM32_MEMMAP + /* If not MemMapped then configure it */ + if (!stm32_ospi_is_memorymap(dev)) { + if (stm32_ospi_set_memorymap(dev) != 0) { + LOG_ERR("READ failed: cannot enable MemoryMap"); + return -EIO; + } + } + LOG_INF("MemoryMap : enable before read"); if (stm32_ospi_is_memorymap(dev)) { LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu", (long)(STM32_OSPI_BASE_ADDRESS + addr), @@ -1379,6 +1405,18 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr, #ifdef CONFIG_STM32_MEMMAP if (stm32_ospi_is_memorymap(dev)) { + /* If the Flash is in MemoryMapped mode, abort it and continue */ + LOG_INF("MemoryMap : disable before write"); + if (stm32_ospi_abort_memmap(dev) != 0) { + LOG_ERR("MemoryMap not aborted correctly"); + return -EIO; + } + } + if (stm32_ospi_is_memorymap(dev)) { + /* + * If the Flash is in MemoryMapped mode, write by memcopy + * should not due to previous operation + */ LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu", (long)(STM32_OSPI_BASE_ADDRESS + addr), size); From 5e10f8acf2b23fdbf81c0075b6b6c2e9f8754f0a Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 6 Sep 2023 15:54:25 +0200 Subject: [PATCH 05/15] soc: arm: stm32u5 device with DCACHE for writing to NOR flash Enable the DCACHE1 in INCR burt mode to allow writing to the external NOR octoFlash when in MemoryMapped mode Signed-off-by: Francois Ramu --- soc/arm/st_stm32/stm32u5/soc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soc/arm/st_stm32/stm32u5/soc.c b/soc/arm/st_stm32/stm32u5/soc.c index d25fec9c680d..68df79d620b5 100644 --- a/soc/arm/st_stm32/stm32u5/soc.c +++ b/soc/arm/st_stm32/stm32u5/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,10 @@ static int stm32u5_init(void) LL_ICACHE_SetMode(LL_ICACHE_1WAY); LL_ICACHE_Enable(); + /* Enable data cache (master port write access) */ + LL_DCACHE_SetReadBurstType(DCACHE1, LL_DCACHE_READ_BURST_INCR); + LL_DCACHE_Enable(DCACHE1); + /* Update CMSIS SystemCoreClock variable (HCLK) */ /* At reset, system core clock is set to 4 MHz from MSIS */ SystemCoreClock = 4000000; From 84aca6d23b42b9f6d197545ac7e7064c997931fa Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 31 Aug 2023 14:43:44 +0200 Subject: [PATCH 06/15] boards: arm: stm32u585 disco kit for XiP on external octoflash Define the Device tree of the b_u585i_iot02a disco kit to access the external NOR octo-flash in MemoryMapped mode for XiP Signed-off-by: Francois Ramu --- boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi | 11 ++++++----- boards/arm/b_u585i_iot02a/b_u585i_iot02a.dts | 6 +----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi b/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi index f2dd82f9ad12..1aa1d94e7555 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi @@ -131,11 +131,10 @@ stm32_lp_tick_source: &lptim1 { status = "okay"; - mx25lm51245: ospi-nor-flash@0 { + mx25lm51245: ospi-nor-flash@70000000 { compatible = "st,stm32-ospi-nor"; - reg = <0>; + reg = <0x70000000 DT_SIZE_M(64)>; /* 512 Mbits */ ospi-max-frequency = ; - size = ; /* 64 MBytes */ spi-bus-width = ; data-rate = ; four-byte-opcodes; @@ -146,8 +145,10 @@ stm32_lp_tick_source: &lptim1 { #address-cells = <1>; #size-cells = <1>; - partition@0 { - reg = <0x00000000 DT_SIZE_M(64)>; + /* put image at the offset of slot1 */ + slot1_partition:partition@100000 { + label = "image-1"; + reg = <0x00100000 DT_SIZE_K(416)>; }; }; }; diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a.dts b/boards/arm/b_u585i_iot02a/b_u585i_iot02a.dts index f8a826b1b6ed..42a9f89b5ce9 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a.dts +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a.dts @@ -16,7 +16,6 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,code-partition = &slot0_partition; }; aliases { @@ -45,10 +44,7 @@ label = "image-0"; reg = <0x00010000 DT_SIZE_K(416)>; }; - slot1_partition: partition@78000 { - label = "image-1"; - reg = <0x00078000 DT_SIZE_K(416)>; - }; + scratch_partition: partition@e0000 { label = "image-scratch"; reg = <0x000e0000 DT_SIZE_K(64)>; From 2d582f4728d67766df7f70f0fdf5ce8f459490b9 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 23 Jan 2024 11:43:07 +0100 Subject: [PATCH 07/15] samples: subsys: fs_little fs on stm32u585 disco in xip Gives a sample to execute the little fs on external memory map (XiP) where the lfs1 partition is in internal mcu flash The application is built/linked/stored in the external NOR flash on slot1 partition. Signed-off-by: Francois Ramu --- .../subsys/fs/littlefs/boards/b_u585i_iot02a.conf | 2 ++ .../fs/littlefs/boards/b_u585i_iot02a.overlay | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.conf b/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.conf index c5f2188e4d31..d906422678e6 100644 --- a/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.conf +++ b/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.conf @@ -5,3 +5,5 @@ # CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 + +CONFIG_STM32_MEMMAP=y diff --git a/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.overlay b/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.overlay index b4996d707100..311f3fce09df 100644 --- a/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.overlay +++ b/samples/subsys/fs/littlefs/boards/b_u585i_iot02a.overlay @@ -5,6 +5,10 @@ */ / { + chosen { + zephyr,code-partition = &slot1_partition; + }; + fstab { compatible = "zephyr,fstab"; lfs1: lfs1 { @@ -21,13 +25,10 @@ }; }; -&mx25lm51245 { +&flash0 { partitions { - /delete-node/ partition; - - /* Use the whole flash for the filesystem. */ - lfs1_partition: partition@0 { - reg = <0x00000000 DT_SIZE_M(64)>; + lfs1_partition: partition@d0000 { + reg = <0x000d0000 DT_SIZE_K(64)>; }; }; }; From 8b6b9ab61f8143deea53466e6b58f169b46fff7d Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 15 Sep 2023 14:59:43 +0200 Subject: [PATCH 08/15] drivers: clock control of the stm32h7 skips pll1 re-init Skip the PLL1 init if it is already running, this will avoid disabling the PLL when running after a jump from mcuboot Signed-off-by: Francois Ramu --- drivers/clock_control/clock_stm32_ll_h7.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index 9d76004c92fd..04865c8c6e79 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -666,6 +666,12 @@ __unused static int set_up_plls(void) { #if defined(STM32_PLL_ENABLED) || defined(STM32_PLL2_ENABLED) || defined(STM32_PLL3_ENABLED) + + /* Skip if PLL1 is already configured */ + if (LL_RCC_PLL1_IsReady()) { + return 0; + } + int r; uint32_t vco_input_range; uint32_t vco_output_range; From 1b1e047e2c9aca80e4946fbfbf1a043809c85cba Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 26 Jan 2024 16:44:34 +0100 Subject: [PATCH 09/15] dts: arm: stm32h7 MPU attribute for the external Memory Define the MPU attribute to be ATTR_MPU_IO for the qspi region, starting at 0x90000000 of the stm32h7 serie. Signed-off-by: Francois Ramu --- dts/arm/st/h7/stm32h7.dtsi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 64ccfbf7241a..10880c62e0ed 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -46,10 +46,11 @@ }; quadspi_memory: memory@90000000 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x90000000 DT_SIZE_M(256)>; + compatible = "zephyr,memory-region"; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ zephyr,memory-region = "QSPI"; - zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; + /* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; clocks { From d9a03a8c9dc9f84f3a9accc5861d67c0136c5e7d Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 4 Sep 2023 16:19:27 +0200 Subject: [PATCH 10/15] boards: arm: stm32h7b3 disco kit for XiP on external octoflash Define the Device tree of the stm32h7b3i_dk disco board to access the external NOR octo-flash in MemoryMapped mode for XiP Set openocd runner for debugging. Signed-off-by: Francois Ramu --- boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts | 41 +++++++++++++++++--- boards/arm/stm32h7b3i_dk/support/openocd.cfg | 7 ++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts index b8b781b3fa10..36861f3d5633 100644 --- a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -242,6 +242,35 @@ def-back-color-blue = <0xFF>; }; +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; + }; + + /* + * The flash starting at offset 0x10000 and ending at + * offset 0x1ffff is reserved for use by the application. + */ + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(800)>; + }; + + scratch_partition: partition@f8000 { + label = "image-scratch"; + reg = <0x000F8000 DT_SIZE_K(16)>; + }; + }; +}; + &octospi1 { pinctrl-0 = <&octospim_p1_clk_pb2 &octospim_p1_ncs_pg6 &octospim_p1_io0_pd11 &octospim_p1_io1_pf9 @@ -253,11 +282,10 @@ status = "okay"; - mx25lm51245: ospi-nor-flash@0 { + mx25lm51245: ospi-nor-flash@90000000 { compatible = "st,stm32-ospi-nor"; - reg = <0>; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Megabits */ ospi-max-frequency = ; - size = ; /* 512 Megabits */ spi-bus-width = ; data-rate = ; status = "okay"; @@ -267,9 +295,10 @@ #address-cells = <1>; #size-cells = <1>; - partition@0 { - label = "nor"; - reg = <0x00000000 DT_SIZE_M(4)>; + /* put image at offset 0 in slot1 */ + slot1_partition:partition@0 { + label = "image-1"; + reg = <0x00000000 DT_SIZE_K(800)>; }; }; }; diff --git a/boards/arm/stm32h7b3i_dk/support/openocd.cfg b/boards/arm/stm32h7b3i_dk/support/openocd.cfg index a078b4b8c978..114bd25b797d 100644 --- a/boards/arm/stm32h7b3i_dk/support/openocd.cfg +++ b/boards/arm/stm32h7b3i_dk/support/openocd.cfg @@ -20,3 +20,10 @@ set CORE_RESET 0 source [find target/stm32h7x.cfg] +# Due to the use of connect_assert_srst, running gdb requires +# to reset halt just after openocd init. +rename init old_init +proc init {} { + old_init + reset halt +} From c54eca3c1c0571556924af0c2ec8ebd181ce1a02 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 23 Jan 2024 13:58:36 +0100 Subject: [PATCH 11/15] samples: subsys: fs_little fs on stm32h7b3 disco in xip Gives a sample to execute the little fs on external memory map (XiP) where the lfs1 partition is in internal mcu flash Signed-off-by: Francois Ramu --- .../fs/littlefs/boards/stm32h7b3i_dk.conf | 3 ++ .../fs/littlefs/boards/stm32h7b3i_dk.overlay | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.conf create mode 100644 samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.overlay diff --git a/samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.conf b/samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.conf new file mode 100644 index 000000000000..8bc2e5b8df52 --- /dev/null +++ b/samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.conf @@ -0,0 +1,3 @@ +CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 + +CONFIG_STM32_MEMMAP=y diff --git a/samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.overlay b/samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.overlay new file mode 100644 index 000000000000..25568e8b76db --- /dev/null +++ b/samples/subsys/fs/littlefs/boards/stm32h7b3i_dk.overlay @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 OS Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + + chosen { + zephyr,code-partition = &slot1_partition; + }; + + fstab { + compatible = "zephyr,fstab"; + lfs1: lfs1 { + compatible = "zephyr,fstab,littlefs"; + read-size = <256>; + prog-size = <256>; + cache-size = <4096>; + lookahead-size = <256>; + block-cycles = <512>; + partition = <&lfs1_partition>; + mount-point = "/lfs1"; + automount; + }; + }; +}; + +&flash0 { + partitions { + lfs1_partition: partition@e0000 { + reg = <0x000e0000 DT_SIZE_K(64)>; + }; + }; +}; From 2bec296ec11d064336da1dad4b10a7444298f9e7 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 29 Jan 2024 16:54:10 +0100 Subject: [PATCH 12/15] drivers: flash: stm32 qspi driver set NOR flash in MemoryMapped Configures the external NOR Flash in MemoryMapped Mode, at the end of the NOR flash-controller initialization. Then reading/writing are performed in MemoryMapped mode with memcopy (and no more with command mode). In this mode: erasing is not supported anymore. The flash size and address are given by the DTS property. Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_qspi.c | 104 +++++++++++++++++- drivers/flash/spi_nor.h | 4 + .../flash_controller/st,stm32-qspi-nor.yaml | 4 +- 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index 6a9f8a585573..d86e5d0d26e2 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -29,6 +29,9 @@ #define STM32_QSPI_USE_QUAD_IO 0 #endif +/* Get the base address of the flash from the DTS node */ +#define STM32_QSPI_BASE_ADDRESS DT_REG_ADDR(DT_INST(0, st_stm32_qspi_nor)) + #define STM32_QSPI_RESET_GPIO DT_INST_NODE_HAS_PROP(0, reset_gpios) #define STM32_QSPI_RESET_CMD DT_INST_NODE_HAS_PROP(0, reset_cmd) @@ -382,6 +385,54 @@ static bool qspi_address_is_valid(const struct device *dev, off_t addr, return (addr >= 0) && ((uint64_t)addr + (uint64_t)size <= flash_size); } +#ifdef CONFIG_STM32_MEMMAP +/* Function to return true if the quad-NOR flash is in MemoryMapped else false */ +static bool qspi_is_memorymap(const struct device *dev) +{ + struct flash_stm32_qspi_data *dev_data = dev->data; + + return ((READ_BIT(dev_data->hqspi.Instance->CCR, + QUADSPI_CCR_FMODE) == QUADSPI_CCR_FMODE) ? + true : false); +} + + +/* Function to configure the memmapped mode */ +static int qspi_set_memorymap(const struct device *dev) +{ + HAL_StatusTypeDef ret; + struct flash_stm32_qspi_data *dev_data = dev->data; + QSPI_CommandTypeDef s_command = {0}; + QSPI_MemoryMappedTypeDef s_memmap_cfg; + + /* Reading sequence */ + s_command.Instruction = SPI_NOR_CMD_4READ; /* 0x6B also supported */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.AddressMode = QSPI_ADDRESS_4_LINES; + s_command.AddressSize = QSPI_ADDRESS_32_BITS; /* valid for stm32H7 and stm32L4 */ + s_command.DataMode = QSPI_DATA_4_LINES; +#ifdef CONFIG_SOC_SERIES_STM32H7X + s_command.DummyCycles = SPI_NOR_DUMMY_RD_QUAD; /* less than 10 is too short */ +#else + s_command.DummyCycles = 4;/* other value than 4 is too short */ +#endif /* CONFIG_SOC_SERIES_STM32H7X */ + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + s_command.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; + + /* Enable the memory-mapping */ + s_memmap_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; + s_memmap_cfg.TimeOutPeriod = 0; + + ret = HAL_QSPI_MemoryMapped(&dev_data->hqspi, &s_command, &s_memmap_cfg); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory map", ret); + return -EIO; + } + + return 0; +} +#endif /* CONFIG_STM32_MEMMAP */ + static int flash_stm32_qspi_read(const struct device *dev, off_t addr, void *data, size_t size) { @@ -398,6 +449,15 @@ static int flash_stm32_qspi_read(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (qspi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu", + (long)(STM32_QSPI_BASE_ADDRESS + addr), size); + memcpy(data, (uint8_t *)STM32_QSPI_BASE_ADDRESS + addr, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ QSPI_CommandTypeDef cmd = { .Instruction = SPI_NOR_CMD_READ, .Address = addr, @@ -457,6 +517,16 @@ static int flash_stm32_qspi_write(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (qspi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu", + (long)(STM32_QSPI_BASE_ADDRESS + addr), size); + memcpy((uint8_t *)STM32_QSPI_BASE_ADDRESS + addr, data, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + QSPI_CommandTypeDef cmd_write_en = { .Instruction = SPI_NOR_CMD_WREN, .InstructionMode = QSPI_INSTRUCTION_1_LINE, @@ -538,6 +608,13 @@ static int flash_stm32_qspi_erase(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (qspi_is_memorymap(dev)) { + LOG_INF("MemoryMapped : cannot erase"); + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + QSPI_CommandTypeDef cmd_write_en = { .Instruction = SPI_NOR_CMD_WREN, .InstructionMode = QSPI_INSTRUCTION_1_LINE, @@ -910,6 +987,7 @@ static int qspi_write_status_register(const struct device *dev, uint8_t reg_num, return qspi_write_access(dev, &cmd, regs_p, size); } +/* Function send a Write Enable and wait it is effective. */ static int qspi_write_enable(const struct device *dev) { uint8_t reg; @@ -1185,6 +1263,17 @@ static int flash_stm32_qspi_init(const struct device *dev) return ret; } + +#ifdef CONFIG_STM32_MEMMAP + /* If MemoryMapped then configure skip init */ + if (qspi_is_memorymap(dev)) { + LOG_INF("NOR init'd in MemMapped mode\n"); + /* Force HAL instance in correct state */ + dev_data->hqspi.State = HAL_QSPI_STATE_BUSY_MEM_MAPPED; + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + #if STM32_QSPI_RESET_GPIO flash_stm32_qspi_gpio_reset(dev); #endif @@ -1364,6 +1453,19 @@ static int flash_stm32_qspi_init(const struct device *dev) } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +#ifdef CONFIG_STM32_MEMMAP + ret = qspi_set_memorymap(dev); + + if (ret != 0) { + LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret); + return -EINVAL; + } + LOG_INF("NOR in MemoryMapped mode at 0x%lx (0x%x bytes)", + (long)(STM32_QSPI_BASE_ADDRESS), + dev_cfg->flash_size); + +#endif /* CONFIG_STM32_MEMMAP */ + return 0; } @@ -1420,7 +1522,7 @@ static const struct flash_stm32_qspi_config flash_stm32_qspi_cfg = { .bus = DT_CLOCKS_CELL(STM32_QSPI_NODE, bus) }, .irq_config = flash_stm32_qspi_irq_config_func, - .flash_size = DT_INST_PROP(0, size) / 8U, + .flash_size = DT_REG_ADDR_BY_IDX(DT_INST(0, st_stm32_qspi_nor), 1), .max_frequency = DT_INST_PROP(0, qspi_max_frequency), .pcfg = PINCTRL_DT_DEV_CONFIG_GET(STM32_QSPI_NODE), #if STM32_QSPI_RESET_GPIO diff --git a/drivers/flash/spi_nor.h b/drivers/flash/spi_nor.h index 8d54cc615089..82147baac532 100644 --- a/drivers/flash/spi_nor.h +++ b/drivers/flash/spi_nor.h @@ -60,6 +60,9 @@ #define SPI_NOR_CMD_PP_1_1_4_4B 0x34 /* Quad Page program (1-1-4) 4 Byte Address */ #define SPI_NOR_CMD_PP_1_4_4_4B 0x3e /* Quad Page program (1-4-4) 4 Byte Address */ +#define SPI_NOR_CMD_RD_VOL_CFG 0x85 /* Read Volatile configuration register */ +#define SPI_NOR_CMD_WR_VOL_CFG 0x81 /* Write Volatile configuration register */ + /* Flash octal opcodes */ #define SPI_NOR_OCMD_SE 0x21DE /* Octal Sector erase */ #define SPI_NOR_OCMD_CE 0xC738 /* Octal Chip erase */ @@ -94,6 +97,7 @@ /* Flash Dummy Cycles values */ #define SPI_NOR_DUMMY_RD 8U +#define SPI_NOR_DUMMY_RD_QUAD 10U #define SPI_NOR_DUMMY_RD_OCTAL 6U #define SPI_NOR_DUMMY_RD_OCTAL_DTR 6U #define SPI_NOR_DUMMY_REG_OCTAL 4U diff --git a/dts/bindings/flash_controller/st,stm32-qspi-nor.yaml b/dts/bindings/flash_controller/st,stm32-qspi-nor.yaml index 6d7bf5105e63..e556d5a1639a 100644 --- a/dts/bindings/flash_controller/st,stm32-qspi-nor.yaml +++ b/dts/bindings/flash_controller/st,stm32-qspi-nor.yaml @@ -26,13 +26,11 @@ on-bus: qspi properties: reg: required: true + description: Flash Memory base address and size in bytes qspi-max-frequency: type: int required: true description: Maximum clock frequency of device's QSPI interface in Hz - size: - required: true - description: Flash Memory size in bits reset-gpios: type: phandle-array description: RESETn pin From c57cff6f9639a489fcd7af82c3cae9efc5bf0db4 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 1 Feb 2024 10:16:10 +0100 Subject: [PATCH 13/15] drivers: flash: stm32 qspi driver in Dual Flash Mode when MemoryMapped Configure the quad-spi in DualFlash Mode when enabling the MemoryMapped then reading is possible with memcopy. Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_qspi.c | 20 ++++++++++++++++---- dts/bindings/qspi/st,stm32-qspi.yaml | 2 ++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index d86e5d0d26e2..1aa82f344ec3 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -412,12 +412,11 @@ static int qspi_set_memorymap(const struct device *dev) s_command.AddressSize = QSPI_ADDRESS_32_BITS; /* valid for stm32H7 and stm32L4 */ s_command.DataMode = QSPI_DATA_4_LINES; #ifdef CONFIG_SOC_SERIES_STM32H7X - s_command.DummyCycles = SPI_NOR_DUMMY_RD_QUAD; /* less than 10 is too short */ + s_command.DummyCycles = SPI_NOR_DUMMY_RD_QUAD; /* other value than 10 is wrong */ #else - s_command.DummyCycles = 4;/* other value than 4 is too short */ + s_command.DummyCycles = 4;/* other value than 4 is wrong */ #endif /* CONFIG_SOC_SERIES_STM32H7X */ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - s_command.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; /* Enable the memory-mapping */ s_memmap_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; @@ -1366,7 +1365,12 @@ static int flash_stm32_qspi_init(const struct device *dev) dev_data->hqspi.Init.ClockPrescaler = prescaler; /* Give a bit position from 0 to 31 to the HAL init minus 1 for the DCR1 reg */ dev_data->hqspi.Init.FlashSize = find_lsb_set(dev_cfg->flash_size) - 2; - +#if ! DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) + /* That means Dual Flash configuration : FlashID is meaningless */ + dev_data->hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE; + /* Set Dual Flash Mode only on MemoryMapped */ + dev_data->hqspi.Init.FlashID = QSPI_FLASH_ID_1; +#endif HAL_QSPI_Init(&dev_data->hqspi); #if DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) @@ -1454,6 +1458,14 @@ static int flash_stm32_qspi_init(const struct device *dev) #endif /* CONFIG_FLASH_PAGE_LAYOUT */ #ifdef CONFIG_STM32_MEMMAP +#if ! DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) + /* Force Dual Flash mode now */ + MODIFY_REG(dev_data->hqspi.Instance->CR, (QUADSPI_CR_DFM), QSPI_DUALFLASH_ENABLE); + LOG_DBG("Dual Flash Mode"); +#else + LOG_ERR("Cannot set MemoryMapped mode if DualFlash is off"); +#endif + ret = qspi_set_memorymap(dev); if (ret != 0) { diff --git a/dts/bindings/qspi/st,stm32-qspi.yaml b/dts/bindings/qspi/st,stm32-qspi.yaml index 04aa6e4d0208..cea2f66a70eb 100644 --- a/dts/bindings/qspi/st,stm32-qspi.yaml +++ b/dts/bindings/qspi/st,stm32-qspi.yaml @@ -66,5 +66,7 @@ properties: QSPI GPIO banks (defined as 'quadspi_bk[12]' in pinctrl property) to communicate with flash memory. + When NOT set, it means Dual Flash Mode. + For example flash-id = <2>; From 279699a0a4dfd579ab94b29f01b443870047ad7c Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 26 Jan 2024 16:41:42 +0100 Subject: [PATCH 14/15] boards: arm: stm32 disco kit for XiP on external quadflash Define the Device tree of the stm32l496g_disco board or stm32h750b disco kit to access the external NOR quad-flash in MemoryMapped mode for XiP Signed-off-by: Francois Ramu --- .../stm32h747i_disco/stm32h747i_disco_m7.dts | 28 ++++++++---- boards/arm/stm32h750b_dk/stm32h750b_dk.dts | 44 ++++++++++++++----- .../arm/stm32l496g_disco/stm32l496g_disco.dts | 39 ++++++++++++++-- 3 files changed, 88 insertions(+), 23 deletions(-) diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts index 514047c8a55b..3e485892fb9f 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts @@ -111,6 +111,16 @@ #address-cells = <1>; #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(416)>; + }; + /* Set 2KB of storage at the end of first 1MB flash */ storage_partition: partition@ff800 { label = "storage"; @@ -232,11 +242,10 @@ zephyr_udc0: &usbotg_hs { pinctrl-names = "default"; status = "okay"; - mt25ql512ab1: qspi-nor-flash-1@0 { + mt25ql512ab1: qspi-nor-flash-1@90000000 { compatible = "st,stm32-qspi-nor"; - reg = <0>; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ qspi-max-frequency = <72000000>; - size = ; /* 64 MBytes */ spi-bus-width = <4>; status = "okay"; @@ -245,17 +254,18 @@ zephyr_udc0: &usbotg_hs { #address-cells = <1>; #size-cells = <1>; - partition@0 { - reg = <0x0 DT_SIZE_M(64)>; - }; + /* put image at offset 0 in slot1 */ + slot1_partition:partition@0 { + label = "image-1"; + reg = <0x00000000 DT_SIZE_K(416)>; + }; }; }; - mt25ql512ab2: qspi-nor-flash-2@0 { + mt25ql512ab2: qspi-nor-flash-2@90000000 { compatible = "st,stm32-qspi-nor"; - reg = <0>; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ qspi-max-frequency = <72000000>; - size = ; /* 64 MBytes */ status = "okay"; }; }; diff --git a/boards/arm/stm32h750b_dk/stm32h750b_dk.dts b/boards/arm/stm32h750b_dk/stm32h750b_dk.dts index efe4b7b27434..da80a4a45944 100644 --- a/boards/arm/stm32h750b_dk/stm32h750b_dk.dts +++ b/boards/arm/stm32h750b_dk/stm32h750b_dk.dts @@ -18,7 +18,6 @@ zephyr,shell-uart = &usart3; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,flash-controller = &mt25ql512ab1; }; sdram2: sdram@d0000000 { @@ -85,6 +84,30 @@ d3ppre = <2>; }; +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(416)>; + }; + + /* Set 2KB of storage at the end of first 1MB flash */ + storage_partition: partition@ff800 { + label = "storage"; + reg = <0x000ff800 DT_SIZE_K(2)>; + }; + }; +}; + &usart3 { pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; pinctrl-names = "default"; @@ -99,14 +122,12 @@ &quadspi_bk1_io2_pf7 &quadspi_bk1_io3_pf6 &quadspi_bk2_io0_ph2 &quadspi_bk2_io1_ph3 &quadspi_bk2_io2_pg9 &quadspi_bk2_io3_pg14>; - flash-id = <1>; status = "okay"; - mt25ql512ab1: qspi-nor-flash-1@0 { + mt25ql512ab1: qspi-nor-flash-1@90000000 { compatible = "st,stm32-qspi-nor"; - reg = <0>; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ qspi-max-frequency = <72000000>; - size = ; /* 64 MBytes */ spi-bus-width = <4>; status = "okay"; @@ -115,17 +136,18 @@ #address-cells = <1>; #size-cells = <1>; - partition@0 { - reg = <0x0 DT_SIZE_M(64)>; - }; + /* put image at offset 0 in slot1 */ + slot1_partition:partition@0 { + label = "image-1"; + reg = <0x00000000 DT_SIZE_K(416)>; + }; }; }; - mt25ql512ab2: qspi-nor-flash-2@1 { + mt25ql512ab2: qspi-nor-flash-2@90000000 { compatible = "st,stm32-qspi-nor"; - reg = <1>; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ qspi-max-frequency = <72000000>; - size = ; /* 64 MBytes */ status = "okay"; }; }; diff --git a/boards/arm/stm32l496g_disco/stm32l496g_disco.dts b/boards/arm/stm32l496g_disco/stm32l496g_disco.dts index 977e70142efe..a03ed8b0a2a1 100644 --- a/boards/arm/stm32l496g_disco/stm32l496g_disco.dts +++ b/boards/arm/stm32l496g_disco/stm32l496g_disco.dts @@ -103,6 +103,28 @@ apb2-prescaler = <1>; }; +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(416)>; + }; + /* Set 2KB of storage at the end of first 1MB flash */ + storage_partition: partition@ff800 { + label = "storage"; + reg = <0x000ff800 DT_SIZE_K(2)>; + }; + }; +}; + &usart1 { pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pg10>; pinctrl-names = "default"; @@ -201,13 +223,24 @@ zephyr_udc0: &usbotg_fs { flash-id = <1>; status = "okay"; - mx25r6435: qspi-nor-flash@0 { + mx25r6435: qspi-nor-flash@90000000 { compatible = "st,stm32-qspi-nor"; - reg = <0>; + reg = <0x90000000 DT_SIZE_M(8)>; qspi-max-frequency = <8000000>; - size = ; /* 8 MBytes */ status = "okay"; spi-bus-width = <4>; writeoc = "PP_1_4_4"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* put image at offset 0 in slot1 */ + slot1_partition:partition@0 { + label = "image-1"; + reg = <0x00000000 DT_SIZE_K(416)>; + }; + }; }; }; From fc6dd457ccc0656b7b92531159372a2f25c1575f Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 29 Jan 2024 11:02:40 +0100 Subject: [PATCH 15/15] samples: subsys: fs_little fs on stm32 qspi disco in xip Gives a sample to execute the little fs on external memory map (XiP) where the lfs1 partition is in internal mcu flash Signed-off-by: Francois Ramu --- .../boards/stm32h747i_disco_m7.overlay | 29 +++++++++++++++ .../fs/littlefs/boards/stm32h750b_dk.conf | 3 ++ .../fs/littlefs/boards/stm32h750b_dk.overlay | 35 +++++++++++++++++++ .../littlefs/boards/stm32l496g_disco.overlay | 34 ++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 samples/subsys/fs/littlefs/boards/stm32h750b_dk.conf create mode 100644 samples/subsys/fs/littlefs/boards/stm32h750b_dk.overlay create mode 100644 samples/subsys/fs/littlefs/boards/stm32l496g_disco.overlay diff --git a/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay index cf1c30e2e87b..c2945675ddec 100644 --- a/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay +++ b/samples/subsys/fs/littlefs/boards/stm32h747i_disco_m7.overlay @@ -4,6 +4,35 @@ * SPDX-License-Identifier: Apache-2.0 */ +/ { + chosen { + zephyr,code-partition = &slot1_partition; + }; + + fstab { + compatible = "zephyr,fstab"; + lfs1: lfs1 { + compatible = "zephyr,fstab,littlefs"; + read-size = <256>; + prog-size = <256>; + cache-size = <4096>; + lookahead-size = <256>; + block-cycles = <512>; + partition = <&lfs1_partition>; + mount-point = "/lfs1"; + automount; + }; + }; +}; + +&flash0 { + partitions { + lfs1_partition: partition@e0000 { + reg = <0x000e0000 DT_SIZE_K(64)>; + }; + }; +}; + &sdmmc1 { sdmmc { compatible = "zephyr,sdmmc-disk"; diff --git a/samples/subsys/fs/littlefs/boards/stm32h750b_dk.conf b/samples/subsys/fs/littlefs/boards/stm32h750b_dk.conf new file mode 100644 index 000000000000..8bc2e5b8df52 --- /dev/null +++ b/samples/subsys/fs/littlefs/boards/stm32h750b_dk.conf @@ -0,0 +1,3 @@ +CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 + +CONFIG_STM32_MEMMAP=y diff --git a/samples/subsys/fs/littlefs/boards/stm32h750b_dk.overlay b/samples/subsys/fs/littlefs/boards/stm32h750b_dk.overlay new file mode 100644 index 000000000000..5eae5f067538 --- /dev/null +++ b/samples/subsys/fs/littlefs/boards/stm32h750b_dk.overlay @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + + chosen { + zephyr,code-partition = &slot1_partition; + }; + + fstab { + compatible = "zephyr,fstab"; + lfs1: lfs1 { + compatible = "zephyr,fstab,littlefs"; + read-size = <256>; + prog-size = <256>; + cache-size = <4096>; + lookahead-size = <256>; + block-cycles = <512>; + partition = <&lfs1_partition>; + mount-point = "/lfs1"; + automount; + }; + }; +}; + +&flash0 { + partitions { + lfs1_partition: partition@e0000 { + reg = <0x000e0000 DT_SIZE_K(64)>; + }; + }; +}; diff --git a/samples/subsys/fs/littlefs/boards/stm32l496g_disco.overlay b/samples/subsys/fs/littlefs/boards/stm32l496g_disco.overlay new file mode 100644 index 000000000000..6d29d31c4aa6 --- /dev/null +++ b/samples/subsys/fs/littlefs/boards/stm32l496g_disco.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,code-partition = &slot1_partition; + }; + + fstab { + compatible = "zephyr,fstab"; + lfs1: lfs1 { + compatible = "zephyr,fstab,littlefs"; + read-size = <256>; + prog-size = <256>; + cache-size = <4096>; + lookahead-size = <256>; + block-cycles = <512>; + partition = <&lfs1_partition>; + mount-point = "/lfs1"; + automount; + }; + }; +}; + +&flash0 { + partitions { + lfs1_partition: partition@e0000 { + reg = <0x000e0000 DT_SIZE_K(64)>; + }; + }; +};