Skip to content

Commit ecfd44d

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 ab7db7c commit ecfd44d

File tree

1 file changed

+113
-84
lines changed

1 file changed

+113
-84
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 113 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -844,100 +844,101 @@ static int stm32_xspi_mem_reset(const struct device *dev)
844844
}
845845

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

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

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

924872
/* Initialize the program command */
925873
s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG;
926-
if (dev_cfg->data_rate == XSPI_STR_TRANSFER) {
927-
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
928-
? ((stm32_xspi_hal_address_size(dev) ==
929-
HAL_XSPI_ADDRESS_24_BITS)
930-
? SPI_NOR_CMD_PP
931-
: SPI_NOR_CMD_PP_4B)
932-
: SPI_NOR_OCMD_PAGE_PRG;
933-
} else {
874+
if (dev_cfg->data_rate == XSPI_DTR_TRANSFER) {
934875
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
876+
s_command.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES;
877+
s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE;
878+
s_command.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS;
879+
s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES;
880+
s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE;
881+
s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS;
882+
s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
883+
s_command.DataMode = HAL_XSPI_DATA_8_LINES;
884+
s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE;
885+
} else {
886+
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
887+
? ((stm32_xspi_hal_address_size(dev) ==
888+
HAL_XSPI_ADDRESS_24_BITS)
889+
? SPI_NOR_CMD_PP
890+
: SPI_NOR_CMD_PP_4B)
891+
: SPI_NOR_OCMD_PAGE_PRG;
892+
s_command.InstructionMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
893+
? HAL_XSPI_INSTRUCTION_1_LINE
894+
: HAL_XSPI_INSTRUCTION_8_LINES;
895+
s_command.InstructionWidth = (dev_cfg->data_mode == XSPI_SPI_MODE)
896+
? HAL_XSPI_INSTRUCTION_8_BITS
897+
: HAL_XSPI_INSTRUCTION_16_BITS;
898+
s_command.AddressMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
899+
? HAL_XSPI_ADDRESS_1_LINE
900+
: HAL_XSPI_ADDRESS_8_LINES;
901+
s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
902+
s_command.AddressWidth = stm32_xspi_hal_address_size(dev);
903+
s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
904+
s_command.DataMode = (dev_cfg->data_mode == XSPI_SPI_MODE)
905+
? HAL_XSPI_DATA_1_LINE
906+
: HAL_XSPI_DATA_8_LINES;
907+
}
908+
#if defined (XSPI_CCR_SIOO)
909+
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
910+
#endif
911+
s_command.DQSMode = HAL_XSPI_DQS_ENABLE;
912+
s_command.DummyCycles = 0U;
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 wr", ret);
916+
return -EIO;
935917
}
936-
s_command.DQSMode = HAL_XSPI_DQS_DISABLE;
937918

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

@@ -946,11 +947,12 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
946947

947948
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
948949
if (ret != HAL_OK) {
949-
LOG_ERR("%d: Failed to enable memory mapped", ret);
950+
LOG_ERR("%d: Failed to set memory map", ret);
950951
return -EIO;
951952
}
952953

953-
LOG_DBG("MemoryMap mode enabled");
954+
LOG_INF("Memory-mapped mode enabled");
955+
954956
return 0;
955957
}
956958

@@ -1022,7 +1024,7 @@ static int flash_stm32_xspi_erase(const struct device *dev, off_t addr,
10221024
goto erase_end;
10231025
}
10241026
}
1025-
#endif
1027+
#endif /* CONFIG_STM32_MEMMAP */
10261028

10271029
XSPI_RegularCmdTypeDef cmd_erase = {
10281030
.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG,
@@ -1192,11 +1194,15 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
11921194

11931195
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
11941196

1195-
LOG_DBG("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
1197+
LOG_INF("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
11961198
memcpy(data, (void *)mmap_addr, size);
1197-
ret = 0;
1199+
1200+
/* After a memory mapped read, do a synchroniztion barrier and an abort (RefMan) */
1201+
__DSB();
1202+
ret = stm32_xspi_abort(dev);
1203+
11981204
goto read_end;
1199-
#else
1205+
#else /* CONFIG_STM32_MEMMAP */
12001206
XSPI_RegularCmdTypeDef cmd = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
12011207

12021208
if (dev_cfg->data_mode != XSPI_OCTO_MODE) {
@@ -1262,7 +1268,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
12621268

12631269
ret = xspi_read_access(dev, &cmd, data, size);
12641270
goto read_end;
1265-
#endif
1271+
#endif /* CONFIG_STM32_MEMMAP */
12661272

12671273
read_end:
12681274
xspi_unlock_thread(dev);
@@ -1293,17 +1299,40 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
12931299
xspi_lock_thread(dev);
12941300

12951301
#ifdef CONFIG_STM32_MEMMAP
1302+
ARG_UNUSED(dev_cfg);
12961303
ARG_UNUSED(dev_data);
1304+
ARG_UNUSED(to_write);
12971305

1298-
if (stm32_xspi_is_memorymap(dev)) {
1299-
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1300-
ret = stm32_xspi_abort(dev);
1306+
/* Do writes through memory-mapping instead of indirect */
1307+
if (!stm32_xspi_is_memorymap(dev)) {
1308+
ret = stm32_xspi_set_memorymap(dev);
13011309
if (ret != 0) {
1302-
LOG_ERR("Failed to abort memory-mapped access before write");
1310+
LOG_ERR("WRITE: failed to set memory mapped");
13031311
goto write_end;
13041312
}
13051313
}
1306-
#endif
1314+
__ASSERT_NO_MSG(stm32_xspi_is_memorymap(dev));
1315+
1316+
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
1317+
1318+
LOG_INF("Memory-mapped write from 0x%08lx, len %zu", mmap_addr, size);
1319+
memcpy((void *)mmap_addr, data, size);
1320+
1321+
/*
1322+
* In memory-mapped mode, not possible to check if the memory is ready
1323+
* after the programming. So a delay corresponding to max page programming
1324+
* time is added */
1325+
k_busy_wait(HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
1326+
1327+
/* After a memory mapped write do a dummy read then a synchroniztion barrier and an abort (RefMan) */
1328+
uint8_t dummy_read[1];
1329+
memcpy(dummy_read, (void *)mmap_addr, 1);
1330+
__DSB();
1331+
ret = stm32_xspi_abort(dev);
1332+
1333+
goto write_end;
1334+
#else /* CONFIG_STM32_MEMMAP */
1335+
13071336
/* page program for STR or DTR mode */
13081337
XSPI_RegularCmdTypeDef cmd_pp = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
13091338

@@ -1396,7 +1425,7 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
13961425
break;
13971426
}
13981427
}
1399-
/* Ends the write operation */
1428+
#endif /* CONFIG_STM32_MEMMAP */
14001429

14011430
write_end:
14021431
xspi_unlock_thread(dev);

0 commit comments

Comments
 (0)