Skip to content

Commit a7b9988

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 a7b9988

File tree

1 file changed

+133
-68
lines changed

1 file changed

+133
-68
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 133 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -839,100 +839,139 @@ 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 -ENOTSUP;
857+
}
858+
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");
856864
return -EIO;
857865
}
858866

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

933972
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
934973
if (ret != HAL_OK) {
935-
LOG_ERR("%d: Failed to set memory mapped", ret);
974+
LOG_ERR("%d: Failed to set memory map rd", ret);
936975
return -EIO;
937976
}
938977

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

942981
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
943982
if (ret != HAL_OK) {
944-
LOG_ERR("%d: Failed to enable memory mapped", ret);
983+
LOG_ERR("%d: Failed to set memory map", ret);
945984
return -EIO;
946985
}
947986

948-
LOG_DBG("MemoryMap mode enabled");
987+
LOG_INF("Memory-mapped mode enabled");
988+
949989
return 0;
950990
}
951991

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

11881228
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
11891229

1190-
LOG_DBG("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
1230+
LOG_INF("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
11911231
memcpy(data, (void *)mmap_addr, size);
1192-
ret = 0;
1232+
1233+
/* After a memory mapped read, do a synchroniztion barrier and an abort (RefMan) */
1234+
__DSB();
1235+
ret = stm32_xspi_abort(dev);
1236+
11931237
goto read_end;
11941238
#else
11951239
XSPI_RegularCmdTypeDef cmd = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
@@ -1290,15 +1334,36 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
12901334
#ifdef CONFIG_STM32_MEMMAP
12911335
ARG_UNUSED(dev_data);
12921336

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

0 commit comments

Comments
 (0)