Skip to content

Commit 1a2ce7f

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 7a8bd3d commit 1a2ce7f

File tree

1 file changed

+112
-83
lines changed

1 file changed

+112
-83
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 112 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -849,106 +849,103 @@ static int stm32_xspi_mem_reset(const struct device *dev)
849849
}
850850

851851
#ifdef CONFIG_STM32_MEMMAP
852-
/* Function to configure the octoflash in MemoryMapped mode */
852+
/* Function to configure the octoflash in MemoryMapped mode for writing and reading */
853853
static int stm32_xspi_set_memorymap(const struct device *dev)
854854
{
855855
HAL_StatusTypeDef ret;
856856
const struct flash_stm32_xspi_config *dev_cfg = dev->config;
857857
struct flash_stm32_xspi_data *dev_data = dev->data;
858-
XSPI_RegularCmdTypeDef s_command = {0}; /* Non-zero values disturb the command */
858+
XSPI_RegularCmdTypeDef s_command = {0};
859859
XSPI_MemoryMappedTypeDef s_MemMappedCfg = {0};
860860

861861
/* Configure octoflash in MemoryMapped mode */
862862
if ((dev_cfg->data_mode == XSPI_SPI_MODE) &&
863863
(stm32_xspi_hal_address_size(dev) == HAL_XSPI_ADDRESS_24_BITS)) {
864864
/* OPI mode and 3-bytes address size not supported by memory */
865865
LOG_ERR("XSPI_SPI_MODE in 3Bytes addressing is not supported");
866-
return -EIO;
866+
return -ENOTSUP;
867867
}
868868

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

929877
/* Initialize the program command */
930878
s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG;
931-
if (dev_cfg->data_rate == XSPI_STR_TRANSFER) {
932-
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
933-
? ((stm32_xspi_hal_address_size(dev) ==
934-
HAL_XSPI_ADDRESS_24_BITS)
935-
? SPI_NOR_CMD_PP
936-
: SPI_NOR_CMD_PP_4B)
937-
: SPI_NOR_OCMD_PAGE_PRG;
938-
} else {
879+
if (dev_cfg->data_rate == XSPI_DTR_TRANSFER) {
939880
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
881+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES;
882+
s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE;
883+
s_command.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS;
884+
s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES;
885+
s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE;
886+
s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS;
887+
s_command.DataMode = HAL_XSPI_DATA_8_LINES;
888+
s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE;
889+
} else {
890+
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
891+
? ((stm32_xspi_hal_address_size(dev) ==
892+
HAL_XSPI_ADDRESS_24_BITS)
893+
? SPI_NOR_CMD_PP
894+
: SPI_NOR_CMD_PP_4B)
895+
: SPI_NOR_OCMD_PAGE_PRG;
896+
s_command.InstructionMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
897+
? HAL_XSPI_INSTRUCTION_1_LINE
898+
: HAL_XSPI_INSTRUCTION_8_LINES;
899+
s_command.InstructionWidth = (dev_cfg->data_mode == XSPI_SPI_MODE)
900+
? HAL_XSPI_INSTRUCTION_8_BITS
901+
: HAL_XSPI_INSTRUCTION_16_BITS;
902+
s_command.AddressMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
903+
? HAL_XSPI_ADDRESS_1_LINE
904+
: HAL_XSPI_ADDRESS_8_LINES;
905+
s_command.AddressWidth = stm32_xspi_hal_address_size(dev);
906+
s_command.DataMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
907+
? HAL_XSPI_DATA_1_LINE
908+
: HAL_XSPI_DATA_8_LINES;
909+
}
910+
#if defined(XSPI_CCR_SIOO)
911+
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
912+
#endif
913+
s_command.DQSMode = HAL_XSPI_DQS_ENABLE;
914+
s_command.DummyCycles = 0U;
915+
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
916+
if (ret != HAL_OK) {
917+
LOG_ERR("%d: Failed to set memory map wr", ret);
918+
return -EIO;
940919
}
941-
s_command.DQSMode = HAL_XSPI_DQS_DISABLE;
942920

921+
/* Initialize the read command */
922+
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
923+
if (dev_cfg->data_rate == XSPI_DTR_TRANSFER) {
924+
s_command.Instruction = SPI_NOR_OCMD_DTR_RD;
925+
s_command.DummyCycles = SPI_NOR_DUMMY_RD_OCTAL_DTR;
926+
} else {
927+
s_command.Instruction = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
928+
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
929+
? ((stm32_xspi_hal_address_size(dev) == HAL_XSPI_ADDRESS_24_BITS)
930+
? SPI_NOR_CMD_READ_FAST
931+
: SPI_NOR_CMD_READ_FAST_4B)
932+
: dev_data->read_opcode)
933+
: SPI_NOR_OCMD_DTR_RD;
934+
s_command.DummyCycles = (dev_cfg->data_mode == XSPI_SPI_MODE)
935+
? SPI_NOR_DUMMY_RD
936+
: SPI_NOR_DUMMY_RD_OCTAL;
937+
}
938+
#if defined(XSPI_CCR_SIOO)
939+
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
940+
#endif
943941
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
944942
if (ret != HAL_OK) {
945-
LOG_ERR("%d: Failed to set memory mapped", ret);
943+
LOG_ERR("%d: Failed to set memory map rd", ret);
946944
return -EIO;
947945
}
948946

949947
/* Enable the memory-mapping */
950948
s_MemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
951-
952949
#ifdef XSPI_CR_NOPREF
953950
s_MemMappedCfg.NoPrefetchData = HAL_XSPI_AUTOMATIC_PREFETCH_ENABLE;
954951
#ifdef XSPI_CR_NOPREF_AXI
@@ -958,11 +955,12 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
958955

959956
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
960957
if (ret != HAL_OK) {
961-
LOG_ERR("%d: Failed to enable memory mapped", ret);
958+
LOG_ERR("%d: Failed to set memory map", ret);
962959
return -EIO;
963960
}
964961

965-
LOG_DBG("MemoryMap mode enabled");
962+
LOG_INF("Memory-mapped mode enabled");
963+
966964
return 0;
967965
}
968966

@@ -1204,11 +1202,15 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
12041202

12051203
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
12061204

1207-
LOG_DBG("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
1205+
LOG_INF("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
12081206
memcpy(data, (void *)mmap_addr, size);
1209-
ret = 0;
1207+
1208+
/* After a memory mapped read, do a synchroniztion barrier and an abort (RefMan) */
1209+
__DSB();
1210+
ret = stm32_xspi_abort(dev);
1211+
12101212
goto read_end;
1211-
#else
1213+
#else /* CONFIG_STM32_MEMMAP */
12121214
XSPI_RegularCmdTypeDef cmd = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
12131215

12141216
if (dev_cfg->data_mode != XSPI_OCTO_MODE) {
@@ -1274,7 +1276,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
12741276

12751277
ret = xspi_read_access(dev, &cmd, data, size);
12761278
goto read_end;
1277-
#endif
1279+
#endif /* CONFIG_STM32_MEMMAP */
12781280

12791281
read_end:
12801282
xspi_unlock_thread(dev);
@@ -1305,17 +1307,44 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
13051307
xspi_lock_thread(dev);
13061308

13071309
#ifdef CONFIG_STM32_MEMMAP
1310+
ARG_UNUSED(dev_cfg);
13081311
ARG_UNUSED(dev_data);
1312+
ARG_UNUSED(to_write);
13091313

1310-
if (stm32_xspi_is_memorymap(dev)) {
1311-
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1312-
ret = stm32_xspi_abort(dev);
1314+
/* Do writes through memory-mapping instead of indirect */
1315+
if (!stm32_xspi_is_memorymap(dev)) {
1316+
ret = stm32_xspi_set_memorymap(dev);
13131317
if (ret != 0) {
1314-
LOG_ERR("Failed to abort memory-mapped access before write");
1318+
LOG_ERR("WRITE: failed to set memory mapped");
13151319
goto write_end;
13161320
}
13171321
}
1318-
#endif
1322+
__ASSERT_NO_MSG(stm32_xspi_is_memorymap(dev));
1323+
1324+
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
1325+
1326+
LOG_INF("Memory-mapped write from 0x%08lx, len %zu", mmap_addr, size);
1327+
memcpy((void *)mmap_addr, data, size);
1328+
1329+
/*
1330+
* In memory-mapped mode, not possible to check if the memory is ready
1331+
* after the programming. So a delay corresponding to max page programming
1332+
* time is added
1333+
*/
1334+
k_busy_wait(HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
1335+
1336+
/*
1337+
* After a memory mapped write do a dummy read
1338+
* then a synchroniztion barrier and an abort (RefMan)
1339+
*/
1340+
uint8_t dummy_read[1];
1341+
1342+
memcpy(dummy_read, (void *)mmap_addr, 1);
1343+
__DSB();
1344+
ret = stm32_xspi_abort(dev);
1345+
1346+
goto write_end;
1347+
#else /* CONFIG_STM32_MEMMAP */
13191348
/* page program for STR or DTR mode */
13201349
XSPI_RegularCmdTypeDef cmd_pp = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
13211350

@@ -1408,7 +1437,7 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
14081437
break;
14091438
}
14101439
}
1411-
/* Ends the write operation */
1440+
#endif /* CONFIG_STM32_MEMMAP */
14121441

14131442
write_end:
14141443
xspi_unlock_thread(dev);

0 commit comments

Comments
 (0)