📄 wm8753.c
字号:
_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 == 1)
{
_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 == 2)
{
_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(0xf1, 0); //111,100,01 : DATA0, MIC Amplifier Gain 21dB, input channel 1 select (input channel 2 off)
}
}
void InitWM8753L(int mode)
{
}
void SetOutputGain (DWORD dwGain)
{
DWORD m_dwOutputGain;
m_dwOutputGain = dwGain & 0xffff; // save off so we can return this from GetGain - but only MONO
// convert 16-bit gain to 5-bit attenuation
UCHAR ucGain;
USHORT reg;
unsigned int left, right;
if (m_dwOutputGain == 0) {
ucGain = 0x0000; // mute: set maximum attenuation
}
right = ((ucGain >> 8) & 0xff) ;
left = (ucGain & 0xff) ;
if (right > 100)
right = 0xff;
if (left > 100)
left = 0xff;
//set LDAC & RDAC Volume output
/* WM8753_LDAC :R8 (8h) Left Channel Digital Volume
Left Volume DAC update
8 LDVU 0 store LDACVOL in intermediate latch(no gain change)
1 Update left and right channel gains(left=LDACVOL, right=intermediate latch)
LDACVOL :Left DAC Digital Volume Control
7:0 LDACVOL 00000000 Digital Mute
00000001 -127DB
...... 0.5DB steps up to
11111111 0DB
*/
reg = wm8753_read_reg_cache(WM8753_LDAC) & 0x100;
wm8753_i2c_write(0x34, WM8753_LDAC, reg | left);
/* WM8753_RDAC :R8 (8h) right Channel Digital Volume
right Volume DAC update
8 RDVU 0 store RDACVOL in intermediate latch(no gain change)
1 Update left and right channel gains(right=RDACVOL, left=intermediate latch)
LDACVOL :Left DAC Digital Volume Control
7:0 RDACVOL 00000000 Digital Mute
00000001 -127DB
...... 0.5DB steps up to
11111111 0DB
*/
reg = wm8753_read_reg_cache(WM8753_RDAC) & 0x100;
wm8753_i2c_write(0x34, WM8753_RDAC, reg | right);
//ses out volume
reg = wm8753_read_reg_cache(WM8753_LOUT1V) & 0x180;
/* WM8753_LOUT1V :R40 (28h) LOUT1 Volume
left Volume update
8 LO1VU 0 store LOUT1VOL in intermediate latch(no gain change)
1 Update left and right channel gains(left=LOUT1VOL, right=intermediate latch)
LO1ZC :Left zero cross enable
7 LO1ZC 0 change gain immediately
1 change gain on zero cross only
LOUT1 Volume
6:0 LOUT1VOL 0101111- 0000000 Analogue Mute
0110000 -73DB
...... 1.0DB steps up to
1111111 +6DB
*/
wm8753_i2c_write(0x34, WM8753_LOUT1V, reg | left);
reg = wm8753_read_reg_cache(WM8753_ROUT1V) & 0x180;
/* WM8753_ROUT1V :R41 (29h) ROUT1 Volume
rightVolume update
8 RO1VU 0 store ROUT1VOL in intermediate latch(no gain change)
1 Update left and right channel gains(right=LOUT1VOL, left=intermediate latch)
RO1ZC :Left zero cross enable
7 RO1ZC 0 change gain immediately
1 change gain on zero cross only
ROUT1 Volume
6:0 ROUT1VOL 0101111- 0000000 Analogue Mute
0110000 -73DB
...... 1.0DB steps up to
1111111 +6DB
*/
wm8753_i2c_write(0x34, WM8753_ROUT1V, reg | right);
return;
}
void _WrL3Addr(U8 data)
{
S32 i,j;
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | L3C; //L3D=L, L3M=L(in address mode), L3C=H
for(j=0;j<4;j++); //tsu(L3) > 190ns
//GPB[4:2]=L3C:L3D:L3M
for(i=0;i<8;i++) //LSB first
{
if(data & 0x1) //If data's LSB is 'H'
{
rGPBDAT &= ~L3C; //L3C=L
rGPBDAT |= L3D; //L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPBDAT |= L3C; //L3C=H
rGPBDAT |= L3D; //L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
else //If data's LSB is 'L'
{
rGPBDAT &= ~L3C; //L3C=L
rGPBDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPBDAT |= L3C; //L3C=H
rGPBDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
data >>= 1;
}
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | (L3C | L3M); //L3M=H,L3C=H
}
void _WrL3Data(U8 data,int halt)
{
S32 i,j;
if(halt)
{
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | L3C; //L3C=H(while tstp, L3 interface halt condition)
for(j=0;j<4;j++); //tstp(L3) > 190ns
}
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | (L3C | L3M); //L3M=H(in data transfer mode)
for(j=0;j<4;j++); //tsu(L3)D > 190ns
//GPB[4:2]=L3C:L3D:L3M
for(i=0;i<8;i++)
{
if(data & 0x1) //if data's LSB is 'H'
{
rGPBDAT &= ~L3C; //L3C=L
rGPBDAT |= L3D; //L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPBDAT |= (L3C | L3D); //L3C=H,L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
else //If data's LSB is 'L'
{
rGPBDAT &= ~L3C; //L3C=L
rGPBDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPBDAT |= L3C; //L3C=H
rGPBDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
data >>= 1; //For check next bit
}
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | (L3C | L3M); //L3M=H,L3C=H
}
/* ISRs */
void __irq DMA1_Rec_Done(void)
{
ClearPending(BIT_DMA1); //Clear pending bit
Rec_Done = 1;
}
void __irq DMA2_Done(void)
{
rIISCON &= ~(1<<0);
rIISCON |= 0x1;
ClearPending(BIT_DMA2); //Clear pending bit
Uart_Printf("\n~~~");
//Uart_Printf("\nrIISMOD=0x%x\n",rIISMOD);
}
void __irq RxInt(void)
{
rSUBSRCPND = BIT_SUB_RXD1; //Clear pending bit (Requested)
rSUBSRCPND;
ClearPending(BIT_UART1);
*_temp ++= RdURXH1();
}
void __irq Muting(void)
{
ClearPending(BIT_EINT0); //Clear pending bit
if(mute) //Mute
{
wm8753_i2c_write(0x34, WM8753_LOUTM1, 0x0);
wm8753_i2c_write(0x34, WM8753_ROUTM1, 0x0);
mute = 0;
Uart_Printf("\nMute on...\n");
}
else //No mute
{
wm8753_i2c_write(0x34, WM8753_LOUTM1, 0x180);
wm8753_i2c_write(0x34, WM8753_ROUTM1, 0x180);
mute = 1;
Uart_Printf("\nMute off...\n");
}
}
//===========================================================
//
// virtual IIC Operations
//==================================================
void SDA_pin_out(void)
{ rGPBCON = (rGPBCON & ~(3<<6)) | 01<<6;
}
void SDA_pin_in(void)
{ rGPBCON = (rGPBCON & ~(3<<6)) | 00<<6;
}
void Delay4us(void)
{
int i=0;
//int j=0;
for(i=0;i<4;i++)
{
// j++;
}
}
U8 i2c_Start(void)
{ //SDA_pin_out();
// SCL_pin_out();
Set_i2c_SDA();
Delay4us();
Set_i2c_SCL();
Delay4us();
if (i2c_SDALo() || i2c_SCLLo())
return FALSE;
Clr_i2c_SDA();
Delay4us();
Clr_i2c_SCL();
return TRUE;
}
//=============================================
// Setup i2c Stop condition
void i2c_Stop(void)
{ // SCL=L, SDA=L, Stop condition.
Clr_i2c_SCL();
Delay4us();
Clr_i2c_SDA();
Delay4us();
Set_i2c_SCL();
Delay4us();
Set_i2c_SDA();
//Delay4us();
}
//============================================
U8 i2c_SendByte(U8 value, int direction)
{
int i;
U8 result;
//int a;
//BYTE BIT71=0x80;
for (i=7; i>=0; i--) // Send data via i2c pin
{
if ((value) & 0x80)
Set_i2c_SDA();
else
Clr_i2c_SDA();
Delay4us();
Set_i2c_SCL();
Delay4us();
value<<=1;
Clr_i2c_SCL();
}
//Set_i2c_SDA();
SDA_pin_in();
Delay4us();
Set_i2c_SCL();
if(i2c_SDALo()) //check ack
result=TRUE;
else
result=FALSE;
Delay4us();
Clr_i2c_SCL();
// Delay4us();
SDA_pin_out();
Clr_i2c_SDA();
return result;
}
//============================================
U8 i2c_ReceiveByte(const U8 ack)
{
U8 i;
U8 value=0;
for (i=0; i<8; i++)
{ value<<=1; //移位
SDA_pin_in();
Set_i2c_SCL();
Delay4us();
if (i2c_SDAHi())
value|=BIT0;
Clr_i2c_SCL();
}
SDA_pin_out();
if (ack)
Clr_i2c_SDA();
else
Set_i2c_SDA();
Delay4us();
Set_i2c_SCL();
Delay4us();
Clr_i2c_SCL();
return value;
}
U8 i2c_BurstWrite(U8 count, U8 *buffer)
{
U8 i = 0;
if(i2c_Start()==FALSE)
return FALSE;
// continue;
while (count--)
{
if (i2c_SendByte(*(buffer++), 0)==FALSE)
{
Uart_Printf("Failure to write the byte!\n");
return FALSE;
}
}
i2c_Stop();
for(i=0;i<100;i++)
Delay4us();
Uart_Printf("Successful to write the byte!\n");
return TRUE;
}
U8 i2c_BurstRead(U8 count, U8 * buffer)
{
U8 i;
for (i=0; i<count-1; i++)
*(buffer+i)=i2c_ReceiveByte(1);
*(buffer+i)=i2c_ReceiveByte(0);
i2c_Stop();
return TRUE;
}
//send start signal and slaveaddr
U8 i2c_MasterStart(I2C_Direction direct, U8 addr)
{
int i,retry=5;
int result;
while (retry--)
{
if(i2c_Start()==FALSE)
continue;
if (i2c_SendByte(addr, 0)==TRUE) // send address success
return TRUE;
// i2c_Stop();
// for(i=0;i<100;i++)
// Delay4us();
}
return FALSE;
}
int wm8753_i2c_write(unsigned char addr, unsigned char buffer1, unsigned short buffer2)
{
// int retry=5;
int i;
unsigned char slaveAddr=0x34;
unsigned char val1 = (unsigned short)buffer1<<1 | (buffer2>>8 & 0x01);
unsigned char val2 = buffer2 & 0xFF;
// rGPBDAT |= 1<<2;
if (i2c_MasterStart(I2C_WRITE, slaveAddr)==FALSE)
return 1;
if (i2c_SendByte(val1, 0)==FALSE)
return 2;
if (i2c_SendByte(val2, 0)==FALSE)
return 3;
i2c_Stop();
for(i=0; i< 100; i++)
Delay4us();
return 0;
}
//===================================
//Play Wave File
void Radio_IIS(void)
{
int i;
int ret = 0;
Uart_Printf("\nPlay Wave File.\n");
// char *wavefile = "denglu.wav";
// for(i=0; i<600*1024; i++){
// wav[i] = (unsigned short )((rand() % 100) * i);
// }
IIS_Port_Init();
Select_IIS_Master_CLK();
// Download_Wave_File();
// Open_Wave_File(wavefile);
// Init1341(PLAY_IIS);
if ((ret = wm8753_init()) != 0) {
Uart_Printf("can't initialise WM8753 \n");
return;
}
/*
// IIS_PlayWave_DMA2(Buf+0x30, size);
IIS_PlayWave_DMA2((unsigned char *)(0x31000000), 155760);
IIS_Port_Return();
mute = 1;
return;
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -