📄 audiotest.c
字号:
mclk = ((mdiv+8)*12000000)/((pdiv+2)*val) ;
Uart_Init(mclk>>2, 115200) ;
}
//==========================================================
static __inline void SetPlayDma(void)
{
// WrUTXH0('@');
SetDMARun(PlayStatus.DevReq|DMA_START, (U32)lpPlayCurBlk->lpData, (U32)IISFIFO, lpPlayCurBlk->dwBufferLength/2);
}
static void StartPlay(void)
{
SetPlayDma();
rIISPSR = CodecPara[PlayStatus.FsIdx].PreScaler;
rIISCON = (1<<5)+(0<<4)+(0<<3)+(1<<2)+(1<<1); //Tx DMA enable[5], Rx idle[2], Prescaler enable[1]
rIISMOD = (0<<8)+(2<<6)+(0<<5)+(1<<4)+((PlayStatus.wBitsPerSample>>4)<<3)+(CodecPara[PlayStatus.FsIdx].ofs<<2)+(1<<0);
rIISFCON = (1<<15) + (1<<13);
rIISCON |= 0x1;
}
static void __irq PlayDMA2Done(void)
{
ClearPending(BIT_DMA2); //Clear pending bit
lpPlayCurBlk->dwLoops--;
if(lpPlayCurBlk->lpNext)
{
lpPlayCurBlk = lpPlayCurBlk->lpNext;
}
else
{
lpPlayCurBlk = lpPlayFstBlk;
}
SetPlayDma();
}
MMRESULT waveOutSetVolume(HWAVEOUT hwo, DWORD dwVolume)
{
if((PlayStatus.handle!=hwo)||(PlayStatus.Status!=DEVICE_PLAY))
return MMSYSERR_INVALHANDLE;
PlayVolume = dwVolume&0xffff;
AdjVolume(PlayVolume);
return MMSYSERR_NOERROR;
}
#define MAX_VOLUME 61
static void AdjVolume(U16 volume)
{
rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //Start condition : L3M=H, L3C=H
rGPBUP = rGPBUP & ~(0x7<<2) |(0x7<<2); //The pull up function is disabled GPB[4:2] 1 1100
rGPBCON = rGPBCON & ~(0x3f<<4) |(0x15<<4); //GPB[4:2]=Output(L3CLOCK):Output(L3DATA):Output(L3MODE)
volume = (volume*MAX_VOLUME)/0xffff;
_WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(MAX_VOLUME-volume, 0);
}
/************************* Control Function *********************/
static void IIS_PortSetting(void)
{
//----------------------------------------------------------
// PORT B GROUP
//Ports : GPB4 GPB3 GPB2
//Signal : L3CLOCK L3DATA L3MODE
//Setting: OUTPUT OUTPUT OUTPUT
// [9:8] [7:6} [5:4]
//Binary : 01 , 01 01
//----------------------------------------------------------
rGPBUP = rGPBUP & ~(0x7<<2) | (0x7<<2); //The pull up function is disabled GPB[4:2] 1 1100
rGPBCON = rGPBCON & ~(0x3f<<4) | (0x15<<4); //GPB[4:2]=Output(L3CLOCK):Output(L3DATA):Output(L3MODE)
//----------------------------------------------------------
// PORT E GROUP
//Ports : GPE4 GPE3 GPE2 GPE1 GPE0
//Signal : I2SSDO I2SSDI CDCLK I2SSCLK I2SLRCK
//Binary : 10 , 10 10 , 10 10
//----------------------------------------------------------
rGPEUP = rGPEUP & ~(0x1f) | 0x1f; //The pull up function is disabled GPE[4:0] 1 1111
rGPECON = rGPECON & ~(0x3ff) | 0x2aa; //GPE[4:0]=I2SSDO:I2SSDI:CDCLK:I2SSCLK:I2SLRCK
}
//==========================================================
#define L3C (1<<4) //GPB4 = L3CLOCK
#define L3D (1<<3) //GPB3 = L3DATA
#define L3M (1<<2) //GPB2 = L3MODE
static 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
}
//==========================================================
static 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
}
//==========================================================
static void Init1341(char mode)
{
U16 FsIdx;
//Port Initialize
//----------------------------------------------------------
// PORT B GROUP
//Ports : GPB4 GPB3 GPB2
//Signal : L3CLOCK L3DATA L3MODE
//Setting: OUTPUT OUTPUT OUTPUT
// [9:8] [7:6} [5:4]
//Binary : 01 , 01 01
//----------------------------------------------------------
rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //Start condition : L3M=H, L3C=H
rGPBUP = rGPBUP & ~(0x7<<2) |(0x7<<2); //The pull up function is disabled GPB[4:2] 1 1100
rGPBCON = rGPBCON & ~(0x3f<<4) |(0x15<<4); //GPB[4:2]=Output(L3CLOCK):Output(L3DATA):Output(L3MODE)
//L3 Interface
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
_WrL3Data(0x60,0); //0,1,10, 000,0 : Status 0,Reset,256fs,IIS-bus,no DC-filtering
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
FsIdx = mode?RecStatus.FsIdx:PlayStatus.FsIdx;
if(CodecPara[FsIdx].ofs)
_WrL3Data(0x18,0); //0,0,01, 000,0 : Status 0,No reset,384fs,IIS-bus,no DC-filtering
else
_WrL3Data(0x28,0); //0,0,10, 000,0 : Status 0,No reset,256fs,IIS-bus,no DC-filtering
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
_WrL3Data(0xc1,0); //1,0,0,0, 0,0,01
//Status 1,Gain of DAC 6 dB,Gain of ADC 0dB,ADC non-inverting,DAC non-inverting
//,Single speed playback,ADC-Off DAC-On
//Record
if(mode) {
_WrL3Addr(0x14 + 2); //STATUS (000101xx+10)
// _WrL3Data(0xa2,0); //1,0,1,0, 0,0,10
//Status 1,Gain of DAC 0 dB,Gain of ADC 6dB,ADC non-inverting,DAC non-inverting
//,Single speed playback,ADC-On DAC-Off
_WrL3Data(0xe3,0); //1,1,1,0, 0,0,11
//Status 1,Gain of DAC 6 dB,Gain of ADC 6dB,ADC non-inverting,DAC non-inverting
//,Single speed playback,ADC-On DAC-On,DAC打开使录音时可从耳机听到声音
// _WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
// _WrL3Data(0x3f,0); //00,11 1111 : Volume control (6 bits)
// _WrL3Data(0x00,0); //00,00 0000 : Volume control (6 bits) 0dB
_WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(0x7b,0); //01,11 10,11 : Data0, Bass Boost 18~24dB, Treble 6dB
// _WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(0xc4,0); //1100 0,100 : Extended addr(3bits), 100
// _WrL3Data(0x90,0); //100,1 00,00 : DATA0, Enable AGC, 00, input amplifier gain channel 2 (2bits)
_WrL3Data(0xf0,0); //111,1 00,00 : DATA0, Enable AGC, 00, input amplifier gain channel 2 (2bits)
// _WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(0xc0,0); //1100 0,000 : Extended addr(3bits), 000
_WrL3Data(0xe4,0); //111, 00000 : MA = 0dB
_WrL3Data(0xc1,0); //1100 0,001 : Extended addr(3bits), 001
_WrL3Data(0xe4,0); //111, 00000 : MB = 0dB
// _WrL3Addr(0x14 + 0); //DATA0 (000101xx+00)
_WrL3Data(0xc2,0); //1100 0,010 : Extended addr(3bits), 010
// _WrL3Data(0x59,0); //010,1 10,01 : DATA0, MIC Amplifier Gain 27dB, input channel 1 select(input channel 2 off)
_WrL3Data(0xf9,0); //111,1 10,11 : DATA0, MIC Amplifier Gain 27dB, input 1 X MA + input 2 X MB
}
}
/******************DMA*********************/
U32 RequestDMA(U32 attr, U32 mode)
{
U16 DevID, ReqSrc, ch;
U32 ret=REQUEST_DMA_FAIL, r;
DevID = attr>>16;
ReqSrc = attr&0xff;
if(((ReqSrc>>4)>=MAX_DMA_CHANNEL)||((ReqSrc&0xf)>4))
return ret;
// ReqSrc>>4 得到DMA 通道,是哪个通道,总共4个所以不能大于等于4 (0-3)
// ReqSrc&0xf 得到的是本通道的DMA的源请求,如I2SSDO,TIMER等等,具体可查看DATASHEET
EnterCritical(&r);
if(DMAChannel[ReqSrc>>4].used!=DMA_IS_FREE)
{
U8 src = ReqSrc;
if(src==REQ_IISDI)
{
if(DMAChannel[2].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x21;
}
else if(src==REQ_SDI)
{
if(DMAChannel[2].used!=DMA_IS_FREE)
{
if(DMAChannel[3].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x31;
}
else
ReqSrc = 0x22;
}
else if(src==REQ_SPI)
{
if(DMAChannel[3].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x32;
}
else if(src==REQ_TIMER)
{
if(DMAChannel[2].used!=DMA_IS_FREE)
{
if(DMAChannel[3].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x33;
}
else
ReqSrc = 0x23;
}
else
goto RequestDmaExit;
}
ch = ReqSrc>>4; //得到请求的DMA通道
if(mode&HW_TRIG) //如果DMA 源是hardware ,DCON[23]
DMAChannel[ch].used = DMA_IS_HWTRIG; //将结构体中的used设置为hardware 标识
else
DMAChannel[ch].used = DMA_IS_SWTRIG; //将结构体中的used设置为software 标识
DMAChannel[ch].DevID = DevID; //DMA结构体标识ID
DMAChannel[ch].pDMA = (DMAReg *)(0x4b000000+(ch)*0x40);//DMA 源地址
DMAChannel[ch].pDMA->DMASKTRIG = 1<<2; //stop dma ,停止DMA 传输 DMASKTRIG[2]
DMAChannel[ch].pDMA->DISRCC = (attr>>8)&3; //设置源的所在总线和源地址是否自增DISRCC[1-0]
DMAChannel[ch].pDMA->DIDSTC = (attr>>12)&3; //设置目的所在的总线和目的地址是否自增DIDSTC[1-0]
mode &= ~0x07000000; //将代表DCON[26-24]位的值清空
mode |= (ReqSrc&0x7)<<24; //将代表DCON[26-24]位的值补上
DMAChannel[ch].pDMA->DCON = mode; //设置DCON[26-24],指定DMA的源是什么
Uart_Printf("Request DMA %x success\n", ReqSrc);
ret = (DevID<<16)|ReqSrc; //设置返回状态
RequestDmaExit:
ExitCritical(&r);
return ret;
}
U16 SetDMARun(U32 attr, U32 src_addr, U32 dst_addr, U32 len)
{
U16 DevID, ReqSrc, ch;
DevID = attr>>16;
ReqSrc = attr&0xf;
ch = (attr&0xf0)>>4;
#if DMA_CHECK_ATTR
if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
return 1;
if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
return 1;
#endif
DMAChannel[ch].pDMA->DISRC = src_addr;
DMAChannel[ch].pDMA->DIDST = dst_addr;
DMAChannel[ch].pDMA->DCON &= ~0xfffff;
DMAChannel[ch].pDMA->DCON |= len&0xfffff;
if(attr&DMA_START)
{
if(DMAChannel[ch].used==DMA_IS_HWTRIG)
DMAChannel[ch].pDMA->DMASKTRIG = 2; //channel on
if(DMAChannel[ch].used==DMA_IS_SWTRIG)
DMAChannel[ch].pDMA->DMASKTRIG = 3; //sw_trig
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -