Skip to content

Commit 0656a0f

Browse files
committed
drivers: flash: stm32 xspi driver to read and write in memmapped mode
Configure the stm32 xspi flash for reading and writing in memorymapped The sequence is from the STM32Cube. The refman requires a dummy read and a synchronization barrier and an abort command after a memory-mapped write and a synchronization barrier and an abort command after a memory-mapped read Signed-off-by: Francois Ramu <[email protected]>
1 parent d453fb9 commit 0656a0f

File tree

1 file changed

+113
-83
lines changed

1 file changed

+113
-83
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 113 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -839,100 +839,98 @@ static int stm32_xspi_mem_reset(const struct device *dev)
839839
}
840840

841841
#ifdef CONFIG_STM32_MEMMAP
842-
/* Function to configure the octoflash in MemoryMapped mode */
842+
/* Function to configure the octoflash in MemoryMapped mode for writing and reading */
843843
static int stm32_xspi_set_memorymap(const struct device *dev)
844844
{
845845
HAL_StatusTypeDef ret;
846846
const struct flash_stm32_xspi_config *dev_cfg = dev->config;
847847
struct flash_stm32_xspi_data *dev_data = dev->data;
848-
XSPI_RegularCmdTypeDef s_command = {0}; /* Non-zero values disturb the command */
849-
XSPI_MemoryMappedTypeDef s_MemMappedCfg;
848+
XSPI_RegularCmdTypeDef s_command = {0};
849+
XSPI_MemoryMappedTypeDef s_MemMappedCfg = {0};
850850

851851
/* Configure octoflash in MemoryMapped mode */
852852
if ((dev_cfg->data_mode == XSPI_SPI_MODE) &&
853853
(stm32_xspi_hal_address_size(dev) == HAL_XSPI_ADDRESS_24_BITS)) {
854854
/* OPI mode and 3-bytes address size not supported by memory */
855855
LOG_ERR("XSPI_SPI_MODE in 3Bytes addressing is not supported");
856-
return -EIO;
856+
return -ENOTSUP;
857857
}
858858

859-
/* Initialize the read command */
860-
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
861-
s_command.InstructionMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
862-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
863-
? HAL_XSPI_INSTRUCTION_1_LINE
864-
: HAL_XSPI_INSTRUCTION_8_LINES)
865-
: HAL_XSPI_INSTRUCTION_8_LINES;
866-
s_command.InstructionDTRMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
867-
? HAL_XSPI_INSTRUCTION_DTR_DISABLE
868-
: HAL_XSPI_INSTRUCTION_DTR_ENABLE;
869-
s_command.InstructionWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
870-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
871-
? HAL_XSPI_INSTRUCTION_8_BITS
872-
: HAL_XSPI_INSTRUCTION_16_BITS)
873-
: HAL_XSPI_INSTRUCTION_16_BITS;
874-
s_command.Instruction = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
875-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
876-
? ((stm32_xspi_hal_address_size(dev) ==
877-
HAL_XSPI_ADDRESS_24_BITS)
878-
? SPI_NOR_CMD_READ_FAST
879-
: SPI_NOR_CMD_READ_FAST_4B)
880-
: dev_data->read_opcode)
881-
: SPI_NOR_OCMD_DTR_RD;
882-
s_command.AddressMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
883-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
884-
? HAL_XSPI_ADDRESS_1_LINE
885-
: HAL_XSPI_ADDRESS_8_LINES)
886-
: HAL_XSPI_ADDRESS_8_LINES;
887-
s_command.AddressDTRMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
888-
? HAL_XSPI_ADDRESS_DTR_DISABLE
889-
: HAL_XSPI_ADDRESS_DTR_ENABLE;
890-
s_command.AddressWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
891-
? stm32_xspi_hal_address_size(dev)
892-
: HAL_XSPI_ADDRESS_32_BITS;
893-
s_command.DataMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
894-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
895-
? HAL_XSPI_DATA_1_LINE
896-
: HAL_XSPI_DATA_8_LINES)
897-
: HAL_XSPI_DATA_8_LINES;
898-
s_command.DataDTRMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
899-
? HAL_XSPI_DATA_DTR_DISABLE
900-
: HAL_XSPI_DATA_DTR_ENABLE;
901-
s_command.DummyCycles = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
902-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
903-
? SPI_NOR_DUMMY_RD
904-
: SPI_NOR_DUMMY_RD_OCTAL)
905-
: SPI_NOR_DUMMY_RD_OCTAL_DTR;
906-
s_command.DQSMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
907-
? HAL_XSPI_DQS_DISABLE
908-
: HAL_XSPI_DQS_ENABLE;
909-
#ifdef XSPI_CCR_SIOO
910-
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
911-
#endif /* XSPI_CCR_SIOO */
912-
913-
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
914-
if (ret != HAL_OK) {
915-
LOG_ERR("%d: Failed to set memory map", ret);
859+
/* Enable write operation */
860+
ret = stm32_xspi_write_enable(dev,
861+
dev_cfg->data_mode, dev_cfg->data_rate);
862+
if (ret != 0) {
863+
LOG_ERR("XSPI: write not enabled");
916864
return -EIO;
917865
}
918866

919867
/* Initialize the program command */
920868
s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG;
921-
if (dev_cfg->data_rate == XSPI_STR_TRANSFER) {
922-
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
923-
? ((stm32_xspi_hal_address_size(dev) ==
924-
HAL_XSPI_ADDRESS_24_BITS)
925-
? SPI_NOR_CMD_PP
926-
: SPI_NOR_CMD_PP_4B)
927-
: SPI_NOR_OCMD_PAGE_PRG;
928-
} else {
869+
if (dev_cfg->data_rate == XSPI_DTR_TRANSFER) {
929870
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
871+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES;
872+
s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE;
873+
s_command.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS;
874+
s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES;
875+
s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE;
876+
s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS;
877+
s_command.DataMode = HAL_XSPI_DATA_8_LINES;
878+
s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE;
879+
} else {
880+
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
881+
? ((stm32_xspi_hal_address_size(dev) ==
882+
HAL_XSPI_ADDRESS_24_BITS)
883+
? SPI_NOR_CMD_PP
884+
: SPI_NOR_CMD_PP_4B)
885+
: SPI_NOR_OCMD_PAGE_PRG;
886+
s_command.InstructionMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
887+
? HAL_XSPI_INSTRUCTION_1_LINE
888+
: HAL_XSPI_INSTRUCTION_8_LINES;
889+
s_command.InstructionWidth = (dev_cfg->data_mode == XSPI_SPI_MODE)
890+
? HAL_XSPI_INSTRUCTION_8_BITS
891+
: HAL_XSPI_INSTRUCTION_16_BITS;
892+
s_command.AddressMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
893+
? HAL_XSPI_ADDRESS_1_LINE
894+
: HAL_XSPI_ADDRESS_8_LINES;
895+
s_command.AddressWidth = stm32_xspi_hal_address_size(dev);
896+
s_command.DataMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
897+
? HAL_XSPI_DATA_1_LINE
898+
: HAL_XSPI_DATA_8_LINES;
899+
}
900+
#if defined(XSPI_CCR_SIOO)
901+
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
902+
#endif
903+
s_command.DQSMode = HAL_XSPI_DQS_ENABLE;
904+
s_command.DummyCycles = 0U;
905+
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
906+
if (ret != HAL_OK) {
907+
LOG_ERR("%d: Failed to set memory map wr", ret);
908+
return -EIO;
930909
}
931-
s_command.DQSMode = HAL_XSPI_DQS_DISABLE;
932910

911+
/* Initialize the read command */
912+
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
913+
if (dev_cfg->data_rate == XSPI_DTR_TRANSFER) {
914+
s_command.Instruction = SPI_NOR_OCMD_DTR_RD;
915+
s_command.DummyCycles = SPI_NOR_DUMMY_RD_OCTAL_DTR;
916+
} else {
917+
s_command.Instruction = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
918+
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
919+
? ((stm32_xspi_hal_address_size(dev) == HAL_XSPI_ADDRESS_24_BITS)
920+
? SPI_NOR_CMD_READ_FAST
921+
: SPI_NOR_CMD_READ_FAST_4B)
922+
: dev_data->read_opcode)
923+
: SPI_NOR_OCMD_DTR_RD;
924+
s_command.DummyCycles = (dev_cfg->data_mode == XSPI_SPI_MODE)
925+
? SPI_NOR_DUMMY_RD
926+
: SPI_NOR_DUMMY_RD_OCTAL;
927+
}
928+
#if defined(XSPI_CCR_SIOO)
929+
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
930+
#endif
933931
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
934932
if (ret != HAL_OK) {
935-
LOG_ERR("%d: Failed to set memory mapped", ret);
933+
LOG_ERR("%d: Failed to set memory map rd", ret);
936934
return -EIO;
937935
}
938936

@@ -941,11 +939,12 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
941939

942940
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
943941
if (ret != HAL_OK) {
944-
LOG_ERR("%d: Failed to enable memory mapped", ret);
942+
LOG_ERR("%d: Failed to set memory map", ret);
945943
return -EIO;
946944
}
947945

948-
LOG_DBG("MemoryMap mode enabled");
946+
LOG_INF("Memory-mapped mode enabled");
947+
949948
return 0;
950949
}
951950

@@ -1187,11 +1186,15 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
11871186

11881187
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
11891188

1190-
LOG_DBG("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
1189+
LOG_INF("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
11911190
memcpy(data, (void *)mmap_addr, size);
1192-
ret = 0;
1191+
1192+
/* After a memory mapped read, do a synchroniztion barrier and an abort (RefMan) */
1193+
__DSB();
1194+
ret = stm32_xspi_abort(dev);
1195+
11931196
goto read_end;
1194-
#else
1197+
#else /* CONFIG_STM32_MEMMAP */
11951198
XSPI_RegularCmdTypeDef cmd = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
11961199

11971200
if (dev_cfg->data_mode != XSPI_OCTO_MODE) {
@@ -1257,7 +1260,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
12571260

12581261
ret = xspi_read_access(dev, &cmd, data, size);
12591262
goto read_end;
1260-
#endif
1263+
#endif /* CONFIG_STM32_MEMMAP */
12611264

12621265
read_end:
12631266
xspi_unlock_thread(dev);
@@ -1288,17 +1291,44 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
12881291
xspi_lock_thread(dev);
12891292

12901293
#ifdef CONFIG_STM32_MEMMAP
1294+
ARG_UNUSED(dev_cfg);
12911295
ARG_UNUSED(dev_data);
1296+
ARG_UNUSED(to_write);
12921297

1293-
if (stm32_xspi_is_memorymap(dev)) {
1294-
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1295-
ret = stm32_xspi_abort(dev);
1298+
/* Do writes through memory-mapping instead of indirect */
1299+
if (!stm32_xspi_is_memorymap(dev)) {
1300+
ret = stm32_xspi_set_memorymap(dev);
12961301
if (ret != 0) {
1297-
LOG_ERR("Failed to abort memory-mapped access before write");
1302+
LOG_ERR("WRITE: failed to set memory mapped");
12981303
goto write_end;
12991304
}
13001305
}
1301-
#endif
1306+
__ASSERT_NO_MSG(stm32_xspi_is_memorymap(dev));
1307+
1308+
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
1309+
1310+
LOG_INF("Memory-mapped write from 0x%08lx, len %zu", mmap_addr, size);
1311+
memcpy((void *)mmap_addr, data, size);
1312+
1313+
/*
1314+
* In memory-mapped mode, not possible to check if the memory is ready
1315+
* after the programming. So a delay corresponding to max page programming
1316+
* time is added
1317+
*/
1318+
k_busy_wait(HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
1319+
1320+
/*
1321+
* After a memory mapped write do a dummy read
1322+
* then a synchroniztion barrier and an abort (RefMan)
1323+
*/
1324+
uint8_t dummy_read[1];
1325+
1326+
memcpy(dummy_read, (void *)mmap_addr, 1);
1327+
__DSB();
1328+
ret = stm32_xspi_abort(dev);
1329+
1330+
goto write_end;
1331+
#else /* CONFIG_STM32_MEMMAP */
13021332
/* page program for STR or DTR mode */
13031333
XSPI_RegularCmdTypeDef cmd_pp = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
13041334

@@ -1391,7 +1421,7 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
13911421
break;
13921422
}
13931423
}
1394-
/* Ends the write operation */
1424+
#endif /* CONFIG_STM32_MEMMAP */
13951425

13961426
write_end:
13971427
xspi_unlock_thread(dev);

0 commit comments

Comments
 (0)