thread-liu пре 4 година
родитељ
комит
73539c6bc0

+ 4 - 0
bsp/stm32/libraries/STM32MPxx_HAL/SConscript

@@ -103,6 +103,10 @@ if GetDepend(['BSP_USING_QSPI']):
 if GetDepend(['BSP_USING_SPDIFRX']):
     src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_spdifrx.c']
 
+if GetDepend(['BSP_USING_DFSDM']):
+    src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dfsdm.c']
+    src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dfsdm_ex.c']
+
 path = [cwd + '/STM32MP1xx_HAL_Driver/Inc',
     cwd + '/CMSIS/Device/ST/STM32MP1xx/Include',
     cwd + '/CMSIS/Core/Include',

+ 1 - 1
bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h

@@ -39,7 +39,7 @@
 #define HAL_DAC_MODULE_ENABLED
 #define HAL_DCMI_MODULE_ENABLED
 /*#define HAL_DSI_MODULE_ENABLED   */
-/*#define HAL_DFSDM_MODULE_ENABLED   */
+#define HAL_DFSDM_MODULE_ENABLED
 /*#define HAL_DTS_MODULE_ENABLED   */
 /*#define HAL_ETH_MODULE_ENABLED   */
 #define HAL_FDCAN_MODULE_ENABLED

+ 131 - 0
bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c

@@ -30,6 +30,8 @@ DMA_HandleTypeDef hdma_sai2_a     = {0};
 DMA_HandleTypeDef hdma_sai2_b     = {0};
 DMA_HandleTypeDef hdma_sai4_a     = {0};
 DMA_HandleTypeDef hdma_spdifrx_rx = {0};
+DMA_HandleTypeDef hdma_dfsdm1_flt0 = {0};
+DMA_HandleTypeDef hdma_dfsdm1_flt1 = {0};
 /* USER CODE END TD */
 
 /* Private define ------------------------------------------------------------*/
@@ -1688,6 +1690,135 @@ void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef* hspdifrx)
     }
 }
 
+void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef* hdfsdm_channel)
+{
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+    if(IS_ENGINEERING_BOOT_MODE())
+    {
+        PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_DFSDM1;
+        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+        {
+          Error_Handler();
+        }
+    }
+    /* Peripheral clock enable */
+    __HAL_RCC_DFSDM1_CLK_ENABLE();
+
+    __HAL_RCC_GPIOC_CLK_ENABLE();
+    __HAL_RCC_GPIOB_CLK_ENABLE();
+    __HAL_RCC_GPIOF_CLK_ENABLE();
+    /**DFSDM1 GPIO Configuration    
+    PC3     ------> DFSDM1_DATIN1
+    PB13     ------> DFSDM1_CKOUT
+    PF13     ------> DFSDM1_DATIN3 
+    */
+    GPIO_InitStruct.Pin         = GPIO_PIN_13;
+    GPIO_InitStruct.Mode        = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull        = GPIO_PULLDOWN;
+    GPIO_InitStruct.Speed       = GPIO_SPEED_FREQ_HIGH;
+    GPIO_InitStruct.Alternate   = GPIO_AF3_DFSDM1;
+    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    
+    GPIO_InitStruct.Pin         = GPIO_PIN_3;
+    GPIO_InitStruct.Alternate   = GPIO_AF3_DFSDM1;
+    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = GPIO_PIN_13;
+    GPIO_InitStruct.Alternate = GPIO_AF6_DFSDM1;
+    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+}
+
+void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef* hdfsdm_filter)
+{
+    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+    
+    if(IS_ENGINEERING_BOOT_MODE())
+    {
+        /** Initializes the peripherals clock 
+        */
+        PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_DFSDM1;
+        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+        {
+          Error_Handler();
+        }
+    }
+      
+    __HAL_RCC_DFSDM1_CLK_ENABLE();
+      /* DMA controller clock enable */
+    __HAL_RCC_DMAMUX_CLK_ENABLE();
+    __HAL_RCC_DMA2_CLK_ENABLE();
+  
+    if(hdfsdm_filter->Instance == DFSDM1_Filter0)
+    {
+        hdma_dfsdm1_flt0.Instance                   = DMA2_Stream2;
+        hdma_dfsdm1_flt0.Init.Request               = DMA_REQUEST_DFSDM1_FLT0;
+        hdma_dfsdm1_flt0.Init.Direction             = DMA_PERIPH_TO_MEMORY;
+        hdma_dfsdm1_flt0.Init.PeriphInc             = DMA_PINC_DISABLE;
+        hdma_dfsdm1_flt0.Init.MemInc                = DMA_MINC_ENABLE;
+        hdma_dfsdm1_flt0.Init.PeriphDataAlignment   = DMA_PDATAALIGN_WORD;
+        hdma_dfsdm1_flt0.Init.MemDataAlignment      = DMA_MDATAALIGN_WORD;
+        hdma_dfsdm1_flt0.Init.Mode                  = DMA_CIRCULAR;
+        hdma_dfsdm1_flt0.Init.Priority              = DMA_PRIORITY_HIGH;
+        hdma_dfsdm1_flt0.Init.FIFOMode              = DMA_FIFOMODE_ENABLE;
+        hdma_dfsdm1_flt0.Init.FIFOThreshold         = DMA_FIFO_THRESHOLD_FULL;
+        hdma_dfsdm1_flt0.Init.MemBurst              = DMA_MBURST_SINGLE;
+        hdma_dfsdm1_flt0.Init.PeriphBurst           = DMA_PBURST_SINGLE;
+        if (HAL_DMA_Init(&hdma_dfsdm1_flt0) != HAL_OK)
+        {
+          Error_Handler();
+        }
+
+        /* Several peripheral DMA handle pointers point to the same DMA handle.
+         Be aware that there is only one channel to perform all the requested DMAs. */
+        __HAL_LINKDMA(hdfsdm_filter,hdmaReg,hdma_dfsdm1_flt0);
+        
+        HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 2, 0);
+        HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
+    }
+
+    if(hdfsdm_filter->Instance == DFSDM1_Filter1)
+    {
+        hdma_dfsdm1_flt1.Instance                   = DMA2_Stream1;
+        hdma_dfsdm1_flt1.Init.Request               = DMA_REQUEST_DFSDM1_FLT1;
+        hdma_dfsdm1_flt1.Init.Direction             = DMA_PERIPH_TO_MEMORY;
+        hdma_dfsdm1_flt1.Init.PeriphInc             = DMA_PINC_DISABLE;
+        hdma_dfsdm1_flt1.Init.MemInc                = DMA_MINC_ENABLE;
+        hdma_dfsdm1_flt1.Init.PeriphDataAlignment   = DMA_PDATAALIGN_WORD;
+        hdma_dfsdm1_flt1.Init.MemDataAlignment      = DMA_MDATAALIGN_WORD;
+        hdma_dfsdm1_flt1.Init.Mode                  = DMA_CIRCULAR;
+        hdma_dfsdm1_flt1.Init.Priority              = DMA_PRIORITY_HIGH;
+        hdma_dfsdm1_flt1.Init.FIFOMode              = DMA_FIFOMODE_ENABLE;
+        hdma_dfsdm1_flt1.Init.FIFOThreshold         = DMA_FIFO_THRESHOLD_FULL;
+        hdma_dfsdm1_flt1.Init.MemBurst              = DMA_MBURST_SINGLE;
+        hdma_dfsdm1_flt1.Init.PeriphBurst           = DMA_PBURST_SINGLE;
+        
+        if (HAL_DMA_Init(&hdma_dfsdm1_flt1) != HAL_OK)
+        {
+          Error_Handler();
+        }
+        
+        __HAL_LINKDMA(hdfsdm_filter,hdmaReg,hdma_dfsdm1_flt1);
+        
+        HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 2, 0);
+        HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
+    }
+}
+
+void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef* hdfsdm_filter)
+{
+    HAL_DMA_DeInit(hdfsdm_filter->hdmaReg);
+}
+
+void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef* hdfsdm_channel)
+{
+    __HAL_RCC_DFSDM1_CLK_DISABLE();
+    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3);
+    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13);
+    HAL_GPIO_DeInit(GPIOF, GPIO_PIN_13);
+}
+
 /**
   * @brief  This function is executed in case of error occurrence.
   * @retval None

+ 14 - 9
bsp/stm32/stm32mp157a-st-ev1/board/Kconfig

@@ -72,15 +72,15 @@ menu "Onboard Peripheral Drivers"
         endif
 
     config BSP_USING_AUDIO
-    bool "Enable Audio Device (WM8994)"
-    select RT_USING_AUDIO
-    select BSP_USING_PMIC
-    select BSP_USING_SDMMC
-    select BSP_USING_SD_CARD
-    select SD_USING_DFS
-    select BSP_USING_I2C
-    select BSP_USING_I2C2
-    default n
+        bool "Enable Audio Device (WM8994)"
+        select RT_USING_AUDIO
+        select BSP_USING_PMIC
+        select BSP_USING_SDMMC
+        select BSP_USING_SD_CARD
+        select SD_USING_DFS
+        select BSP_USING_I2C
+        select BSP_USING_I2C2
+        default n
 
     config BSP_USING_DCMI
         bool "Enable CAMERA (ov5640)"
@@ -113,6 +113,11 @@ menu "On-chip Peripheral Drivers"
         select BSP_USING_AUDIO
         default n
 
+    config BSP_USING_DFSDM
+        bool "Enable dfsdm"
+        select BSP_USING_AUDIO
+        default n
+
     menuconfig BSP_USING_UART
         bool "Enable UART"
         select RT_USING_SERIAL

+ 3 - 0
bsp/stm32/stm32mp157a-st-ev1/board/SConscript

@@ -49,6 +49,9 @@ if GetDepend(['BSP_USING_QSPI']):
 if GetDepend(['BSP_USING_SPDIFRX']):
     src += Glob('ports/drv_spdifrx.c')
 
+if GetDepend(['BSP_USING_DFSDM']):
+    src += Glob('ports/drv_dfsdm.c')
+
 if GetDepend(['BSP_USING_OPENAMP']):
     src +=  Glob('CubeMX_Config/CM4/Src/ipcc.c')
     src +=  Glob('CubeMX_Config/CM4/Src/openamp.c')

+ 385 - 0
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c

@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-07-07     thread-liu   first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_DFSDM)
+#include "drv_wm8994.h"
+#include "drv_dfsdm.h"
+
+#define DRV_DEBUG
+#define LOG_TAG             "drv.dfsdm"
+#include <drv_log.h>
+
+#define          FILTER_FIFO_SIZE         (1024)
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFC8000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFC8000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC8000
+#endif
+rt_int32_t FILTER0_FIFO[FILTER_FIFO_SIZE];
+
+#define PALY_SIZE 2048
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFCA000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFCA000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFCA000
+#endif
+static rt_int16_t PLAY_BUF[PALY_SIZE];
+    
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFC9000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFC9000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC9000
+#endif
+rt_int32_t FILTER1_FIFO[FILTER_FIFO_SIZE];
+
+static volatile rt_uint8_t DmaLeftRecBuffCplt  = 0;
+static volatile rt_uint8_t DmaRightRecBuffCplt = 0;
+static volatile rt_uint8_t DmaLeftRecHalfBuffCplt = 0;
+static volatile rt_uint8_t DmaRightRecHalfBuffCplt = 0;
+
+static DFSDM_Channel_HandleTypeDef hdfsdm1_channel0 = {0}; /* data_in1_right */
+static DFSDM_Channel_HandleTypeDef hdfsdm1_channel1 = {0}; /* data_in1_left */
+
+static DFSDM_Filter_HandleTypeDef hdfsdm1_filter0 = {0}; /* data_in1_right */
+static DFSDM_Filter_HandleTypeDef hdfsdm1_filter1 = {0}; /* data_in1_left */
+
+extern DMA_HandleTypeDef hdma_dfsdm1_flt0;
+extern DMA_HandleTypeDef hdma_dfsdm1_flt1;
+
+static struct rt_device dfsdm_dev =  {0};
+
+void DMA2_Stream2_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+    
+    HAL_DMA_IRQHandler(&hdma_dfsdm1_flt1);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+void DMA2_Stream1_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+    
+    HAL_DMA_IRQHandler(&hdma_dfsdm1_flt0);
+    
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+    if(hdfsdm_filter == &hdfsdm1_filter1)
+    {
+        DmaLeftRecHalfBuffCplt = 1;
+    }
+    else
+    {
+        DmaRightRecHalfBuffCplt = 1;
+    }
+}
+
+void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+    if (hdfsdm_filter == &hdfsdm1_filter1)
+    {
+        DmaLeftRecBuffCplt = 1;
+    }
+    else
+    {
+        DmaRightRecBuffCplt = 1;
+    }
+}
+
+static int rt_hw_dfsdm_init(void)
+{
+    /* DATAIN1_LEFT */
+    __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hdfsdm1_channel1);
+    hdfsdm1_channel1.Instance                      = DFSDM1_Channel1;
+    hdfsdm1_channel1.Init.OutputClock.Activation   = ENABLE;
+    hdfsdm1_channel1.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM; /* 209MHZ */
+    hdfsdm1_channel1.Init.OutputClock.Divider      = 74; /* 209/74 = 2.82MHZ*/
+    hdfsdm1_channel1.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+    hdfsdm1_channel1.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
+    hdfsdm1_channel1.Init.Input.Pins               = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
+    hdfsdm1_channel1.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_RISING ;   /* left */
+    hdfsdm1_channel1.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+    hdfsdm1_channel1.Init.Awd.FilterOrder          = DFSDM_CHANNEL_FASTSINC_ORDER; 
+    hdfsdm1_channel1.Init.Awd.Oversampling         = 10; 
+    hdfsdm1_channel1.Init.Offset                   = 0;
+    hdfsdm1_channel1.Init.RightBitShift            = 2;
+    if(HAL_OK != HAL_DFSDM_ChannelInit(&hdfsdm1_channel1))
+    {
+        return RT_ERROR;
+    }
+    
+    /* DATAIN1_RIGHT */
+    __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hdfsdm1_channel0);
+    hdfsdm1_channel0.Instance                      = DFSDM1_Channel0;
+    hdfsdm1_channel0.Init.OutputClock.Activation   = ENABLE;
+    hdfsdm1_channel0.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM;
+    hdfsdm1_channel0.Init.OutputClock.Divider      = 74;  /* 209/74 = 2.82MHZ*/
+    hdfsdm1_channel0.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+    hdfsdm1_channel0.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE; 
+    hdfsdm1_channel0.Init.Input.Pins               = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
+    hdfsdm1_channel0.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_FALLING;   /* right */
+    hdfsdm1_channel0.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+    hdfsdm1_channel0.Init.Awd.FilterOrder          = DFSDM_CHANNEL_FASTSINC_ORDER;
+    hdfsdm1_channel0.Init.Awd.Oversampling         = 10;
+    hdfsdm1_channel0.Init.Offset                   = 0;
+    hdfsdm1_channel0.Init.RightBitShift            = 2;
+    if(HAL_OK != HAL_DFSDM_ChannelInit(&hdfsdm1_channel0))
+    {
+        return RT_ERROR;
+    }
+
+    /* Initialize filter 0 (data_in1 right channel) */
+    __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hdfsdm1_filter0);
+    hdfsdm1_filter0.Instance                          = DFSDM1_Filter0;
+    hdfsdm1_filter0.Init.RegularParam.Trigger         = DFSDM_FILTER_SW_TRIGGER;
+    hdfsdm1_filter0.Init.RegularParam.FastMode        = ENABLE;
+    hdfsdm1_filter0.Init.RegularParam.DmaMode         = ENABLE;
+    hdfsdm1_filter0.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
+    hdfsdm1_filter0.Init.InjectedParam.ScanMode       = DISABLE;
+    hdfsdm1_filter0.Init.InjectedParam.DmaMode        = DISABLE; 
+    hdfsdm1_filter0.Init.FilterParam.SincOrder        = DFSDM_FILTER_SINC3_ORDER;
+    hdfsdm1_filter0.Init.FilterParam.Oversampling     = 64; /* 209 / ( 74 * 64) = 44.1KHZ*/
+    hdfsdm1_filter0.Init.FilterParam.IntOversampling  = 1;
+    if (HAL_OK != HAL_DFSDM_FilterInit(&hdfsdm1_filter0))
+    {
+        return RT_ERROR;
+    }
+
+    /* Initialize filter 1 (data_in1 left channel) */
+    __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hdfsdm1_filter1);
+    hdfsdm1_filter1.Instance                          = DFSDM1_Filter1;
+    hdfsdm1_filter1.Init.RegularParam.Trigger         = DFSDM_FILTER_SW_TRIGGER;
+    hdfsdm1_filter1.Init.RegularParam.FastMode        = ENABLE;
+    hdfsdm1_filter1.Init.RegularParam.DmaMode         = ENABLE;
+    hdfsdm1_filter1.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER; 
+    hdfsdm1_filter1.Init.InjectedParam.ScanMode       = DISABLE; 
+    hdfsdm1_filter1.Init.InjectedParam.DmaMode        = DISABLE; 
+    hdfsdm1_filter1.Init.FilterParam.SincOrder        = DFSDM_FILTER_SINC3_ORDER;
+    hdfsdm1_filter1.Init.FilterParam.Oversampling     = 64; /* 209 / ( 74 * 64) = 44.1KHZ*/
+    hdfsdm1_filter1.Init.FilterParam.IntOversampling  = 1;
+    if (HAL_OK != HAL_DFSDM_FilterInit(&hdfsdm1_filter1))
+    {
+        return RT_ERROR;
+    }
+
+    /* Configure regular channel and continuous mode for filter 0 (data_in1 left channel) */
+    if (HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter1, DFSDM_CHANNEL_1, DFSDM_CONTINUOUS_CONV_ON))
+    {
+        return RT_ERROR;
+    }
+
+    /* Configure regular channel and continuous mode for filter 1 (data_in1 right channel) */
+    if (HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter0, DFSDM_CHANNEL_0, DFSDM_CONTINUOUS_CONV_ON))
+    {
+        return RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+/* dfsdm start coversions */
+static rt_err_t rt_hw_dfsdm_open(void)
+{
+    if (HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, FILTER0_FIFO, FILTER_FIFO_SIZE))
+    {
+        LOG_E("DFSDM DATA_IN1 rifht channel start conversions failed!");
+        return RT_ERROR;
+    }
+
+    if (HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter1, FILTER1_FIFO, FILTER_FIFO_SIZE))
+    {
+        LOG_E("DFSDM DATA_IN1 left channel start conversions failed!");
+        return RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t _init(rt_device_t dev)
+{
+   RT_ASSERT(dev != RT_NULL);
+   
+   rt_hw_dfsdm_init();
+
+   return RT_EOK;
+}
+
+static rt_err_t _open(rt_device_t dev, rt_uint16_t oflag)
+{
+   RT_ASSERT(dev != RT_NULL);
+   
+   rt_hw_dfsdm_open();
+
+   return RT_EOK;
+}
+
+static rt_err_t _close(rt_device_t dev)
+{
+   RT_ASSERT(dev != RT_NULL);
+   
+   HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter0);
+   HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter1);
+    
+   return RT_EOK;
+}
+
+static rt_size_t _read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    RT_ASSERT(dev != RT_NULL);
+    rt_uint32_t i = 0;
+    rt_int16_t *p = RT_NULL;
+    p = (rt_int16_t *)buffer;
+    
+    if (!pos)
+    {
+        for (i = 0; i < 512; i++)
+        {
+            p[2*i]     = (int16_t)SaturaLH((FILTER0_FIFO[i] >> 8), -32768, 32767);
+            p[(2*i)+1] = (int16_t)SaturaLH((FILTER1_FIFO[i] >> 8), -32768, 32767);
+        }
+    }
+    else
+    {
+        for (i = 512; i < 1024; i++)
+        {
+            p[2*i]     = (int16_t)SaturaLH((FILTER0_FIFO[i] >> 8), -32768, 32767);
+            p[(2*i)+1] = (int16_t)SaturaLH((FILTER1_FIFO[i] >> 8), -32768, 32767);
+        } 
+    }
+
+    return size;
+}
+
+static rt_size_t _write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+   RT_ASSERT(dev != RT_NULL);
+   
+   return RT_EOK;
+}
+
+static rt_err_t _control(rt_device_t dev, int cmd, void *args)
+{
+   RT_ASSERT(dev != RT_NULL);
+
+   return RT_EOK;
+}
+
+int dfsdm_init(void)
+{
+    dfsdm_dev.type      = RT_Device_Class_Miscellaneous;
+    dfsdm_dev.init      = _init;
+    dfsdm_dev.open      = _open;
+    dfsdm_dev.close     = _close;
+    dfsdm_dev.read      = _read;
+    dfsdm_dev.write     = _write;
+    dfsdm_dev.control   = _control;
+    dfsdm_dev.user_data = RT_NULL;
+
+    rt_device_register(&dfsdm_dev, "dfsdm1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+    
+    LOG_I("dfsdm1 init success!");
+    
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(dfsdm_init);
+
+static int dfsdm_sample(int argc, char **argv)
+{
+    if (argc != 1)
+    {
+        rt_kprintf("Usage:\n");
+        rt_kprintf("dfsdm_sample\n");
+        return -1;
+    }
+    
+    static struct rt_device *dfsdm_dev = RT_NULL;  
+    static struct rt_device *sound_dev = RT_NULL; 
+    rt_uint16_t play_type = OUTPUT_DEVICE_HEADPHONE;
+    rt_uint16_t tickstart = 0;
+    
+    extern SAI_HandleTypeDef hsai_BlockA2;
+    
+    dfsdm_dev = rt_device_find("dfsdm1");
+    if (dfsdm_dev == RT_NULL)
+    {
+        rt_kprintf("no dfsdm device!");
+        return RT_ERROR;
+    }
+    
+    sound_dev = rt_device_find("decoder");
+    if (sound_dev == RT_NULL)
+    {
+        rt_kprintf("no decoder device!");
+        return RT_ERROR;    
+    }
+
+    /* open dfsdm device */
+    rt_device_open(dfsdm_dev, RT_DEVICE_OFLAG_RDWR);
+    /* open sound device */
+    rt_device_open(sound_dev, RT_DEVICE_OFLAG_WRONLY);
+    
+    rt_device_control(sound_dev, SET_PLAY_TYPE, &play_type);
+    rt_device_control(sound_dev, START_PLAY, RT_NULL);
+    
+    rt_memset(PLAY_BUF, 0, PALY_SIZE);
+    
+    tickstart = rt_tick_get();
+    if (HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t *)PLAY_BUF, PALY_SIZE) != HAL_OK)
+    {
+        rt_kprintf("sai transmit dma failed!\n");
+        return RT_ERROR;
+    }
+    rt_kprintf("dfsdm audio record test begin!\n");
+    
+    while (1)
+    {
+        if ((rt_tick_get() - tickstart) > 0x1000)
+        {
+            HAL_SAI_DMAStop(&hsai_BlockA2);
+            rt_device_close(dfsdm_dev);
+            break;
+        }
+        if (DmaLeftRecHalfBuffCplt && DmaRightRecHalfBuffCplt)
+        {
+            rt_device_read(dfsdm_dev, 0, PLAY_BUF, 512);
+            DmaLeftRecHalfBuffCplt  = 0;
+            DmaRightRecHalfBuffCplt = 0;
+        }
+        else if (DmaLeftRecBuffCplt && DmaRightRecBuffCplt)
+        {
+            rt_device_read(dfsdm_dev, 1, PLAY_BUF, 512);
+            DmaLeftRecBuffCplt  = 0;
+            DmaRightRecBuffCplt = 0;
+        }
+    }
+    
+    rt_kprintf("dfsdm audio record test end!\n");
+    
+    return RT_EOK;
+}
+MSH_CMD_EXPORT(dfsdm_sample, dfsdm audiorecord test);
+
+#endif

+ 26 - 0
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-07-07     thread-liu   first version
+ */
+
+#ifndef __DRV_DFSDM_H__
+#define __DRV_DFSDM_H__
+
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif