📄 iis-s3c44b0.c
字号:
#include "../ucos-ii/includes.h"
#include "../startup/44b.h"
#include "../inc/drv/IIS-S3C44B0.h"
#include "../ucos-ii/Uhal/isr.h"
#include "..\inc\drv\OSFile.h"
///////////////////////////////////S3C44B0 IIS////////////////////////////////////////
#define IISCON_RIGHT_INDEX 0x100 //Right Channel
#define IISCON_TXFIFO_NE 0x80 //Transmit FIFO not empty flag
#define IISCON_RXFIFO_NE 0x40 //Transmit FIFO not empty flag
#define IISCON_TXDMA 0x20 //Transmit DMA service request enable
#define IISCON_RXDMA 0x10 //Receive DMA service request enable
#define IISCON_TXIDLE 0x08 //Transmit channel idle
#define IISCON_RXIDLE 0x04 //Receive channel idle
#define IISCON_PRESCALE 0x02 //IIS prescaler enable
#define IISCON_ENABLE 0x01 //IIS interface enable(start)
#define IISMOD_SLAVE 0x100 //slave mode select
#define IISMOD_TX 0x80 //Transmit mode
#define IISMOD_RX 0x40 //receive mode
#define IISMOD_RACTIVE 0x20 //Active level of right
#define IISMOD_MSBJ 0x10 //MSB-justified Serial interface format
#define IISMOD_16BIT 0x08 //Serial data 16bit per channel
#define IISMOD_MCLK_384FS 0x04 //Master clock frequency
#define IISMOD_32FS 0x01 //Serial bit clock frequency=32fs
#define IISMOD_48FS 0x02 //Serial bit clock frequency=48fs
#define IISFCON_TXDMA 0x800 //Transmit FIFO access DMA mode
#define IISFCON_RXDMA 0x400 //Receive FIFO access DMA mode
#define IISFCON_TXFIFO 0x200 //Transmit FIFO enable
#define IISFCON_RXFIFO 0x100 //Receive FIFO enable
/************************************************************
S3C44B0 IIS初始化函数,函数开启IIS,
参数isChangePLL是否改变锁频换
如果是,则设置MCLK时钟速度为67.5M
否则,不变
************************************************************/
void Init_IIS(BOOL isChangePLL)
{
if(isChangePLL){
ChangePllValue(0x52, 2, 1);
Delay(100);
}
rIISCON=0; //disable;
rIISMOD=IISMOD_TX|IISMOD_RX|IISMOD_16BIT|IISMOD_32FS|IISMOD_MCLK_384FS; //IIS mode, active left
rIISFCON=IISFCON_TXDMA|IISFCON_RXFIFO|IISFCON_TXFIFO;
rIISPSR=0x11; //CODECLK= 1/4 MCLK
rIISCON=IISCON_PRESCALE|IISCON_ENABLE;
}
///////////////////////////UDA1341/////////////////////////////////////////////////
#define UDA1341_MODE (1<<14) //GPC14
#define UDAADDR 0x14 //UDA1341 address
#define UDA_DATA0 0x00 //UDA1341 data0
#define UDA_DATA1 0x01 //UDA1341 data1
#define UDA_STATUS 0x02 //UDA1341 status
#define UDASTATUS0_RST 0x40 //UDA1341 status reset
#define UDASTATUS0_SC512 0x00 //UDA1341 status SC
#define UDASTATUS0_SC384 0x10 //UDA1341 status SC
#define UDASTATUS0_SC256 0x20 //UDA1341 status SC
#define UDASTATUS0_IIS 0x00 //UDA1341 status IF2-0=0 IIS
#define UDASTATUS0_DC 0x01 //UDA1341 status DC-filtering
#define UDASTATUS1_OGS6 (0x80|0x40) //UDA1341 status gain of DAC 6dB
#define UDASTATUS1_IGS6 (0x80|0x20) //UDA1341 status gain of ADC 6dB
#define UDASTATUS1_PADINV (0x80|0x10) //UDA1341 status ADC inverting
#define UDASTATUS1_PDAINV (0x80|0x08) //UDA1341 status DAC inverting
#define UDASTATUS1_DBSPD (0x80|0x04) //UDA1341 status double speed
#define UDASTATUS1_ADCON (0x80|0x02) //UDA1341 status ADC on
#define UDASTATUS1_DACON (0x80|0x01) //UDA1341 status DAC on
#define UDADATA0_VOL 0x00 //UDA1341 data0 volume value 6bit
#define L3CLK 0x100 //GPC8
#define L3DATA 0x200 //GPC9
void UDA1341_Send(unsigned char data)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
int i,j;
OS_ENTER_CRITICAL();
for(i=0;i<8;i++){
if(data&0x1)
rPDATC|=L3DATA;
else
rPDATC&=~L3DATA;
rPDATC&=~L3CLK;
data>>=1;
for(j=0;j<20;j++);
rPDATC|=L3CLK;
for(j=0;j<20;j++);
}
OS_EXIT_CRITICAL();
}
void Init_UDA1341()
{
rPDATC&=~UDA1341_MODE;
UDA1341_Send(UDAADDR|UDA_STATUS);
rPDATC|=UDA1341_MODE;
UDA1341_Send(UDASTATUS0_RST);
Delay(1);
rPDATC&=~UDA1341_MODE;
UDA1341_Send(UDAADDR|UDA_STATUS);
rPDATC|=UDA1341_MODE;
UDA1341_Send(UDASTATUS0_SC384|UDASTATUS0_DC);
rPDATC&=~UDA1341_MODE;
UDA1341_Send(UDAADDR|UDA_STATUS);
rPDATC|=UDA1341_MODE;
UDA1341_Send(UDASTATUS1_ADCON|UDASTATUS1_DACON);
Delay(1);
}
/////////////////////////////////////Audio Function///////////////////////////////
static OS_EVENT* AudioDMA_Sem=NULL; //系统DMA资源
////////////////////播放音频相关变量/////////////////////
#define NextSendBuffer() do{if(nCurrentSendBuffer==0)\
nCurrentSendBuffer=1;\
else\
nCurrentSendBuffer=0;\
nCurrentSendpos=0;\
}while(0);
#define NextPlayBuffer() do{if(nCurrentPlayBuffer==0)\
nCurrentPlayBuffer=1;\
else\
nCurrentPlayBuffer=0;\
}while(0);
static unsigned int AudioOutBuffer[2][AUDIO_OUT_BUFFERSIZE];
static unsigned int AudioOutBuflength[2]; //缓冲区长度,如果为0,表示未就绪
static unsigned int nCurrentSendpos=0;
static unsigned int nCurrentSendBuffer=0; //当前发送缓冲区
static unsigned int nCurrentPlayBuffer=0; //当前播放缓冲区
static OS_EVENT* AudioPlayDone_Sem=NULL;
static BOOL isPlaying=FALSE;
////////////////////录音相关变量///////////////////////
#define NextGetBuffer() do{if(nCurrentGetBuffer==0)\
nCurrentGetBuffer=1;\
else\
nCurrentGetBuffer=0;\
nCurrentGetpos=0;\
}while(0);
#define NextRecBuffer() do{if(nCurrentRecBuffer==0)\
nCurrentRecBuffer=1;\
else\
nCurrentRecBuffer=0;\
}while(0);
static unsigned int AudioInBuffer[2][AUDIO_IN_BUFFERSIZE];
static unsigned int AudioInBuflength[2]; //缓冲区长度,如果为0,表示未就绪
static unsigned int nCurrentGetpos=0;
static unsigned int nCurrentGetBuffer=0; //当前取声音的缓冲区
static unsigned int nCurrentRecBuffer=0; //当前的录音缓冲区
static OS_EVENT* AudioRecDone_Sem=NULL;
static BOOL isRecing=FALSE; //是否在录音状态
/************************************************************
音频缓冲区录音完毕中断函数
************************************************************/
void BufferRec_Done_ISR()
{
NextGetBuffer();
if(nCurrentRecBuffer!=nCurrentGetBuffer && AudioInBuflength[nCurrentRecBuffer]){
//如果另一个缓冲区已经读取完毕,则继续录音
/****** BDMA1 Initialize ******/
//for Source
rBDISRC0=(1<<30)|(3<<28)|((int)0x1d18010); //M2IO,fix,IISFIF
//for des
rBDIDES0=(((unsigned int)2<<30))|(1<<28)|(int)(&(AudioInBuffer[nCurrentRecBuffer])); //Half word,inc,Buf
//iis,reserve,done_int,not auto-reload/start,DMA enable,COUNT
rBDICNT0=(1<<30)+(1<<26)+(3<<22)+(0<<21)+(0<<20)+(AudioInBuflength[nCurrentRecBuffer]&(~0x3));
rBDICNT0 |= (1<<20);//enable
//Enable DMA
rBDCON0 = 0x0<<2;
}
else{ //否则,停止播放
isRecing=FALSE;
rIISCON&=~IISCON_RXDMA; //TxDMA stop
rBDICNT0=0x0; //BDMA stop
OSSemPost(AudioDMA_Sem);
}
OSSemPost(AudioRecDone_Sem);
}
/************************************************************
音频缓冲区播放/录音完毕中断函数
************************************************************/
void BufferPlay_Done_ISR()
{
if(isPlaying){
AudioOutBuflength[nCurrentPlayBuffer]=0;
NextPlayBuffer();
if(nCurrentPlayBuffer!=nCurrentSendBuffer && AudioOutBuflength[nCurrentPlayBuffer]){
//如果另一个缓冲区就绪,则继续播放
/****** BDMA0 ReInitialize ******/
//for Source //Half word,inc,Buf
rBDISRC0=(1<<30)|(1<<28)|((int)(&(AudioOutBuffer[nCurrentPlayBuffer])));
//for des
rBDIDES0=(1<<30)|(3<<28)|((int)0x1d18010); //M2IO,fix,IISFIF
//Size
//iis,reserve,done_int,not auto-reload/start,DMA enable,COUNT
rBDICNT0=(1<<30)|(1<<26)|(3<<22)|(0<<21)|(0<<20)|
(AudioOutBuflength[nCurrentPlayBuffer]&(~0x3));
rBDICNT0 |= (1<<20);//enable
//Enable DMA
rBDCON0 = 0x0<<2;
}
else{ //否则,停止播放
isPlaying=FALSE;
rIISCON&=~IISCON_TXDMA; //TxDMA stop
rBDICNT0=0x0; //BDMA stop
OSSemPost(AudioDMA_Sem);
}
OSSemPost(AudioPlayDone_Sem);
}
else if(isRecing)
BufferRec_Done_ISR();
}
/************************************************************
音频初始化函数
参数isChangePLL是否改变锁频换
如果是,则设置MCLK时钟速度为67.5M
否则,不变
************************************************************/
void Init_Audio(BOOL isChangePLL)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
INT8U err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -