#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "wm8711.h"
#include "pcm1870.h"
#include "eeprom.h"
#include "wm8978.h"
/*--------------------------------------
--------音频DAC I2S3 引脚 PA15 PB3 PB5--
---------PB6 PB7 wm8711 IIC配置引脚 ----
---------PC7 MCLK输出引脚---------------
---------------------------------------*/
//I2S_3 PB12-WS PB13-CK PB15-SD PC6-MCLK
void WM8711_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 |GPIO_Pin_14 | GPIO_Pin_15;//WS CK SD
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_I2S2ext);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //MCLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_SPI2);
//------------------wm8711 I2C GPIO Init
// pcm1770 cs- pc8 md- pa8 mc- pc9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//md
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//mc
// GPIO_Init(GPIOA, &GPIO_InitStructure);
IIC_SDA=1;
IIC_SCL=1;
}
// I2S3 初始化
void I2S3_Init(void)
{
I2S_InitTypeDef I2S_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_I2S_DeInit(SPI2);
I2S_StructInit(&I2S_InitStructure);
I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_8k;;
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
I2S_Init(SPI2, &I2S_InitStructure);
I2S_FullDuplexConfig(I2S2ext, &I2S_InitStructure);
I2S_Cmd(SPI2, ENABLE);
I2S_Cmd(I2S2ext, ENABLE);
}
void I2S3_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
}
// WM8711初始化
void WM8711_Init(void)
{
WM8711_GPIO_Init();
WM8711_Config();
I2S3_Init();
printf("WM1870初始化 \r\n\n");
}
void SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void I2S_Start(void)
{
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_RXNE, DISABLE);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
I2S_Cmd(SPI2, ENABLE);
I2S_Cmd(SPI3, ENABLE);
printf("REAL_VOICE START \r\n\n");
}
void delayus(u8 nus)
{
u32 i,j;
for(i=0;i<nus;i++)
for(j=0;j<50;j++);
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delayus(2); //min 1.3us
IIC_SDA=0; //START:when CLK is high,DATA change form high to low
delayus(1); //min 600ns
IIC_SCL=0; //钳住I2C总线,准备发送或接收数据
delayus(2); //min 1.3us
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delayus(2);//min 1.3us
IIC_SCL=1;
delayus(1);//min 600ns
IIC_SDA=1;//发送I2C总线结束信号
delayus(2);//min 1.3us
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u16 ucErrTime=0;
IIC_SDA=1;
IIC_SCL=1;
delayus(1);//min 600ns
SDA_IN(); //SDA设置为输入
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>450)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
IIC_SDA=0;
IIC_SCL=0;//拉低时钟开始数据传输
SDA_OUT();
for(t=0;t<8;t++)
{
if(txd&0x80)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
IIC_SCL=1;
delayus(1); // min 600ns
IIC_SCL=0;
}
}
void WM8711_Control(u8 reg,u8 Wdata)
{
IIC_Start(); //起始信号
IIC_Send_Byte(WM8711_Address&WM8711_Write); //WM8711地址 + 写入
IIC_Wait_Ack();
IIC_Send_Byte(reg); //寄存器地址
IIC_Wait_Ack();
IIC_Send_Byte(Wdata); //寄存器值
IIC_Wait_Ack();
IIC_Stop();
}
void codec_send(u16 Wdata)
{
IIC_Start(); //起始信号
IIC_Send_Byte(0x34); //WM8711地址 + 写入
IIC_Wait_Ack();
IIC_Send_Byte((Wdata>>8)&0xFF); //寄存器地址
IIC_Wait_Ack();
IIC_Send_Byte(Wdata&0xFF); //寄存器值
IIC_Wait_Ack();
IIC_Stop();
}
extern uint16_t const VirtAddVarTab[];
void WM8711_Config(void)
{
FLASH_Unlock(); //获取标志信息
EE_Init();
Vol=0xDA;
WM8711_Control(0x1E,0x00); //reset
WM8711_Control(0x1E,0x00); //reset
WM8711_Control(0x04,0x80|Vol); //Left Channel Zero Cross detect enable volume:1111001
WM8711_Control(0x06,0x80|Vol); //Right Channel Zero Cross detect enable volume:1111001
WM8711_Control(0x08,0x18); //R4 DAC SEL BYPASS Enable
WM8711_Control(0x0A,0x01); //DAC MUTE Disable
WM8711_Control(0x0C,0x07); //R6 power OFF: 0x87 ON :0x07
WM8711_Control(0x0E,0x22); //MODE : Master Slaver
WM8711_Control(0x10,0x04); // Normal mode 8K
WM8711_Control(0x12,0x01); // Activate Interface
}
void TUNING(void)
{
WM8711_Control(0x05,0x80|Vol);
WM8711_Control(0x07,0x80|Vol);
}
void vol(uint16_t v) // 0~99
{
v = 63*v/100;
v = (v & VOL_MASK) << VOL_POS;
codec_send(REG_LOUT1_VOL | v);
codec_send(REG_ROUT1_VOL | HPVU | v);
codec_send(REG_LOUT2_VOL | v);
codec_send(REG_ROUT2_VOL | SPKVU | v);
}
static uint16_t r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1 | BCLK_DIV16;
void sample_rate(int sr)
{
uint16_t r07 = REG_ADDITIONAL;
switch (sr)
{
case 8000:
r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1 | BCLK_DIV16 ;
// r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV6 | BCLK_DIV8 | (r06 & MS);
r07 |= SR_8KHZ;
break;
case 11025:
r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV8 | BCLK_DIV8 | (r06 & MS);
r07 |= SR_12KHZ;
break;
#i
评论0