Skip to content

Commit fffa26e

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 88b108d commit fffa26e

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
@@ -846,106 +846,103 @@ static int stm32_xspi_mem_reset(const struct device *dev)
846846
}
847847

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

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

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

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

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

946944
/* Enable the memory-mapping */
947945
s_MemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
948-
949946
#ifdef XSPI_CR_NOPREF
950947
s_MemMappedCfg.NoPrefetchData = HAL_XSPI_AUTOMATIC_PREFETCH_ENABLE;
951948
#ifdef XSPI_CR_NOPREF_AXI
@@ -955,11 +952,12 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
955952

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

962-
LOG_DBG("MemoryMap mode enabled");
959+
LOG_INF("Memory-mapped mode enabled");
960+
963961
return 0;
964962
}
965963

@@ -1201,11 +1199,15 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
12011199

12021200
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
12031201

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

12111213
if (dev_cfg->data_mode != XSPI_OCTO_MODE) {
@@ -1271,7 +1273,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
12711273

12721274
ret = xspi_read_access(dev, &cmd, data, size);
12731275
goto read_end;
1274-
#endif
1276+
#endif /* CONFIG_STM32_MEMMAP */
12751277

12761278
read_end:
12771279
xspi_unlock_thread(dev);
@@ -1302,17 +1304,44 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
13021304
xspi_lock_thread(dev);
13031305

13041306
#ifdef CONFIG_STM32_MEMMAP
1307+
ARG_UNUSED(dev_cfg);
13051308
ARG_UNUSED(dev_data);
1309+
ARG_UNUSED(to_write);
13061310

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

@@ -1405,7 +1434,7 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
14051434
break;
14061435
}
14071436
}
1408-
/* Ends the write operation */
1437+
#endif /* CONFIG_STM32_MEMMAP */
14091438

14101439
write_end:
14111440
xspi_unlock_thread(dev);

0 commit comments

Comments
 (0)