?? codecs.c
字號(hào):
/******************************************************************************
*
* Purpose: CODEC Functions
*
* Comment: Type of codec can be set with the defines : CODEC_PCM3002 or
* CODEC_WM8731
* USE_DUAL_CODEC : if this define is set the interface B will also
* be enabled.
* VOLUME_DARR and VOLUME_CODEC defines if the volume on mu is
* control using the codec or using the DARR79 volume registers.
*
* Creator: Rob Lansbergen
*
* Version: $Revision: 9 $
*
* File Name: $Workfile: codecs.c $
*
* Author: Rob Lansbergen
*
* Check in: $Author: Chong.cheeleong $
*
* The information is provided 揳s is?without any express or implied warranty
* of any kind, * including warranties of merchantability, noninfringement of
* intellectual property, or fitness for any particular purpose. In no event sha
* Wireless Sound Solutions and/or its affiliate companies, or its suppliers be
* liable for any damages whatsoever arising out of the use of or inability to
* use the information or the materials. Wireless Sound Solutions, its affiliate
* companies, and its suppliers further do not warrant the accuracy or
* completeness of information, text, graphics, or other items contained within
* materials. Wireless Sound Solutions, Inc., may make changes to materials, or
* the products described within, at any time, without notice.
* ?007 Wireless Sound Solutions. All rights reserved. Wireless Sound Solutions
* STS and STS-wireless are trademarks of Wireless Sound Solutions.
******************************************************************************/
#include "defines.h"
unsigned char Wolfson_Slave_Address;
unsigned char Wireless_Codec_Select;
unsigned char prev_Sync_Stat = 0;
/* Local function declarations */
unsigned char Config_Codec_PCM3002 (void);
unsigned char Config_Codec_WM8731 (void);
unsigned char Config_Codec_CS4251 (void);
unsigned char ConfigCodecSingle_WM8731(unsigned char Codec_A_B);
unsigned char Config_Codec_CS4341 (void);
void Set_PCM3003 (unsigned char address, int data);
unsigned char Set_WM8731 (unsigned char address, int data);
unsigned char Set_CS4251 (unsigned char address, int data);
unsigned char Set_CS4341 (unsigned char address, int data);
void SetInVolume_PCM3002 (unsigned char Left_Right, unsigned char Volume);
void SetInVolume_WM8731 (unsigned char Left_Right, unsigned char Volume);
void SetInVolume_CS4251 (unsigned char Left_Right, unsigned char Volume);
void SetInVolume_CS4341 (unsigned char Left_Right, unsigned char Volume);
void SetVolume_PCM3002 (unsigned char Left_Right, unsigned char Volume);
void SetVolume_WM8731 (unsigned char Left_Right, unsigned char Volume);
void SetVolume_DARR80 (unsigned char Left_Right, unsigned char Volume);
void SetVolume_CS4251 (unsigned char Left_Right, unsigned char Volume);
void SetVolume_CS4341 (unsigned char Left_Right, unsigned char Volume);
extern char key_state;
/******************************************************************************
*
* Function Name : Config Codec
*
* Purpose : Config the codec to I2S 48 Khz
*
* Return value : none
*
******************************************************************************/
unsigned char Config_Codec(void)
{
#ifdef CODEC_PCM3002
return(Config_Codec_PCM3002());
#endif
#ifdef CODEC_WM8731
return(Config_Codec_WM8731());
#endif
#ifdef CODEC_CS5341_WM8728
return(0);
#endif
#ifdef CODEC_CS5368
return(0);
#endif
#ifdef CODEC_CS4251
return(Config_Codec_CS4251());
#endif
#ifdef CODEC_CS4341
return(Config_Codec_CS4341());
#endif
}
/******************************************************************************
*
* Function Name : SetVolume
*
* Purpose : Set Volume
*
* arguments : Left_Right
* 0 is Left
* 1 is Right
* Volume is a value from 0 to 0xFF
* Return value : none
*
******************************************************************************/
void SetVolume(unsigned char Left_Right, unsigned char Volume)
{
#ifdef VOLUME_DARR
SetVolume_DARR80(Left_Right, Volume);
#endif
#ifdef CODEC_PCM3002
#ifdef VOLUME_CODEC
SetVolume_PCM3002(Left_Right, Volume);
#endif
#endif
#ifdef CODEC_WM8731
#ifdef VOLUME_CODEC
SetVolume_WM8731(Left_Right, Volume);
#endif
#endif
#ifdef CODEC_CS5341_WM8728
#endif
#ifdef CODEC_CS5368
#endif
#ifdef CODEC_WM8731
#ifdef VOLUME_CODEC
SetVolume_CS4251(Left_Right, Volume);
#endif
#endif
#ifdef CODEC_CS4251
#ifdef VOLUME_CODEC
SetVolume_CS4251(Left_Right, Volume);
#endif
#endif
#ifdef CODEC_CS4341
#ifdef VOLUME_CODEC
SetVolume_CS4341(Left_Right, 0x00);
#endif
#endif
}
/******************************************************************************
*
* Function Name : SetInVolume
*
* Purpose : Set Volume
*
* arguments : Left_Right
* 0 is Left
* 1 is Right
* Volume is a value from 0 to 0xff
* Return value : none
*
******************************************************************************/
void SetInVolume(unsigned char Left_Right, unsigned char Volume)
{
#ifdef CODEC_PCM3002
SetInVolume_PCM3002(Left_Right, Volume);
#endif
#ifdef CODEC_WM8731
SetInVolume_WM8731(Left_Right, Volume);
#endif
#ifdef CODEC_CS5341_WM8728
#endif
#ifdef CODEC_CS5368
#endif
#ifdef CODEC_CS4251
SetInVolume_CS4251(Left_Right, Volume);
#endif
#ifdef CODEC_CS4341
SetInVolume_CS4341(Left_Right, 0x00);
#endif
}
//==============================================================================================
/*********************/
/*** CODEC_PCM3002 ***/
/*********************/
void Set_PCM3003 (unsigned char address, int data)
{
#ifdef CODEC_PCM3002
unsigned char i;
unsigned int tmp16;
tmp16 = ((address & 0x03) << 9) + (data & 0x1FF); /* set Registers Address */
PCM_ML_HIGH;
PCM_MC_HIGH;
PCM_ML_LOW;
for (i = 0; i < 16; i++)
{
PCM_MC_LOW;
if (tmp16 & 0x8000) {PCM_MD_HIGH;}
else {PCM_MD_LOW;}
tmp16 = tmp16 << 1;
PCM_MC_HIGH;
}
PCM_MC_LOW;
PCM_ML_HIGH;
#endif
}
void SetInVolume_PCM3002(unsigned char Left_Right, unsigned char Volume)
{
//Set_PCM3003(Left_Right & 0x01, Volume | 0x100);
}
void SetVolume_PCM3002(unsigned char Left_Right, unsigned char Volume)
{
//Set_PCM3003(Left_Right & 0x01, Volume | 0x100);
}
unsigned char Config_Codec_PCM3002(void)
{
#ifdef CODEC_PCM3002
RESET_CODEC_OFF;
if (Use_ModuleMode == MU)
Set_PCM3003(2, 0x100 | 2);
else
Set_PCM3003(2, 0x40 | 2);
Set_PCM3003(0x03, 0x0000E); /* Set to I2S */
//Set_PCM3003(0x00, 0x100 | START_UP_VOLUME);
//Set_PCM3003(0x01, 0x100 | START_UP_VOLUME);
#endif
return (0);
}
//==============================================================================================
/********************/
/*** CODEC_WM8731 ***/
/********************/
unsigned char Set_WM8731 (unsigned char address, int data)
{
unsigned char I2C_error = 0;
/* Warning, disable unit before configuring */
/* Wolfson register map */
/* address part 7 bits */
/* data part 9 bits */
/* i2c_map = 7 bits address + MSB bit of Wolfson data */
/* i2c_data = lower 8 bits of Wolfson data */
if (Wireless_Codec_Select == 0)
{
i2cSlaveAddress = Wolfson_Slave_Address; /* Address of Wolfson */
I2C_error = I2C_Write_Byte((address << 1) + ((data >> 8) & 0x01), data & 0xFF);
/* switch back to org i2c slave address */
i2cSlaveAddress = I2C_SLAVE_ADDRESS;
}
else /* codec on MU side is programm by CU using the wireless I2C mechanism */
{
TX_Data_send_array[0] = MSG_TYPE_WRITE_WITHOUT_ACK + 4;
TX_Data_send_array[1] = IMSL_ADDR;
TX_Data_send_array[2] = Wolfson_Slave_Address; // Slave Address
TX_Data_send_array[3] = (address << 1) + ((data >> 8) & 0x01);
TX_Data_send_array[4] = 1; // Amount of I2C Words
TX_Data_send_array[5] = data & 0xff;
Send_Message(STR_A, 2049); /* Magic number!!! */
}
return (I2C_error);
}
void SetInVolume_WM8731(unsigned char Left_Right, unsigned char Volume)
{
if ((Left_Right == 0x00) || (Left_Right == 0x01))
{
Wolfson_Slave_Address = 0x34;
Set_WM8731(0x00 + (Left_Right), Volume >> 3); /* volume is 8->5 bit */
}
#ifdef USE_DUAL_CODEC
else /* 0x02 & 0x03 stript down to 0x00 and 0x01 */
{
Wolfson_Slave_Address = 0x36; /* Codec B */
Set_WM8731(0x00 + (Left_Right & 0x01), Volume >> 3); /* volume is 8->5 bit */
Wolfson_Slave_Address = 0x34;
}
#endif /* USE_DUAL_CODEC */
}
void SetVolume_WM8731(unsigned char Left_Right, unsigned char Volume)
{
if ((Left_Right == 0x00) || (Left_Right == 0x01))
{
Wolfson_Slave_Address = 0x34;
Set_WM8731(0x02 + (Left_Right & 0x01), Volume >> 1); /* volume is 8->7 bit */
}
#ifdef USE_DUAL_CODEC
else
{
Wolfson_Slave_Address = 0x36; /* Codec B */
Set_WM8731(0x02 + (Left_Right & 0x01), Volume >> 1); /* volume is 8->7 bit */
Wolfson_Slave_Address = 0x34;
}
#endif /* END USE_DUAL_CODEC */
}
unsigned char Config_Codec_WM8731(void)
{
unsigned char I2C_error = 0;
I2C_error = ConfigCodecSingle_WM8731(0); /* Inteface A */
#ifdef USE_DUAL_CODEC
I2C_error = ConfigCodecSingle_WM8731(1); /* Inteface B */
#endif
#ifdef VOLUME_DARR
/* set darr to start-up volume, with IB the max setting is 126 because of clipping signals */
SetVolume_DARR80(0, START_UP_VOLUME);
SetVolume_DARR80(1, START_UP_VOLUME);
SetVolume_DARR80(2, START_UP_VOLUME);
SetVolume_DARR80(3, START_UP_VOLUME);
#endif
return (I2C_error);
}
/* Power down Registers bit address */
#define LINEIN_ON 0x00
#define LINEIN_OFF 0x01
#define MIC_ON 0x00
#define MIC_OFF 0x02
#define ADC_ON 0x00
#define ADC_OFF 0x04
#define DAC_ON 0x00
#define DAC_OFF 0x08
#define LINEOUT_ON 0x00
#define LINEOUT_OFF 0x10
#define OSC_ON 0x00
#define OSC_OFF 0x20
#define CLKOUT_ON 0x00
#define CLKOUT_OFF 0x40
#define POWER_ON 0x00
#define POWER_OFF 0x80
unsigned char ConfigCodecSingle_WM8731(unsigned char Codec_A_B)
{
unsigned char I2C_error = 0;
if (Codec_A_B == 0) Wolfson_Slave_Address = 0x34;
else Wolfson_Slave_Address = 0x36;
I2C_error += Set_WM8731(0, 0x17); /* LinVol Left 17 is 0 db versterking */
I2C_error += Set_WM8731(1, 0x17); /* LinVol Right 17 is 0 db versterking */
I2C_error += Set_WM8731(2, 0x7F); /* HPVol Left */
I2C_error += Set_WM8731(3, 0x7F); /* HPVol Right */
I2C_error += Set_WM8731(4, 0x12); /* Analog audio path control */
I2C_error += Set_WM8731(5, 0x01); /* Digital audio path control */
if (Use_ModuleMode == MU)
{
if (Codec_A_B == 0)
{
#ifdef USE_DUAL_CODEC
I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_ON|MIC_OFF|DAC_ON|ADC_ON|LINEOUT_ON|LINEIN_ON);
#else
I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_OFF|MIC_OFF|DAC_ON|ADC_OFF|LINEOUT_ON|LINEIN_OFF);
#endif
}
if (Codec_A_B != 0)
I2C_error += Set_WM8731(6, OSC_OFF|POWER_ON|CLKOUT_OFF|MIC_OFF|DAC_ON|ADC_ON|LINEOUT_ON);
}
else
{
/* if bit 6 is set the ADC does not work anymore (according to the data sheet this bit should be set. */
/* Keep LINEOUT_ON also on CU because this helps VMID to get to the correct value faster */
if (Codec_A_B == 0)
{
#ifdef USE_DUAL_CODEC
I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_ON|ADC_ON|DAC_ON|LINEOUT_ON);
#else
I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_OFF|ADC_ON|DAC_OFF|LINEOUT_ON|LINEIN_ON);
#endif
}
if (Codec_A_B != 0)
I2C_error += Set_WM8731(6, OSC_OFF|POWER_ON|CLKOUT_OFF|MIC_OFF|DAC_ON|ADC_ON|LINEOUT_ON);
}
if (Codec_A_B == 0) I2C_error += Set_WM8731(7, 0x4A); /* Master */
else I2C_error += Set_WM8731(7, 0x0A); /* Slave */
if (Use_SPDIF) I2C_error += Set_WM8731(8, 0x00); /* codecs are not used, set 12MHz clock undivided to DARR79 */
else
{
#ifdef USE_WM8731_12Mhz
I2C_error += Set_WM8731(8, 0x5D); /* half Sampling control : use USB mode (12MHZ/250=48KHz) */
#else
if (Codec_A_B == 0) I2C_error += Set_WM8731(8, 0x5c); /* half Clock output(Div intclock) */
else I2C_error += Set_WM8731(8, 0x1c); /* receive halve clock but still use 96 kHZ */
#endif
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -