Skip to content

Commit 7593a14

Browse files
FRASTMdleach02
authored andcommitted
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 1425ae1 commit 7593a14

File tree

1 file changed

+182
-4
lines changed

1 file changed

+182
-4
lines changed

drivers/flash/flash_stm32_ospi.c

Lines changed: 182 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -978,11 +978,135 @@ static int stm32_ospi_mem_reset(const struct device *dev)
978978
return 0;
979979
}
980980

981+
#ifdef CONFIG_STM32_MEMMAP
982+
/* Function to configure the octoflash in MemoryMapped mode */
983+
static int stm32_ospi_set_memorymap(const struct device *dev)
984+
{
985+
HAL_StatusTypeDef ret;
986+
const struct flash_stm32_ospi_config *dev_cfg = dev->config;
987+
struct flash_stm32_ospi_data *dev_data = dev->data;
988+
OSPI_RegularCmdTypeDef s_command;
989+
OSPI_MemoryMappedTypeDef s_MemMappedCfg;
990+
991+
/* Configure octoflash in MemoryMapped mode */
992+
if ((dev_cfg->data_mode == OSPI_SPI_MODE) &&
993+
(stm32_ospi_hal_address_size(dev) == HAL_OSPI_ADDRESS_24_BITS)) {
994+
/* OPI mode and 3-bytes address size not supported by memory */
995+
LOG_ERR("OSPI_SPI_MODE in 3Bytes addressing is not supported");
996+
return -EIO;
997+
}
998+
999+
/* Initialize the read command */
1000+
s_command.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
1001+
s_command.FlashId = HAL_OSPI_FLASH_ID_1;
1002+
s_command.InstructionMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1003+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1004+
? HAL_OSPI_INSTRUCTION_1_LINE
1005+
: HAL_OSPI_INSTRUCTION_8_LINES)
1006+
: HAL_OSPI_INSTRUCTION_8_LINES;
1007+
s_command.InstructionDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1008+
? HAL_OSPI_INSTRUCTION_DTR_DISABLE
1009+
: HAL_OSPI_INSTRUCTION_DTR_ENABLE;
1010+
s_command.InstructionSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1011+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1012+
? HAL_OSPI_INSTRUCTION_8_BITS
1013+
: HAL_OSPI_INSTRUCTION_16_BITS)
1014+
: HAL_OSPI_INSTRUCTION_16_BITS;
1015+
s_command.Instruction = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1016+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1017+
? ((stm32_ospi_hal_address_size(dev) ==
1018+
HAL_OSPI_ADDRESS_24_BITS)
1019+
? SPI_NOR_CMD_READ_FAST
1020+
: SPI_NOR_CMD_READ_FAST_4B)
1021+
: SPI_NOR_OCMD_RD)
1022+
: SPI_NOR_OCMD_DTR_RD;
1023+
s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1024+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1025+
? HAL_OSPI_ADDRESS_1_LINE
1026+
: HAL_OSPI_ADDRESS_8_LINES)
1027+
: HAL_OSPI_ADDRESS_8_LINES;
1028+
s_command.AddressDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1029+
? HAL_OSPI_ADDRESS_DTR_DISABLE
1030+
: HAL_OSPI_ADDRESS_DTR_ENABLE;
1031+
s_command.AddressSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1032+
? stm32_ospi_hal_address_size(dev)
1033+
: HAL_OSPI_ADDRESS_32_BITS;
1034+
s_command.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
1035+
s_command.DataMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1036+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1037+
? HAL_OSPI_DATA_1_LINE
1038+
: HAL_OSPI_DATA_8_LINES)
1039+
: HAL_OSPI_DATA_8_LINES;
1040+
s_command.DataDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1041+
? HAL_OSPI_DATA_DTR_DISABLE
1042+
: HAL_OSPI_DATA_DTR_ENABLE;
1043+
s_command.DummyCycles = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1044+
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
1045+
? SPI_NOR_DUMMY_RD
1046+
: SPI_NOR_DUMMY_RD_OCTAL)
1047+
: SPI_NOR_DUMMY_RD_OCTAL_DTR;
1048+
s_command.DQSMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
1049+
? HAL_OSPI_DQS_DISABLE
1050+
: HAL_OSPI_DQS_ENABLE;
1051+
1052+
s_command.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
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 map", ret);
1057+
return -EIO;
1058+
}
1059+
1060+
/* Initialize the program command */
1061+
s_command.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
1062+
if (dev_cfg->data_rate == OSPI_STR_TRANSFER) {
1063+
s_command.Instruction = (dev_cfg->data_mode == OSPI_SPI_MODE)
1064+
? ((stm32_ospi_hal_address_size(dev) ==
1065+
HAL_OSPI_ADDRESS_24_BITS)
1066+
? SPI_NOR_CMD_PP
1067+
: SPI_NOR_CMD_PP_4B)
1068+
: SPI_NOR_OCMD_PAGE_PRG;
1069+
} else {
1070+
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
1071+
}
1072+
s_command.DQSMode = HAL_OSPI_DQS_DISABLE;
1073+
1074+
ret = HAL_OSPI_Command(&dev_data->hospi, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
1075+
if (ret != HAL_OK) {
1076+
LOG_ERR("%d: Failed to set memory mapped", ret);
1077+
return -EIO;
1078+
}
1079+
1080+
/* Enable the memory-mapping */
1081+
s_MemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
1082+
1083+
ret = HAL_OSPI_MemoryMapped(&dev_data->hospi, &s_MemMappedCfg);
1084+
if (ret != HAL_OK) {
1085+
LOG_ERR("%d: Failed to set memory mapped", ret);
1086+
return -EIO;
1087+
}
1088+
1089+
LOG_INF("MemoryMap mode enabled");
1090+
return 0;
1091+
}
1092+
1093+
/* Function to return true if the octoflash is in MemoryMapped else false */
1094+
static bool stm32_ospi_is_memorymap(const struct device *dev)
1095+
{
1096+
struct flash_stm32_ospi_data *dev_data = dev->data;
1097+
1098+
return ((READ_BIT(dev_data->hospi.Instance->CR,
1099+
OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ?
1100+
true : false);
1101+
}
1102+
#endif /* CONFIG_STM32_MEMMAP */
1103+
9811104
/*
9821105
* Function to erase the flash : chip or sector with possible OSPI/SPI and STR/DTR
9831106
* to erase the complete chip (using dedicated command) :
9841107
* set size >= flash size
9851108
* set addr = 0
1109+
* NOTE: cannot erase in MemoryMapped mode
9861110
*/
9871111
static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
9881112
size_t size)
@@ -1012,6 +1136,13 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
10121136
return -ENOTSUP;
10131137
}
10141138

1139+
#ifdef CONFIG_STM32_MEMMAP
1140+
if (stm32_ospi_is_memorymap(dev)) {
1141+
LOG_DBG("MemoryMap : cannot erase");
1142+
return 0;
1143+
}
1144+
#endif /* CONFIG_STM32_MEMMAP */
1145+
10151146
OSPI_RegularCmdTypeDef cmd_erase = {
10161147
.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG,
10171148
.FlashId = HAL_OSPI_FLASH_ID_1,
@@ -1026,9 +1157,9 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
10261157

10271158
if (stm32_ospi_mem_ready(dev_data,
10281159
dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
1029-
ospi_unlock_thread(dev);
10301160
LOG_ERR("Erase failed : flash busy");
1031-
return -EBUSY;
1161+
ret = -EBUSY;
1162+
goto end_erase;
10321163
}
10331164

10341165
cmd_erase.InstructionMode = (dev_cfg->data_mode == OSPI_OPI_MODE)
@@ -1137,6 +1268,7 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
11371268

11381269
}
11391270

1271+
end_erase:
11401272
ospi_unlock_thread(dev);
11411273

11421274
return ret;
@@ -1161,6 +1293,17 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
11611293
return 0;
11621294
}
11631295

1296+
#ifdef CONFIG_STM32_MEMMAP
1297+
if (stm32_ospi_is_memorymap(dev)) {
1298+
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
1299+
(long)(STM32_OSPI_BASE_ADDRESS + addr),
1300+
size);
1301+
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size);
1302+
1303+
return 0;
1304+
}
1305+
#endif /* CONFIG_STM32_MEMMAP */
1306+
11641307
OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
11651308

11661309
if (dev_cfg->data_mode != OSPI_OPI_MODE) {
@@ -1229,7 +1372,10 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
12291372
return ret;
12301373
}
12311374

1232-
/* Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR */
1375+
/*
1376+
* Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR
1377+
* NOTE: writing in MemoryMapped mode is not guaranted
1378+
*/
12331379
static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
12341380
const void *data, size_t size)
12351381
{
@@ -1249,6 +1395,16 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
12491395
return 0;
12501396
}
12511397

1398+
#ifdef CONFIG_STM32_MEMMAP
1399+
if (stm32_ospi_is_memorymap(dev)) {
1400+
LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu",
1401+
(long)(STM32_OSPI_BASE_ADDRESS + addr),
1402+
size);
1403+
memcpy((uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, data, size);
1404+
1405+
return 0;
1406+
}
1407+
#endif /* CONFIG_STM32_MEMMAP */
12521408
/* page program for STR or DTR mode */
12531409
OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
12541410

@@ -1913,6 +2069,16 @@ static int flash_stm32_ospi_init(const struct device *dev)
19132069
return -ENODEV;
19142070
}
19152071

2072+
#ifdef CONFIG_STM32_MEMMAP
2073+
/* If MemoryMapped then configure skip init */
2074+
if (stm32_ospi_is_memorymap(dev)) {
2075+
LOG_DBG("NOR init'd in MemMapped mode\n");
2076+
/* Force HAL instance in correct state */
2077+
dev_data->hospi.State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
2078+
return 0;
2079+
}
2080+
#endif /* CONFIG_STM32_MEMMAP */
2081+
19162082
#if STM32_OSPI_USE_DMA
19172083
/*
19182084
* DMA configuration
@@ -2292,9 +2458,21 @@ static int flash_stm32_ospi_init(const struct device *dev)
22922458
}
22932459
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
22942460

2295-
LOG_INF("NOR octo-flash at 0x%lx (0x%x bytes)",
2461+
#ifdef CONFIG_STM32_MEMMAP
2462+
/* Now configure the octo Flash in MemoryMapped (access by address) */
2463+
ret = stm32_ospi_set_memorymap(dev);
2464+
if (ret != 0) {
2465+
LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret);
2466+
return -EINVAL;
2467+
}
2468+
LOG_DBG("NOR octo-flash in MemoryMapped mode at 0x%lx (0x%x bytes)",
2469+
(long)(STM32_OSPI_BASE_ADDRESS),
2470+
dev_cfg->flash_size);
2471+
#else
2472+
LOG_DBG("NOR octo-flash at 0x%lx (0x%x bytes)",
22962473
(long)(STM32_OSPI_BASE_ADDRESS),
22972474
dev_cfg->flash_size);
2475+
#endif /* CONFIG_STM32_MEMMAP */
22982476

22992477
return 0;
23002478
}

0 commit comments

Comments
 (0)