⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2s_codec.c

📁 stm32.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
	  }
  }
}

/*******************************************************************************
* 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  : I2S_GPIO_Config
* Description    : Initializes the GPIO pins used by the codec application.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
static 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
*******************************************************************************/
static 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 );
		
    /* Uncomment these lines and set the correct filters values to use the 
        codec digital filters (for more details refer to the codec datasheet) */
		//  /* Filter 1 programming as High Pass filter (Fc=500Hz, Fs=8KHz, K=20, A=1, B=1) */
		//  counter += CODEC_WriteRegister(0x1C, 0x01);
		//  counter += CODEC_WriteRegister(0x1D, 0x80);
		//  counter += CODEC_WriteRegister(0x1E, 0xA0);
		//  counter += CODEC_WriteRegister(0x1F, 0x0B);
		
		//  /* Filter 3 programming as Low Pass filter (Fc=20KHz, Fs=8KHz, K=40, A=1, B=1) */
		//  counter += CODEC_WriteRegister(0x1C, 0x01);
		//  counter += CODEC_WriteRegister(0x1D, 0x00);
		//  counter += CODEC_WriteRegister(0x1E, 0x01);
		//  counter += CODEC_WriteRegister(0x1F, 0x01);
		
		//  /* Equilizer programming BP filter (Fc1=20Hz, Fc2=2.5KHz, Fs=44.1KHz, K=40, A=?, B=?, C=?) */
		//  counter += CODEC_WriteRegister(0x16, 0x00);
		//  counter += CODEC_WriteRegister(0x17, 0x75);
		//  counter += CODEC_WriteRegister(0x18, 0x00);
		//  counter += CODEC_WriteRegister(0x19, 0x01);
		//  counter += CODEC_WriteRegister(0x1A, 0x00);
		//  counter += CODEC_WriteRegister(0x1B, 0x51);
		
		/* 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);
		}
	
	  /* 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);
	  
	  /* ReSelect the MCKI frequency (FS0-1 bits): 256.Fs */
	  counter += CODEC_WriteRegister(0x05, 0x02 );
	  /* Set up the path "DAC->Speaker-Amp" with no power save (DACS and SPPSN bits) */ 
	  counter += CODEC_WriteRegister(0x02, 0x20 );
	  /* Speaker Gain (SPKG0-1 bits): Gain=+10.65dB(ALC off)/+12.65(ALC on) */
	  counter += CODEC_WriteRegister(0x03, 0x10);
	
	  /* 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, 0x91 );
	  counter += CODEC_WriteRegister(0x0C, 0x91 );
	
	  /* Left Channel Digital Volume control */
	  counter += CODEC_WriteRegister(0x0A, Volume);  
	  /* Right Channel Digital Volume control */
	  counter += CODEC_WriteRegister(0x0D, Volume);
	  /* Power up Speaker and DAC (PMSPK and PMDAC bits)*/
	  counter += CODEC_WriteRegister(0x00, 0x54);
	  /* Set up the path "DAC -> Speaker-Amp" with no power save */ 
	  counter += CODEC_WriteRegister(0x02, 0xA0 /*0xA1*/);   
  }

  /* Disable the I2S2 TXE Interrupt */ 
  SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
  
	/* Disable the sending of Dummy data */
	ResetVar_SendDummyData();

  /* Return the counter value */
	return counter;
}

/*******************************************************************************
* Function Name  : CODEC_WriteRegister
* Description    : Writes a value in a register of the audio Codec through I2C.
* Input          :  - RegisterAddr: The target register adress (between 00x and 0x24)
*                :  - RegisterValue: The target register value to be written 
*                :  - Verify: 0-> Don't verify the written data, 1-> Verify the written data
* Output         : None
* Return         : - 0  -> Correct write operation
*                : - !0 -> Incorrect write operation
*******************************************************************************/
u32 CODEC_WriteRegister(u32 RegisterAddr, u32 RegisterValue)
{
	u32 read_verif = 0;
  
	/* Reset all I2C2 registers */       
  I2C_SoftwareResetCmd(I2C1, ENABLE);
  I2C_SoftwareResetCmd(I2C1, DISABLE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -