Skip to content

Commit e604bad

Browse files
committed
drivers! flash: stm32 xspi driver can read and write in mem map mode
1 parent bbe36b4 commit e604bad

File tree

1 file changed

+100
-65
lines changed

1 file changed

+100
-65
lines changed

drivers/flash/flash_stm32_xspi.c

Lines changed: 100 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -840,21 +840,22 @@ static int stm32_xspi_mem_reset(const struct device *dev)
840840

841841
#ifdef CONFIG_STM32_MEMMAP
842842
/* Function to configure the octoflash in MemoryMapped mode for writing and reading */
843-
static int stm32_xspi_set_memorymap(const struct device *dev)
843+
static int stm32_xspi_set_memorymap(const struct device *dev, bool memmap_wr)
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 -EIO;
856+
return -ENOTSUP;
857857
}
858+
858859
/* Enable write operation */
859860
ret = stm32_xspi_write_enable(dev,
860861
dev_cfg->data_mode, dev_cfg->data_rate);
@@ -865,94 +866,129 @@ static int stm32_xspi_set_memorymap(const struct device *dev)
865866

866867
/* Initialize the program command */
867868
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-
}
878-
s_command.InstructionMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
879-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
880-
? HAL_XSPI_INSTRUCTION_1_LINE
881-
: HAL_XSPI_INSTRUCTION_8_LINES)
882-
: HAL_XSPI_INSTRUCTION_8_LINES;
883-
s_command.InstructionDTRMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
884-
? HAL_XSPI_INSTRUCTION_DTR_DISABLE
885-
: HAL_XSPI_INSTRUCTION_DTR_ENABLE;
869+
s_command.Instruction = dev_data->write_opcode; /* Expecting SPI_NOR_OCMD_PAGE_PRG */
886870
s_command.InstructionWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
887871
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
888872
? HAL_XSPI_INSTRUCTION_8_BITS
889873
: HAL_XSPI_INSTRUCTION_16_BITS)
890874
: HAL_XSPI_INSTRUCTION_16_BITS;
891-
s_command.AddressMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
892-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
893-
? HAL_XSPI_ADDRESS_1_LINE
894-
: HAL_XSPI_ADDRESS_8_LINES)
895-
: HAL_XSPI_ADDRESS_8_LINES;
896-
s_command.AddressDTRMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
897-
? HAL_XSPI_ADDRESS_DTR_DISABLE
898-
: HAL_XSPI_ADDRESS_DTR_ENABLE;
899875
s_command.AddressWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
900876
? stm32_xspi_hal_address_size(dev)
901877
: HAL_XSPI_ADDRESS_32_BITS;
902-
s_command.DataMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
903-
? ((dev_cfg->data_mode == XSPI_SPI_MODE)
904-
? HAL_XSPI_DATA_1_LINE
905-
: HAL_XSPI_DATA_8_LINES)
906-
: HAL_XSPI_DATA_8_LINES;
907-
s_command.DataDTRMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
908-
? HAL_XSPI_DATA_DTR_DISABLE
909-
: HAL_XSPI_DATA_DTR_ENABLE;
910-
s_command.DQSMode = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
911-
? HAL_XSPI_DQS_DISABLE
912-
: HAL_XSPI_DQS_ENABLE;
913-
#ifdef XSPI_CCR_SIOO
914-
s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
915-
#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+
}
916911

917912
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
918913
if (ret != HAL_OK) {
919914
LOG_ERR("%d: Failed to set memory map wr", ret);
920915
return -EIO;
921916
}
922917

923-
/* Initialize the read command */
924918
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)
927-
? ((stm32_xspi_hal_address_size(dev) ==
928-
HAL_XSPI_ADDRESS_24_BITS)
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;
919+
s_command.AddressWidth = (dev_cfg->data_rate == XSPI_STR_TRANSFER)
920+
? stm32_xspi_hal_address_size(dev)
921+
: HAL_XSPI_ADDRESS_32_BITS;
938922
s_command.DQSMode = HAL_XSPI_DQS_DISABLE;
939923

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;
958+
} else {
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+
}
969+
}
970+
940971
ret = HAL_XSPI_Command(&dev_data->hxspi, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
941972
if (ret != HAL_OK) {
942973
LOG_ERR("%d: Failed to set memory map rd", ret);
943974
return -EIO;
944975
}
945976

946977
/* Enable the memory-mapping */
978+
if (memmap_wr) {
947979
s_MemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_ENABLE;
948-
s_MemMappedCfg.TimeoutPeriodClock = 0x50;
980+
s_MemMappedCfg.TimeoutPeriodClock = 0xffff;
981+
} else {
982+
s_MemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
983+
}
984+
949985
ret = HAL_XSPI_MemoryMapped(&dev_data->hxspi, &s_MemMappedCfg);
950986
if (ret != HAL_OK) {
951987
LOG_ERR("%d: Failed to set memory map", ret);
952988
return -EIO;
953989
}
954990

955-
LOG_INF("MemoryMap mode enabled");
991+
LOG_INF("Memory-mapped mode enabled");
956992

957993
return 0;
958994
}
@@ -1147,13 +1183,12 @@ static int flash_stm32_xspi_erase(const struct device *dev, off_t addr,
11471183
ret = stm32_xspi_mem_ready(dev, dev_cfg->data_mode,
11481184
dev_cfg->data_rate);
11491185
}
1150-
11511186
}
11521187
/* Ends the erase operation */
11531188

11541189
erase_end:
11551190
xspi_unlock_thread(dev);
1156-
1191+
stm32_xspi_set_memorymap(dev, true);
11571192
return ret;
11581193
}
11591194

@@ -1184,7 +1219,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr,
11841219

11851220
/* Do reads through memory-mapping instead of indirect */
11861221
if (!stm32_xspi_is_memorymap(dev)) {
1187-
ret = stm32_xspi_set_memorymap(dev);
1222+
ret = stm32_xspi_set_memorymap(dev, false);
11881223
if (ret != 0) {
11891224
LOG_ERR("READ: failed to set memory mapped");
11901225
goto read_end;
@@ -1300,7 +1335,7 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
13001335

13011336
/* Do writes through memory-mapping instead of indirect */
13021337
if (!stm32_xspi_is_memorymap(dev)) {
1303-
ret = stm32_xspi_set_memorymap(dev);
1338+
ret = stm32_xspi_set_memorymap(dev, false);
13041339
if (ret != 0) {
13051340
LOG_ERR("WRITE: failed to set memory mapped");
13061341
goto write_end;
@@ -1319,8 +1354,8 @@ static int flash_stm32_xspi_write(const struct device *dev, off_t addr,
13191354
* after the programming. So a delay corresponding to max page programming
13201355
* time is added */
13211356
k_busy_wait(HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
1357+
13221358
goto write_end;
1323-
13241359
#endif /* CONFIG_STM32_MEMMAP */
13251360

13261361
/* page program for STR or DTR mode */
@@ -2364,7 +2399,7 @@ static int flash_stm32_xspi_init(const struct device *dev)
23642399
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
23652400

23662401
#ifdef CONFIG_STM32_MEMMAP
2367-
ret = stm32_xspi_set_memorymap(dev);
2402+
ret = stm32_xspi_set_memorymap(dev, true);
23682403
if (ret != 0) {
23692404
LOG_ERR("Failed to enable memory-mapped mode: %d", ret);
23702405
return ret;

0 commit comments

Comments
 (0)