Skip to content

Commit 44a1934

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 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 <[email protected]>
1 parent 3291b4c commit 44a1934

File tree

2 files changed

+187
-7
lines changed

2 files changed

+187
-7
lines changed

drivers/flash/flash_stm32_ospi.c

Lines changed: 186 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ LOG_MODULE_REGISTER(flash_stm32_ospi, CONFIG_FLASH_LOG_LEVEL);
3636
(_CONCAT(HAL_OSPIM_, DT_STRING_TOKEN(STM32_OSPI_NODE, prop))), \
3737
((default_value)))
3838

39+
/* Get the base address of the flash from the DTS node */
40+
#define STM32_OSPI_BASE_ADDRESS DT_REG_ADDR(DT_INST(0, st_stm32_ospi_nor))
41+
3942
#define STM32_OSPI_RESET_GPIO DT_INST_NODE_HAS_PROP(0, reset_gpios)
4043

4144
#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)
955958
return 0;
956959
}
957960

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

1120+
#ifdef CONFIG_STM32_MEMMAP
1121+
if (stm32_ospi_is_memorymap(dev)) {
1122+
LOG_INF("MemoryMap : cannot erase");
1123+
return 0;
1124+
}
1125+
#endif /* CONFIG_STM32_MEMMAP */
1126+
9921127
OSPI_RegularCmdTypeDef cmd_erase = {
9931128
.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG,
9941129
.FlashId = HAL_OSPI_FLASH_ID_1,
@@ -1003,9 +1138,9 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
10031138

10041139
if (stm32_ospi_mem_ready(&dev_data->hospi,
10051140
dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
1006-
ospi_unlock_thread(dev);
10071141
LOG_ERR("Erase failed : flash busy");
1008-
return -EBUSY;
1142+
ret = -EBUSY;
1143+
goto end_erase;
10091144
}
10101145

10111146
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,
11151250

11161251
}
11171252

1253+
end_erase:
11181254
ospi_unlock_thread(dev);
11191255

11201256
return ret;
@@ -1139,6 +1275,17 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
11391275
return 0;
11401276
}
11411277

1278+
#ifdef CONFIG_STM32_MEMMAP
1279+
if (stm32_ospi_is_memorymap(dev)) {
1280+
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
1281+
(long)(STM32_OSPI_BASE_ADDRESS + addr),
1282+
size);
1283+
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size);
1284+
1285+
return 0;
1286+
}
1287+
#endif /* CONFIG_STM32_MEMMAP */
1288+
11421289
OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
11431290

11441291
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,
12071354
return ret;
12081355
}
12091356

1210-
/* Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR */
1357+
/*
1358+
* Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR
1359+
* NOTE: writing in MemoryMapped mode is not guaranted
1360+
*/
12111361
static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
12121362
const void *data, size_t size)
12131363
{
@@ -1227,6 +1377,16 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
12271377
return 0;
12281378
}
12291379

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

@@ -1891,6 +2051,16 @@ static int flash_stm32_ospi_init(const struct device *dev)
18912051
return -ENODEV;
18922052
}
18932053

2054+
#ifdef CONFIG_STM32_MEMMAP
2055+
/* If MemoryMapped then configure skip init */
2056+
if (stm32_ospi_is_memorymap(dev)) {
2057+
LOG_INF("NOR init'd in MemMapped mode\n");
2058+
/* Force HAL instance in correct state */
2059+
dev_data->hospi.State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
2060+
return 0;
2061+
}
2062+
#endif /* CONFIG_STM32_MEMMAP */
2063+
18942064
#if STM32_OSPI_USE_DMA
18952065
/*
18962066
* DMA configuration
@@ -2235,6 +2405,18 @@ static int flash_stm32_ospi_init(const struct device *dev)
22352405
}
22362406
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
22372407

2408+
#ifdef CONFIG_STM32_MEMMAP
2409+
/* Now configure the octo Flash in MemoryMapped (access by address) */
2410+
ret = stm32_ospi_set_memorymap(dev);
2411+
if (ret != 0) {
2412+
LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret);
2413+
return -EINVAL;
2414+
}
2415+
LOG_INF("NOR in MemoryMapped mode at 0x%lx (0x%x bytes)",
2416+
(long)(STM32_OSPI_BASE_ADDRESS),
2417+
dev_cfg->flash_size);
2418+
2419+
#endif /* CONFIG_STM32_MEMMAP */
22382420
return 0;
22392421
}
22402422

@@ -2300,7 +2482,7 @@ static const struct flash_stm32_ospi_config flash_stm32_ospi_cfg = {
23002482
.enr = DT_CLOCKS_CELL_BY_NAME(STM32_OSPI_NODE, ospi_mgr, bits)},
23012483
#endif
23022484
.irq_config = flash_stm32_ospi_irq_config_func,
2303-
.flash_size = DT_INST_PROP(0, size) / 8U,
2485+
.flash_size = DT_REG_ADDR_BY_IDX(DT_INST(0, st_stm32_ospi_nor), 1),
23042486
.max_frequency = DT_INST_PROP(0, ospi_max_frequency),
23052487
.data_mode = DT_INST_PROP(0, spi_bus_width), /* SPI or OPI */
23062488
.data_rate = DT_INST_PROP(0, data_rate), /* DTR or STR */

dts/bindings/flash_controller/st,stm32-ospi-nor.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ on-bus: ospi
2525
properties:
2626
reg:
2727
required: true
28+
description: Flash Memory base address and size in bytes
2829
ospi-max-frequency:
2930
type: int
3031
required: true
3132
description: Maximum clock frequency of device's OSPI interface in Hz
32-
size:
33-
required: true
34-
description: Flash Memory size in bits
3533
reset-gpios:
3634
type: phandle-array
3735
description: RESETn pin

0 commit comments

Comments
 (0)