Skip to content

Commit 76e3012

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. mode. The external NOR flash must be erased (in indirect mode) before writing. Signed-off-by: Francois Ramu <[email protected]>
1 parent d453fb9 commit 76e3012

File tree

1 file changed

+62
-38
lines changed

1 file changed

+62
-38
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ 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;
@@ -855,9 +855,26 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
855855
LOG_ERR("XSPI_SPI_MODE in 3Bytes addressing is not supported");
856856
return -EIO;
857857
}
858+
/* Enable write operation */
859+
ret = stm32_xspi_write_enable(dev,
860+
dev_cfg->data_mode, dev_cfg->data_rate);
861+
if (ret != 0) {
862+
LOG_ERR("XSPI: write not enabled");
863+
return ret;
864+
}
858865

859-
/* Initialize the read command */
860-
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
866+
/* Initialize the program command */
867+
s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG;
868+
if (dev_cfg->data_rate == XSPI_STR_TRANSFER) {
869+
s_command.Instruction = (dev_cfg->data_mode == XSPI_SPI_MODE)
870+
? ((stm32_xspi_hal_address_size(dev) ==
871+
HAL_XSPI_ADDRESS_24_BITS)
872+
? SPI_NOR_CMD_PP
873+
: SPI_NOR_CMD_PP_4B)
874+
: SPI_NOR_OCMD_PAGE_PRG;
875+
} else {
876+
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
877+
}
861878
s_command.InstructionMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
862879
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
863880
? HAL_XSPI_INSTRUCTION_1_LINE
@@ -871,14 +888,6 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
871888
? HAL_XSPI_INSTRUCTION_8_BITS
872889
: HAL_XSPI_INSTRUCTION_16_BITS)
873890
: 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;
882891
s_command.AddressMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
883892
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
884893
? HAL_XSPI_ADDRESS_1_LINE
@@ -898,11 +907,6 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
898907
s_command.DataDTRMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
899908
? HAL_XSPI_DATA_DTR_DISABLE
900909
: 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;
906910
s_command.DQSMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
907911
? HAL_XSPI_DQS_DISABLE
908912
: HAL_XSPI_DQS_ENABLE;
@@ -912,40 +916,44 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
912916

913917
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
914918
if (ret != HAL_OK) {
915-
LOG_ERR("%d: Failed to set memory map", ret);
919+
LOG_ERR("%d: Failed to set memory map wr", ret);
916920
return -EIO;
917921
}
918922

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+
/* Initialize the read command */
924+
s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
925+
s_command.Instruction = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
926+
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
923927
? ((stm32_xspi_hal_address_size(dev) ==
924928
HAL_XSPI_ADDRESS_24_BITS)
925-
? SPI_NOR_CMD_PP
926-
: SPI_NOR_CMD_PP_4B)
927-
: SPI_NOR_OCMD_PAGE_PRG;
928-
} else {
929-
s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG;
930-
}
929+
? SPI_NOR_CMD_READ_FAST
930+
: SPI_NOR_CMD_READ_FAST_4B)
931+
: dev_data->read_opcode)
932+
: SPI_NOR_OCMD_DTR_RD;
933+
s_command.DummyCycles = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
934+
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
935+
? SPI_NOR_DUMMY_RD
936+
: SPI_NOR_DUMMY_RD_OCTAL)
937+
: SPI_NOR_DUMMY_RD_OCTAL_DTR;
931938
s_command.DQSMode = HAL_XSPI_DQS_DISABLE;
932939

933940
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
934941
if (ret != HAL_OK) {
935-
LOG_ERR("%d: Failed to set memory mapped", ret);
942+
LOG_ERR("%d: Failed to set memory map rd", ret);
936943
return -EIO;
937944
}
938945

939946
/* Enable the memory-mapping */
940-
s_MemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
941-
947+
s_MemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_ENABLE;
948+
s_MemMappedCfg.TimeoutPeriodClock = 0x50;
942949
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
943950
if (ret != HAL_OK) {
944-
LOG_ERR("%d: Failed to enable memory mapped", ret);
951+
LOG_ERR("%d: Failed to set memory map", ret);
945952
return -EIO;
946953
}
947954

948-
LOG_DBG("MemoryMap mode enabled");
955+
LOG_INF("MemoryMap mode enabled");
956+
949957
return 0;
950958
}
951959

@@ -1187,7 +1195,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
11871195

11881196
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
11891197

1190-
LOG_DBG("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
1198+
LOG_INF("Memory-mapped read from 0x%08lx, len %zu", mmap_addr, size);
11911199
memcpy(data, (void *)mmap_addr, size);
11921200
ret = 0;
11931201
goto read_end;
@@ -1290,15 +1298,31 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
12901298
#ifdef CONFIG_STM32_MEMMAP
12911299
ARG_UNUSED(dev_data);
12921300

1293-
if (stm32_xspi_is_memorymap(dev)) {
1294-
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1295-
ret = stm32_xspi_abort(dev);
1301+
/* Do writes through memory-mapping instead of indirect */
1302+
if (!stm32_xspi_is_memorymap(dev)) {
1303+
ret = stm32_xspi_set_memorymap(dev);
12961304
if (ret != 0) {
1297-
LOG_ERR("Failed to abort memory-mapped access before write");
1305+
LOG_ERR("WRITE: failed to set memory mapped");
12981306
goto write_end;
12991307
}
13001308
}
1301-
#endif
1309+
__ASSERT_NO_MSG(stm32_xspi_is_memorymap(dev));
1310+
1311+
uintptr_t mmap_addr = STM32_XSPI_BASE_ADDRESS + addr;
1312+
1313+
LOG_INF("Memory-mapped write from 0x%08lx, len %zu", mmap_addr, size);
1314+
memcpy((void *)mmap_addr, data, size);
1315+
ret = 0;
1316+
1317+
/*
1318+
* In memory-mapped mode, not possible to check if the memory is ready
1319+
* after the programming. So a delay corresponding to max page programming
1320+
* time is added */
1321+
k_busy_wait(HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
1322+
goto write_end;
1323+
1324+
#endif /* CONFIG_STM32_MEMMAP */
1325+
13021326
/* page program for STR or DTR mode */
13031327
XSPI_RegularCmdTypeDef cmd_pp = xspi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
13041328

0 commit comments

Comments
 (0)