Skip to content

Commit 4125b27

Browse files
committed
drivers: flash: stm32 ospi drivers with Memorymapped mode
Enable the MemoryMapped Mode for the stm32 octoFlash driver Configure the Flash in MemoryMapped to use memcopy for writing/reading. TBC for erasing command. Signed-off-by: Francois Ramu <[email protected]>
1 parent 4ccc671 commit 4125b27

File tree

2 files changed

+176
-2
lines changed

2 files changed

+176
-2
lines changed

drivers/flash/Kconfig.stm32_ospi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ config FLASH_STM32_OSPI
1818
select FLASH_JESD216
1919
select FLASH_PAGE_LAYOUT
2020
select FLASH_HAS_PAGE_LAYOUT
21+
select STM32_XIP
2122
select DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || $(DT_STM32_OCTOSPI_2_HAS_DMA)
2223
select USE_STM32_HAL_DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || \
2324
$(DT_STM32_OCTOSPI_2_HAS_DMA)

drivers/flash/flash_stm32_ospi.c

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ LOG_MODULE_REGISTER(flash_stm32_ospi, CONFIG_FLASH_LOG_LEVEL);
4242

4343
#define STM32_OSPI_USE_DMA DT_NODE_HAS_PROP(STM32_OSPI_NODE, dmas)
4444

45+
/* The Base Address of the octo spi chosen by the Flash controller */
46+
#define STM32_NOR_FLASH_BASE_ADDRESS OCTOSPI2_BASE
47+
4548
#if STM32_OSPI_USE_DMA
4649
#include <zephyr/drivers/dma/dma_stm32.h>
4750
#include <zephyr/drivers/dma.h>
@@ -955,6 +958,127 @@ static int stm32_ospi_mem_reset(const struct device *dev)
955958
return 0;
956959
}
957960

961+
#ifdef CONFIG_STM32_XIP
962+
static int stm32_ospi_set_memorymap(const struct device *dev)
963+
{
964+
HAL_StatusTypeDef ret;
965+
const struct flash_stm32_ospi_config *dev_cfg = dev->config;
966+
struct flash_stm32_ospi_data *dev_data = dev->data;
967+
OSPI_RegularCmdTypeDef s_command = {0};
968+
OSPI_MemoryMappedTypeDef s_MemMappedCfg = {0};
969+
970+
/* Configure octoflash in MemoryMapped mode */
971+
if ((dev_cfg->data_mode == OSPI_SPI_MODE) &&
972+
(stm32_ospi_hal_address_size(dev) == HAL_OSPI_ADDRESS_24_BITS)) {
973+
/* OPI mode and 3-bytes address size not supported by memory */
974+
LOG_ERR("OSPI_SPI_MODE in 3Bytes addressing is not supported");
975+
return -EIO;
976+
}
977+
978+
/* Initialize the read command */
979+
s_command.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
980+
s_command.FlashId = HAL_OSPI_FLASH_ID_1;
981+
s_command.InstructionMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
982+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
983+
? HAL_OSPI_INSTRUCTION_1_LINE
984+
: HAL_OSPI_INSTRUCTION_8_LINES)
985+
: HAL_OSPI_INSTRUCTION_8_LINES;
986+
s_command.InstructionDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
987+
? HAL_OSPI_INSTRUCTION_DTR_DISABLE
988+
: HAL_OSPI_INSTRUCTION_DTR_ENABLE;
989+
s_command.InstructionSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
990+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
991+
? HAL_OSPI_INSTRUCTION_8_BITS
992+
: HAL_OSPI_INSTRUCTION_16_BITS)
993+
: HAL_OSPI_INSTRUCTION_16_BITS;
994+
s_command.Instruction = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
995+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
996+
? ((stm32_ospi_hal_address_size(dev) ==
997+
HAL_OSPI_ADDRESS_24_BITS)
998+
? SPI_NOR_CMD_READ_FAST
999+
: SPI_NOR_CMD_READ_FAST_4B)
1000+
: SPI_NOR_OCMD_RD)
1001+
: SPI_NOR_OCMD_DTR_RD;
1002+
s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1003+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1004+
? HAL_OSPI_ADDRESS_1_LINE
1005+
: HAL_OSPI_ADDRESS_8_LINES)
1006+
: HAL_OSPI_ADDRESS_8_LINES;
1007+
s_command.AddressDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1008+
? HAL_OSPI_ADDRESS_DTR_DISABLE
1009+
: HAL_OSPI_ADDRESS_DTR_ENABLE;
1010+
s_command.AddressSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1011+
? stm32_ospi_hal_address_size(dev)
1012+
: HAL_OSPI_ADDRESS_32_BITS;
1013+
s_command.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
1014+
s_command.DataMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1015+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1016+
? HAL_OSPI_DATA_1_LINE
1017+
: HAL_OSPI_DATA_8_LINES)
1018+
: HAL_OSPI_DATA_8_LINES;
1019+
s_command.DataDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1020+
? HAL_OSPI_DATA_DTR_DISABLE
1021+
: HAL_OSPI_DATA_DTR_ENABLE;
1022+
s_command.DummyCycles = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1023+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1024+
? SPI_NOR_DUMMY_RD
1025+
: SPI_NOR_DUMMY_RD_OCTAL)
1026+
: SPI_NOR_DUMMY_RD_OCTAL_DTR;
1027+
s_command.DQSMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1028+
? HAL_OSPI_DQS_DISABLE
1029+
: HAL_OSPI_DQS_ENABLE;
1030+
1031+
s_command.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
1032+
1033+
ret = HAL_OSPI_Command(&dev_data->hospi, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
1034+
if (ret != HAL_OK) {
1035+
LOG_ERR("%d: Failed to set memory map", ret);
1036+
return -EIO;
1037+
}
1038+
1039+
/* Initialize the program command */
1040+
s_command.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
1041+
if (dev_cfg->data_rate == OSPI_STR_TRANSFER) {
1042+
s_command.Instruction = (dev_cfg->data_mode == OSPI_SPI_MODE)
1043+
? ((stm32_ospi_hal_address_size(dev) ==
1044+
HAL_OSPI_ADDRESS_24_BITS)
1045+
? SPI_NOR_CMD_PP
1046+
: SPI_NOR_CMD_PP_4B)
1047+
: SPI_NOR_OCMD_PAGE_PRG;
1048+
} else {
1049+
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
1050+
}
1051+
s_command.DQSMode = HAL_OSPI_DQS_DISABLE;
1052+
s_command.DummyCycles = 0U;
1053+
1054+
ret = HAL_OSPI_Command(&dev_data->hospi, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
1055+
if (ret != HAL_OK) {
1056+
LOG_ERR("%d: Failed to set memory mapped", ret);
1057+
return -EIO;
1058+
}
1059+
1060+
/* Enable the memory-mapping */
1061+
s_MemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
1062+
1063+
ret = HAL_OSPI_MemoryMapped(&dev_data->hospi, &s_MemMappedCfg);
1064+
if (ret != HAL_OK) {
1065+
LOG_ERR("%d: Failed to set memory mapped", ret);
1066+
return -EIO;
1067+
}
1068+
1069+
return 0;
1070+
}
1071+
1072+
/* Function to return true if the octoflash is in MemoryMapped else false */
1073+
static bool stm32_ospi_is_memorymapped(const struct device *dev)
1074+
{
1075+
struct flash_stm32_ospi_data *dev_data = dev->data;
1076+
1077+
return (HAL_OSPI_IsMemoryMapped(&dev_data->hospi) == 1) ? true : false;
1078+
1079+
}
1080+
#endif /* CONFIG_STM32_XIP */
1081+
9581082
/*
9591083
* Function to erase the flash : chip or sector with possible OSPI/SPI and STR/DTR
9601084
* to erase the complete chip (using dedicated command) :
@@ -989,6 +1113,13 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
9891113
return -ENOTSUP;
9901114
}
9911115

1116+
#ifdef CONFIG_STM32_XIP
1117+
if (stm32_ospi_is_memorymapped(dev)) {
1118+
LOG_INF("MemoryMapped : cannot erase");
1119+
return 0;
1120+
}
1121+
#endif /* CONFIG_STM32_XIP */
1122+
9921123
OSPI_RegularCmdTypeDef cmd_erase = {
9931124
.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG,
9941125
.FlashId = HAL_OSPI_FLASH_ID_1,
@@ -1003,9 +1134,9 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
10031134

10041135
if (stm32_ospi_mem_ready(&dev_data->hospi,
10051136
dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
1006-
ospi_unlock_thread(dev);
10071137
LOG_ERR("Erase failed : flash busy");
1008-
return -EBUSY;
1138+
ret = -EBUSY;
1139+
goto end_erase;
10091140
}
10101141

10111142
cmd_erase.InstructionMode = (dev_cfg->data_mode == OSPI_OPI_MODE)
@@ -1112,8 +1243,19 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
11121243

11131244
}
11141245

1246+
end_erase:
11151247
ospi_unlock_thread(dev);
11161248

1249+
#ifdef CONFIG_STM32_XIP
1250+
ret = stm32_ospi_set_memorymap(dev);
1251+
/* re-enable MemoryMapped mode */
1252+
if (ret != 0) {
1253+
LOG_ERR("Erase failed: cannot enable MemoryMap");
1254+
1255+
return -EIO;
1256+
}
1257+
#endif /* CONFIG_STM32_XIP */
1258+
11171259
return ret;
11181260
}
11191261

@@ -1136,6 +1278,17 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
11361278
return 0;
11371279
}
11381280

1281+
#ifdef CONFIG_STM32_XIP
1282+
if (stm32_ospi_is_memorymapped(dev)) {
1283+
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
1284+
(long)(STM32_NOR_FLASH_BASE_ADDRESS + addr),
1285+
size);
1286+
memcpy(data, (uint8_t *)STM32_NOR_FLASH_BASE_ADDRESS + addr, size);
1287+
1288+
return 0;
1289+
}
1290+
#endif /* CONFIG_STM32_XIP */
1291+
11391292
OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
11401293

11411294
if (dev_cfg->data_mode != OSPI_OPI_MODE) {
@@ -1224,6 +1377,16 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
12241377
return 0;
12251378
}
12261379

1380+
#ifdef CONFIG_STM32_XIP
1381+
if (stm32_ospi_is_memorymapped(dev)) {
1382+
LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu",
1383+
(long)(STM32_NOR_FLASH_BASE_ADDRESS + addr),
1384+
size);
1385+
memcpy((uint8_t *)STM32_NOR_FLASH_BASE_ADDRESS + addr, data, size);
1386+
1387+
return 0;
1388+
}
1389+
#endif /* CONFIG_STM32_XIP */
12271390
/* page program for STR or DTR mode */
12281391
OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
12291392

@@ -2232,6 +2395,16 @@ static int flash_stm32_ospi_init(const struct device *dev)
22322395
}
22332396
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
22342397

2398+
#ifdef CONFIG_STM32_XIP
2399+
/* Now configure the octo Flash in MemoryMapped (access by address) */
2400+
ret = stm32_ospi_set_memorymap(dev);
2401+
if (ret != 0) {
2402+
LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret);
2403+
return -EINVAL;
2404+
}
2405+
LOG_INF("NOR in MemoryMapped mode");
2406+
2407+
#endif /* CONFIG_STM32_XIP */
22352408
return 0;
22362409
}
22372410

0 commit comments

Comments
 (0)