📄 i2s_codec.c
字号:
u32 GetVar_AudioPlayStatus(void)
{
return AudioPlayStatus;
}
/*******************************************************************************
* Function Name : SetVar_AudioPlayStatus
* Description : Set the AudioDataIndex variable to Status.
* Input : Status: could be AudioPlayStatus_STOPPED, AudioPlayStatus_PLAYING
* : or AudioPlayStatus_PAUSED.
* Output : None
* Return : AudioPlayStatus value.
*******************************************************************************/
u32 SetVar_AudioPlayStatus(u32 Status)
{
AudioPlayStatus = (u32)Status;
return AudioPlayStatus;
}
/*******************************************************************************
* Function Name : GetVar_AudioReplay
* Description : returns AudioReplay variable value.
* Input : None
* Output : None
* Return : AudioReplay value.
*******************************************************************************/
u32 GetVar_AudioReplay(void)
{
return AudioReplay;
}
/*******************************************************************************
* Function Name : SetVar_AudioReplay
* Description : Decrement the AudioReplayCount variable if AudioReplay is different
* : from zero (infinite replaying).
* Input : None.
* Output : None
* Return : AudioPlayStatus value.
*******************************************************************************/
void Decrement_AudioReplay(void)
{
if (AudioReplay != 0)
{
AudioReplayCount--;
if (AudioReplayCount == 0)
{
/* Command the Stop of the audio playing */
SetVar_AudioPlayStatus(AudioPlayStatus_STOPPED);
/* Reset the counter */
AudioReplayCount = AudioReplay;
}
}
}
/*******************************************************************************
* Function Name : GetVar_CurrentOutputDevice
* Description : Get the current output device selected .
* Input : None
* Output : None
* Return : None
*******************************************************************************/
u32 GetVar_CurrentOutputDevice(void)
{
return CurrentOutputDevice;
}
/*******************************************************************************
* Function Name : GetVar_AudioDataLength
* Description : Get the current audio file data length .
* Input : None
* Output : None
* Return : None
*******************************************************************************/
u32 GetVar_AudioDataLength(void)
{
return AudioDataLength;
}
/*******************************************************************************
* Function Name : GetVar_i2saudiofreq
* Description : Get the current audio frequency .
* Input : None
* Output : None
* Return : None
*******************************************************************************/
u16 GetVar_i2saudiofreq(void)
{
return i2saudiofreq;
}
/*******************************************************************************
* Function Name : AudioFile_Init
* Description : Initializes the SPI_Flsh and returns the Wavadatalength variable.
* Input : None
* Output : None
* Return : - The length of the wave file read from the SPI_Flash
* - 1 if an error occured when initializing the memory.
* - 2 if an error occured on the audio file intialization.
*******************************************************************************/
u32 AudioFile_Init(void)
{
u32 err = 0;
/* Initialize the media support */
err = Media_Init();
/* Check if Memory initialization is OK */
if (err != 0)
{
return 1;
}
/* Read a Byte buffer and store it in the Header table*/
Media_BufferRead(AudioFileHeader, AudioFileAddress, HEADER_SIZE);
/* Read and check the audio file Header */
WaveFileStatus = I2S_CODEC_WaveParsing(AudioFileHeader);
/* Check if the selected file is a correct wave file */
if (WaveFileStatus == Valid_WAVE_File)
{
/* Read and set the audio data length (/!\ data are counted as BYTES /!\) */
AudioDataLength = WAVE_Format.DataSize ;
/* Read and set the audio frequency */
i2saudiofreq = (u16)WAVE_Format.SampleRate;
/* Return the audio file length */
return AudioDataLength;
}
else /* Wrong wave file */
{
return 2;
}
}
/*******************************************************************************
* Function Name : NVIC_Config
* Description : Configure the I2Ss NVIC channel.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
static void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* SPI2 IRQ Channel configuration */
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* Function Name : GPIO_Config
* Description : Initializes the GPIO pins used by the codec application.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void I2S_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOB, GPIOC and AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOG |
RCC_APB2Periph_GPIOF | RCC_APB2Periph_AFIO, ENABLE);
/* I2S2 SD, CK and WS pins configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* I2S2 MCK pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* LEDs pins configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOF, &GPIO_InitStructure);
/* I2C1 SCL PB6 and SDA PB7 pins configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable the I2C1 APB1 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Turn Off All LEDs */
GPIO_ResetBits(GPIOF, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);
GPIO_ResetBits(Codec_PDN_GPIO, Codec_PDN_Pin);
/* Configure the Codec PDN pin as output PushPull */
GPIO_InitStructure.GPIO_Pin = Codec_PDN_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(Codec_PDN_GPIO, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : I2S_Config
* Description : Configure the I2S Peripheral.
* Input : - Standard: I2S_Standard_Phillips, I2S_Standard_MSB or I2S_Standard_LSB
* - MCLKOutput: I2S_MCLKOutput_Enable or I2S_MCLKOutput_Disable
* - AudioFreq: I2S_AudioFreq_8K, I2S_AudioFreq_16K, I2S_AudioFreq_22K,
* I2S_AudioFreq_44K or I2S_AudioFreq_48K
* Output : None
* Return : None
*******************************************************************************/
void I2S_Config(u16 Standard, u16 MCLKOutput, u16 AudioFreq)
{
I2S_InitTypeDef I2S_InitStructure;
/* Enable I2S2 APB1 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/* Deinitialize SPI2 peripheral */
SPI_I2S_DeInit(SPI2);
/* I2S2 peripheral configuration */
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
I2S_InitStructure.I2S_Standard = Standard;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitStructure.I2S_MCLKOutput = MCLKOutput;
I2S_InitStructure.I2S_AudioFreq = AudioFreq;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_Init(SPI2, &I2S_InitStructure);
/* Disable the I2S2 TXE Interrupt */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
/* Enable the SPI2/I2S2 peripheral */
I2S_Cmd(SPI2, ENABLE);
}
/*******************************************************************************
* Function Name : I2C_Config
* Description : Configure the I2C1 Peripheral.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
static void I2C_Config(void)
{
I2C_InitTypeDef I2C_InitStructure;
/* I2C1 configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x33;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 200000;
I2C_Init(I2C1, &I2C_InitStructure);
}
/*******************************************************************************
* Function Name : CODEC_Config
* Description : Configure the Codec in Headphone mode.
* Input : - OutputDevice: OutputDeviceHEADPHONE or OutputDeviceSPEAKER
* : - I2S_Standard: I2S communication standard could be I2S_Standard_Phillips
* : I2S_Standard_MSB or I2S_Standard_LSB.
* : - I2S_MCLKOutput: could be I2S_MCLKOutput_
* : - Volume:
* Output : None
* Return : 0-> correct communication, else wrong communication
*******************************************************************************/
u32 CODEC_Config(u16 OutputDevice, u16 I2S_Standard, u16 I2S_MCLKOutput, u8 Volume)
{
u32 Standard = 0, counter = 0, PLLMode = 0;
/* Command the sending of dummy data */
ResetVar_SendDummyData();
/* Reset the Codec Registers */
I2S_CODEC_Reset();
/* Determine the I2S standard used */
switch (I2S_Standard)
{
case I2S_Standard_Phillips:
Standard = 0x03;
break;
case I2S_Standard_MSB:
Standard = 0x02;
break;
default :
Standard = 0x01;
break;
}
/* HEADPHONE codec configuration */
if ((OutputDevice & OutputDevice_HEADPHONE) != 0)
{
/* PLL Slave SD/WS reference mode ----------------------*/
if (I2S_MCLKOutput == I2S_MCLKOutput_Disable)
{
/* set the PLLMode variable */
PLLMode = 0x1;
/* Phillips(0x03)/MSB(0x02)/LSB(0x01) mode with PLL */
counter += CODEC_WriteRegister(0x04, (Standard | 0x20));
/* MCKI input frequency = 256.Fs */
counter += CODEC_WriteRegister(0x05, 0x03);
/* VCOM Power up (PMVCM bit)*/
counter += CODEC_WriteRegister(0x00, 0x40);
/* Enable PLL*/
counter += CODEC_WriteRegister(0x01, 0x01);
}
/* Ext Slave mode with no PLL --------------------------*/
else
{
/* Reset the PLL mode variable */
PLLMode = 0;
/* Phillips(0x03)/MSB(0x02)/LSB(0x01) mode with no PLL */
counter += CODEC_WriteRegister(0x04, Standard);
/* MCKI input frequency = 256.Fs */
counter += CODEC_WriteRegister(0x05, 0x00);
/* VCOM Power up (PMVCM bit)*/
counter += CODEC_WriteRegister(0x00, 0x40);
}
/* Command the sending of dummy data */
SetVar_SendDummyData();
/* Enable the I2S2 TXE Interrupt => Generate the clocks*/
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
/* Extra Configuration (of the ALC) */
counter += CODEC_WriteRegister(0x06, 0x3C );
counter += CODEC_WriteRegister(0x08, 0xE1 );
counter += CODEC_WriteRegister(0x0B, 0x00 );
counter += CODEC_WriteRegister(0x07, 0x20 );
counter += CODEC_WriteRegister(0x09, 0xC1 );
counter += CODEC_WriteRegister(0x0C, 0xC1 );
/* MCKI is 256.Fs with no PLL */
counter += CODEC_WriteRegister(0x05, 0x00 );
/* Switch control from DAC to Headphone */
counter += CODEC_WriteRegister(0x0F, 0x09 );
/* Bass Boost and Demphasis enable */
counter += CODEC_WriteRegister(0x0E, 0x18 );
/* Left Channel Digital Volume control */
counter += CODEC_WriteRegister(0x0A, Volume);
/* Right Channel Digital Volume control */
counter += CODEC_WriteRegister(0x0D, Volume);
/* Power up MIN and DAC (PMMIN and PMDAC bits)*/
counter += CODEC_WriteRegister(0x00, 0x74);
/* Enable Slave mode and Left/Right HP lines*/
counter += CODEC_WriteRegister(0x01, (0x30 | PLLMode));
/* Exit HP mute mode */
counter += CODEC_WriteRegister(0x01, (0x70 | PLLMode));
}
/* SPEAKER codec configuration */
if ((OutputDevice & OutputDevice_SPEAKER) != 0)
{
/* PLL Slave SD/WS reference mode ----------------------*/
if (I2S_MCLKOutput == I2S_MCLKOutput_Disable)
{
/* Phillips(0x03)/MSB(0x02)/LSB(0x01) mode with no PLL */
counter += CODEC_WriteRegister(0x04, (Standard | 0x20));
/* MCKI input frequency = 256.Fs */
counter += CODEC_WriteRegister(0x05, 0x03);
/* VCOM Power up (PMVCM bit)*/
counter += CODEC_WriteRegister(0x00, 0x40);
/* Enable PLL*/
counter += CODEC_WriteRegister(0x01, 0x01);
}
/* Ext Slave mode with no PLL --------------------------*/
else
{
/* Phillips(0x03)/MSB(0x02)/LSB(0x01) mode with no PLL */
counter += CODEC_WriteRegister(0x04, Standard);
/* MCKI input frequency = 256.Fs */
counter += CODEC_WriteRegister(0x05, 0x00);
/* VCOM Power up (PMVCM bit)*/
counter += CODEC_WriteRegister(0x00, 0x40);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -