Commit 7b73a343 authored by Francois Ramu's avatar Francois Ramu Committed by David Leach
Browse files

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: default avatarFrancois Ramu <francois.ramu@st.com>
parent 7593a14a
Loading
Loading
Loading
Loading
+54 −24
Original line number Diff line number Diff line
@@ -1018,7 +1018,7 @@ static int stm32_ospi_set_memorymap(const struct device *dev)
					HAL_OSPI_ADDRESS_24_BITS)
						? SPI_NOR_CMD_READ_FAST
						: SPI_NOR_CMD_READ_FAST_4B)
					: SPI_NOR_OCMD_RD)
					: dev_data->read_opcode)
				: SPI_NOR_OCMD_DTR_RD;
	s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
				? ((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) ?
			  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 */

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

	ospi_lock_thread(dev);

#ifdef CONFIG_STM32_MEMMAP
	if (stm32_ospi_is_memorymap(dev)) {
		LOG_DBG("MemoryMap : cannot erase");
		return 0;
		/* Abort ongoing transfer to force CS high/BUSY deasserted */
		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 */

	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,
	};

	ospi_lock_thread(dev);

	if (stm32_ospi_mem_ready(dev_data,
		dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
		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,
						dev_cfg->data_rate);
		}

	}
	goto end_erase;

end_erase:
	ospi_unlock_thread(dev);
@@ -1278,9 +1297,7 @@ end_erase:
static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
				 void *data, size_t size)
{
	const struct flash_stm32_ospi_config *dev_cfg = dev->config;
	struct flash_stm32_ospi_data *dev_data = dev->data;
	int ret;
	int ret = 0;

	if (!ospi_address_is_valid(dev, addr, size)) {
		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
	if (stm32_ospi_is_memorymap(dev)) {
	/* If not MemMapped then configure it */
	if (!stm32_ospi_is_memorymap(dev)) {
		if (stm32_ospi_set_memorymap(dev) != 0) {
			LOG_ERR("READ failed: cannot enable MemoryMap");
			return -EIO;
		}
	}
	/* 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);

		return 0;
	}
#endif /* CONFIG_STM32_MEMMAP */
#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);

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

	ospi_unlock_thread(dev);

#endif /* CONFIG_STM32_MEMMAP */
	return ret;
}

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

	ospi_lock_thread(dev);

#ifdef CONFIG_STM32_MEMMAP
	if (stm32_ospi_is_memorymap(dev)) {
		LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu",
			(long)(STM32_OSPI_BASE_ADDRESS + addr),
			size);
		memcpy((uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, data, size);

		return 0;
		/* Abort ongoing transfer to force CS high/BUSY deasserted */
		ret = stm32_ospi_abort(dev);
		if (ret != 0) {
			LOG_ERR("Failed to abort memory-mapped access before write");
			goto end_write;
		}
	}
	/* Continue with Indirect Mode */
#endif /* CONFIG_STM32_MEMMAP */
	/* page program for STR or DTR mode */
	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;

	LOG_DBG("OSPI: write %zu data", size);
	ospi_lock_thread(dev);

	ret = stm32_ospi_mem_ready(dev_data,
				   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;
		}
	}
	goto end_write;

end_write:
	ospi_unlock_thread(dev);

	return ret;