Skip to content

Commit 7b73a34

Browse files
FRASTMdleach02
authored andcommitted
drivers: flash: stm32 ospi driver aborts memmap before erase/write
This change is aborting the memoryMapped mode of the octo-flash before erasing or writing the NOR. Operations are performed in command mode. Reading is always performed in MemoryMapped mode (memcopy) Signed-off-by: Francois Ramu <[email protected]>
1 parent 7593a14 commit 7b73a34

File tree

1 file changed

+54
-24
lines changed

1 file changed

+54
-24
lines changed

drivers/flash/flash_stm32_ospi.c

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ static int stm32_ospi_set_memorymap(const struct device *dev)
10181018
HAL_OSPI_ADDRESS_24_BITS)
10191019
? SPI_NOR_CMD_READ_FAST
10201020
: SPI_NOR_CMD_READ_FAST_4B)
1021-
: SPI_NOR_OCMD_RD)
1021+
: dev_data->read_opcode)
10221022
: SPI_NOR_OCMD_DTR_RD;
10231023
s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
10241024
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
@@ -1099,6 +1099,20 @@ static bool stm32_ospi_is_memorymap(const struct device *dev)
10991099
OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ?
11001100
true : false);
11011101
}
1102+
1103+
static int stm32_ospi_abort(const struct device *dev)
1104+
{
1105+
struct flash_stm32_ospi_data *dev_data = dev->data;
1106+
HAL_StatusTypeDef hal_ret;
1107+
1108+
hal_ret = HAL_OSPI_Abort(&dev_data->hospi);
1109+
if (hal_ret != HAL_OK) {
1110+
LOG_ERR("%d: OSPI abort failed", hal_ret);
1111+
return -EIO;
1112+
}
1113+
1114+
return 0;
1115+
}
11021116
#endif /* CONFIG_STM32_MEMMAP */
11031117

11041118
/*
@@ -1136,11 +1150,18 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
11361150
return -ENOTSUP;
11371151
}
11381152

1153+
ospi_lock_thread(dev);
1154+
11391155
#ifdef CONFIG_STM32_MEMMAP
11401156
if (stm32_ospi_is_memorymap(dev)) {
1141-
LOG_DBG("MemoryMap : cannot erase");
1142-
return 0;
1157+
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1158+
ret = stm32_ospi_abort(dev);
1159+
if (ret != 0) {
1160+
LOG_ERR("Failed to abort memory-mapped access before erase");
1161+
goto end_erase;
1162+
}
11431163
}
1164+
/* Continue with Indirect Mode */
11441165
#endif /* CONFIG_STM32_MEMMAP */
11451166

11461167
OSPI_RegularCmdTypeDef cmd_erase = {
@@ -1153,8 +1174,6 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
11531174
.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD,
11541175
};
11551176

1156-
ospi_lock_thread(dev);
1157-
11581177
if (stm32_ospi_mem_ready(dev_data,
11591178
dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
11601179
LOG_ERR("Erase failed : flash busy");
@@ -1265,8 +1284,8 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
12651284
ret = stm32_ospi_mem_ready(dev_data, dev_cfg->data_mode,
12661285
dev_cfg->data_rate);
12671286
}
1268-
12691287
}
1288+
goto end_erase;
12701289

12711290
end_erase:
12721291
ospi_unlock_thread(dev);
@@ -1278,9 +1297,7 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
12781297
static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
12791298
void *data, size_t size)
12801299
{
1281-
const struct flash_stm32_ospi_config *dev_cfg = dev->config;
1282-
struct flash_stm32_ospi_data *dev_data = dev->data;
1283-
int ret;
1300+
int ret = 0;
12841301

12851302
if (!ospi_address_is_valid(dev, addr, size)) {
12861303
LOG_ERR("Error: address or size exceeds expected values: "
@@ -1294,15 +1311,23 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
12941311
}
12951312

12961313
#ifdef CONFIG_STM32_MEMMAP
1297-
if (stm32_ospi_is_memorymap(dev)) {
1298-
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
1299-
(long)(STM32_OSPI_BASE_ADDRESS + addr),
1300-
size);
1301-
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size);
1302-
1303-
return 0;
1314+
/* If not MemMapped then configure it */
1315+
if (!stm32_ospi_is_memorymap(dev)) {
1316+
if (stm32_ospi_set_memorymap(dev) != 0) {
1317+
LOG_ERR("READ failed: cannot enable MemoryMap");
1318+
return -EIO;
1319+
}
13041320
}
1305-
#endif /* CONFIG_STM32_MEMMAP */
1321+
/* Now in MemMapped mode : read with memcopy */
1322+
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
1323+
(long)(STM32_OSPI_BASE_ADDRESS + addr),
1324+
size);
1325+
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size);
1326+
1327+
#else /* CONFIG_STM32_MEMMAP */
1328+
const struct flash_stm32_ospi_config *dev_cfg = dev->config;
1329+
struct flash_stm32_ospi_data *dev_data = dev->data;
1330+
13061331

13071332
OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
13081333

@@ -1369,6 +1394,7 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
13691394

13701395
ospi_unlock_thread(dev);
13711396

1397+
#endif /* CONFIG_STM32_MEMMAP */
13721398
return ret;
13731399
}
13741400

@@ -1395,15 +1421,18 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
13951421
return 0;
13961422
}
13971423

1424+
ospi_lock_thread(dev);
1425+
13981426
#ifdef CONFIG_STM32_MEMMAP
13991427
if (stm32_ospi_is_memorymap(dev)) {
1400-
LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu",
1401-
(long)(STM32_OSPI_BASE_ADDRESS + addr),
1402-
size);
1403-
memcpy((uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, data, size);
1404-
1405-
return 0;
1428+
/* Abort ongoing transfer to force CS high/BUSY deasserted */
1429+
ret = stm32_ospi_abort(dev);
1430+
if (ret != 0) {
1431+
LOG_ERR("Failed to abort memory-mapped access before write");
1432+
goto end_write;
1433+
}
14061434
}
1435+
/* Continue with Indirect Mode */
14071436
#endif /* CONFIG_STM32_MEMMAP */
14081437
/* page program for STR or DTR mode */
14091438
OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
@@ -1448,7 +1477,6 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
14481477
cmd_pp.DummyCycles = 0U;
14491478

14501479
LOG_DBG("OSPI: write %zu data", size);
1451-
ospi_lock_thread(dev);
14521480

14531481
ret = stm32_ospi_mem_ready(dev_data,
14541482
dev_cfg->data_mode, dev_cfg->data_rate);
@@ -1497,7 +1525,9 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
14971525
break;
14981526
}
14991527
}
1528+
goto end_write;
15001529

1530+
end_write:
15011531
ospi_unlock_thread(dev);
15021532

15031533
return ret;

0 commit comments

Comments
 (0)