From 093daed06cc7ffa4d7b88fa04c402b86df6e7a40 Mon Sep 17 00:00:00 2001 From: Mario Paja Date: Mon, 25 Aug 2025 15:34:07 +0200 Subject: [PATCH 1/3] dts: st: l4: add sai1 node Add SAI1 A & B nodes for STM32L4xx series Signed-off-by: Mario Paja --- dts/arm/st/l4/stm32l4.dtsi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dts/arm/st/l4/stm32l4.dtsi b/dts/arm/st/l4/stm32l4.dtsi index fe2e27c94eb09..b2d19314323b5 100644 --- a/dts/arm/st/l4/stm32l4.dtsi +++ b/dts/arm/st/l4/stm32l4.dtsi @@ -2,6 +2,7 @@ * Copyright (c) 2017 Linaro Limited * Copyright (c) 2019 Centaur Analytics, Inc * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2025 Mario Paja * * SPDX-License-Identifier: Apache-2.0 */ @@ -567,6 +568,30 @@ i2c = <&i2c3>; status = "disabled"; }; + + sai1_a: sai1@40015404 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015404 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 21)>, + <&rcc STM32_SRC_PLLSAI1_P SAI1_SEL(0)>; + dmas = <&dma2 1 1 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS)>; + status = "disabled"; + }; + + sai1_b: sai1@40015424 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015424 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 21)>, + <&rcc STM32_SRC_PLLSAI1_P SAI1_SEL(0)>; + dmas = <&dma2 2 1 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS)>; + status = "disabled"; + }; }; &nvic { From f1a9592d4dc7f17b01077dcf722aa5c24d339d2f Mon Sep 17 00:00:00 2001 From: Mario Paja Date: Tue, 26 Aug 2025 10:18:47 +0200 Subject: [PATCH 2/3] drivers: i2s: i2s_stm32_sai add support for stm32l4xx STM32L4xx series shares several SAI & DMA configurations with the other platforms. These changes aim to remove specific DMA & SAI configurations which are not used by STM32L4xx Signed-off-by: Mario Paja --- drivers/i2s/i2s_stm32_sai.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/i2s/i2s_stm32_sai.c b/drivers/i2s/i2s_stm32_sai.c index f349100ad0a51..f692af120c9d3 100644 --- a/drivers/i2s/i2s_stm32_sai.c +++ b/drivers/i2s/i2s_stm32_sai.c @@ -282,11 +282,14 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) return ret; } -#if defined(CONFIG_SOC_SERIES_STM32H7X) + hdma->Instance = STM32_DMA_GET_INSTANCE(stream->reg, stream->dma_channel); + hdma->Init.Request = dma_cfg.dma_slot; + hdma->Init.Mode = DMA_NORMAL; + +#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32L4X) hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma->Init.Priority = DMA_PRIORITY_HIGH; - hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma->Init.PeriphInc = DMA_PINC_DISABLE; hdma->Init.MemInc = DMA_MINC_ENABLE; #else @@ -299,14 +302,15 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT0; hdma->Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; #endif - hdma->Instance = STM32_DMA_GET_INSTANCE(stream->reg, stream->dma_channel); - hdma->Init.Request = dma_cfg.dma_slot; - hdma->Init.Mode = DMA_NORMAL; + +#if defined(CONFIG_SOC_SERIES_STM32H7X) + hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; +#endif 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) +#if !defined(CONFIG_SOC_SERIES_STM32H7X) && !defined(CONFIG_SOC_SERIES_STM32L4X) hdma->Init.SrcInc = DMA_SINC_INCREMENTED; hdma->Init.DestInc = DMA_DINC_FIXED; #endif @@ -315,7 +319,7 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) } else { hdma->Init.Direction = DMA_PERIPH_TO_MEMORY; -#if !defined(CONFIG_SOC_SERIES_STM32H7X) +#if !defined(CONFIG_SOC_SERIES_STM32H7X) && !defined(CONFIG_SOC_SERIES_STM32L4X) hdma->Init.SrcInc = DMA_SINC_FIXED; hdma->Init.DestInc = DMA_DINC_INCREMENTED; #endif @@ -334,7 +338,7 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) LOG_ERR("HAL_DMA_ConfigChannelAttributes: "); return -EIO; } -#elif !defined(CONFIG_SOC_SERIES_STM32H7X) +#elif !defined(CONFIG_SOC_SERIES_STM32H7X) && !defined(CONFIG_SOC_SERIES_STM32L4X) if (HAL_DMA_ConfigChannelAttributes(&dev_data->hdma, DMA_CHANNEL_NPRIV) != HAL_OK) { LOG_ERR("HAL_DMA_ConfigChannelAttributes: "); return -EIO; @@ -449,21 +453,28 @@ static int i2s_stm32_sai_configure(const struct device *dev, enum i2s_dir dir, return -EINVAL; } + /* Control of MCLK output from SAI configuration is not possible on STM32L4xx MCUs */ +#if !defined(CONFIG_SOC_SERIES_STM32L4X) if (cfg->mclk_enable && stream->master) { hsai->Init.MckOutput = SAI_MCK_OUTPUT_ENABLE; } else { hsai->Init.MckOutput = SAI_MCK_OUTPUT_DISABLE; } +#endif if (cfg->mclk_div == (enum mclk_divider)MCLK_NO_DIV) { hsai->Init.NoDivider = SAI_MASTERDIVIDER_DISABLED; } else { hsai->Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; + + /* MckOverSampling is not supported by all STM32L4xx MCUs */ +#if !defined(CONFIG_SOC_SERIES_STM32L4X) if (cfg->mclk_div == (enum mclk_divider)MCLK_DIV_256) { hsai->Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE; } else { hsai->Init.MckOverSampling = SAI_MCK_OVERSAMPLING_ENABLE; } +#endif } /* AudioFrequency */ From 53d39a33ef8231a1da55fb9fb3b63ada4cd9eadb Mon Sep 17 00:00:00 2001 From: Mario Paja Date: Tue, 26 Aug 2025 10:15:26 +0200 Subject: [PATCH 3/3] samples: i2s: output: add nucleo_l432kc Add nucleo_l432kc in samples/drivers/i2s/output Signed-off-by: Mario Paja --- .../i2s/output/boards/nucleo_l432kc.conf | 1 + .../i2s/output/boards/nucleo_l432kc.overlay | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 samples/drivers/i2s/output/boards/nucleo_l432kc.conf create mode 100644 samples/drivers/i2s/output/boards/nucleo_l432kc.overlay diff --git a/samples/drivers/i2s/output/boards/nucleo_l432kc.conf b/samples/drivers/i2s/output/boards/nucleo_l432kc.conf new file mode 100644 index 0000000000000..4f3f73a1e06a5 --- /dev/null +++ b/samples/drivers/i2s/output/boards/nucleo_l432kc.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=4192 diff --git a/samples/drivers/i2s/output/boards/nucleo_l432kc.overlay b/samples/drivers/i2s/output/boards/nucleo_l432kc.overlay new file mode 100644 index 0000000000000..994083d1ad7b7 --- /dev/null +++ b/samples/drivers/i2s/output/boards/nucleo_l432kc.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Mario Paja + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + i2s-tx = &sai1_a; + }; +}; + +/* 44.27KHz (0.38% Error) */ +&pllsai1 { + div-m = <1>; + mul-n = <17>; + div-r = <2>; + div-q = <2>; + div-p = <12>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&dma2 { + status = "okay"; +}; + +&sai1_a { + pinctrl-0 = <&sai1_mclk_a_pa3 &sai1_sd_a_pa10 + &sai1_fs_a_pa9 &sai1_sck_a_pa8>; + pinctrl-names = "default"; + status = "okay"; + mclk-enable; + mclk-divider = "div-256"; + dma-names = "tx"; +}; + +/* USART1 TX conflicts with SAI1_A FS */ +&usart1 { + status = "disabled"; +};