Skip to content

Commit 6b3a37b

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 6b3a37b

File tree

1 file changed

+140
-82
lines changed

1 file changed

+140
-82
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 140 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -839,100 +839,131 @@ 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.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
878+
s_command.DataMode = HAL_XSPI_DATA_8_LINES;
879+
s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE;
880+
} else {
881+
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
882+
? ((stm32_xspi_hal_address_size(dev) ==
883+
HAL_XSPI_ADDRESS_24_BITS)
884+
? SPI_NOR_CMD_PP
885+
: SPI_NOR_CMD_PP_4B)
886+
: SPI_NOR_OCMD_PAGE_PRG;
887+
s_command.InstructionMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
888+
? HAL_XSPI_INSTRUCTION_1_LINE
889+
: HAL_XSPI_INSTRUCTION_8_LINES;
890+
s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
891+
s_command.InstructionWidth = (dev_cfg->data_mode == XSPI_SPI_MODE)
892+
? HAL_XSPI_INSTRUCTION_8_BITS
893+
: HAL_XSPI_INSTRUCTION_16_BITS;
894+
s_command.AddressMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
895+
? HAL_XSPI_ADDRESS_1_LINE
896+
: HAL_XSPI_ADDRESS_8_LINES;
897+
s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
898+
s_command.AddressWidth = stm32_xspi_hal_address_size(dev);
899+
s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
900+
s_command.DataMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
901+
? HAL_XSPI_DATA_1_LINE
902+
: HAL_XSPI_DATA_8_LINES;
903+
s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
904+
}
905+
#if defined (XSPI_CCR_SIOO)
906+
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
907+
#endif
908+
s_command.DQSMode = HAL_XSPI_DQS_ENABLE;
909+
s_command.DummyCycles = 0U;
910+
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
911+
if (ret != HAL_OK) {
912+
LOG_ERR("%d: Failed to set memory map wr", ret);
913+
return -EIO;
930914
}
931-
s_command.DQSMode = HAL_XSPI_DQS_DISABLE;
932915

916+
/* Initialize the read command */
917+
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
918+
if (dev_cfg->data_rate == XSPI_DTR_TRANSFER) {
919+
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
920+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES;
921+
s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE;
922+
s_command.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS;
923+
s_command.Instruction = SPI_NOR_OCMD_DTR_RD;
924+
s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES;
925+
s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE;
926+
s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS;
927+
s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
928+
s_command.DataMode = HAL_XSPI_DATA_8_LINES;
929+
s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE;
930+
s_command.DummyCycles = SPI_NOR_DUMMY_RD_OCTAL_DTR;
931+
} else {
932+
s_command.InstructionMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
933+
? HAL_XSPI_INSTRUCTION_1_LINE
934+
: HAL_XSPI_INSTRUCTION_8_LINES;
935+
s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
936+
s_command.InstructionWidth = (dev_cfg->data_mode == XSPI_SPI_MODE)
937+
? HAL_XSPI_INSTRUCTION_8_BITS
938+
: HAL_XSPI_INSTRUCTION_16_BITS;
939+
s_command.Instruction = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
940+
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
941+
? ((stm32_xspi_hal_address_size(dev) == HAL_XSPI_ADDRESS_24_BITS)
942+
? SPI_NOR_CMD_READ_FAST
943+
: SPI_NOR_CMD_READ_FAST_4B)
944+
: dev_data->read_opcode)
945+
: SPI_NOR_OCMD_DTR_RD;
946+
s_command.AddressMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
947+
? HAL_XSPI_ADDRESS_1_LINE
948+
: HAL_XSPI_ADDRESS_8_LINES;
949+
s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
950+
s_command.AddressWidth = stm32_xspi_hal_address_size(dev);
951+
s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
952+
s_command.DataMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
953+
? HAL_XSPI_DATA_1_LINE
954+
: HAL_XSPI_DATA_8_LINES;
955+
s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
956+
s_command.DummyCycles = (dev_cfg->data_mode == XSPI_SPI_MODE)
957+
? SPI_NOR_DUMMY_RD
958+
: SPI_NOR_DUMMY_RD_OCTAL;
959+
}
960+
961+
#if defined (XSPI_CCR_SIOO)
962+
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
963+
#endif
933964
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
934965
if (ret != HAL_OK) {
935-
LOG_ERR("%d: Failed to set memory mapped", ret);
966+
LOG_ERR("%d: Failed to set memory map rd", ret);
936967
return -EIO;
937968
}
938969

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

942973
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
943974
if (ret != HAL_OK) {
944-
LOG_ERR("%d: Failed to enable memory mapped", ret);
975+
LOG_ERR("%d: Failed to set memory map", ret);
945976
return -EIO;
946977
}
947978

948-
LOG_DBG("MemoryMap mode enabled");
979+
LOG_INF("Memory-mapped mode enabled");
980+
949981
return 0;
950982
}
951983

@@ -1187,9 +1219,13 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
11871219

11881220
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
11891221

1190-
LOG_DBG("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
1222+
LOG_INF("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
11911223
memcpy(data, (void *)mmap_addr, size);
1192-
ret = 0;
1224+
1225+
/* After a memory mapped read, do a synchroniztion barrier and an abort (RefMan) */
1226+
__DSB();
1227+
ret = stm32_xspi_abort(dev);
1228+
11931229
goto read_end;
11941230
#else
11951231
XSPI_RegularCmdTypeDef cmd = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
@@ -1257,8 +1293,9 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
12571293

12581294
ret = xspi_read_access(dev, &cmd, data, size);
12591295
goto read_end;
1260-
#endif
1296+
#endif /* CONFIG_STM32_MEMMAP */
12611297

1298+
/* Ends the read operation */
12621299
read_end:
12631300
xspi_unlock_thread(dev);
12641301

@@ -1290,15 +1327,35 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
12901327
#ifdef CONFIG_STM32_MEMMAP
12911328
ARG_UNUSED(dev_data);
12921329

1293-
if (stm32_xspi_is_memorymap(dev)) {
1294-
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1295-
ret = stm32_xspi_abort(dev);
1330+
/* Do writes through memory-mapping instead of indirect */
1331+
if (!stm32_xspi_is_memorymap(dev)) {
1332+
ret = stm32_xspi_set_memorymap(dev);
12961333
if (ret != 0) {
1297-
LOG_ERR("Failed to abort memory-mapped access before write");
1334+
LOG_ERR("WRITE: failed to set memory mapped");
12981335
goto write_end;
12991336
}
13001337
}
1301-
#endif
1338+
__ASSERT_NO_MSG(stm32_xspi_is_memorymap(dev));
1339+
1340+
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
1341+
1342+
LOG_INF("Memory-mapped write from 0x%08lx, len %zu", mmap_addr, size);
1343+
memcpy((void *)mmap_addr, data, size);
1344+
1345+
/*
1346+
* In memory-mapped mode, not possible to check if the memory is ready
1347+
* after the programming. So a delay corresponding to max page programming
1348+
* time is added */
1349+
k_busy_wait(HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
1350+
1351+
/* After a memory mapped write do a dummy read then a synchroniztion barrier and an abort (RefMan) */
1352+
uint8_t dummy_read[1];
1353+
memcpy(dummy_read, (void *)mmap_addr, 1);
1354+
__DSB();
1355+
ret = stm32_xspi_abort(dev);
1356+
1357+
goto write_end;
1358+
#else
13021359
/* page program for STR or DTR mode */
13031360
XSPI_RegularCmdTypeDef cmd_pp = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
13041361

@@ -1391,8 +1448,9 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
13911448
break;
13921449
}
13931450
}
1394-
/* Ends the write operation */
1451+
#endif /* CONFIG_STM32_MEMMAP */
13951452

1453+
/* Ends the write operation */
13961454
write_end:
13971455
xspi_unlock_thread(dev);
13981456

0 commit comments

Comments
 (0)