summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
authorEvalZero <[email protected]>2019-08-06 15:10:37 +0800
committerEvalZero <[email protected]>2019-08-06 16:52:52 +0800
commit4e8278fa7e2d28e22188fba20fb7a3f1065ebb55 (patch)
tree10a69db375a47ac50b514da52341852bccd4957e /bsp
parent559e297e4b17e73d30fc7317868889bc0f4d0e6a (diff)
[bsp][stm32][stm32l475-atk-pandora]add stm32l475-atk-pandora audio device drivers.
Diffstat (limited to 'bsp')
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject10
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h2
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc142
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c130
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c91
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/Kconfig17
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/SConscript10
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.c285
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.h93
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_mic.c360
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c456
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.h7
12 files changed, 1540 insertions, 63 deletions
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject
index 87900023d1..29431439f6 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject
@@ -1,16 +1,16 @@
[PreviousGenFiles]
-HeaderPath=D:/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc
+HeaderPath=D:/dev/others/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc
HeaderFiles=stm32l4xx_it.h;stm32l4xx_hal_conf.h;main.h;
-SourcePath=D:/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src
+SourcePath=D:/dev/others/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src
SourceFiles=stm32l4xx_it.c;stm32l4xx_hal_msp.c;main.c;
[PreviousLibFiles]
-LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l475xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;
+LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l475xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h;
[PreviousUsedKeilFiles]
-SourceFiles=..\Src\main.c;..\Src\stm32l4xx_it.c;..\Src\stm32l4xx_hal_msp.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;null;
+SourceFiles=..\Src\main.c;..\Src\stm32l4xx_it.c;..\Src\stm32l4xx_hal_msp.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;null;
HeaderPath=..\Drivers\STM32L4xx_HAL_Driver\Inc;..\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\Drivers\CMSIS\Include;..\Inc;
-CDefines=USE_HAL_DRIVER;STM32L475xx;
+CDefines=USE_HAL_DRIVER;STM32L475xx;USE_HAL_DRIVER;STM32L475xx;
[]
SourceFiles=;;
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
index 54357c5f9b..50ea5af90e 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
@@ -81,7 +81,7 @@
#define HAL_QSPI_MODULE_ENABLED
/*#define HAL_RNG_MODULE_ENABLED */
#define HAL_RTC_MODULE_ENABLED
-/*#define HAL_SAI_MODULE_ENABLED */
+#define HAL_SAI_MODULE_ENABLED
/*#define HAL_SD_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc
index c667ad5c3e..cc3128d10f 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc
@@ -11,65 +11,73 @@ KeepUserPlacement=false
Mcu.Family=STM32L4
Mcu.IP0=ADC1
Mcu.IP1=IWDG
-Mcu.IP10=TIM2
-Mcu.IP11=TIM4
-Mcu.IP12=TIM15
-Mcu.IP13=TIM16
-Mcu.IP14=TIM17
-Mcu.IP15=USART1
-Mcu.IP16=USART2
-Mcu.IP17=USB_OTG_FS
+Mcu.IP10=TIM1
+Mcu.IP11=TIM2
+Mcu.IP12=TIM4
+Mcu.IP13=TIM15
+Mcu.IP14=TIM16
+Mcu.IP15=TIM17
+Mcu.IP16=USART1
+Mcu.IP17=USART2
+Mcu.IP18=USB_OTG_FS
Mcu.IP2=NVIC
Mcu.IP3=QUADSPI
Mcu.IP4=RCC
Mcu.IP5=RTC
-Mcu.IP6=SPI1
-Mcu.IP7=SPI2
-Mcu.IP8=SYS
-Mcu.IP9=TIM1
-Mcu.IPNb=18
+Mcu.IP6=SAI1
+Mcu.IP7=SPI1
+Mcu.IP8=SPI2
+Mcu.IP9=SYS
+Mcu.IPNb=19
Mcu.Name=STM32L475V(C-E-G)Tx
Mcu.Package=LQFP100
-Mcu.Pin0=PC14-OSC32_IN (PC14)
-Mcu.Pin1=PC15-OSC32_OUT (PC15)
-Mcu.Pin10=PE9
-Mcu.Pin11=PE10
-Mcu.Pin12=PE11
-Mcu.Pin13=PE12
-Mcu.Pin14=PE13
-Mcu.Pin15=PE14
-Mcu.Pin16=PE15
-Mcu.Pin17=PB10
-Mcu.Pin18=PB11
-Mcu.Pin19=PB13
-Mcu.Pin2=PH0-OSC_IN (PH0)
-Mcu.Pin20=PB14
-Mcu.Pin21=PB15
-Mcu.Pin22=PA9
-Mcu.Pin23=PA10
-Mcu.Pin24=PA11
-Mcu.Pin25=PA12
-Mcu.Pin26=PA13 (JTMS-SWDIO)
-Mcu.Pin27=PA14 (JTCK-SWCLK)
-Mcu.Pin28=PB7
-Mcu.Pin29=PB8
-Mcu.Pin3=PH1-OSC_OUT (PH1)
-Mcu.Pin30=VP_IWDG_VS_IWDG
-Mcu.Pin31=VP_RTC_VS_RTC_Activate
-Mcu.Pin32=VP_SYS_VS_Systick
-Mcu.Pin33=VP_TIM1_VS_ClockSourceINT
-Mcu.Pin34=VP_TIM2_VS_ClockSourceINT
-Mcu.Pin35=VP_TIM4_VS_ClockSourceINT
-Mcu.Pin36=VP_TIM15_VS_ClockSourceINT
-Mcu.Pin37=VP_TIM16_VS_ClockSourceINT
-Mcu.Pin38=VP_TIM17_VS_ClockSourceINT
-Mcu.Pin4=PA2
-Mcu.Pin5=PA3
-Mcu.Pin6=PA5
-Mcu.Pin7=PA6
-Mcu.Pin8=PA7
-Mcu.Pin9=PC5
-Mcu.PinsNb=39
+Mcu.Pin0=PE2
+Mcu.Pin1=PE3
+Mcu.Pin10=PA3
+Mcu.Pin11=PA5
+Mcu.Pin12=PA6
+Mcu.Pin13=PA7
+Mcu.Pin14=PC5
+Mcu.Pin15=PE9
+Mcu.Pin16=PE10
+Mcu.Pin17=PE11
+Mcu.Pin18=PE12
+Mcu.Pin19=PE13
+Mcu.Pin2=PE4
+Mcu.Pin20=PE14
+Mcu.Pin21=PE15
+Mcu.Pin22=PB10
+Mcu.Pin23=PB11
+Mcu.Pin24=PB13
+Mcu.Pin25=PB14
+Mcu.Pin26=PB15
+Mcu.Pin27=PA9
+Mcu.Pin28=PA10
+Mcu.Pin29=PA11
+Mcu.Pin3=PE5
+Mcu.Pin30=PA12
+Mcu.Pin31=PA13 (JTMS-SWDIO)
+Mcu.Pin32=PA14 (JTCK-SWCLK)
+Mcu.Pin33=PB7
+Mcu.Pin34=PB8
+Mcu.Pin35=VP_IWDG_VS_IWDG
+Mcu.Pin36=VP_RTC_VS_RTC_Activate
+Mcu.Pin37=VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC
+Mcu.Pin38=VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC
+Mcu.Pin39=VP_SYS_VS_Systick
+Mcu.Pin4=PE6
+Mcu.Pin40=VP_TIM1_VS_ClockSourceINT
+Mcu.Pin41=VP_TIM2_VS_ClockSourceINT
+Mcu.Pin42=VP_TIM4_VS_ClockSourceINT
+Mcu.Pin43=VP_TIM15_VS_ClockSourceINT
+Mcu.Pin44=VP_TIM16_VS_ClockSourceINT
+Mcu.Pin45=VP_TIM17_VS_ClockSourceINT
+Mcu.Pin5=PC14-OSC32_IN (PC14)
+Mcu.Pin6=PC15-OSC32_OUT (PC15)
+Mcu.Pin7=PH0-OSC_IN (PH0)
+Mcu.Pin8=PH1-OSC_OUT (PH1)
+Mcu.Pin9=PA2
+Mcu.PinsNb=46
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32L475VETx
@@ -152,6 +160,16 @@ PE14.Signal=QUADSPI_BK1_IO2
PE15.Locked=true
PE15.Mode=Single Bank
PE15.Signal=QUADSPI_BK1_IO3
+PE2.Mode=SAI_A_MasterWithClock
+PE2.Signal=SAI1_MCLK_A
+PE3.Mode=SAI_B_SyncSlave
+PE3.Signal=SAI1_SD_B
+PE4.Mode=SAI_A_MasterWithClock
+PE4.Signal=SAI1_FS_A
+PE5.Mode=SAI_A_MasterWithClock
+PE5.Signal=SAI1_SCK_A
+PE6.Mode=SAI_A_MasterWithClock
+PE6.Signal=SAI1_SD_A
PE9.Signal=S_TIM1_CH1
PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
@@ -240,6 +258,20 @@ RCC.VCOInputFreq_Value=8000000
RCC.VCOOutputFreq_Value=160000000
RCC.VCOSAI1OutputFreq_Value=96000000
RCC.VCOSAI2OutputFreq_Value=64000000
+SAI1.AudioFrequency-SAI_A_MasterWithClock=SAI_AUDIO_FREQUENCY_44K
+SAI1.ErrorAudioFreq-SAI_A_MasterWithClock=-72.09 %
+SAI1.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,InitProtocol-SAI_A_MasterWithClock,VirtualProtocol-SAI_A_BASIC,AudioFrequency-SAI_A_MasterWithClock,OutputDrive-SAI_A_MasterWithClock,Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,InitProtocol-SAI_B_SyncSlave,VirtualProtocol-SAI_B_BASIC
+SAI1.InitProtocol-SAI_A_MasterWithClock=Enable
+SAI1.InitProtocol-SAI_B_SyncSlave=Enable
+SAI1.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A
+SAI1.Instance-SAI_B_SyncSlave=SAI$Index_Block_B
+SAI1.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE
+SAI1.OutputDrive-SAI_A_MasterWithClock=SAI_OUTPUTDRIVE_ENABLE
+SAI1.RealAudioFreq-SAI_A_MasterWithClock=53.571 KHz
+SAI1.VirtualMode-SAI_A_MasterWithClock=VM_MASTER
+SAI1.VirtualMode-SAI_B_SyncSlave=VM_SLAVE
+SAI1.VirtualProtocol-SAI_A_BASIC=VM_BASIC_PROTOCOL
+SAI1.VirtualProtocol-SAI_B_BASIC=VM_BASIC_PROTOCOL
SH.ADCx_IN14.0=ADC1_IN14,IN14-Single-Ended
SH.ADCx_IN14.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
@@ -280,6 +312,10 @@ VP_IWDG_VS_IWDG.Mode=IWDG_Activate
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
+VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Mode=SAI_A_BASIC
+VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIA_SAI_BASIC
+VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Mode=SAI_B_BASIC
+VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIB_SAI_BASIC
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM15_VS_ClockSourceINT.Mode=Internal
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c
index fce54d3775..2deff2622d 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c
@@ -70,10 +70,14 @@ QSPI_HandleTypeDef hqspi;
RTC_HandleTypeDef hrtc;
+SAI_HandleTypeDef hsai_BlockA1;
+SAI_HandleTypeDef hsai_BlockB1;
+
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2;
TIM_HandleTypeDef htim1;
+TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim15;
TIM_HandleTypeDef htim16;
@@ -105,6 +109,8 @@ static void MX_TIM16_Init(void);
static void MX_TIM15_Init(void);
static void MX_TIM4_Init(void);
static void MX_TIM1_Init(void);
+static void MX_SAI1_Init(void);
+static void MX_TIM2_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
@@ -158,6 +164,8 @@ int main(void)
MX_TIM15_Init();
MX_TIM4_Init();
MX_TIM1_Init();
+ MX_SAI1_Init();
+ MX_TIM2_Init();
MX_USB_OTG_FS_PCD_Init();
/* USER CODE BEGIN 2 */
@@ -222,10 +230,11 @@ void SystemClock_Config(void)
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1
- |RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_USB
- |RCC_PERIPHCLK_ADC;
+ |RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_SAI1
+ |RCC_PERIPHCLK_USB|RCC_PERIPHCLK_ADC;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
+ PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
@@ -235,7 +244,8 @@ void SystemClock_Config(void)
PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
- PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK|RCC_PLLSAI1_ADC1CLK;
+ PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK|RCC_PLLSAI1_48M2CLK
+ |RCC_PLLSAI1_ADC1CLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
@@ -410,6 +420,55 @@ static void MX_RTC_Init(void)
}
/**
+ * @brief SAI1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_SAI1_Init(void)
+{
+
+ /* USER CODE BEGIN SAI1_Init 0 */
+
+ /* USER CODE END SAI1_Init 0 */
+
+ /* USER CODE BEGIN SAI1_Init 1 */
+
+ /* USER CODE END SAI1_Init 1 */
+ hsai_BlockA1.Instance = SAI1_Block_A;
+ hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX;
+ hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
+ hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+ hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
+ hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
+ hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
+ hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
+ hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
+ hsai_BlockA1.Init.TriState = SAI_OUTPUT_NOTRELEASED;
+ if (HAL_SAI_InitProtocol(&hsai_BlockA1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ hsai_BlockB1.Instance = SAI1_Block_B;
+ hsai_BlockB1.Init.AudioMode = SAI_MODESLAVE_RX;
+ hsai_BlockB1.Init.Synchro = SAI_SYNCHRONOUS;
+ hsai_BlockB1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
+ hsai_BlockB1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
+ hsai_BlockB1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
+ hsai_BlockB1.Init.MonoStereoMode = SAI_STEREOMODE;
+ hsai_BlockB1.Init.CompandingMode = SAI_NOCOMPANDING;
+ hsai_BlockB1.Init.TriState = SAI_OUTPUT_NOTRELEASED;
+ if (HAL_SAI_InitProtocol(&hsai_BlockB1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN SAI1_Init 2 */
+
+ /* USER CODE END SAI1_Init 2 */
+
+}
+
+/**
* @brief SPI1 Initialization Function
* @param None
* @retval None
@@ -570,6 +629,69 @@ static void MX_TIM1_Init(void)
}
/**
+ * @brief TIM2 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_TIM2_Init(void)
+{
+
+ /* USER CODE BEGIN TIM2_Init 0 */
+
+ /* USER CODE END TIM2_Init 0 */
+
+ TIM_ClockConfigTypeDef sClockSourceConfig = {0};
+ TIM_MasterConfigTypeDef sMasterConfig = {0};
+ TIM_OC_InitTypeDef sConfigOC = {0};
+
+ /* USER CODE BEGIN TIM2_Init 1 */
+
+ /* USER CODE END TIM2_Init 1 */
+ htim2.Instance = TIM2;
+ htim2.Init.Prescaler = 0;
+ htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
+ htim2.Init.Period = 0;
+ htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+ htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
+ if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
+ if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+ sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+ if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sConfigOC.OCMode = TIM_OCMODE_PWM1;
+ sConfigOC.Pulse = 0;
+ sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
+ sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
+ if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN TIM2_Init 2 */
+
+ /* USER CODE END TIM2_Init 2 */
+ HAL_TIM_MspPostInit(&htim2);
+
+}
+
+/**
* @brief TIM4 Initialization Function
* @param None
* @retval None
@@ -856,10 +978,10 @@ static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
- __HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
}
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c
index 372cbadf67..f5a7fbddc6 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c
@@ -814,6 +814,97 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)
}
+static uint32_t SAI1_client =0;
+
+void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
+{
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+/* SAI1 */
+ if(hsai->Instance==SAI1_Block_A)
+ {
+ /* Peripheral clock enable */
+ if (SAI1_client == 0)
+ {
+ __HAL_RCC_SAI1_CLK_ENABLE();
+ }
+ SAI1_client ++;
+
+ /**SAI1_A_Block_A GPIO Configuration
+ PE2 ------> SAI1_MCLK_A
+ PE4 ------> SAI1_FS_A
+ PE5 ------> SAI1_SCK_A
+ PE6 ------> SAI1_SD_A
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF13_SAI1;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ }
+ if(hsai->Instance==SAI1_Block_B)
+ {
+ /* Peripheral clock enable */
+ if (SAI1_client == 0)
+ {
+ __HAL_RCC_SAI1_CLK_ENABLE();
+ }
+ SAI1_client ++;
+
+ /**SAI1_B_Block_B GPIO Configuration
+ PE3 ------> SAI1_SD_B
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_3;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF13_SAI1;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ }
+}
+
+void HAL_SAI_MspDeInit(SAI_HandleTypeDef* hsai)
+{
+
+/* SAI1 */
+ if(hsai->Instance==SAI1_Block_A)
+ {
+ SAI1_client --;
+ if (SAI1_client == 0)
+ {
+ /* Peripheral clock disable */
+ __HAL_RCC_SAI1_CLK_DISABLE();
+ }
+
+ /**SAI1_A_Block_A GPIO Configuration
+ PE2 ------> SAI1_MCLK_A
+ PE4 ------> SAI1_FS_A
+ PE5 ------> SAI1_SCK_A
+ PE6 ------> SAI1_SD_A
+ */
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
+
+ }
+ if(hsai->Instance==SAI1_Block_B)
+ {
+ SAI1_client --;
+ if (SAI1_client == 0)
+ {
+ /* Peripheral clock disable */
+ __HAL_RCC_SAI1_CLK_DISABLE();
+ }
+
+ /**SAI1_B_Block_B GPIO Configuration
+ PE3 ------> SAI1_SD_B
+ */
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3);
+
+ }
+}
+
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig
index 62c2bc34a6..208a40c026 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig
+++ b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig
@@ -47,6 +47,23 @@ menu "Onboard Peripheral Drivers"
select PKG_USING_AHT10_LATEST_VERSION
default n
+ menuconfig BSP_USING_AUDIO
+ bool "Enable Audio Device"
+ select RT_USING_AUDIO
+ select BSP_USING_I2C
+ select BSP_USING_I2C3
+ default n
+
+ if BSP_USING_AUDIO
+ config BSP_USING_AUDIO_PLAY
+ bool "Enable Audio Play"
+ default y
+
+ config BSP_USING_AUDIO_RECORD
+ bool "Enable Audio Record"
+ default n
+ endif
+
endmenu
menu "On-chip Peripheral Drivers"
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/SConscript b/bsp/stm32/stm32l475-atk-pandora/board/SConscript
index a525708b65..859d01d6b1 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/SConscript
+++ b/bsp/stm32/stm32l475-atk-pandora/board/SConscript
@@ -21,10 +21,20 @@ if GetDepend(['BSP_USING_SDCARD']):
if GetDepend(['BSP_USING_ICM20608']) or GetDepend(['BSP_USING_AHT10']):
src += Glob('ports/sensor_port.c')
+if GetDepend(['BSP_USING_AUDIO']):
+ src += Glob('ports/audio/drv_es8388.c')
+ src += Glob('ports/audio/drv_sound.c')
+
+if GetDepend(['BSP_USING_AUDIO_RECORD']):
+ src += Glob('ports/audio/drv_mic.c')
+
path = [cwd]
path += [cwd + '/CubeMX_Config/Inc']
path += [cwd + '/ports']
+if GetDepend(['BSP_USING_AUDIO']):
+ path += [cwd + '/ports/audio']
+
startup_path_prefix = SDK_LIB
if rtconfig.CROSS_TOOL == 'gcc':
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.c b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.c
new file mode 100644
index 0000000000..089fc79572
--- /dev/null
+++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.c
@@ -0,0 +1,285 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date Author Notes
+ * 2019-07-31 Zero-Free first implementation
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "drv_es8388.h"
+
+/* ES8388 address */
+#define ES8388_ADDR 0x10 /*0x11:CE=1;0x10:CE=0*/
+
+struct es8388_device
+{
+ struct rt_i2c_bus_device *i2c;
+ rt_uint16_t pin;
+};
+
+static struct es8388_device es_dev = {0};
+
+static rt_uint16_t reg_read(rt_uint8_t addr)
+{
+ struct rt_i2c_msg msg[2] = {0};
+ uint8_t val = 0xff;
+
+ RT_ASSERT(es_dev.i2c != RT_NULL);
+
+ msg[0].addr = ES8388_ADDR;
+ msg[0].flags = RT_I2C_WR;
+ msg[0].len = 1;
+ msg[0].buf = &addr;
+
+ msg[1].addr = ES8388_ADDR;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = 1;
+ msg[1].buf = &val;
+
+ if (rt_i2c_transfer(es_dev.i2c, msg, 2) != 2)
+ {
+ rt_kprintf("I2C read data failed, reg = 0x%02x. \n", addr);
+ return 0xff;
+ }
+
+ return val;
+}
+
+static void reg_write(rt_uint8_t addr, rt_uint8_t val)
+{
+ struct rt_i2c_msg msgs[1] = {0};
+ rt_uint8_t buff[2] = {0};
+
+ RT_ASSERT(es_dev.i2c != RT_NULL);
+
+ buff[0] = addr;
+ buff[1] = val;
+
+ msgs[0].addr = ES8388_ADDR;
+ msgs[0].flags = RT_I2C_WR;
+ msgs[0].buf = buff;
+ msgs[0].len = 2;
+
+ if (rt_i2c_transfer(es_dev.i2c, msgs, 1) != 1)
+ {
+ rt_kprintf("I2C write data failed, reg = 0x%2x. \n", addr);
+ return;
+ }
+}
+
+static int es8388_set_adc_dac_volume(int mode, int volume, int dot)
+{
+ int res = 0;
+ if (volume < -96 || volume > 0)
+ {
+ if (volume < -96)
+ volume = -96;
+ else
+ volume = 0;
+ }
+ dot = (dot >= 5 ? 1 : 0);
+ volume = (-volume << 1) + dot;
+ if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
+ {
+ reg_write(ES8388_ADCCONTROL8, volume);
+ reg_write(ES8388_ADCCONTROL9, volume); //ADC Right Volume=0db
+ }
+ if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
+ {
+ reg_write(ES8388_DACCONTROL5, volume);
+ reg_write(ES8388_DACCONTROL4, volume);
+ }
+ return res;
+}
+
+void es8388_set_voice_mute(rt_bool_t enable)
+{
+ uint8_t reg = 0;
+
+ reg = reg_read(ES8388_DACCONTROL3);
+ reg = reg & 0xFB;
+ reg_write(ES8388_DACCONTROL3, reg | (((int)enable) << 2));
+}
+
+rt_err_t es8388_init(const char *i2c_name, rt_uint16_t pin)
+{
+ es_dev.i2c = rt_i2c_bus_device_find(i2c_name);
+ if (es_dev.i2c == RT_NULL)
+ {
+ rt_kprintf("%s bus not found\n", i2c_name);
+ return -RT_ERROR;
+ }
+
+ es_dev.pin = pin;
+
+ reg_write(ES8388_DACCONTROL3, 0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and disabled digital volume control soft ramp
+ /* Chip Control and Power Management */
+ reg_write(ES8388_CONTROL2, 0x50);
+ reg_write(ES8388_CHIPPOWER, 0x00); //normal all and power up all
+ reg_write(ES8388_MASTERMODE, 0x00); //TODO:CODEC IN I2S SLAVE MODE
+
+ /* dac */
+ reg_write(ES8388_DACPOWER, 0xC0); //disable DAC and disable Lout/Rout/1/2
+ reg_write(ES8388_CONTROL1, 0x12); //Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
+ // reg_write(ES8388_CONTROL2, 0); //LPVrefBuf=0,Pdn_ana=0
+ reg_write(ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24
+ reg_write(ES8388_DACCONTROL2, 0x02); //DACFsMode,SINGLE SPEED; DACFsRatio,256
+ reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
+ reg_write(ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
+ reg_write(ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
+ reg_write(ES8388_DACCONTROL21, 0x80); //set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK
+ reg_write(ES8388_DACCONTROL23, 0x00); //vroi=0
+ es8388_set_adc_dac_volume(ES_MODE_DAC, 0, 0); // 0db
+
+ reg_write(ES8388_DACPOWER, 0x3c); //0x3c Enable DAC and Enable Lout/Rout/1/2
+ /* adc */
+ reg_write(ES8388_ADCPOWER, 0xFF);
+ reg_write(ES8388_ADCCONTROL1, 0xbb); // MIC Left and Right channel PGA gain
+ reg_write(ES8388_ADCCONTROL2, 0x00); //0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input; DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1
+ reg_write(ES8388_ADCCONTROL3, 0x02);
+ reg_write(ES8388_ADCCONTROL4, 0x0d); // Left/Right data, Left/Right justified mode, Bits length, I2S format
+ reg_write(ES8388_ADCCONTROL5, 0x02); //ADCFsMode,singel SPEED,RATIO=256
+ //ALC for Microphone
+ es8388_set_adc_dac_volume(ES_MODE_ADC, 0, 0); // 0db
+ reg_write(ES8388_ADCPOWER, 0x09); //Power on ADC, Enable LIN&RIN, Power off MICBIAS, set int1lp to low power mode
+ /* enable es8388 PA */
+ es8388_pa_power(RT_TRUE);
+
+ return RT_EOK;
+}
+
+rt_err_t es8388_start(enum es8388_mode mode)
+{
+ int res = 0;
+ uint8_t prev_data = 0, data = 0;
+
+ prev_data = reg_read(ES8388_DACCONTROL21);
+ if (mode == ES_MODE_LINE)
+ {
+ reg_write(ES8388_DACCONTROL16, 0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
+ reg_write(ES8388_DACCONTROL17, 0x50); // left DAC to left mixer enable and LIN signal to left mixer enable 0db : bupass enable
+ reg_write(ES8388_DACCONTROL20, 0x50); // right DAC to right mixer enable and LIN signal to right mixer enable 0db : bupass enable
+ reg_write(ES8388_DACCONTROL21, 0xC0); //enable adc
+ }
+ else
+ {
+ reg_write(ES8388_DACCONTROL21, 0x80); //enable dac
+ }
+ data = reg_read(ES8388_DACCONTROL21);
+
+ if (prev_data != data)
+ {
+ reg_write(ES8388_CHIPPOWER, 0xF0); //start state machine
+ // reg_write(ES8388_ADDR, ES8388_CONTROL1, 0x16);
+ // reg_write(ES8388_ADDR, ES8388_CONTROL2, 0x50);
+ reg_write(ES8388_CHIPPOWER, 0x00); //start state machine
+ }
+ if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE)
+ {
+ reg_write(ES8388_ADCPOWER, 0x00); //power up adc and line in
+ }
+ if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE)
+ {
+ reg_write(ES8388_DACPOWER, 0x3c); //power up dac and line out
+ es8388_set_voice_mute(RT_FALSE);
+ }
+
+ return res;
+}
+
+rt_err_t es8388_stop(enum es8388_mode mode)
+{
+ int res = 0;
+ if (mode == ES_MODE_LINE)
+ {
+ reg_write(ES8388_DACCONTROL21, 0x80); //enable dac
+ reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
+ reg_write(ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
+ reg_write(ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
+ return res;
+ }
+ if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
+ {
+ reg_write(ES8388_DACPOWER, 0x00);
+ es8388_set_voice_mute(RT_TRUE); //res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); // 0db
+ // reg_write(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //power down dac and line out
+ }
+ if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
+ {
+ // Es8388SetAdcDacVolume(ES_MODULE_ADC, -96, 5); // 0db
+ reg_write(ES8388_ADCPOWER, 0xFF); //power down adc and line in
+ }
+ if (mode == ES_MODE_DAC_ADC)
+ {
+ reg_write(ES8388_DACCONTROL21, 0x9C); //disable mclk
+ // reg_write(ES8388_CONTROL1, 0x00);
+ // reg_write(ES8388_CONTROL2, 0x58);
+ // reg_write(ES8388_CHIPPOWER, 0xF3); //stop state machine
+ }
+
+ return RT_EOK;
+}
+
+rt_err_t es8388_fmt_set(enum es8388_mode mode, enum es8388_format fmt)
+{
+ uint8_t reg = 0;
+
+ if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
+ {
+ reg = reg_read(ES8388_ADCCONTROL4);
+ reg = reg & 0xfc;
+ reg_write(ES8388_ADCCONTROL4, reg | fmt);
+ }
+ if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
+ {
+ reg = reg_read(ES8388_DACCONTROL1);
+ reg = reg & 0xf9;
+ reg_write(ES8388_DACCONTROL1, reg | (fmt << 1));
+ }
+
+ return RT_EOK;
+}
+
+void es8388_volume_set(rt_uint8_t volume)
+{
+ if (volume > 100)
+ volume = 100;
+ volume /= 3;
+
+ reg_write(ES8388_DACCONTROL24, volume);
+ reg_write(ES8388_DACCONTROL25, volume);
+}
+
+rt_uint8_t es8388_volume_get(void)
+{
+ rt_uint8_t volume;
+
+ volume = reg_read(ES8388_DACCONTROL24);
+ if (volume == 0xff)
+ {
+ volume = 0;
+ }
+ else
+ {
+ volume *= 3;
+ if (volume == 99)
+ volume = 100;
+ }
+
+ return volume;
+}
+
+void es8388_pa_power(rt_bool_t enable)
+{
+ rt_pin_mode(es_dev.pin, PIN_MODE_OUTPUT);
+
+ if (enable)
+ {
+ rt_pin_write(es_dev.pin, PIN_HIGH);
+ }
+ else
+ {
+ rt_pin_write(es_dev.pin, PIN_LOW);
+ }
+}
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.h b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.h
new file mode 100644
index 0000000000..1dc5806505
--- /dev/null
+++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.h
@@ -0,0 +1,93 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date Author Notes
+ * 2019-07-31 Zero-Free first implementation
+ */
+
+#ifndef __DRV_ES8388_H__
+#define __DRV_ES8388_H__
+
+/* ES8388 register space */
+#define ES8388_CONTROL1 0x00
+#define ES8388_CONTROL2 0x01
+#define ES8388_CHIPPOWER 0x02
+#define ES8388_ADCPOWER 0x03
+#define ES8388_DACPOWER 0x04
+#define ES8388_CHIPLOPOW1 0x05
+#define ES8388_CHIPLOPOW2 0x06
+#define ES8388_ANAVOLMANAG 0x07
+#define ES8388_MASTERMODE 0x08
+#define ES8388_ADCCONTROL1 0x09
+#define ES8388_ADCCONTROL2 0x0a
+#define ES8388_ADCCONTROL3 0x0b
+#define ES8388_ADCCONTROL4 0x0c
+#define ES8388_ADCCONTROL5 0x0d
+#define ES8388_ADCCONTROL6 0x0e
+#define ES8388_ADCCONTROL7 0x0f
+#define ES8388_ADCCONTROL8 0x10
+#define ES8388_ADCCONTROL9 0x11
+#define ES8388_ADCCONTROL10 0x12
+#define ES8388_ADCCONTROL11 0x13
+#define ES8388_ADCCONTROL12 0x14
+#define ES8388_ADCCONTROL13 0x15
+#define ES8388_ADCCONTROL14 0x16
+
+#define ES8388_DACCONTROL1 0x17
+#define ES8388_DACCONTROL2 0x18
+#define ES8388_DACCONTROL3 0x19
+#define ES8388_DACCONTROL4 0x1a
+#define ES8388_DACCONTROL5 0x1b
+#define ES8388_DACCONTROL6 0x1c
+#define ES8388_DACCONTROL7 0x1d
+#define ES8388_DACCONTROL8 0x1e
+#define ES8388_DACCONTROL9 0x1f
+#define ES8388_DACCONTROL10 0x20
+#define ES8388_DACCONTROL11 0x21
+#define ES8388_DACCONTROL12 0x22
+#define ES8388_DACCONTROL13 0x23
+#define ES8388_DACCONTROL14 0x24
+#define ES8388_DACCONTROL15 0x25
+#define ES8388_DACCONTROL16 0x26
+#define ES8388_DACCONTROL17 0x27
+#define ES8388_DACCONTROL18 0x28
+#define ES8388_DACCONTROL19 0x29
+#define ES8388_DACCONTROL20 0x2a
+#define ES8388_DACCONTROL21 0x2b
+#define ES8388_DACCONTROL22 0x2c
+#define ES8388_DACCONTROL23 0x2d
+#define ES8388_DACCONTROL24 0x2e
+#define ES8388_DACCONTROL25 0x2f
+#define ES8388_DACCONTROL26 0x30
+#define ES8388_DACCONTROL27 0x31
+#define ES8388_DACCONTROL28 0x32
+#define ES8388_DACCONTROL29 0x33
+#define ES8388_DACCONTROL30 0x34
+
+enum es8388_mode
+{
+ ES_MODE_NONE = 0x00,
+ ES_MODE_DAC = 0x01,
+ ES_MODE_ADC = 0x02,
+ ES_MODE_DAC_ADC = 0x03,
+ ES_MODE_LINE = 0x04,
+ ES_MODE_MAX = 0x06,
+};
+
+enum es8388_format
+{
+ ES_FMT_NORMAL = 0,
+ ES_FMT_LEFT = 1,
+ ES_FMT_RIGHT = 2,
+ ES_FMT_DSP = 3,
+};
+
+rt_err_t es8388_init(const char *i2c_name, rt_uint16_t pin);
+rt_err_t es8388_start(enum es8388_mode mode);
+rt_err_t es8388_stop(enum es8388_mode mode);
+rt_err_t es8388_fmt_set(enum es8388_mode mode, enum es8388_format fmt);
+void es8388_volume_set(rt_uint8_t volume);
+rt_uint8_t es8388_volume_get(void);
+void es8388_pa_power(rt_bool_t enable);
+
+#endif
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_mic.c b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_mic.c
new file mode 100644
index 0000000000..894e57f6d9
--- /dev/null
+++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_mic.c
@@ -0,0 +1,360 @@
+#include <board.h>
+
+#include "drv_es8388.h"
+
+#define DBG_TAG "drv.mic"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define RX_FIFO_SIZE (1024)
+
+struct mic_device
+{
+ struct rt_audio_device audio;
+ struct rt_audio_configure record_config;
+ rt_uint8_t *rx_fifo;
+ rt_uint8_t volume;
+};
+
+static struct mic_device mic_dev = {0};
+static rt_uint16_t zero_frame[2] = {0};
+
+static SAI_HandleTypeDef SAI1B_Handler = {0};
+static DMA_HandleTypeDef SAI1_RXDMA_Handler = {0};
+
+extern SAI_HandleTypeDef SAI1A_Handler;
+extern DMA_HandleTypeDef SAI1_RXDMA_Handler;
+extern void SAIA_Frequency_Set(uint32_t frequency);
+
+void SAIB_Init(void)
+{
+ HAL_SAI_DeInit(&SAI1B_Handler);
+
+ SAI1B_Handler.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
+ SAI1B_Handler.Instance = SAI1_Block_B;
+ SAI1B_Handler.Init.AudioMode = SAI_MODESLAVE_RX;
+ SAI1B_Handler.Init.Synchro = SAI_SYNCHRONOUS;
+ SAI1B_Handler.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+ SAI1B_Handler.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ SAI1B_Handler.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
+ SAI1B_Handler.Init.MonoStereoMode = SAI_MONOMODE;
+ SAI1B_Handler.Init.Protocol = SAI_FREE_PROTOCOL;
+ SAI1B_Handler.Init.DataSize = SAI_DATASIZE_16;
+ SAI1B_Handler.Init.FirstBit = SAI_FIRSTBIT_MSB;
+ SAI1B_Handler.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+
+ SAI1B_Handler.FrameInit.FrameLength = 64;
+ SAI1B_Handler.FrameInit.ActiveFrameLength = 32;
+ SAI1B_Handler.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+ SAI1B_Handler.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ SAI1B_Handler.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+ SAI1B_Handler.SlotInit.FirstBitOffset = 0;
+ SAI1B_Handler.SlotInit.SlotSize = SAI_SLOTSIZE_32B;
+ SAI1B_Handler.SlotInit.SlotNumber = 2;
+ SAI1B_Handler.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
+
+ HAL_SAI_Init(&SAI1B_Handler);
+ __HAL_SAI_ENABLE(&SAI1B_Handler);
+
+ /* Configure DMA used for SAI1 */
+ __HAL_RCC_DMA2_CLK_ENABLE();
+
+ SAI1_RXDMA_Handler.Init.Request = DMA_REQUEST_1;
+ SAI1_RXDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ SAI1_RXDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;
+ SAI1_RXDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;
+ SAI1_RXDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ SAI1_RXDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ SAI1_RXDMA_Handler.Init.Mode = DMA_CIRCULAR;
+ SAI1_RXDMA_Handler.Init.Priority = DMA_PRIORITY_HIGH;
+ SAI1_RXDMA_Handler.Instance = DMA2_Channel2;
+ __HAL_LINKDMA(&SAI1B_Handler, hdmarx, SAI1_RXDMA_Handler);
+ HAL_DMA_DeInit(&SAI1_RXDMA_Handler);
+ HAL_DMA_Init(&SAI1_RXDMA_Handler);
+ __HAL_DMA_ENABLE(&SAI1_RXDMA_Handler);
+
+ HAL_NVIC_SetPriority(DMA2_Channel2_IRQn, 0x01, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Channel2_IRQn);
+}
+
+void SAIB_Channels_Set(uint8_t channels)
+{
+ if (channels == 1)
+ {
+ SAI1B_Handler.Init.MonoStereoMode = SAI_MONOMODE;
+ }
+ else
+ {
+ SAI1B_Handler.Init.MonoStereoMode = SAI_STEREOMODE;
+ }
+
+ __HAL_SAI_DISABLE(&SAI1B_Handler);
+ HAL_SAI_Init(&SAI1B_Handler);
+ __HAL_SAI_ENABLE(&SAI1B_Handler);
+}
+
+void DMA2_Channel2_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(&SAI1_RXDMA_Handler);
+}
+
+void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[0], RX_FIFO_SIZE / 2);
+}
+
+void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[RX_FIFO_SIZE / 2], RX_FIFO_SIZE / 2);
+}
+
+static rt_err_t mic_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct mic_device *mic_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_TYPE_QUERY:
+ caps->udata.mask = AUDIO_TYPE_INPUT | AUDIO_TYPE_MIXER;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_INPUT: /* Provide capabilities of INPUT unit */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ caps->udata.config.samplerate = mic_dev->record_config.samplerate;
+ caps->udata.config.channels = mic_dev->record_config.channels;
+ caps->udata.config.samplebits = mic_dev->record_config.samplebits;
+ break;
+
+ case AUDIO_DSP_SAMPLERATE:
+ caps->udata.config.samplerate = mic_dev->record_config.samplerate;
+ break;
+
+ case AUDIO_DSP_CHANNELS:
+ caps->udata.config.channels = mic_dev->record_config.channels;
+ break;
+
+ case AUDIO_DSP_SAMPLEBITS:
+ caps->udata.config.samplebits = mic_dev->record_config.samplebits;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_MIXER: /* report the Mixer Units */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_QUERY:
+ caps->udata.mask = AUDIO_MIXER_VOLUME | AUDIO_MIXER_LINE;
+ break;
+
+ case AUDIO_MIXER_VOLUME:
+ caps->udata.value = mic_dev->volume;
+ break;
+
+ case AUDIO_MIXER_LINE:
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t mic_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct mic_device *mic_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_MIXER:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_VOLUME:
+ {
+ rt_uint32_t volume = caps->udata.value;
+ mic_dev->volume = volume;
+ LOG_D("set volume %d", volume);
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_INPUT:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ {
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ HAL_SAI_DMAStop(&SAI1B_Handler);
+ SAIB_Channels_Set(caps->udata.config.channels);
+ HAL_SAI_Transmit(&SAI1A_Handler, (uint8_t *)&zero_frame[0], 2, 0);
+ HAL_SAI_Receive_DMA(&SAI1B_Handler, mic_dev->rx_fifo, RX_FIFO_SIZE / 2);
+
+ /* save configs */
+ mic_dev->record_config.samplerate = caps->udata.config.samplerate;
+ mic_dev->record_config.channels = caps->udata.config.channels;
+ mic_dev->record_config.samplebits = caps->udata.config.samplebits;
+ LOG_D("set samplerate %d", mic_dev->record_config.samplerate);
+ LOG_D("set channels %d", mic_dev->record_config.channels);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLERATE:
+ {
+ mic_dev->record_config.samplerate = caps->udata.config.samplerate;
+ LOG_D("set channels %d", mic_dev->record_config.channels);
+ break;
+ }
+
+ case AUDIO_DSP_CHANNELS:
+ {
+ mic_dev->record_config.channels = caps->udata.config.channels;
+ LOG_D("set channels %d", mic_dev->record_config.channels);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t mic_init(struct rt_audio_device *audio)
+{
+ struct mic_device *mic_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+
+ SAIB_Init();
+
+ /* set default params */
+ SAIB_Channels_Set(mic_dev->record_config.channels);
+
+ return RT_EOK;
+}
+
+static rt_err_t mic_start(struct rt_audio_device *audio, int stream)
+{
+ struct mic_device *mic_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+
+ if (stream == AUDIO_STREAM_RECORD)
+ {
+ es8388_start(ES_MODE_ADC);
+ HAL_SAI_Transmit(&SAI1A_Handler, (uint8_t *)&zero_frame[0], 2, 0);
+ HAL_SAI_Receive_DMA(&SAI1B_Handler, mic_dev->rx_fifo, RX_FIFO_SIZE / 2);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t mic_stop(struct rt_audio_device *audio, int stream)
+{
+ if (stream == AUDIO_STREAM_RECORD)
+ {
+ HAL_SAI_DMAStop(&SAI1B_Handler);
+ HAL_SAI_Abort(&SAI1A_Handler);
+ es8388_stop(ES_MODE_ADC);
+ }
+
+ return RT_EOK;
+}
+
+static struct rt_audio_ops mic_ops =
+{
+ .getcaps = mic_getcaps,
+ .configure = mic_configure,
+ .init = mic_init,
+ .start = mic_start,
+ .stop = mic_stop,
+ .transmit = RT_NULL,
+ .buffer_info = RT_NULL,
+};
+
+int rt_hw_mic_init(void)
+{
+ rt_uint8_t *rx_fifo;
+
+ if (mic_dev.rx_fifo)
+ return RT_EOK;
+
+ rx_fifo = rt_malloc(RX_FIFO_SIZE);
+ if (rx_fifo == RT_NULL)
+ return -RT_ENOMEM;
+ rt_memset(rx_fifo, 0, RX_FIFO_SIZE);
+ mic_dev.rx_fifo = rx_fifo;
+
+ /* init default configuration */
+ {
+ mic_dev.record_config.samplerate = 44100;
+ mic_dev.record_config.channels = 2;
+ mic_dev.record_config.samplebits = 16;
+ mic_dev.volume = 55;
+ }
+
+ /* register sound device */
+ mic_dev.audio.ops = &mic_ops;
+ rt_audio_register(&mic_dev.audio, "mic0", RT_DEVICE_FLAG_RDONLY, &mic_dev);
+
+ return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_mic_init);
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c
new file mode 100644
index 0000000000..db84881630
--- /dev/null
+++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c
@@ -0,0 +1,456 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date Author Notes
+ * 2019-07-31 Zero-Free first implementation
+ */
+
+#include <board.h>
+
+#include "drv_sound.h"
+#include "drv_es8388.h"
+
+#define DBG_TAG "drv.sound"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define TX_FIFO_SIZE (2048)
+
+struct sound_device
+{
+ struct rt_audio_device audio;
+ struct rt_audio_configure replay_config;
+ rt_uint8_t *tx_fifo;
+ rt_uint8_t volume;
+};
+
+static struct sound_device snd_dev = {0};
+SAI_HandleTypeDef SAI1A_Handler = {0};
+DMA_HandleTypeDef SAI1_TXDMA_Handler = {0};
+
+static void SAIA_Init(void)
+{
+ RCC_PeriphCLKInitTypeDef PeriphClkInit;
+
+ /* Configure and enable PLLSAI1 clock to generate 45.714286MHz */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
+ PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2;
+ PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_HSE;
+ PeriphClkInit.PLLSAI2.PLLSAI2M = 1;
+ PeriphClkInit.PLLSAI2.PLLSAI2N = 40;
+ PeriphClkInit.PLLSAI2.PLLSAI2P = RCC_PLLP_DIV7;
+ PeriphClkInit.PLLSAI2.PLLSAI2R = RCC_PLLR_DIV2;
+ PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK;
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
+
+ HAL_SAI_DeInit(&SAI1A_Handler);
+ SAI1A_Handler.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
+ SAI1A_Handler.Instance = SAI1_Block_A;
+ SAI1A_Handler.Init.AudioMode = SAI_MODEMASTER_TX;
+ SAI1A_Handler.Init.Synchro = SAI_ASYNCHRONOUS;
+ SAI1A_Handler.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+ SAI1A_Handler.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ SAI1A_Handler.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
+ SAI1A_Handler.Init.MonoStereoMode = SAI_STEREOMODE;
+ SAI1A_Handler.Init.Protocol = SAI_FREE_PROTOCOL;
+ SAI1A_Handler.Init.DataSize = SAI_DATASIZE_16;
+ SAI1A_Handler.Init.FirstBit = SAI_FIRSTBIT_MSB;
+ SAI1A_Handler.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+
+ SAI1A_Handler.FrameInit.FrameLength = 64;
+ SAI1A_Handler.FrameInit.ActiveFrameLength = 32;
+ SAI1A_Handler.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+ SAI1A_Handler.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ SAI1A_Handler.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+ SAI1A_Handler.SlotInit.FirstBitOffset = 0;
+ SAI1A_Handler.SlotInit.SlotSize = SAI_SLOTSIZE_32B;
+ SAI1A_Handler.SlotInit.SlotNumber = 2;
+ SAI1A_Handler.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
+
+ HAL_SAI_Init(&SAI1A_Handler);
+ __HAL_SAI_ENABLE(&SAI1A_Handler);
+
+ /* Configure DMA used for SAI1 */
+ __HAL_RCC_DMA2_CLK_ENABLE();
+
+ SAI1_TXDMA_Handler.Init.Request = DMA_REQUEST_1;
+ SAI1_TXDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ SAI1_TXDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;
+ SAI1_TXDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;
+ SAI1_TXDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ SAI1_TXDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ SAI1_TXDMA_Handler.Init.Mode = DMA_CIRCULAR;
+ SAI1_TXDMA_Handler.Init.Priority = DMA_PRIORITY_HIGH;
+ SAI1_TXDMA_Handler.Instance = DMA2_Channel1;
+ __HAL_LINKDMA(&SAI1A_Handler, hdmatx, SAI1_TXDMA_Handler);
+ HAL_DMA_DeInit(&SAI1_TXDMA_Handler);
+ HAL_DMA_Init(&SAI1_TXDMA_Handler);
+ __HAL_DMA_ENABLE(&SAI1_TXDMA_Handler);
+
+ HAL_NVIC_SetPriority(DMA2_Channel1_IRQn, 0x01, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Channel1_IRQn);
+}
+
+void DMA2_Channel1_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(&SAI1_TXDMA_Handler);
+}
+
+void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ if (hsai == &SAI1A_Handler)
+ {
+ rt_audio_tx_complete(&snd_dev.audio);
+ }
+}
+
+void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ if (hsai == &SAI1A_Handler)
+ {
+ rt_audio_tx_complete(&snd_dev.audio);
+ }
+}
+
+void SAIA_Frequency_Set(uint32_t frequency)
+{
+ RCC_PeriphCLKInitTypeDef PeriphClkInit;
+
+ HAL_RCCEx_GetPeriphCLKConfig(&PeriphClkInit);
+
+ if ((frequency == SAI_AUDIO_FREQUENCY_11K) || (frequency == SAI_AUDIO_FREQUENCY_22K) || (frequency == SAI_AUDIO_FREQUENCY_44K))
+ {
+ /* Configure and enable PLLSAI1 clock to generate 45.714286MHz */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
+ PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2;
+ PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_HSE;
+ PeriphClkInit.PLLSAI2.PLLSAI2M = 1;
+ PeriphClkInit.PLLSAI2.PLLSAI2N = 40;
+ PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK;
+
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
+ }
+ else
+ {
+ /* Configure and enable PLLSAI1 clock to generate 49.142857MHz */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
+ PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2;
+ PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_HSE;
+ PeriphClkInit.PLLSAI2.PLLSAI2M = 1;
+ PeriphClkInit.PLLSAI2.PLLSAI2N = 43;
+ PeriphClkInit.PLLSAI2.PLLSAI2P = RCC_PLLP_DIV7;
+ PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK;
+
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
+ }
+
+ /* Disable SAI peripheral to allow access to SAI internal registers */
+ __HAL_SAI_DISABLE(&SAI1A_Handler);
+ /* Update the SAI audio frequency configuration */
+ SAI1A_Handler.Init.AudioFrequency = frequency;
+ HAL_SAI_Init(&SAI1A_Handler);
+ /* Enable SAI peripheral to generate MCLK */
+ __HAL_SAI_ENABLE(&SAI1A_Handler);
+}
+
+void SAIA_Channels_Set(uint8_t channels)
+{
+ if (channels == 1)
+ {
+ SAI1A_Handler.Init.MonoStereoMode = SAI_MONOMODE;
+ }
+ else
+ {
+ SAI1A_Handler.Init.MonoStereoMode = SAI_STEREOMODE;
+ }
+
+ __HAL_SAI_DISABLE(&SAI1A_Handler);
+ HAL_SAI_Init(&SAI1A_Handler);
+ __HAL_SAI_ENABLE(&SAI1A_Handler);
+}
+
+/**
+ * RT-Thread Audio Device Driver Interface
+ */
+static rt_err_t sound_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_TYPE_QUERY:
+ caps->udata.mask = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_MIXER;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_OUTPUT: /* Provide capabilities of OUTPUT unit */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ caps->udata.config.samplerate = snd_dev->replay_config.samplerate;
+ caps->udata.config.channels = snd_dev->replay_config.channels;
+ caps->udata.config.samplebits = snd_dev->replay_config.samplebits;
+ break;
+
+ case AUDIO_DSP_SAMPLERATE:
+ caps->udata.config.samplerate = snd_dev->replay_config.samplerate;
+ break;
+
+ case AUDIO_DSP_CHANNELS:
+ caps->udata.config.channels = snd_dev->replay_config.channels;
+ break;
+
+ case AUDIO_DSP_SAMPLEBITS:
+ caps->udata.config.samplebits = snd_dev->replay_config.samplebits;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_MIXER: /* report the Mixer Units */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_QUERY:
+ caps->udata.mask = AUDIO_MIXER_VOLUME;
+ break;
+
+ case AUDIO_MIXER_VOLUME:
+ caps->udata.value = es8388_volume_get();
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t sound_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_MIXER:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_VOLUME:
+ {
+ rt_uint8_t volume = caps->udata.value;
+
+ es8388_volume_set(volume);
+ snd_dev->volume = volume;
+ LOG_D("set volume %d", volume);
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_OUTPUT:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ {
+ /* set samplerate */
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ /* set channels */
+ SAIA_Channels_Set(caps->udata.config.channels);
+
+ /* save configs */
+ snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+ snd_dev->replay_config.channels = caps->udata.config.channels;
+ snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+ LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLERATE:
+ {
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+ LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+ break;
+ }
+
+ case AUDIO_DSP_CHANNELS:
+ {
+ SAIA_Channels_Set(caps->udata.config.channels);
+ snd_dev->replay_config.channels = caps->udata.config.channels;
+ LOG_D("set channels %d", snd_dev->replay_config.channels);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLEBITS:
+ {
+ /* not support */
+ snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t sound_init(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ es8388_init("i2c3", GET_PIN(A, 5));
+ SAIA_Init();
+
+ /* set default params */
+ SAIA_Frequency_Set(snd_dev->replay_config.samplerate);
+ SAIA_Channels_Set(snd_dev->replay_config.channels);
+
+ return result;
+}
+
+static rt_err_t sound_start(struct rt_audio_device *audio, int stream)
+{
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ LOG_D("open sound device");
+ es8388_start(ES_MODE_DAC);
+ HAL_SAI_Transmit_DMA(&SAI1A_Handler, snd_dev->tx_fifo, TX_FIFO_SIZE / 2);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t sound_stop(struct rt_audio_device *audio, int stream)
+{
+ RT_ASSERT(audio != RT_NULL);
+
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ HAL_SAI_DMAStop(&SAI1A_Handler);
+ es8388_stop(ES_MODE_DAC);
+ LOG_D("close sound device");
+ }
+
+ return RT_EOK;
+}
+
+static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info)
+{
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ /**
+ * TX_FIFO
+ * +----------------+----------------+
+ * | block1 | block2 |
+ * +----------------+----------------+
+ * \ block_size /
+ */
+ info->buffer = snd_dev->tx_fifo;
+ info->total_size = TX_FIFO_SIZE;
+ info->block_size = TX_FIFO_SIZE / 2;
+ info->block_count = 2;
+}
+
+static struct rt_audio_ops snd_ops =
+{
+ .getcaps = sound_getcaps,
+ .configure = sound_configure,
+ .init = sound_init,
+ .start = sound_start,
+ .stop = sound_stop,
+ .transmit = RT_NULL,
+ .buffer_info = sound_buffer_info,
+};
+
+int rt_hw_sound_init(void)
+{
+ rt_uint8_t *tx_fifo;
+
+ if (snd_dev.tx_fifo)
+ return RT_EOK;
+
+ tx_fifo = rt_malloc(TX_FIFO_SIZE);
+ if (tx_fifo == RT_NULL)
+ return -RT_ENOMEM;
+ rt_memset(tx_fifo, 0, TX_FIFO_SIZE);
+ snd_dev.tx_fifo = tx_fifo;
+
+ /* init default configuration */
+ {
+ snd_dev.replay_config.samplerate = 44100;
+ snd_dev.replay_config.channels = 2;
+ snd_dev.replay_config.samplebits = 16;
+ snd_dev.volume = 55;
+ }
+
+ /* register sound device */
+ snd_dev.audio.ops = &snd_ops;
+ rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev);
+
+ return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_sound_init);
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.h b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.h
new file mode 100644
index 0000000000..8fcc109bc6
--- /dev/null
+++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.h
@@ -0,0 +1,7 @@
+#ifndef __DRV_SOUND_H__
+#define __DRV_SOUND_H__
+
+int rt_hw_sound_init(void);
+int rt_hw_mic_init(void);
+
+#endif