📄 aic27.c
字号:
DMCSSAL(AIC27RXCH) = (u16)addr;
DMCSSAU(AIC27RXCH) = (u16)((addr & 0xff0000)>>16);
// set dst address
addr = ((u32)&dmaRxBuf) << 1;
DMCDSAL(AIC27RXCH) = (u16)addr;
DMCDSAU(AIC27RXCH) = (u16)((addr & 0xff0000)>>16);
DMCEN(AIC27RXCH) = DMA_BUFSIZE;
DMCFN(AIC27RXCH) = 1;
DMCEI(AIC27RXCH) = 0;
DMCFI(AIC27RXCH) = 0;
}
static void reset_dma()
{
//Stop any current transfers
DMCCR(AIC27TXCH) = 0;
DMCCR(AIC27RXCH) = 0;
//reset Tx DMA ch
DMCSDP(AIC27TXCH) = 0;
DMCICR(AIC27TXCH) = 0;
DMCSSAL(AIC27TXCH) = 0;
DMCSSAU(AIC27TXCH) = 0;
DMCDSAL(AIC27TXCH) = 0;
DMCDSAU(AIC27TXCH) = 0;
DMCEN(AIC27TXCH) = 0;
DMCFN(AIC27TXCH) = 0;
DMCEI(AIC27TXCH) = 0;
DMCFI(AIC27TXCH) = 0;
//reset Rx DMA ch
DMCSDP(AIC27RXCH) = 0;
DMCICR(AIC27RXCH) = 0;
DMCSSAL(AIC27RXCH) = 0;
DMCSSAU(AIC27RXCH) = 0;
DMCDSAL(AIC27RXCH) = 0;
DMCDSAU(AIC27RXCH) = 0;
DMCEN(AIC27RXCH) = 0;
DMCFN(AIC27RXCH) = 0;
DMCEI(AIC27RXCH) = 0;
DMCFI(AIC27RXCH) = 0;
}
/******************************************************************************/
/* _setup_aic27_serial_port() - setup serial port for AIC27 codec */
/******************************************************************************/
static void _setup_aic27_serial_port()
{
SPCR1(AIC27_PORT) = SPCR1_VAL;
SPCR2(AIC27_PORT) = SPCR2_VAL;
RCR1(AIC27_PORT) = RCR1_VAL;
RCR2(AIC27_PORT) = RCR2_VAL;
XCR1(AIC27_PORT) = XCR1_VAL;
XCR2(AIC27_PORT) = XCR2_VAL;
SRGR1(AIC27_PORT) = 0;
SRGR2(AIC27_PORT) = 0;
MCR1(AIC27_PORT) = 0;
MCR2(AIC27_PORT) = 0;
PCR(AIC27_PORT) = PCR_VAL;
RCERA(AIC27_PORT) = 0;
RCERB(AIC27_PORT) = 0;
RCERC(AIC27_PORT) = 0;
RCERD(AIC27_PORT) = 0;
RCERE(AIC27_PORT) = 0;
RCERF(AIC27_PORT) = 0;
RCERG(AIC27_PORT) = 0;
RCERH(AIC27_PORT) = 0;
XCERA(AIC27_PORT) = 0;
XCERB(AIC27_PORT) = 0;
XCERC(AIC27_PORT) = 0;
XCERD(AIC27_PORT) = 0;
XCERE(AIC27_PORT) = 0;
XCERF(AIC27_PORT) = 0;
XCERG(AIC27_PORT) = 0;
XCERH(AIC27_PORT) = 0;
readDone = writeDone = True;
//now start McBsp and DMA transfers
DMA_ENABLE(AIC27RXCH);
DMA_ENABLE(AIC27TXCH);
// Enable serial port (both TX/RX)
MCBSP_ENABLE(AIC27_PORT, MCBSP_BOTH);
//wait until codec is ready (b15 of slot 1 must be '1')
while (!(aic27Status.tag & AIC27_CODEC_READY));
}
/******************************************************************************/
/* _serial_reset() - Resets the device's serial port */
/******************************************************************************/
static void _serial_reset()
{
// Reset McBSP
MCBSP_TX_RESET(AIC27_PORT);
MCBSP_RX_RESET(AIC27_PORT);
// Disable interrupts
IER0 &= (u16)(~(1<<AIC27_RXDMA_FLAG));
// Clear pending interrupt flags
IFR0 |= (u16)(1<<AIC27_RXDMA_FLAG);
}
/******************************************************************************/
/* _setup_aic27_registers() - Sets up the AIC27 codec registers */
/******************************************************************************/
static void _setup_aic27_registers()
{
//enable variable rate audio
aic27_write_reg(EXTD_AUDIO_STATCTRL, 0x0001, 0xffff);
aic27_write_reg(MASTER_VOL, 0x0000, 0xffff);
aic27_write_reg(MIC_VOL, 0x0000, 0xffff);
aic27_write_reg(LINEIN_VOL, 0x0000, 0xffff);
//set pcmout volume to about -13dB gain
aic27_write_reg(PCMOUT_VOL, 0x0808, 0xffff);
aic27_write_reg(REC_SEL, MIC_IN, 0xffff); //mic
aic27_write_reg(REC_GAIN, 0x0000, 0xffff);
//mute front mixer vol to disable loopback path
aic27_write_reg(FRONT_MIXER_VOL, 0x8000, 0xffff);
aic27_sample_rate(AUDIO_ADC_RRATE, AIC27_8000HZ);
aic27_sample_rate(FRONT_DAC_SRATE, AIC27_8000HZ);
}
/******************************************************************************/
/* _aic27_rxdma_isr() - ISR for DMA ch 5 block interrupt */
/* NOTE: The transmit handling is done here also after the receive handling */
/* since rx/tx are synchronized and transmit must occur after receive */
/* to support dynamic sample rates. */
/******************************************************************************/
interrupt void _aic27_rxdma_isr(void)
{
volatile int dummy;
volatile u32 slotReq;
int *pRx = cdx.rxPkt.pBuf[cdx.rxPkt.bufi];
int *pTx = cdx.txPkt.pBuf[cdx.txPkt.bufi];
//clear interrupt conditions
dummy = DMCSR(AIC27RXCH);
dummy = DMCSR(AIC27TXCH);
//*********************************************************************/
//Receive Processing
//*********************************************************************/
//*********************************************************************/
//read 16-bit Input Frame TAG
//*********************************************************************/
aic27Status.tag = dmaRxBuf.tag;
//*********************************************************************/
//read 20-bit reg address
//*********************************************************************/
aic27Status.addr = dmaRxBuf.addr;
//*********************************************************************/
//read 20-bit reg value
//*********************************************************************/
aic27Status.data = dmaRxBuf.data;
if (aic27Status.tag & AIC27_VALID_REGDATA_CH)
{
readDone = True;
aic27Cmd.tag &= ~(AIC27_VALID_REGADDR_CH | AIC27_VALID_REGDATA_CH);
}
//*********************************************************************/
//Only read PCM left channel into buffer if buffer address is non-zero
//*********************************************************************/
if ((pRx != NULL) && (aic27Status.tag & AIC27_LEFT_CH))
{
pRx[cdx.rxPkt.indx++] = (u16)(dmaRxBuf.leftCh >> 4);
}
//*********************************************************************/
//Only read PCM Right channel into buffer if buffer address is non-zero
//*********************************************************************/
if ((pRx != NULL) && (aic27Status.tag & AIC27_RIGHT_CH))
{
pRx[cdx.rxPkt.indx++] = (u16)(dmaRxBuf.rightCh >> 4);
}
//*********************************************************************/
//Ping-pong Rx buffers if necessary
//*********************************************************************/
if (pRx != NULL)
{
if (cdx.rxPkt.indx == cdx.rxPkt.size)
{
cdx.rxPkt.bufi ^= 1; //swap buffers
cdx.rxPkt.indx = 0; //reset buffer index
cdx.rxPkt.status = 0; //indicate transfer completion
// Invoke callback routine if provided
if (cdx.rxPkt.callback != NULL)
(*cdx.rxPkt.callback)(); //invoke rx callback routine
}
}
//*********************************************************************/
//Transmit Processing
//*********************************************************************/
//*********************************************************************/
//write 16-bit output Frame TAG
//*********************************************************************/
slotReq = ((aic27Status.addr & AIC27_DATA_REQ) ^ AIC27_DATA_REQ) << 1;
dmaTxBuf.tag = aic27Cmd.tag | slotReq;
//if at least one slot valid, indicate valid frame
if (dmaTxBuf.tag)
{
dmaTxBuf.tag |= AIC27_VALID_FRAME;
}
//*********************************************************************/
//write 20-bit reg address
//*********************************************************************/
dmaTxBuf.addr = aic27Cmd.addr;
//*********************************************************************/
//write 20-bit reg value
//*********************************************************************/
dmaTxBuf.data = aic27Cmd.data;
//clear cmd and data port
aic27Cmd.tag &= 0; // ~(AIC27_VALID_REGADDR_CH | AIC27_VALID_REGDATA_CH);
aic27Cmd.data = aic27Cmd.addr = 0;
writeDone = True;
//*********************************************************************/
//Only write PCM left channel from buffer if buffer address is non-zero
//and AIC27 has requested data.
//*********************************************************************/
if ((pTx != NULL) && (!(aic27Status.addr & AIC27_SLOT3_REQ)))
{
//get left channel data and shift to left by 4 to fill 20-bit slot
dmaTxBuf.leftCh = (u32)pTx[cdx.txPkt.indx++] << 4;
}
else
{
//no data was requested
dmaTxBuf.leftCh = 0;
}
//*********************************************************************/
//Only write PCM Right channel from buffer if buffer address is non-zero
//and AIC27 has requested data.
//*********************************************************************/
if ((pTx != NULL) && (!(aic27Status.addr & AIC27_SLOT4_REQ)))
{
//get right channel data and shift to left by 4 to fill 20-bit slot
dmaTxBuf.rightCh = (u32)pTx[cdx.txPkt.indx++] << 4;
}
else
{
dmaTxBuf.rightCh = 0x0;
}
// Allow TX DMA to auto-init now with valid tag data
DMCCR(AIC27TXCH) |= (1<<DM_END_PROG);
DMCCR(AIC27TXCH) &= (~(1<<DM_END_PROG));
//*********************************************************************/
//Ping-pong Tx buffers if necessary
//*********************************************************************/
if (pTx != NULL)
{
if (cdx.txPkt.indx == cdx.txPkt.size)
{
cdx.txPkt.bufi ^= 1; //swap buffers
cdx.txPkt.indx = 0; //reset buffer index
cdx.txPkt.status = 0; //indicate transfer completion
// Invoke callback routine if provided
if (cdx.txPkt.callback != NULL)
(*cdx.txPkt.callback)(); //invoke tx callback routine
}
}
}
static void enable_codec_comm()
{
_reset_aic27_pkts();
_serial_reset();
_setup_aic27_dma();
_enable_aic27_interrupt();
//Setup McBSP
_setup_aic27_serial_port();
}
static void disable_codec_comm()
{
rx_stop = tx_stop = True;
dma_reset(AIC27TXCH); //reset Tx DMA ch
dma_reset(AIC27RXCH); //reset Rx DMA ch
_disable_aic27_interrupt();
_reset_aic27_pkts();
_serial_reset();
cdx.state = AIC27_CODEC_OPENED;
}
static u16 setMemSpace(u32 addr)
{
if (addr < 0x8000ul)
return DM_DARAM;
else if (addr < 0x28000ul)
return DM_SARAM;
else
return DM_EMIF;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -