Skip to content

Commit e24c525

Browse files
FRASTMfabiobaltieri
authored andcommitted
drivers: flash: stm32 octospi NOR flash with DMA on stm32u5x
This commit set the stm32 octospi drivers for the stm32u5x when DMA (GPDMA) is transferring. Valid for octospi1 or octospi2. Signed-off-by: Francois Ramu <[email protected]>
1 parent 1c4011f commit e24c525

File tree

2 files changed

+72
-14
lines changed

2 files changed

+72
-14
lines changed

drivers/flash/Kconfig.stm32_ospi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,8 @@ config FLASH_STM32_OSPI
2020
select DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || $(DT_STM32_OCTOSPI_2_HAS_DMA)
2121
select USE_STM32_HAL_DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || \
2222
$(DT_STM32_OCTOSPI_2_HAS_DMA)
23+
select USE_STM32_HAL_DMA_EX if SOC_SERIES_STM32U5X && \
24+
($(DT_STM32_OCTOSPI_1_HAS_DMA) || \
25+
$(DT_STM32_OCTOSPI_2_HAS_DMA))
2326
help
2427
Enable OSPI-NOR support on the STM32 family of processors.

drivers/flash/flash_stm32_ospi.c

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ LOG_MODULE_REGISTER(flash_stm32_ospi, CONFIG_FLASH_LOG_LEVEL);
3030
#define STM32_OSPI_RESET_GPIO DT_INST_NODE_HAS_PROP(0, reset_gpios)
3131

3232
#define STM32_OSPI_USE_DMA DT_NODE_HAS_PROP(DT_PARENT(DT_DRV_INST(0)), dmas)
33+
3334
#if STM32_OSPI_USE_DMA
3435
#include <zephyr/drivers/dma/dma_stm32.h>
3536
#include <zephyr/drivers/dma.h>
@@ -50,6 +51,27 @@ LOG_MODULE_REGISTER(flash_stm32_ospi, CONFIG_FLASH_LOG_LEVEL);
5051
#define SPI_NOR_WRITEOC_NONE 0xFF
5152

5253
#if STM32_OSPI_USE_DMA
54+
#if CONFIG_DMA_STM32U5
55+
static const uint32_t table_src_size[] = {
56+
LL_DMA_SRC_DATAWIDTH_BYTE,
57+
LL_DMA_SRC_DATAWIDTH_HALFWORD,
58+
LL_DMA_SRC_DATAWIDTH_WORD,
59+
};
60+
61+
static const uint32_t table_dest_size[] = {
62+
LL_DMA_DEST_DATAWIDTH_BYTE,
63+
LL_DMA_DEST_DATAWIDTH_HALFWORD,
64+
LL_DMA_DEST_DATAWIDTH_WORD,
65+
};
66+
67+
/* Lookup table to set dma priority from the DTS */
68+
static const uint32_t table_priority[] = {
69+
LL_DMA_LOW_PRIORITY_LOW_WEIGHT,
70+
LL_DMA_LOW_PRIORITY_MID_WEIGHT,
71+
LL_DMA_LOW_PRIORITY_HIGH_WEIGHT,
72+
LL_DMA_HIGH_PRIORITY,
73+
};
74+
#else
5375
static const uint32_t table_m_size[] = {
5476
LL_DMA_MDATAALIGN_BYTE,
5577
LL_DMA_MDATAALIGN_HALFWORD,
@@ -69,6 +91,7 @@ static const uint32_t table_priority[] = {
6991
DMA_PRIORITY_HIGH,
7092
DMA_PRIORITY_VERY_HIGH,
7193
};
94+
#endif /* CONFIG_DMA_STM32U5 */
7295

7396
struct stream {
7497
DMA_TypeDef *reg;
@@ -126,7 +149,7 @@ struct flash_stm32_ospi_data {
126149
int cmd_status;
127150
#if STM32_OSPI_USE_DMA
128151
struct stream dma;
129-
#endif
152+
#endif /* STM32_OSPI_USE_DMA */
130153
};
131154

132155
static inline void ospi_lock_thread(const struct device *dev)
@@ -227,7 +250,7 @@ static int ospi_write_access(const struct device *dev, OSPI_RegularCmdTypeDef *c
227250
#endif
228251

229252
if (hal_ret != HAL_OK) {
230-
LOG_ERR("%d: Failed to read data", hal_ret);
253+
LOG_ERR("%d: Failed to write data", hal_ret);
231254
return -EIO;
232255
}
233256

@@ -1053,18 +1076,19 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
10531076
LOG_DBG("OSPI: write %zu data", size);
10541077
ospi_lock_thread(dev);
10551078

1079+
ret = stm32_ospi_mem_ready(&dev_data->hospi,
1080+
dev_cfg->data_mode, dev_cfg->data_rate);
1081+
if (ret != 0) {
1082+
LOG_ERR("OSPI: write not ready");
1083+
return -EIO;
1084+
}
1085+
10561086
while ((size > 0) && (ret == 0)) {
10571087
to_write = size;
1058-
1059-
ret = stm32_ospi_mem_ready(&dev_data->hospi,
1060-
dev_cfg->data_mode, dev_cfg->data_rate);
1061-
if (ret != 0) {
1062-
break;
1063-
}
1064-
10651088
ret = stm32_ospi_write_enable(&dev_data->hospi,
10661089
dev_cfg->data_mode, dev_cfg->data_rate);
10671090
if (ret != 0) {
1091+
LOG_ERR("OSPI: write not enabled");
10681092
break;
10691093
}
10701094
/* Don't write more than a page. */
@@ -1082,6 +1106,7 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
10821106

10831107
ret = ospi_write_access(dev, &cmd_pp, data, to_write);
10841108
if (ret != 0) {
1109+
LOG_ERR("OSPI: write not access");
10851110
break;
10861111
}
10871112

@@ -1093,6 +1118,7 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
10931118
ret = stm32_ospi_mem_ready(&dev_data->hospi,
10941119
dev_cfg->data_mode, dev_cfg->data_rate);
10951120
if (ret != 0) {
1121+
LOG_ERR("OSPI: write PP not ready");
10961122
break;
10971123
}
10981124
}
@@ -1685,8 +1711,11 @@ static int flash_stm32_ospi_init(const struct device *dev)
16851711
/* HACK: This field is used to inform driver that it is overridden */
16861712
dma_cfg.linked_channel = STM32_DMA_HAL_OVERRIDE;
16871713
/* Because of the STREAM OFFSET, the DMA channel given here is from 1 - 8 */
1688-
ret = dma_config(dev_data->dma.dev, dev_data->dma.channel + 1, &dma_cfg);
1714+
ret = dma_config(dev_data->dma.dev,
1715+
(dev_data->dma.channel + STM32_DMA_STREAM_OFFSET), &dma_cfg);
16891716
if (ret != 0) {
1717+
LOG_ERR("Failed to configure DMA channel %d",
1718+
dev_data->dma.channel + STM32_DMA_STREAM_OFFSET);
16901719
return ret;
16911720
}
16921721

@@ -1698,29 +1727,55 @@ static int flash_stm32_ospi_init(const struct device *dev)
16981727

16991728
int index = find_lsb_set(dma_cfg.source_data_size) - 1;
17001729

1730+
#if CONFIG_DMA_STM32U5
1731+
/* Fill the structure for dma init */
1732+
hdma.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
1733+
hdma.Init.SrcInc = DMA_SINC_FIXED;
1734+
hdma.Init.DestInc = DMA_DINC_INCREMENTED;
1735+
hdma.Init.SrcDataWidth = table_src_size[index];
1736+
hdma.Init.DestDataWidth = table_dest_size[index];
1737+
hdma.Init.SrcBurstLength = 4;
1738+
hdma.Init.DestBurstLength = 4;
1739+
hdma.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1;
1740+
hdma.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
1741+
#else
17011742
hdma.Init.PeriphDataAlignment = table_p_size[index];
17021743
hdma.Init.MemDataAlignment = table_m_size[index];
17031744
hdma.Init.PeriphInc = DMA_PINC_DISABLE;
17041745
hdma.Init.MemInc = DMA_MINC_ENABLE;
1746+
#endif /* CONFIG_DMA_STM32U5 */
17051747
hdma.Init.Mode = DMA_NORMAL;
17061748
hdma.Init.Priority = table_priority[dma_cfg.channel_priority];
17071749
hdma.Init.Direction = DMA_PERIPH_TO_MEMORY;
1750+
#ifdef CONFIG_DMA_STM32_V1
1751+
/* TODO: Not tested in this configuration */
1752+
hdma.Init.Channel = dma_cfg.dma_slot;
1753+
hdma.Instance = __LL_DMA_GET_STREAM_INSTANCE(dev_data->dma.reg,
1754+
dev_data->dma.channel);
1755+
#else
17081756
hdma.Init.Request = dma_cfg.dma_slot;
1709-
#ifdef CONFIG_DMAMUX_STM32
1757+
#if CONFIG_DMA_STM32U5
1758+
hdma.Instance = LL_DMA_GET_CHANNEL_INSTANCE(dev_data->dma.reg,
1759+
dev_data->dma.channel);
1760+
#elif defined(CONFIG_DMAMUX_STM32)
17101761
/*
17111762
* HAL expects a valid DMA channel (not DMAMUX).
1712-
* The channel is from 0 to 7 because of the STREAM_OFFSET in the dma_stm32 driver
1763+
* The channel is from 0 to 7 because of the STM32_DMA_STREAM_OFFSET in the dma_stm32 driver
17131764
*/
17141765
hdma.Instance = __LL_DMA_GET_CHANNEL_INSTANCE(dev_data->dma.reg,
17151766
dev_data->dma.channel);
17161767
#else
17171768
hdma.Instance = __LL_DMA_GET_CHANNEL_INSTANCE(dev_data->dma.reg,
17181769
dev_data->dma.channel-1);
1719-
#endif /* CONFIG_DMAMUX_STM32 */
1770+
#endif /* CONFIG_DMA_STM32U5 */
1771+
#endif /* CONFIG_DMA_STM32_V1 */
17201772

17211773
/* Initialize DMA HAL */
17221774
__HAL_LINKDMA(&dev_data->hospi, hdma, hdma);
1723-
HAL_DMA_Init(&hdma);
1775+
if (HAL_DMA_Init(&hdma) != HAL_OK) {
1776+
LOG_ERR("OSPI DMA Init failed");
1777+
return -EIO;
1778+
}
17241779
LOG_INF("OSPI with DMA transfer");
17251780

17261781
#endif /* STM32_OSPI_USE_DMA */

0 commit comments

Comments
 (0)