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 <francois.ramu@st.com>
This commit is contained in:
parent
7593a14a0a
commit
7b73a343cb
1 changed files with 54 additions and 24 deletions
|
@ -1018,7 +1018,7 @@ static int stm32_ospi_set_memorymap(const struct device *dev)
|
||||||
HAL_OSPI_ADDRESS_24_BITS)
|
HAL_OSPI_ADDRESS_24_BITS)
|
||||||
? SPI_NOR_CMD_READ_FAST
|
? SPI_NOR_CMD_READ_FAST
|
||||||
: SPI_NOR_CMD_READ_FAST_4B)
|
: SPI_NOR_CMD_READ_FAST_4B)
|
||||||
: SPI_NOR_OCMD_RD)
|
: dev_data->read_opcode)
|
||||||
: SPI_NOR_OCMD_DTR_RD;
|
: SPI_NOR_OCMD_DTR_RD;
|
||||||
s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
|
s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
|
||||||
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
|
? ((dev_cfg->data_mode == OSPI_SPI_MODE)
|
||||||
|
@ -1099,6 +1099,20 @@ static bool stm32_ospi_is_memorymap(const struct device *dev)
|
||||||
OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ?
|
OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ?
|
||||||
true : false);
|
true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stm32_ospi_abort(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct flash_stm32_ospi_data *dev_data = dev->data;
|
||||||
|
HAL_StatusTypeDef hal_ret;
|
||||||
|
|
||||||
|
hal_ret = HAL_OSPI_Abort(&dev_data->hospi);
|
||||||
|
if (hal_ret != HAL_OK) {
|
||||||
|
LOG_ERR("%d: OSPI abort failed", hal_ret);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* CONFIG_STM32_MEMMAP */
|
#endif /* CONFIG_STM32_MEMMAP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1136,11 +1150,18 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ospi_lock_thread(dev);
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_MEMMAP
|
#ifdef CONFIG_STM32_MEMMAP
|
||||||
if (stm32_ospi_is_memorymap(dev)) {
|
if (stm32_ospi_is_memorymap(dev)) {
|
||||||
LOG_DBG("MemoryMap : cannot erase");
|
/* Abort ongoing transfer to force CS high/BUSY deasserted */
|
||||||
return 0;
|
ret = stm32_ospi_abort(dev);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_ERR("Failed to abort memory-mapped access before erase");
|
||||||
|
goto end_erase;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* Continue with Indirect Mode */
|
||||||
#endif /* CONFIG_STM32_MEMMAP */
|
#endif /* CONFIG_STM32_MEMMAP */
|
||||||
|
|
||||||
OSPI_RegularCmdTypeDef cmd_erase = {
|
OSPI_RegularCmdTypeDef cmd_erase = {
|
||||||
|
@ -1153,8 +1174,6 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
|
||||||
.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD,
|
.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD,
|
||||||
};
|
};
|
||||||
|
|
||||||
ospi_lock_thread(dev);
|
|
||||||
|
|
||||||
if (stm32_ospi_mem_ready(dev_data,
|
if (stm32_ospi_mem_ready(dev_data,
|
||||||
dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
|
dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
|
||||||
LOG_ERR("Erase failed : flash busy");
|
LOG_ERR("Erase failed : flash busy");
|
||||||
|
@ -1265,8 +1284,8 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
|
||||||
ret = stm32_ospi_mem_ready(dev_data, dev_cfg->data_mode,
|
ret = stm32_ospi_mem_ready(dev_data, dev_cfg->data_mode,
|
||||||
dev_cfg->data_rate);
|
dev_cfg->data_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
goto end_erase;
|
||||||
|
|
||||||
end_erase:
|
end_erase:
|
||||||
ospi_unlock_thread(dev);
|
ospi_unlock_thread(dev);
|
||||||
|
@ -1278,9 +1297,7 @@ end_erase:
|
||||||
static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
|
static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
|
||||||
void *data, size_t size)
|
void *data, size_t size)
|
||||||
{
|
{
|
||||||
const struct flash_stm32_ospi_config *dev_cfg = dev->config;
|
int ret = 0;
|
||||||
struct flash_stm32_ospi_data *dev_data = dev->data;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!ospi_address_is_valid(dev, addr, size)) {
|
if (!ospi_address_is_valid(dev, addr, size)) {
|
||||||
LOG_ERR("Error: address or size exceeds expected values: "
|
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_MEMMAP
|
#ifdef CONFIG_STM32_MEMMAP
|
||||||
if (stm32_ospi_is_memorymap(dev)) {
|
/* If not MemMapped then configure it */
|
||||||
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
|
if (!stm32_ospi_is_memorymap(dev)) {
|
||||||
(long)(STM32_OSPI_BASE_ADDRESS + addr),
|
if (stm32_ospi_set_memorymap(dev) != 0) {
|
||||||
size);
|
LOG_ERR("READ failed: cannot enable MemoryMap");
|
||||||
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size);
|
return -EIO;
|
||||||
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_STM32_MEMMAP */
|
/* Now in MemMapped mode : read with memcopy */
|
||||||
|
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
|
||||||
|
(long)(STM32_OSPI_BASE_ADDRESS + addr),
|
||||||
|
size);
|
||||||
|
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size);
|
||||||
|
|
||||||
|
#else /* CONFIG_STM32_MEMMAP */
|
||||||
|
const struct flash_stm32_ospi_config *dev_cfg = dev->config;
|
||||||
|
struct flash_stm32_ospi_data *dev_data = dev->data;
|
||||||
|
|
||||||
|
|
||||||
OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
|
OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
|
||||||
|
|
||||||
|
@ -1369,6 +1394,7 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
|
||||||
|
|
||||||
ospi_unlock_thread(dev);
|
ospi_unlock_thread(dev);
|
||||||
|
|
||||||
|
#endif /* CONFIG_STM32_MEMMAP */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1395,15 +1421,18 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ospi_lock_thread(dev);
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_MEMMAP
|
#ifdef CONFIG_STM32_MEMMAP
|
||||||
if (stm32_ospi_is_memorymap(dev)) {
|
if (stm32_ospi_is_memorymap(dev)) {
|
||||||
LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu",
|
/* Abort ongoing transfer to force CS high/BUSY deasserted */
|
||||||
(long)(STM32_OSPI_BASE_ADDRESS + addr),
|
ret = stm32_ospi_abort(dev);
|
||||||
size);
|
if (ret != 0) {
|
||||||
memcpy((uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, data, size);
|
LOG_ERR("Failed to abort memory-mapped access before write");
|
||||||
|
goto end_write;
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
/* Continue with Indirect Mode */
|
||||||
#endif /* CONFIG_STM32_MEMMAP */
|
#endif /* CONFIG_STM32_MEMMAP */
|
||||||
/* page program for STR or DTR mode */
|
/* page program for STR or DTR mode */
|
||||||
OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
|
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,
|
||||||
cmd_pp.DummyCycles = 0U;
|
cmd_pp.DummyCycles = 0U;
|
||||||
|
|
||||||
LOG_DBG("OSPI: write %zu data", size);
|
LOG_DBG("OSPI: write %zu data", size);
|
||||||
ospi_lock_thread(dev);
|
|
||||||
|
|
||||||
ret = stm32_ospi_mem_ready(dev_data,
|
ret = stm32_ospi_mem_ready(dev_data,
|
||||||
dev_cfg->data_mode, dev_cfg->data_rate);
|
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,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
goto end_write;
|
||||||
|
|
||||||
|
end_write:
|
||||||
ospi_unlock_thread(dev);
|
ospi_unlock_thread(dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue