[add] sai and wm8994 codec driver.

This commit is contained in:
thread-liu
2020-12-02 17:28:35 +08:00
parent 840af38dac
commit c5612fd2e1
8 changed files with 1645 additions and 4 deletions

View File

@@ -67,8 +67,6 @@ if GetDepend(['RT_USING_SDIO']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_delayblock.c']
if GetDepend(['RT_USING_AUDIO']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_i2s.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_i2s_ex.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai_ex.c']

View File

@@ -57,7 +57,7 @@
/*#define HAL_PCD_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */
/*#define HAL_SAI_MODULE_ENABLED */
#define HAL_SAI_MODULE_ENABLED
#define HAL_SD_MODULE_ENABLED
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */

View File

@@ -26,7 +26,9 @@
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
DMA_HandleTypeDef hdma_sai2_a = {0};
DMA_HandleTypeDef hdma_sai2_b = {0};
DMA_HandleTypeDef hdma_sai4_a = {0};
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
@@ -1201,6 +1203,200 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
}
}
void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/* SAI2 */
if (hsai->Instance==SAI2_Block_A)
{
/* Peripheral clock enable */
if(IS_ENGINEERING_BOOT_MODE())
{
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
PeriphClkInit.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLL3_Q;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_SAI2_CLK_ENABLE();
/**SAI2_A_Block_A GPIO Configuration
PE0 ------> SAI2_MCLK_A
PI7 ------> SAI2_FS_A
PI5 ------> SAI2_SCK_A
PI6 ------> SAI2_SD_A
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_5|GPIO_PIN_6;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
/* Configure DMA used for SAI2 */
__HAL_RCC_DMAMUX_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_sai2_a.Instance = DMA1_Stream0;
hdma_sai2_a.Init.Request = DMA_REQUEST_SAI2_A;
hdma_sai2_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sai2_a.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sai2_a.Init.MemInc = DMA_MINC_ENABLE;
hdma_sai2_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
hdma_sai2_a.Init.Priority = DMA_PRIORITY_HIGH;
hdma_sai2_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sai2_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sai2_a.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_sai2_a.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_DeInit(&hdma_sai2_a);
if (HAL_DMA_Init(&hdma_sai2_a) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hsai,hdmatx,hdma_sai2_a);
__HAL_DMA_ENABLE(&hdma_sai2_a);
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0x02, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
if (hsai->Instance==SAI2_Block_B)
{
/* Peripheral clock enable */
if (IS_ENGINEERING_BOOT_MODE())
{
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
PeriphClkInit.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLL3_Q;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_SAI2_CLK_ENABLE();
/**SAI2_B_Block_B GPIO Configuration
PE12 ------> SAI2_MCLK_B
PE13 ------> SAI2_FS_B
PE14 ------> SAI2_SCK_B
PF11 ------> SAI2_SD_B
*/
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
__HAL_RCC_DMAMUX_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* Peripheral DMA init*/
hdma_sai2_b.Instance = DMA1_Stream1;
hdma_sai2_b.Init.Request = DMA_REQUEST_SAI2_B;
hdma_sai2_b.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sai2_b.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sai2_b.Init.MemInc = DMA_MINC_ENABLE;
hdma_sai2_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_sai2_b.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_sai2_b.Init.Mode = DMA_CIRCULAR;
hdma_sai2_b.Init.Priority = DMA_PRIORITY_HIGH;
hdma_sai2_b.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sai2_b.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sai2_b.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_sai2_b.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_DeInit(&hdma_sai2_b);
if (HAL_DMA_Init(&hdma_sai2_b) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hsai,hdmarx,hdma_sai2_b);
__HAL_DMA_ENABLE(&hdma_sai2_b);
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0x02, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
/* SAI4 */
if(hsai->Instance==SAI4_Block_A)
{
/* Peripheral clock enable */
if(IS_ENGINEERING_BOOT_MODE())
{
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI4;
PeriphClkInit.Sai4ClockSelection = RCC_SAI4CLKSOURCE_PLL3_Q;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_SAI4_CLK_ENABLE();
/**SAI4_A_Block_A GPIO Configuration
PB5 ------> SAI4_SD_A
*/
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_SAI4;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral DMA init*/
__HAL_RCC_DMAMUX_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_sai4_a.Instance = DMA1_Stream2;
hdma_sai4_a.Init.Request = DMA_REQUEST_SAI4_A;
hdma_sai4_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sai4_a.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sai4_a.Init.MemInc = DMA_MINC_ENABLE;
hdma_sai4_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_sai4_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_sai4_a.Init.Mode = DMA_CIRCULAR;
hdma_sai4_a.Init.Priority = DMA_PRIORITY_HIGH;
hdma_sai4_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sai4_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sai4_a.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_sai4_a.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_DeInit(&hdma_sai4_a);
if (HAL_DMA_Init(&hdma_sai4_a) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hsai,hdmatx,hdma_sai4_a);
__HAL_DMA_ENABLE(&hdma_sai4_a);
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0x02, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
}
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None

View File

@@ -63,6 +63,15 @@ menu "Onboard Peripheral Drivers"
default n
endif
endif
config BSP_USING_AUDIO
bool "Enable Audio Device (WM8994)"
select RT_USING_AUDIO
select BSP_USING_PMIC
select BSP_USING_I2C
select BSP_USING_I2C2
default n
endmenu
menu "On-chip Peripheral Drivers"

View File

@@ -28,6 +28,10 @@ if GetDepend(['BSP_USING_SD_CARD']):
if GetDepend(['BSP_USING_EMMC']):
src += Glob('ports/drv_emmc.c')
if GetDepend(['BSP_USING_AUDIO']):
src += Glob('ports/drv_wm8994.c')
src += Glob('ports/drv_sound.c')
if GetDepend(['BSP_USING_OPENAMP']):
src += Glob('CubeMX_Config/CM4/Src/ipcc.c')
src += Glob('CubeMX_Config/CM4/Src/openamp.c')

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-02 thread-liu first version
*/
#ifndef __DRV_WM8994_H__
#define __DRV_WM8994_H__
#include "board.h"
#ifdef __cplusplus
extern "C" {
#endif
enum{
GET_ID,
SET_FREQUENCE,
SET_VOLUME,
GET_VOLUME,
SET_MUTE,
SET_RESET,
START_PLAY,
SET_PLAY_TYPE,
};
/* codec device play type */
#define DEVICE_NONE ((uint16_t)0x0000)
#define OUTPUT_DEVICE_SPEAKER ((uint16_t)0x0001)
#define OUTPUT_DEVICE_HEADPHONE ((uint16_t)0x0002)
#define OUTPUT_DEVICE_BOTH ((uint16_t)0x0004)
#define OUTPUT_DEVICE_AUTO ((uint16_t)0x0008)
#define INPUT_DEVICE_DIGITAL_MICROPHONE_1 ((uint16_t)0x0010)
#define INPUT_DEVICE_DIGITAL_MICROPHONE_2 ((uint16_t)0x0020)
#define INPUT_DEVICE_INPUT_LINE_1 ((uint16_t)0x0040)
#define INPUT_DEVICE_INPUT_LINE_2 ((uint16_t)0x0080)
#define INPUT_DEVICE_DIGITAL_MIC1_MIC2 ((uint16_t)0x0100)
/* volume levels values */
#define DEFAULT_VOLMIN 0x00
#define DEFAULT_VOLMAX 0xFF
#define DEFAULT_VOLSTEP 0x04
#define AUDIO_PAUSE 0
#define AUDIO_RESUME 1
/* Codec POWER DOWN modes */
#define CODEC_PDWN_HW 1
#define CODEC_PDWN_SW 2
/* MUTE commands */
#define AUDIO_MUTE_ON 1
#define AUDIO_MUTE_OFF 0
/* AUDIO FREQUENCY */
#define AUDIO_FREQUENCY_192K ((uint32_t)192000)
#define AUDIO_FREQUENCY_96K ((uint32_t)96000)
#define AUDIO_FREQUENCY_48K ((uint32_t)48000)
#define AUDIO_FREQUENCY_44K ((uint32_t)44100)
#define AUDIO_FREQUENCY_32K ((uint32_t)32000)
#define AUDIO_FREQUENCY_22K ((uint32_t)22050)
#define AUDIO_FREQUENCY_16K ((uint32_t)16000)
#define AUDIO_FREQUENCY_11K ((uint32_t)11025)
#define AUDIO_FREQUENCY_8K ((uint32_t)8000)
#define VOLUME_CONVERT(Volume) (((Volume) > 100)? 100:((uint8_t)(((Volume) * 63) / 100)))
#define VOLUME_IN_CONVERT(Volume) (((Volume) >= 100)? 239:((uint8_t)(((Volume) * 240) / 100)))
#define WM8994_ID 0x8994
#define WM8994_CHIPID_ADDR 0x00
#ifdef __cplusplus
}
#endif
#endif