diff --git a/drivers/i2s/i2s_stm32_sai.c b/drivers/i2s/i2s_stm32_sai.c index ae496d201844e..1ae504be43578 100644 --- a/drivers/i2s/i2s_stm32_sai.c +++ b/drivers/i2s/i2s_stm32_sai.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2024 ZAL Zentrum für Angewandte Luftfahrtforschung GmbH - * Copyright (c) 2024 Mario Paja + * Copyright (c) 2024-2025 ZAL Zentrum für Angewandte Luftfahrtforschung GmbH + * Copyright (c) 2024-2025 Mario Paja * * SPDX-License-Identifier: Apache-2.0 */ @@ -276,8 +276,8 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) /* HACK: This field is used to inform driver that it is overridden */ dma_cfg.linked_channel = STM32_DMA_HAL_OVERRIDE; - /* Because of the STREAM OFFSET, the DMA channel given here is from 1 - */ - ret = dma_config(stream->dma_dev, stream->dma_channel, &dma_cfg); + /* Because of the STREAM OFFSET, the DMA channel given here is from 1 - 8 */ + ret = dma_config(stream->dma_dev, stream->dma_channel + STM32_DMA_STREAM_OFFSET, &dma_cfg); if (ret != 0) { LOG_ERR("Failed to configure DMA channel %d", @@ -285,8 +285,14 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) return ret; } +#if defined(CONFIG_SOC_SERIES_STM32H7X) + hdma->Instance = __LL_DMA_GET_STREAM_INSTANCE(stream->reg, stream->dma_channel); + hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma->Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma->Init.Priority = DMA_PRIORITY_HIGH; + hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; +#else hdma->Instance = LL_DMA_GET_CHANNEL_INSTANCE(stream->reg, stream->dma_channel); - hdma->Init.Request = dma_cfg.dma_slot; hdma->Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; hdma->Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD; hdma->Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD; @@ -295,17 +301,34 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Init.DestBurstLength = 1; hdma->Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT0; hdma->Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; +#endif + + hdma->Init.Request = dma_cfg.dma_slot; hdma->Init.Mode = DMA_NORMAL; if (stream->dma_cfg.channel_direction == (enum dma_channel_direction)MEMORY_TO_PERIPHERAL) { hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; + +#if defined(CONFIG_SOC_SERIES_STM32H7X) + hdma->Init.PeriphInc = DMA_PINC_DISABLE; + hdma->Init.MemInc = DMA_MINC_ENABLE; +#else hdma->Init.SrcInc = DMA_SINC_INCREMENTED; hdma->Init.DestInc = DMA_DINC_FIXED; +#endif + __HAL_LINKDMA(hsai, hdmatx, dev_data->hdma); } else { hdma->Init.Direction = DMA_PERIPH_TO_MEMORY; + +#if defined(CONFIG_SOC_SERIES_STM32H7X) + hdma->Init.PeriphInc = DMA_PINC_ENABLE; + hdma->Init.MemInc = DMA_MINC_DISABLE; +#else hdma->Init.SrcInc = DMA_SINC_FIXED; hdma->Init.DestInc = DMA_DINC_INCREMENTED; +#endif + __HAL_LINKDMA(hsai, hdmarx, dev_data->hdma); } @@ -314,10 +337,12 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) return -EIO; } +#ifndef CONFIG_SOC_SERIES_STM32H7X if (HAL_DMA_ConfigChannelAttributes(&dev_data->hdma, DMA_CHANNEL_NPRIV) != HAL_OK) { LOG_ERR("HAL_DMA_ConfigChannelAttributes: "); return -EIO; } +#endif return 0; } diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 5cbf3c9b09003..d5fd289fdb190 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -3,6 +3,7 @@ * Copyright (c) 2019 Centaur Analytics, Inc * Copyright (c) 2020 Teslabs Engineering S.L. * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2025 ZAL Zentrum für Angewandte Luftfahrtforschung GmbH * * SPDX-License-Identifier: Apache-2.0 */ @@ -1091,6 +1092,30 @@ STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; status = "disabled"; }; + + sai1_a: sai1@40015804 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015804 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>, + <&rcc STM32_SRC_PLL2_P SAI1_SEL(1)>; + dmas = <&dma1 1 87 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; + + sai1_b: sai1@40015824 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015824 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>, + <&rcc STM32_SRC_PLL2_P SAI1_SEL(1)>; + dmas = <&dma1 0 88 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; }; die_temp: dietemp { diff --git a/samples/drivers/i2s/output/boards/nucleo_h745zi_q_stm32h745xx_m7.conf b/samples/drivers/i2s/output/boards/nucleo_h745zi_q_stm32h745xx_m7.conf new file mode 100644 index 0000000000000..4f3f73a1e06a5 --- /dev/null +++ b/samples/drivers/i2s/output/boards/nucleo_h745zi_q_stm32h745xx_m7.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=4192 diff --git a/samples/drivers/i2s/output/boards/nucleo_h745zi_q_stm32h745xx_m7.overlay b/samples/drivers/i2s/output/boards/nucleo_h745zi_q_stm32h745xx_m7.overlay new file mode 100644 index 0000000000000..0821cd243d697 --- /dev/null +++ b/samples/drivers/i2s/output/boards/nucleo_h745zi_q_stm32h745xx_m7.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 ZAL Zentrum für Angewandte Luftfahrtforschung GmbH + * Copyright (c) 2025 Mario Paja + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + i2s-tx = &sai1_b; + }; +}; + +&pll2 { + /* 44.1KHz (0.03% Error) */ + div-m = <8>; + mul-n = <192>; + div-q = <2>; + div-r = <2>; + div-p = <17>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&sai1_b { + pinctrl-0 = <&sai1_mclk_b_pf7 &sai1_sd_b_pe3 + &sai1_fs_b_pf9 &sai1_sck_b_pf8>; + pinctrl-names = "default"; + status = "okay"; + mclk-enable; + mclk-divider = "div-256"; + dma-names = "tx"; +}; + +&dmamux1{ + status = "okay"; +}; + +&dma1{ + status = "okay"; +};