From 73539c6bc02d316b35bcc78a903abdb0315233b6 Mon Sep 17 00:00:00 2001 From: thread-liu Date: Sat, 5 Dec 2020 09:43:08 +0800 Subject: [PATCH] [add] dfsdm driver. --- bsp/stm32/libraries/STM32MPxx_HAL/SConscript | 4 + .../CM4/Inc/stm32mp1xx_hal_conf.h | 2 +- .../CM4/Src/stm32mp1xx_hal_msp.c | 131 ++++++ bsp/stm32/stm32mp157a-st-ev1/board/Kconfig | 23 +- bsp/stm32/stm32mp157a-st-ev1/board/SConscript | 3 + .../board/ports/drv_dfsdm.c | 385 ++++++++++++++++++ .../board/ports/drv_dfsdm.h | 26 ++ 7 files changed, 564 insertions(+), 10 deletions(-) create mode 100644 bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c create mode 100644 bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h diff --git a/bsp/stm32/libraries/STM32MPxx_HAL/SConscript b/bsp/stm32/libraries/STM32MPxx_HAL/SConscript index 359a62a7db..70acd4d549 100644 --- a/bsp/stm32/libraries/STM32MPxx_HAL/SConscript +++ b/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', diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h index 5196204198..8f442b3087 100644 --- a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h +++ b/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 diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c index 0477b7e2be..ebab8fc422 100644 --- a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c +++ b/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 diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig b/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig index 6451fa2d84..c5dc1feeba 100644 --- a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig +++ b/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 diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript b/bsp/stm32/stm32mp157a-st-ev1/board/SConscript index 6ff0669579..91f0d0c998 100644 --- a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript +++ b/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') diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c new file mode 100644 index 0000000000..c348751881 --- /dev/null +++ b/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 + +#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 diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h new file mode 100644 index 0000000000..bf40fbf2f8 --- /dev/null +++ b/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 -- GitLab