STM32H750XB_RT-THREAD/38-SAI—音频/SAI—录音与回放/User/wm8978/bsp_wm8978.c

835 lines
22 KiB
C
Raw Permalink Normal View History

2025-07-21 06:34:29 +00:00
/*
******************************************************************************
* @file bsp_led.c
* @author fire
* @version V1.0
* @date 2015-xx-xx
* @brief wm8978<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
******************************************************************************
* @attention
*
* ʵ<EFBFBD><EFBFBD>ƽ̨:Ұ<EFBFBD><EFBFBD> STM32 H750 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD>̳ :http://www.chuxue123.com
* <EFBFBD>Ա<EFBFBD> :http://firestm32.taobao.com
*
******************************************************************************
*/
#include "./wm8978/bsp_wm8978.h"
#include "./usart/bsp_debug_usart.h"
#include "main.h"
#include "./i2c/i2c.h"
//#include "./Recorder/Recorder.h"
#include "./delay/core_delay.h"
extern I2C_HandleTypeDef I2C_Handle;
uint32_t AudioTotalSize ; /* <20><>Ƶ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ܴ<EFBFBD>С */
uint32_t AudioRemSize; /* <20><>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD> */
uint16_t *CurrentPos; /* <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>ĵ<EFBFBD>ǰλ<C7B0><CEBB> */
DMA_HandleTypeDef hdma_spi2_tx;
DMA_HandleTypeDef hdma_spi2_rx;
/**
*******************************************************************************************************
* I2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD>WM8978<EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD>
*******************************************************************************************************
*/
static uint8_t WM8978_I2C_WriteRegister(uint8_t RegisterAddr, uint16_t RegisterValue);
static uint16_t wm8978_ReadReg(uint8_t _ucRegAddr);
static uint8_t wm8978_WriteReg(uint8_t _ucRegAddr, uint16_t _usValue);
/*
wm8978<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>WM8978<EFBFBD><EFBFBD>I2C<EFBFBD><EFBFBD><EFBFBD>߽ӿڲ<EFBFBD>֧<EFBFBD>ֶ<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˼Ĵ<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>ʱͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>»<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>ʱ
ֱ<EFBFBD>ӷ<EFBFBD><EFBFBD>ػ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>ֵ<EFBFBD><EFBFBD>
<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>MAP <EFBFBD><EFBFBD>WM8978(V4.5_2011).pdf <EFBFBD>ĵ<EFBFBD>89ҳ<EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD>7bit<EFBFBD><EFBFBD> <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>9bit
*/
static uint16_t wm8978_RegCash[] = {
0x000, 0x000, 0x000, 0x000, 0x050, 0x000, 0x140, 0x000,
0x000, 0x000, 0x000, 0x0FF, 0x0FF, 0x000, 0x100, 0x0FF,
0x0FF, 0x000, 0x12C, 0x02C, 0x02C, 0x02C, 0x02C, 0x000,
0x032, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
0x038, 0x00B, 0x032, 0x000, 0x008, 0x00C, 0x093, 0x0E9,
0x000, 0x000, 0x000, 0x000, 0x003, 0x010, 0x010, 0x100,
0x100, 0x002, 0x001, 0x001, 0x039, 0x039, 0x039, 0x039,
0x001, 0x001
};
/**
* @brief ͨ<EFBFBD><EFBFBD>I2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param RegisterAddr: <EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ
* @param RegisterValue: Ҫд<EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>ֵ
* @retval ͨ<EFBFBD>ųɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD>0
*/
static uint8_t WM8978_I2C_WriteRegister(uint8_t RegisterAddr, uint16_t RegisterValue)
{
uint16_t tmp;
tmp = (RegisterValue&0xff) << 8;
tmp |= ((RegisterAddr << 1) & 0xFE) | ((RegisterValue >> 8) & 0x1);
if(HAL_I2C_Master_Transmit(&I2C_Handle,WM8978_SLAVE_ADDRESS,(uint8_t *)&tmp,2,WM8978_I2C_FLAG_TIMEOUT)==HAL_OK)
{
return 1;
}
else
return 0;
}
/**
* @brief <EFBFBD><EFBFBD>cash<EFBFBD>ж<EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD>wm8978<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>
* @param _ucRegAddr <EFBFBD><EFBFBD> <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
* @retval <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>ֵ
*/
static uint16_t wm8978_ReadReg(uint8_t _ucRegAddr)
{
return wm8978_RegCash[_ucRegAddr];
}
/**
* @brief дwm8978<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>
* @param _ucRegAddr<EFBFBD><EFBFBD> <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
* @param _usValue<EFBFBD><EFBFBD> <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>ֵ
* @retval 0<EFBFBD><EFBFBD>д<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
* 1<EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
*/
static uint8_t wm8978_WriteReg(uint8_t _ucRegAddr, uint16_t _usValue)
{
uint8_t res;
res=WM8978_I2C_WriteRegister(_ucRegAddr,_usValue);
wm8978_RegCash[_ucRegAddr] = _usValue;
return res;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>I2C GPIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>I2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>WM8978<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval 1,<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>;
* 0,<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>
*/
uint8_t wm8978_Init(void)
{
uint8_t res;
I2cMaster_Init(); /* <20><>ʼ<EFBFBD><CABC>I2C<32>ӿ<EFBFBD> */
res=wm8978_Reset(); /* Ӳ<><D3B2><EFBFBD><EFBFBD>λWM8978<37><38><EFBFBD>мĴ<D0BC><C4B4><EFBFBD><EFBFBD><EFBFBD>ȱʡ״̬ */
wm8978_CtrlGPIO1(1); /* <20><><EFBFBD><EFBFBD>WM8978<37><38>һ<EFBFBD><D2BB>GPIO<49>ӿڿ<D3BF><DABF><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>״̬ */
return res;
}
/**
* @brief <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param _ucVolume <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ, 0-63
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_SetOUT1Volume(uint8_t _ucVolume)
{
uint16_t regL;
uint16_t regR;
if (_ucVolume > 0x3F)
{
_ucVolume = 0x3F;
}
regL = _ucVolume;
regR = _ucVolume;
/*
R52 LOUT1 Volume control
R53 ROUT1 Volume control
*/
/* <20>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
wm8978_WriteReg(52, regL | 0x00);
/* <20><>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
wm8978_WriteReg(53, regR | 0x100); /* 0x180<38><30>ʾ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0ʱ<30>ٸ<EFBFBD><D9B8>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵġ<D6B5><C4A1><EFBFBD><EFBFBD>ա<EFBFBD><D5A1><EFBFBD> */
}
/**
* @brief <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param _ucVolume <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ, 0-63
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_SetOUT2Volume(uint8_t _ucVolume)
{
uint16_t regL;
uint16_t regR;
if (_ucVolume > 0x3F)
{
_ucVolume = 0x3F;
}
regL = _ucVolume;
regR = _ucVolume;
/*
R54 LOUT2 (SPK) Volume control
R55 ROUT2 (SPK) Volume control
*/
/* <20>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
wm8978_WriteReg(54, regL | 0x00);
/* <20><>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
wm8978_WriteReg(55, regR | 0x100); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0ʱ<30>ٸ<EFBFBD><D9B8>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵġ<D6B5><C4A1><EFBFBD><EFBFBD>ա<EFBFBD><D5A1><EFBFBD> */
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
*/
uint8_t wm8978_ReadOUT1Volume(void)
{
return (uint8_t)(wm8978_ReadReg(52) & 0x3F );
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
*/
uint8_t wm8978_ReadOUT2Volume(void)
{
return (uint8_t)(wm8978_ReadReg(54) & 0x3F );
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
* @param _ucMute<EFBFBD><EFBFBD>ģʽѡ<EFBFBD><EFBFBD>
* @arg 1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @arg 0<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_OutMute(uint8_t _ucMute)
{
uint16_t usRegValue;
if (_ucMute == 1) /* <20><><EFBFBD><EFBFBD> */
{
usRegValue = wm8978_ReadReg(52); /* Left Mixer Control */
usRegValue |= (1u << 6);
wm8978_WriteReg(52, usRegValue);
usRegValue = wm8978_ReadReg(53); /* Left Mixer Control */
usRegValue |= (1u << 6);
wm8978_WriteReg(53, usRegValue);
usRegValue = wm8978_ReadReg(54); /* Right Mixer Control */
usRegValue |= (1u << 6);
wm8978_WriteReg(54, usRegValue);
usRegValue = wm8978_ReadReg(55); /* Right Mixer Control */
usRegValue |= (1u << 6);
wm8978_WriteReg(55, usRegValue);
}
else /* ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
{
usRegValue = wm8978_ReadReg(52);
usRegValue &= ~(1u << 6);
wm8978_WriteReg(52, usRegValue);
usRegValue = wm8978_ReadReg(53); /* Left Mixer Control */
usRegValue &= ~(1u << 6);
wm8978_WriteReg(53, usRegValue);
usRegValue = wm8978_ReadReg(54);
usRegValue &= ~(1u << 6);
wm8978_WriteReg(54, usRegValue);
usRegValue = wm8978_ReadReg(55); /* Left Mixer Control */
usRegValue &= ~(1u << 6);
wm8978_WriteReg(55, usRegValue);
}
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param _ucGain <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ, 0-63
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_SetMicGain(uint8_t _ucGain)
{
if (_ucGain > GAIN_MAX)
{
_ucGain = GAIN_MAX;
}
/* PGA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> R45<34><35> R46 WM8978(V4.5_2011).pdf 25ҳ
Bit8 INPPGAUPDATE
Bit7 INPPGAZCL <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD><EFBFBD><EFBFBD>
Bit6 INPPGAMUTEL PGA<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Bit5:0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>010000<EFBFBD><EFBFBD>0dB
*/
wm8978_WriteReg(45, _ucGain);
wm8978_WriteReg(46, _ucGain | (1 << 8));
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Line<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param _ucGain <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ, 0-7. 7<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>С<EFBFBD><EFBFBD> <EFBFBD><EFBFBD>˥<EFBFBD><EFBFBD><EFBFBD>ɷŴ<EFBFBD><EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_SetLineGain(uint8_t _ucGain)
{
uint16_t usRegValue;
if (_ucGain > 7)
{
_ucGain = 7;
}
/*
Mic <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PGABOOSTL <EFBFBD><EFBFBD> PGABOOSTR <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Aux <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> AUXL2BOOSTVO[2:0] <EFBFBD><EFBFBD> AUXR2BOOSTVO[2:0] <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Line <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LIP2BOOSTVOL[2:0] <EFBFBD><EFBFBD> RIP2BOOSTVOL[2:0] <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
/* WM8978(V4.5_2011).pdf 29ҳ<39><D2B3>R47<34><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>R48<34><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, MIC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD>
R47 (R48<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ)
B8 PGABOOSTL = 1, 0<EFBFBD><EFBFBD>ʾMIC<EFBFBD>ź<EFBFBD>ֱͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾMIC<EFBFBD>ź<EFBFBD>+20dB<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD>Ծٵ<EFBFBD>·<EFBFBD><EFBFBD>
B7 = 0<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B6:4 L2_2BOOSTVOL = x<EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>1-7<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>-12dB ~ +6dB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˥<EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD>ԷŴ<EFBFBD><EFBFBD><EFBFBD>
B3 = 0<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B2:0` AUXL2BOOSTVOL = x<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>1-7<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>-12dB ~ +6dB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˥<EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD>ԷŴ<EFBFBD><EFBFBD><EFBFBD>
*/
usRegValue = wm8978_ReadReg(47);
usRegValue &= 0x8F;/* <20><>Bit6:4<><34>0 1000 1111*/
usRegValue |= (_ucGain << 4);
wm8978_WriteReg(47, usRegValue); /* д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD> */
usRegValue = wm8978_ReadReg(48);
usRegValue &= 0x8F;/* <20><>Bit6:4<><34>0 1000 1111*/
usRegValue |= (_ucGain << 4);
wm8978_WriteReg(48, usRegValue); /* д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD> */
}
/**
* @brief <EFBFBD>ر<EFBFBD>wm8978<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD>ģʽ
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_PowerDown(void)
{
wm8978_Reset(); /* Ӳ<><D3B2><EFBFBD><EFBFBD>λWM8978<37><38><EFBFBD>мĴ<D0BC><C4B4><EFBFBD><EFBFBD><EFBFBD>ȱʡ״̬ */
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>WM8978<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ӿ<EFBFBD>(I2S)
* @param _usStandard : <EFBFBD>ӿڱ<EFBFBD>׼<EFBFBD><EFBFBD>I2S_Standard_Phillips, I2S_Standard_MSB <EFBFBD><EFBFBD> I2S_Standard_LSB
* @param _ucWordLen : <EFBFBD>ֳ<EFBFBD><EFBFBD><EFBFBD>16<EFBFBD><EFBFBD>24<EFBFBD><EFBFBD>32 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>20bit<EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_CfgAudioIF(uint16_t _usStandard, uint8_t _ucWordLen)
{
uint16_t usReg;
/* WM8978(V4.5_2011).pdf 73ҳ<33><D2B3><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>б<EFBFBD> */
/* REG R4, <20><>Ƶ<EFBFBD>ӿڿ<D3BF><DABF>ƼĴ<C6BC><C4B4><EFBFBD>
B8 BCP = X, BCLK<EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B7 LRCP = x, LRCʱ<EFBFBD>Ӽ<EFBFBD><EFBFBD>ԣ<EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B6:5 WL = x<EFBFBD><EFBFBD> <EFBFBD>ֳ<EFBFBD><EFBFBD><EFBFBD>00=16bit<EFBFBD><EFBFBD>01=20bit<EFBFBD><EFBFBD>10=24bit<EFBFBD><EFBFBD>11=32bit <EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD><EFBFBD><EFBFBD>ģʽֻ<EFBFBD>ܲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>24bit)
B4:3 FMT = x<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ<EFBFBD><EFBFBD>00=<EFBFBD>Ҷ<EFBFBD><EFBFBD>01=<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>10=I2S<EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>11=PCM
B2 DACLRSWAP = x, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>DAC<EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LRCʱ<EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߻<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ұ<EFBFBD>
B1 ADCLRSWAP = x<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ADC<EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LRCʱ<EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߻<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ұ<EFBFBD>
B0 MONO = 0<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч
*/
usReg = 0;
if (_usStandard == SAI_I2S_STANDARD) /* I2S<32><53><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>׼ */
{
usReg |= (2 << 3);
}
else if (_usStandard == SAI_I2S_MSBJUSTIFIED) /* MSB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׼(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) */
{
usReg |= (1 << 3);
}
else if (_usStandard == SAI_I2S_LSBJUSTIFIED) /* LSB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׼(<28>Ҷ<EFBFBD><D2B6><EFBFBD>) */
{
usReg |= (0 << 3);
}
else /* PCM<43><4D>׼(16λͨ<CEBB><CDA8>֡<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡ͬ<D6A1><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>16λ<36><CEBB><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>չΪ32λͨ<CEBB><CDA8>֡) */
{
usReg |= (3 << 3);;
}
if (_ucWordLen == 24)
{
usReg |= (2 << 5);
}
else if (_ucWordLen == 32)
{
usReg |= (3 << 5);
}
else
{
usReg |= (0 << 5); /* 16bit */
}
wm8978_WriteReg(4, usReg);
/*
R6<EFBFBD><EFBFBD>ʱ<EFBFBD>Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<EFBFBD><EFBFBD><EFBFBD>
MS = 0, WM8978<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ӣ<EFBFBD><EFBFBD><EFBFBD>MCU<EFBFBD>MCLKʱ<EFBFBD><EFBFBD>
*/
wm8978_WriteReg(6, 0x000);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>wm8978<EFBFBD><EFBFBD>Ƶͨ<EFBFBD><EFBFBD>
* @param _InPath : <EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param _OutPath : <EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_CfgAudioPath(uint16_t _InPath, uint16_t _OutPath)
{
uint16_t usReg;
/* <20>鿴WM8978<37><38><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD> REGISTER MAP <20>½ڣ<C2BD> <20><>89ҳ */
if ((_InPath == IN_PATH_OFF) && (_OutPath == OUT_PATH_OFF))
{
wm8978_PowerDown();
return;
}
/* --------------------------- <20><>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>üĴ<C3BC><C4B4><EFBFBD> -----------------------*/
/*
R1 <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> Power manage 1
Bit8 BUFDCOPEN, Output stage 1.5xAVDD/2 driver enable
Bit7 OUT4MIXEN, OUT4 mixer enable
Bit6 OUT3MIXEN, OUT3 mixer enable
Bit5 PLLEN .<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Bit4 MICBEN ,Microphone Bias Enable (MICƫ<EFBFBD>õ<EFBFBD>·ʹ<EFBFBD><EFBFBD>)
Bit3 BIASEN ,Analogue amplifier bias control <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ1ģ<EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD><EFBFBD><EFBFBD>
Bit2 BUFIOEN , Unused input/output tie off buffer enable
Bit1:0 VMIDSEL, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>00ֵģ<EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD><EFBFBD><EFBFBD>
*/
usReg = (1 << 3) | (3 << 0);
if (_OutPath & OUT3_4_ON) /* OUT3<54><33>OUT4ʹ<34><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GSMģ<4D><C4A3> */
{
usReg |= ((1 << 7) | (1 << 6));
}
if ((_InPath & MIC_LEFT_ON) || (_InPath & MIC_RIGHT_ON))
{
usReg |= (1 << 4);
}
wm8978_WriteReg(1, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
/*
R2 <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> Power manage 2
Bit8 ROUT1EN, ROUT1 output enable <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
Bit7 LOUT1EN, LOUT1 output enable <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
Bit6 SLEEP, 0 = Normal device operation 1 = Residual current reduced in device standby mode
Bit5 BOOSTENR, Right channel Input BOOST enable <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD>Ծٵ<EFBFBD>·ʹ<EFBFBD><EFBFBD>. <EFBFBD>õ<EFBFBD>PGA<EFBFBD>Ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
Bit4 BOOSTENL, Left channel Input BOOST enable
Bit3 INPGAENR, Right channel input PGA enable <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PGAʹ<EFBFBD><EFBFBD>
Bit2 INPGAENL, Left channel input PGA enable
Bit1 ADCENR, Enable ADC right channel
Bit0 ADCENL, Enable ADC left channel
*/
usReg = 0;
if (_OutPath & EAR_LEFT_ON)
{
usReg |= (1 << 7);
}
if (_OutPath & EAR_RIGHT_ON)
{
usReg |= (1 << 8);
}
if (_InPath & MIC_LEFT_ON)
{
usReg |= ((1 << 4) | (1 << 2));
}
if (_InPath & MIC_RIGHT_ON)
{
usReg |= ((1 << 5) | (1 << 3));
}
if (_InPath & LINE_ON)
{
usReg |= ((1 << 4) | (1 << 5));
}
if (_InPath & MIC_RIGHT_ON)
{
usReg |= ((1 << 5) | (1 << 3));
}
if (_InPath & ADC_ON)
{
usReg |= ((1 << 1) | (1 << 0));
}
wm8978_WriteReg(2, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
/*
R3 <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> Power manage 3
Bit8 OUT4EN, OUT4 enable
Bit7 OUT3EN, OUT3 enable
Bit6 LOUT2EN, LOUT2 output enable
Bit5 ROUT2EN, ROUT2 output enable
Bit4 0,
Bit3 RMIXEN, Right mixer enable
Bit2 LMIXEN, Left mixer enable
Bit1 DACENR, Right channel DAC enable
Bit0 DACENL, Left channel DAC enable
*/
usReg = 0;
if (_OutPath & OUT3_4_ON)
{
usReg |= ((1 << 8) | (1 << 7));
}
if (_OutPath & SPK_ON)
{
usReg |= ((1 << 6) | (1 << 5));
}
if (_OutPath != OUT_PATH_OFF)
{
usReg |= ((1 << 3) | (1 << 2));
}
if (_InPath & DAC_ON)
{
usReg |= ((1 << 1) | (1 << 0));
}
wm8978_WriteReg(3, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
/*
R44 <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> Input ctrl
Bit8 MBVSEL, Microphone Bias Voltage Control 0 = 0.9 * AVDD 1 = 0.6 * AVDD
Bit7 0
Bit6 R2_2INPPGA, Connect R2 pin to right channel input PGA positive terminal
Bit5 RIN2INPPGA, Connect RIN pin to right channel input PGA negative terminal
Bit4 RIP2INPPGA, Connect RIP pin to right channel input PGA amplifier positive terminal
Bit3 0
Bit2 L2_2INPPGA, Connect L2 pin to left channel input PGA positive terminal
Bit1 LIN2INPPGA, Connect LIN pin to left channel input PGA negative terminal
Bit0 LIP2INPPGA, Connect LIP pin to left channel input PGA amplifier positive terminal
*/
usReg = 0 << 8;
if (_InPath & LINE_ON)
{
usReg |= ((1 << 6) | (1 << 2));
}
if (_InPath & MIC_RIGHT_ON)
{
usReg |= ((1 << 5) | (1 << 4));
}
if (_InPath & MIC_LEFT_ON)
{
usReg |= ((1 << 1) | (1 << 0));
}
wm8978_WriteReg(44, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
/*
R14 <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> ADC Control
<EFBFBD><EFBFBD><EFBFBD>ø<EFBFBD>ͨ<EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD>ģ<EFBFBD> WM8978(V4.5_2011).pdf 31 32ҳ,
Bit8 HPFEN, High Pass Filter Enable<EFBFBD><EFBFBD>ͨ<EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ܣ<EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾʹ<EFBFBD><EFBFBD>
BIt7 HPFAPP, Select audio mode or application mode ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶģʽ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>Ƶģʽ<EFBFBD><EFBFBD>
Bit6:4 HPFCUT<EFBFBD><EFBFBD>Application mode cut-off frequency 000-111ѡ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>ģʽ<EFBFBD>Ľ<EFBFBD>ֹƵ<EFBFBD><EFBFBD>
Bit3 ADCOSR, ADC oversample rate select: 0=64x (lower power) 1=128x (best performance)
Bit2 0
Bit1 ADC right channel polarity adjust: 0=normal 1=inverted
Bit0 ADC left channel polarity adjust: 0=normal 1=inverted
*/
if (_InPath & ADC_ON)
{
usReg = (1 << 3) | (0 << 8) | (4 << 0); /* <20><>ֹADC<44><43>ͨ<EFBFBD>˲<EFBFBD><CBB2><EFBFBD>, <20><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>Ƶ<EFBFBD><C6B5> */
}
else
{
usReg = 0;
}
wm8978_WriteReg(14, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
/* <20><><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD>notch filter<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Х<EFBFBD><D0A5>. <20><>ʱ<EFBFBD>ر<EFBFBD>
R27<EFBFBD><EFBFBD>R28<EFBFBD><EFBFBD>R29<EFBFBD><EFBFBD>R30 <EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>޲<EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>WM8978(V4.5_2011).pdf 33ҳ
R7<EFBFBD><EFBFBD> Bit7 NFEN = 0 <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾʹ<EFBFBD><EFBFBD>
*/
if (_InPath & ADC_ON)
{
usReg = (0 << 7);
wm8978_WriteReg(27, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
usReg = 0;
wm8978_WriteReg(28, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD>,<2C><>0<EFBFBD><30><EFBFBD><EFBFBD>Ϊ<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD> */
wm8978_WriteReg(29, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD>,<2C><>0<EFBFBD><30><EFBFBD><EFBFBD>Ϊ<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD> */
wm8978_WriteReg(30, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD>,<2C><>0<EFBFBD><30><EFBFBD><EFBFBD>Ϊ<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD> */
}
/* <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ALC, R32 - 34 WM8978(V4.5_2011).pdf 36ҳ */
{
usReg = 0; /* <20><>ֹ<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
wm8978_WriteReg(32, usReg);
wm8978_WriteReg(33, usReg);
wm8978_WriteReg(34, usReg);
}
/* R35 ALC Noise Gate Control
Bit3 NGATEN, Noise gate function enable
Bit2:0 Noise gate threshold:
*/
usReg = (3 << 1) | (7 << 0); /* <20><>ֹ<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
wm8978_WriteReg(35, usReg);
/*
Mic <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PGABOOSTL <EFBFBD><EFBFBD> PGABOOSTR <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Aux <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> AUXL2BOOSTVO[2:0] <EFBFBD><EFBFBD> AUXR2BOOSTVO[2:0] <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Line <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LIP2BOOSTVOL[2:0] <EFBFBD><EFBFBD> RIP2BOOSTVOL[2:0] <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
/* WM8978(V4.5_2011).pdf 29ҳ<39><D2B3>R47<34><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>R48<34><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, MIC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD>
R47 (R48<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ)
B8 PGABOOSTL = 1, 0<EFBFBD><EFBFBD>ʾMIC<EFBFBD>ź<EFBFBD>ֱͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾMIC<EFBFBD>ź<EFBFBD>+20dB<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD>Ծٵ<EFBFBD>·<EFBFBD><EFBFBD>
B7 = 0<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B6:4 L2_2BOOSTVOL = x<EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>1-7<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>-12dB ~ +6dB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˥<EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD>ԷŴ<EFBFBD><EFBFBD><EFBFBD>
B3 = 0<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B2:0` AUXL2BOOSTVOL = x<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>1-7<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>-12dB ~ +6dB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˥<EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD>ԷŴ<EFBFBD><EFBFBD><EFBFBD>
*/
usReg = 0;
if ((_InPath & MIC_LEFT_ON) || (_InPath & MIC_RIGHT_ON))
{
usReg |= (1 << 8); /* MIC<49><43><EFBFBD><EFBFBD>ȡ+20dB */
}
if (_InPath & AUX_ON)
{
usReg |= (3 << 0); /* Aux<75><78><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD>ȡ3<C8A1><33><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD> */
}
if (_InPath & LINE_ON)
{
usReg |= (3 << 4); /* Line<6E><65><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD>ȡ3<C8A1><33><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD> */
}
wm8978_WriteReg(47, usReg); /* д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD> */
wm8978_WriteReg(48, usReg); /* д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD> */
/* <20><><EFBFBD><EFBFBD>ADC<44><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>pdf 35ҳ
R15 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ADC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>R16<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ADC<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Bit8 ADCVU = 1 ʱ<EFBFBD>Ÿ<EFBFBD><EFBFBD>£<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ADC<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Bit7:0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0000 0000 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0000 0001 = -127dB
0000 0010 = -12.5dB <EFBFBD><EFBFBD>0.5dB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1111 1111 = 0dB <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˥<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
usReg = 0xFF;
wm8978_WriteReg(15, usReg); /* ѡ<><D1A1>0dB<64><42><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
usReg = 0x1FF;
wm8978_WriteReg(16, usReg); /* ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
/* ͨ<><CDA8> wm8978_SetMicGain <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mic PGA<47><41><EFBFBD><EFBFBD> */
/* R43 <20>Ĵ<EFBFBD><C4B4><EFBFBD> AUXR <20>C ROUT2 BEEP Mixer Function
B8:6 = 0
B5 MUTERPGA2INV, Mute input to INVROUT2 mixer
B4 INVROUT2, Invert ROUT2 output <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B3:1 BEEPVOL = 7; AUXR input to ROUT2 inverter gain
B0 BEEPEN = 1; Enable AUXR beep input
*/
usReg = 0;
if (_OutPath & SPK_ON)
{
usReg |= (1 << 4); /* ROUT2 <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
}
if (_InPath & AUX_ON)
{
usReg |= ((7 << 1) | (1 << 0));
}
wm8978_WriteReg(43, usReg);
/* R49 Output ctrl
B8:7 0
B6 DACL2RMIX, Left DAC output to right output mixer
B5 DACR2LMIX, Right DAC output to left output
B4 OUT4BOOST, 0 = OUT4 output gain = -1; DC = AVDD / 2<EFBFBD><EFBFBD>1 = OUT4 output gain = +1.5<EFBFBD><EFBFBD>DC = 1.5 x AVDD / 2
B3 OUT3BOOST, 0 = OUT3 output gain = -1; DC = AVDD / 2<EFBFBD><EFBFBD>1 = OUT3 output gain = +1.5<EFBFBD><EFBFBD>DC = 1.5 x AVDD / 2
B2 SPKBOOST, 0 = Speaker gain = -1; DC = AVDD / 2 ; 1 = Speaker gain = +1.5; DC = 1.5 x AVDD / 2
B1 TSDEN, Thermal Shutdown Enable <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ܣ<EFBFBD>ȱʡ1<EFBFBD><EFBFBD>
B0 VROI, Disabled Outputs to VREF Resistance
*/
usReg = 0;
if (_InPath & DAC_ON)
{
usReg |= ((1 << 6) | (1 << 5));
}
if (_OutPath & SPK_ON)
{
usReg |= ((1 << 2) | (1 << 1)); /* SPK 1.5x<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>ȱ<EFBFBD><C8B1><EFBFBD>ʹ<EFBFBD><CAB9> */
}
if (_OutPath & OUT3_4_ON)
{
usReg |= ((1 << 4) | (1 << 3)); /* BOOT3 BOOT4 1.5x<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
}
wm8978_WriteReg(49, usReg);
/* REG 50 (50<35><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>51<35><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>üĴ<C3BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>) WM8978(V4.5_2011).pdf 56ҳ
B8:6 AUXLMIXVOL = 111 AUX<EFBFBD><EFBFBD><EFBFBD><EFBFBD>FM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B5 AUXL2LMIX = 1 Left Auxilliary input to left channel
B4:2 BYPLMIXVOL <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B1 BYPL2LMIX = 0; Left bypass path (from the left channel input boost output) to left output mixer
B0 DACL2LMIX = 1; Left DAC output to left output mixer
*/
usReg = 0;
if (_InPath & AUX_ON)
{
usReg |= ((7 << 6) | (1 << 5));
}
if ((_InPath & LINE_ON) || (_InPath & MIC_LEFT_ON) || (_InPath & MIC_RIGHT_ON))
{
usReg |= ((7 << 2) | (1 << 1));
}
if (_InPath & DAC_ON)
{
usReg |= (1 << 0);
}
wm8978_WriteReg(50, usReg);
wm8978_WriteReg(51, usReg);
/* R56 <20>Ĵ<EFBFBD><C4B4><EFBFBD> OUT3 mixer ctrl
B8:7 0
B6 OUT3MUTE, 0 = Output stage outputs OUT3 mixer; 1 = Output stage muted <EFBFBD>C drives out VMID.
B5:4 0
B3 BYPL2OUT3, OUT4 mixer output to OUT3 (<EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
B4 0
B2 LMIX2OUT3, Left ADC input to OUT3
B1 LDAC2OUT3, Left DAC mixer to OUT3
B0 LDAC2OUT3, Left DAC output to OUT3
*/
usReg = 0;
if (_OutPath & OUT3_4_ON)
{
usReg |= (1 << 3);
}
wm8978_WriteReg(56, usReg);
/* R57 <20>Ĵ<EFBFBD><C4B4><EFBFBD> OUT4 (MONO) mixer ctrl
B8:7 0
B6 OUT4MUTE, 0 = Output stage outputs OUT4 mixer 1 = Output stage muted <EFBFBD>C drives outVMID.
B5 HALFSIG, 0 = OUT4 normal output 1 = OUT4 attenuated by 6dB
B4 LMIX2OUT4, Left DAC mixer to OUT4
B3 LDAC2UT4, Left DAC to OUT4
B2 BYPR2OUT4, Right ADC input to OUT4
B1 RMIX2OUT4, Right DAC mixer to OUT4
B0 RDAC2OUT4, Right DAC output to OUT4
*/
usReg = 0;
if (_OutPath & OUT3_4_ON)
{
usReg |= ((1 << 4) | (1 << 1));
}
wm8978_WriteReg(57, usReg);
/* R11, 12 <20>Ĵ<EFBFBD><C4B4><EFBFBD> DAC<41><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
R11 Left DAC Digital Volume
R12 Right DAC Digital Volume
*/
if (_InPath & DAC_ON)
{
wm8978_WriteReg(11, 255);
wm8978_WriteReg(12, 255 | 0x100);
}
else
{
wm8978_WriteReg(11, 0);
wm8978_WriteReg(12, 0 | 0x100);
}
/* R10 <20>Ĵ<EFBFBD><C4B4><EFBFBD> DAC Control
B8 0
B7 0
B6 SOFTMUTE, Softmute enable:
B5 0
B4 0
B3 DACOSR128, DAC oversampling rate: 0=64x (lowest power) 1=128x (best performance)
B2 AMUTE, Automute enable
B1 DACPOLR, Right DAC output polarity
B0 DACPOLL, Left DAC output polarity:
*/
if (_InPath & DAC_ON)
{
wm8978_WriteReg(10, 0);
}
;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>notch filter<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD>Ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Х<EFBFBD><EFBFBD>
* @param NFA0[13:0] and NFA1[13:0]
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_NotchFilter(uint16_t _NFA0, uint16_t _NFA1)
{
uint16_t usReg;
/* page 26
A programmable notch filter is provided. This filter has a variable centre frequency and bandwidth,
programmable via two coefficients, a0 and a1. a0 and a1 are represented by the register bits
NFA0[13:0] and NFA1[13:0]. Because these coefficient values require four register writes to setup
there is an NFU (Notch Filter Update) flag which should be set only when all four registers are setup.
*/
usReg = (1 << 7) | (_NFA0 & 0x3F);
wm8978_WriteReg(27, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
usReg = ((_NFA0 >> 7) & 0x3F);
wm8978_WriteReg(28, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
usReg = (_NFA1 & 0x3F);
wm8978_WriteReg(29, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
usReg = (1 << 8) | ((_NFA1 >> 7) & 0x3F);
wm8978_WriteReg(30, usReg); /* д<>Ĵ<EFBFBD><C4B4><EFBFBD> */
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>WM8978<EFBFBD><EFBFBD>GPIO1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* 1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* 0<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>
* @param _ucValue <EFBFBD><EFBFBD>GPIO1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>1
* @retval <EFBFBD><EFBFBD>
*/
void wm8978_CtrlGPIO1(uint8_t _ucValue)
{
uint16_t usRegValue;
/* R8<52><38> pdf 62ҳ */
if (_ucValue == 0) /* <20><><EFBFBD><EFBFBD>0 */
{
usRegValue = 6; /* B2:0 = 110 */
}
else
{
usRegValue = 7; /* B2:0 = 111 */
}
wm8978_WriteReg(8, usRegValue);
}
/**
* @brief <EFBFBD><EFBFBD>λwm8978<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еļĴ<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>ȱʡֵ
* @param <EFBFBD><EFBFBD>
* @retval 1: <EFBFBD><EFBFBD>λ<EFBFBD>ɹ<EFBFBD>
* 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λʧ<EFBFBD><EFBFBD>
*/
uint8_t wm8978_Reset(void)
{
/* wm8978<37>Ĵ<EFBFBD><C4B4><EFBFBD>ȱʡֵ */
const uint16_t reg_default[] = {
0x000, 0x000, 0x000, 0x000, 0x050, 0x000, 0x140, 0x000,
0x000, 0x000, 0x000, 0x0FF, 0x0FF, 0x000, 0x100, 0x0FF,
0x0FF, 0x000, 0x12C, 0x02C, 0x02C, 0x02C, 0x02C, 0x000,
0x032, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
0x038, 0x00B, 0x032, 0x000, 0x008, 0x00C, 0x093, 0x0E9,
0x000, 0x000, 0x000, 0x000, 0x003, 0x010, 0x010, 0x100,
0x100, 0x002, 0x001, 0x001, 0x039, 0x039, 0x039, 0x039,
0x001, 0x001
};
uint8_t res;
uint8_t i;
res=wm8978_WriteReg(0x00, 0);
for (i = 0; i < sizeof(reg_default) / 2; i++)
{
wm8978_RegCash[i] = reg_default[i];
}
return res;
}
/***************************** (END OF FILE) *********************************/