📄 codec.c
字号:
void Init1341(int mode)
{
rGPGDAT = rGPGDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //Start condition : L3M=H, L3C=H
if(mode == PLAY_IIS)
{ //L3 Interface
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
_WrL3Data(0x50,0); //0,1,01, 000,0 : Status 0,Reset, 384fs,IIS-bus,no DC-filtering
// _WrL3Data(0x60,0); //0,1,10, 000,0 : Status 0,Reset, 256fs,IIS-bus,no DC-filtering
// _WrL3Data(0x40,0); //0,1,00, 000,0 : Status 0,Reset, 512fs,IIS-bus,no DC-filtering
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
_WrL3Data(0x81,0); //bit[7:0] => 1,0,0,0, 0,0,01
}
//Record Sound via MIC-In
if(mode == RECORD_MIC_IN)
{
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
_WrL3Data(0xa2,0); //bit[7:0] => 1,0,1,0,0,0,10
_WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(0xc2, 0); //1100 0,010 : Extended addr(3bits), 010
_WrL3Data(0xf2, 0); //111,100,10 : DATA0, MIC Amplifier Gain 21dB, input channel 2 select (input channel 1 off)
}
//Record Sound via Line-In
if(mode == RECORD_LINE_IN)
{
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
_WrL3Data(0xa2,0); //bit[7:0] => 1,0,1,0, 0,0,10 Gain of ADC 6dB, ADC(on) DAC(off)
_WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(0xc2, 0); //1100 0,010 : Extended addr(3bits), 010
_WrL3Data(0xf1, 0); //111,100,01 : DATA0, MIC Amplifier Gain 15dB, input channel 1 select (input channel 2 off)
}
// Record & play simultaneously
if(mode == RECORD_PLAY_SIM)
{
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
_WrL3Data(0xa3,0); // 1,0,1,0,0,0,11 : OGS=0,IGS=1,ADC_NI,DAC_NI,sngl speed,AonDon
_WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(0xc2,0); //11000,010 : DATA0, Extended addr(010)
_WrL3Data(0xff,0); //010,011,01 : DATA0, MS=9dB, Ch1=on Ch2=on
}
}
//WM8580 Audio Codec using I2C 2 wire Interface
void I2SCODEC_SendWmData(unsigned char i2c_addr, unsigned char reg_addr, unsigned short data)
{
unsigned char ucReg_addr, ucData;
ucReg_addr = (reg_addr<<1 | (unsigned char)(data>>8));
ucData = (unsigned char)data;
I2SCODEC_WrSerial(i2c_addr, ucReg_addr, ucData);
}
void I2SCODEC_RecvWmData(unsigned char i2c_addr, unsigned char reg_addr, unsigned char* data)
{
I2SCODEC_RdSerial(i2c_addr, reg_addr, data);
}
//CodecChipFs (ex) 384 means codecclk is 384fs(fs=44100) :
// needed I2S is slave mode, codec is master
bool I2SCODEC_InitWm8580(int OpMode,
int txr, int dataformat, int CodecClkFs, int BitperCh)
{
U32 i,uCalRfs;
U8 x;
U16 uBclkRate, uSamplingFreq, uBitSpl, uPaif3, uPaif1, uPaif2, uPaif4, uI2sFmt;
//IIC_open(200000); // Serial EEPROM IIC clk = 200KHz
IIC_open(10000); // Serial EEPROM IIC clk = 200KHz
if(BitperCh==16 ||BitperCh==8)
uBitSpl=0;
else if(BitperCh==24)
uBitSpl=2;
else
return 0;//assert
if(dataformat==I2S_FORMAT_I2S)
uI2sFmt = 2;
else if(dataformat==I2S_FORMAT_MSB)
uI2sFmt = 1;
else if(dataformat==I2S_FORMAT_LSB)
uI2sFmt = 0;
else
{
IIC_close();
return 0;//assert
}
//codec reset, check interface
{
U8 status1;
I2SCODEC_SendWmData(WM8580_ID_WR, 53, 0x000); // Reset WM8580
#if 0
I2SCODEC_RecvWmData(WM8580_ID_RD, 44, &status1);//channel 1 status register
if( status1 & 0x1)
{
printf("Consumer mode ok.\n");
}
#endif
// I2SCODEC_SendWmData(WM8580_ID_WR, 52, 0x010); //enable readback, cont mode, error status
// printf("i2c test \n");
// getchar();
// I2SCODEC_RdSerial(0x35, 0, &status1);//error status
// printf("device id 1 : %d\n", status1);
// return;
// I2SCODEC_RecvWmData(WM8580_ID_RD, 1, &status1);//device id1
// printf("device id 2 : %d\n", status1);
// I2SCODEC_RecvWmData(WM8580_ID_RD, 2, &status1);//device id1
// printf("device rev : %d\n", status1);
}
uPaif3 = (uBitSpl<<2)|(uI2sFmt<<0);
if(OpMode == I2S_MASTER)
{
/// 1. Master Play Setting
if(txr == I2S_MODE_TX)
{
I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x002); // All Digital running, ADC disable, DAC1,2,3 enable, DACs under control of DACPD[3:0]
I2SCODEC_SendWmData(WM8580_ID_WR, 16, 0x089); // IZD mute detection enable, all dac zero flag on, left=left, right=right
// I2SCODEC_SendWmData(WM8580_ID_WR, 26, 0x0FF); // need for volume setting
// I2SCODEC_SendWmData(WM8580_ID_WR, 27, 0x0FF); // need for volume setting
//I2SCODEC_SendWmData(WM8580_ID_WR, 28, 0x1CF); //volume control
I2SCODEC_SendWmData(WM8580_ID_WR, 28, 0x1FF); //volume control
I2SCODEC_SendWmData(WM8580_ID_WR, 12, (3<<7)|uPaif3); // If Ap is Tx, Wm8580 is Rx,
//dac1 source : paif receiver data, dac oversampling 128x, bclk not inverted, lrclk not inverted, 16~32bit, format(i2s,l,r)
}
/// 2. Master Iine-In Record Setting
else if(txr == I2S_MODE_RX)
{
I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x07c); // PWRDN1, All DACs disable, DAC1,2,3 disabled, ADC enabled, All digital circuit running.
I2SCODEC_SendWmData(WM8580_ID_WR, 8, 0x01c); // DAC clock sourcen MCLK pin
I2SCODEC_SendWmData(WM8580_ID_WR, 13, (1<<7)|uPaif3); // I2S FMT, Bit rate Setting
}
else if(txr == I2S_MODE_TXR)
{
I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x00);
I2SCODEC_SendWmData(WM8580_ID_WR, 26, 0x0FF); // need for volume setting
I2SCODEC_SendWmData(WM8580_ID_WR, 27, 0x0FF); // need for volume setting
I2SCODEC_SendWmData(WM8580_ID_WR, 28, 0x1CF); //volume control
I2SCODEC_SendWmData(WM8580_ID_WR, 8, 0x01c); // DAC clock sourcen MCLK pin
I2SCODEC_SendWmData(WM8580_ID_WR, 12, (3<<7)|uPaif3); // Tx I2S FMT, Bit rate Setting
I2SCODEC_SendWmData(WM8580_ID_WR, 13, (1<<7)|uPaif3); // Rx I2S FMT, Bit rate Setting
}
/// 3. WM8580_mode setting error
else
return 0;//assert
}
else if(OpMode == I2S_SLAVE)
{
if(CodecClkFs == 256) uSamplingFreq=2;//256fs
else if(CodecClkFs == 384) uSamplingFreq=3;
else if(CodecClkFs == 512) uSamplingFreq=4;
else if(CodecClkFs == 768) uSamplingFreq=5;
else
{
printf("codecclkfs setting is not matching : %d\n",CodecClkFs );
return 0;//assert
}
//>bitperch*2>
//ap side bitclk=xfs, cdclk=yfs setting are not needed
if(BitperCh==16)
uBclkRate = 1;//32fs
else if(BitperCh==8)
uBclkRate = 2;//16fs
else if(BitperCh==24)
uBclkRate = 0;//62fs?
else
return 0;//assert
uPaif1 = 0<<7|1<<5|uBclkRate<<3 |uSamplingFreq<<0; // Wm8580 receiver. [5]-1.Master Mode
uPaif2 = 1<<5|uBclkRate<<3 |uSamplingFreq<<0; // Wm8580 transmitter. [5]-1.Master Mode
/// 1. Slave Play Setting
if(txr == I2S_MODE_TX)
{
I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x022); // All Digital running, ADC disable, DAC1,2,3 enable, DACs under control of DACPD[3:0]
I2SCODEC_SendWmData(WM8580_ID_WR, 9 , uPaif1); // slave mode setting
//I2SCODEC_SendWmData(WM8580_ID_WR, 26, 0x0FF); // need for volume setting
//I2SCODEC_SendWmData(WM8580_ID_WR, 27, 0x0FF); // nedd for volume setting
//I2SCODEC_SendWmData(WM8580_ID_WR, 28, 0x1cF); //volume control
I2SCODEC_SendWmData(WM8580_ID_WR, 28, 0x1FF); //volume control
I2SCODEC_SendWmData(WM8580_ID_WR, 12, (3<<7)|uPaif3); // If Ap is Tx, Wm8580 is Rx,
}
/// 2. Slave Iine-In Record Setting
else if(txr == I2S_MODE_RX)
{
I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x07c); //ok, PWRDN1, All DACs disable, DAC1,2,3 disabled, ADC enabled, All digital circuit running.
//I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x020); //ok All Digital running, ADC enable, DAC1,2,3 enable, DACs under control of DACPD[3:0]
//I2SCODEC_SendWmData(WM8580_ID_WR, 8, 0x01c); //not ok DAC clock sourcen MCLK pin
I2SCODEC_SendWmData(WM8580_ID_WR, 10, uPaif2); // In AP, Rx => In Wm8580, PAIFTX, slave mode setting
I2SCODEC_SendWmData(WM8580_ID_WR, 13, (1<<7)|uPaif3); // Rx I2S FMT, Bit rate Setting
/* I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x00);
I2SCODEC_SendWmData(WM8580_ID_WR, 26, 0x0FF); // need for volume setting
I2SCODEC_SendWmData(WM8580_ID_WR, 27, 0x0FF); // need for volume setting
I2SCODEC_SendWmData(WM8580_ID_WR, 28, 0x1bF); //volume control
I2SCODEC_SendWmData(WM8580_ID_WR, 8, 0x01c); // DAC clock sourcen MCLK pin
I2SCODEC_SendWmData(WM8580_ID_WR, 9 , uPaif1); // slave mode setting
I2SCODEC_SendWmData(WM8580_ID_WR, 10, uPaif2); // In AP, Rx => In Wm8580, PAIFTX, slave mode setting
I2SCODEC_SendWmData(WM8580_ID_WR, 12, (3<<7)|uPaif3); // Tx I2S FMT, Bit rate Setting
I2SCODEC_SendWmData(WM8580_ID_WR, 13, (1<<7)|uPaif3); // Rx I2S FMT, Bit rate Setting
*/
}
else if(txr == I2S_MODE_TXR)
{
I2SCODEC_SendWmData(WM8580_ID_WR, 50, 0x00);
I2SCODEC_SendWmData(WM8580_ID_WR, 26, 0x0FF); // need for volume setting
I2SCODEC_SendWmData(WM8580_ID_WR, 27, 0x0FF); // need for volume setting
I2SCODEC_SendWmData(WM8580_ID_WR, 28, 0x1bF); //volume control
I2SCODEC_SendWmData(WM8580_ID_WR, 8, 0x01c); // DAC clock sourcen MCLK pin
I2SCODEC_SendWmData(WM8580_ID_WR, 9 , uPaif1); // slave mode setting
I2SCODEC_SendWmData(WM8580_ID_WR, 10, uPaif2); // In AP, Rx => In Wm8580, PAIFTX, slave mode setting
I2SCODEC_SendWmData(WM8580_ID_WR, 12, (3<<7)|uPaif3); // Tx I2S FMT, Bit rate Setting
I2SCODEC_SendWmData(WM8580_ID_WR, 13, (1<<7)|uPaif3); // Rx I2S FMT, Bit rate Setting
}
/// 3. WM8580_mode setting error
else
return 0;//assert
}
else
return 0;//assert
// SendWmData(19, 0x0ff); //Mute
IIC_close();
return 1;
}
//return SR[4:0] ,
//ClockingMode : 0 - in normal mode 1- USB mode(12Mhz goes to MCLK, in case of AP is slave)
char I2SCODEC_8753SRbit(int CodecClkFs, int SyncClkFreq, int ClockingMode)
{
char SRbit;
//normal mode-ap is master
if(ClockingMode == 0)
{
if(CodecClkFs == 256)
{
SRbit = (SyncClkFreq==44100)? 0x10 :
(SyncClkFreq==48000)? 0x0 : -1;
}
else if(CodecClkFs == 512)
{
SRbit = (SyncClkFreq==22050)? 0x1a :
(SyncClkFreq==24000)? 0x1c : -1;
}
else if(CodecClkFs == 384)
{
SRbit = (SyncClkFreq==44100)? 0x11 :
(SyncClkFreq==48000)? 0x1 : -1;
}
else if(CodecClkFs == 768)
{
SRbit = (SyncClkFreq==22050)? 0x1b :
(SyncClkFreq==24000)? 0x1d : -1;
}
if(SRbit == -1) SRbit = 0x10;//44100, 256fs
}
else
{
SRbit = (SyncClkFreq==8000)? 0x06 :
(SyncClkFreq==11025)? 0x19 ://ok
(SyncClkFreq==12000)? 0x08 :
(SyncClkFreq==16000)? 0x0a :
(SyncClkFreq==22050)? 0x1b ://ok
(SyncClkFreq==24000)? 0x1c ://ok
(SyncClkFreq==32000)? 0x0c ://ok
(SyncClkFreq==44100)? 0x11 ://ok
(SyncClkFreq==48000)? 0x00 ://ok
(SyncClkFreq==88200)? 0x1f ://ok
(SyncClkFreq==96000)? 0x0e : -1;//ok
if(SRbit == -1) SRbit = 0x11;//44100, 272fs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -