Skip to content

Commit d6fe784

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 an abort command after a memory-mapped write and an abort command after a memory-mapped read Signed-off-by: Francois Ramu <[email protected]>
1 parent d453fb9 commit d6fe784

File tree

1 file changed

+131
-69
lines changed

1 file changed

+131
-69
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 131 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -839,100 +839,138 @@ 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 */
848+
XSPI_RegularCmdTypeDef s_command = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
849849
XSPI_MemoryMappedTypeDef s_MemMappedCfg;
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;
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");
864+
return ret;
865+
}
866+
867+
/* Initialize the program command */
868+
s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG;
869+
s_command.Instruction = dev_data->write_opcode; /* Expecting SPI_NOR_OCMD_PAGE_PRG */
869870
s_command.InstructionWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
870871
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
871872
? HAL_XSPI_INSTRUCTION_8_BITS
872873
: HAL_XSPI_INSTRUCTION_16_BITS)
873874
: 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;
890875
s_command.AddressWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
891876
? stm32_xspi_hal_address_size(dev)
892877
: 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 */
878+
s_command.DummyCycles = 0U;
879+
/* Adapt lines based on write opcode */
880+
switch (s_command.Instruction) {
881+
case SPI_NOR_CMD_PP_4B:
882+
__fallthrough;
883+
case SPI_NOR_CMD_PP:
884+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
885+
s_command.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
886+
s_command.DataMode = HAL_XSPI_DATA_1_LINE;
887+
break;
888+
case SPI_NOR_CMD_PP_1_1_2:
889+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
890+
s_command.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
891+
s_command.DataMode = HAL_XSPI_DATA_2_LINES;
892+
break;
893+
case SPI_NOR_CMD_PP_1_1_4_4B:
894+
__fallthrough;
895+
case SPI_NOR_CMD_PP_1_1_4:
896+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
897+
s_command.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
898+
s_command.DataMode = HAL_XSPI_DATA_4_LINES;
899+
break;
900+
case SPI_NOR_CMD_PP_1_4_4_4B:
901+
__fallthrough;
902+
case SPI_NOR_CMD_PP_1_4_4:
903+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
904+
s_command.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
905+
s_command.DataMode = HAL_XSPI_DATA_4_LINES;
906+
break;
907+
default:
908+
/* Use lines based on data_mode set in ospi_prepare_cmd */
909+
break;
910+
}
912911

913912
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
914913
if (ret != HAL_OK) {
915-
LOG_ERR("%d: Failed to set memory map", ret);
914+
LOG_ERR("%d: Failed to set memory map wr", ret);
916915
return -EIO;
917916
}
918917

919-
/* Initialize the program command */
920-
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;
918+
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
919+
s_command.AddressWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
920+
? stm32_xspi_hal_address_size(dev)
921+
: HAL_XSPI_ADDRESS_32_BITS;
922+
923+
/* Adapt lines based on read_mode */
924+
if (dev_cfg->data_mode != XSPI_OCTO_MODE) {
925+
switch (dev_data->read_mode) {
926+
case JESD216_MODE_112:
927+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
928+
s_command.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
929+
s_command.DataMode = HAL_XSPI_DATA_2_LINES;
930+
break;
931+
case JESD216_MODE_122:
932+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
933+
s_command.AddressMode = HAL_XSPI_ADDRESS_2_LINES;
934+
s_command.DataMode = HAL_XSPI_DATA_2_LINES;
935+
break;
936+
case JESD216_MODE_114:
937+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
938+
s_command.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
939+
s_command.DataMode = HAL_XSPI_DATA_4_LINES;
940+
break;
941+
case JESD216_MODE_144:
942+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
943+
s_command.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
944+
s_command.DataMode = HAL_XSPI_DATA_4_LINES;
945+
break;
946+
default:
947+
/* Use lines based on data_mode set in ospi_prepare_cmd */
948+
break;
949+
}
950+
}
951+
952+
/* Set instruction and dummy cycles parameters */
953+
if (dev_cfg->data_rate == XSPI_DTR_TRANSFER) {
954+
/* DTR transfer rate (==> Octal mode) */
955+
s_command.Instruction = SPI_NOR_OCMD_DTR_RD;
956+
s_command.DummyCycles = SPI_NOR_DUMMY_RD_OCTAL_DTR;
928957
} else {
929-
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
958+
/* STR transfer rate */
959+
if (dev_cfg->data_mode == XSPI_OCTO_MODE) {
960+
/* OPI and STR */
961+
s_command.Instruction = SPI_NOR_OCMD_RD;
962+
s_command.DummyCycles = SPI_NOR_DUMMY_RD_OCTAL;
963+
} else {
964+
/* use SFDP:BFP read instruction */
965+
s_command.Instruction = dev_data->read_opcode;
966+
s_command.DummyCycles = dev_data->read_dummy;
967+
}
930968
}
931969
s_command.DQSMode = HAL_XSPI_DQS_DISABLE;
932970

933971
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
934972
if (ret != HAL_OK) {
935-
LOG_ERR("%d: Failed to set memory mapped", ret);
973+
LOG_ERR("%d: Failed to set memory map rd", ret);
936974
return -EIO;
937975
}
938976

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

942980
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
943981
if (ret != HAL_OK) {
944-
LOG_ERR("%d: Failed to enable memory mapped", ret);
982+
LOG_ERR("%d: Failed to set memory map", ret);
945983
return -EIO;
946984
}
947985

948-
LOG_DBG("MemoryMap mode enabled");
986+
LOG_INF("Memory-mapped mode enabled");
987+
949988
return 0;
950989
}
951990

@@ -1187,9 +1226,12 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
11871226

11881227
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
11891228

1190-
LOG_DBG("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
1229+
LOG_INF("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
11911230
memcpy(data, (void *)mmap_addr, size);
1192-
ret = 0;
1231+
1232+
/* After a memory mapped read, do an abort (RefMan) */
1233+
ret = stm32_xspi_abort(dev);
1234+
11931235
goto read_end;
11941236
#else
11951237
XSPI_RegularCmdTypeDef cmd = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
@@ -1290,15 +1332,35 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
12901332
#ifdef CONFIG_STM32_MEMMAP
12911333
ARG_UNUSED(dev_data);
12921334

1293-
if (stm32_xspi_is_memorymap(dev)) {
1294-
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1295-
ret = stm32_xspi_abort(dev);
1335+
/* Do writes through memory-mapping instead of indirect */
1336+
if (!stm32_xspi_is_memorymap(dev)) {
1337+
ret = stm32_xspi_set_memorymap(dev);
12961338
if (ret != 0) {
1297-
LOG_ERR("Failed to abort memory-mapped access before write");
1339+
LOG_ERR("WRITE: failed to set memory mapped");
12981340
goto write_end;
12991341
}
13001342
}
1301-
#endif
1343+
__ASSERT_NO_MSG(stm32_xspi_is_memorymap(dev));
1344+
1345+
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
1346+
1347+
LOG_INF("Memory-mapped write from 0x%08lx, len %zu", mmap_addr, size);
1348+
memcpy((void *)mmap_addr, data, size);
1349+
1350+
/*
1351+
* In memory-mapped mode, not possible to check if the memory is ready
1352+
* after the programming. So a delay corresponding to max page programming
1353+
* time is added */
1354+
k_busy_wait(HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
1355+
1356+
/* After a memory mapped write do a dummy read and an abort (RefMan) */
1357+
uint8_t dummy_read[1];
1358+
memcpy((void *)mmap_addr, dummy_read, 1);
1359+
ret = stm32_xspi_abort(dev);
1360+
1361+
goto write_end;
1362+
#endif /* CONFIG_STM32_MEMMAP */
1363+
13021364
/* page program for STR or DTR mode */
13031365
XSPI_RegularCmdTypeDef cmd_pp = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
13041366

0 commit comments

Comments
 (0)