📄 aic27.c
字号:
//clear read flag
readDone = False;
//enable receive DMA interrupt
IER0 |= (u16)(1<<AIC27_RXDMA_FLAG);
//wait until register data is available
while (readDone == False);
// return value of register
return (u16)(aic27Status.data >> 4);
}
/******************************************************************************/
/* aic27_write_reg() - Write an AIC27 control register */
/* */
/* Parameters - */
/* reg - an element of an enumeration indicating the register to write. */
/* value - a number containing the bits to by written, already in their */
/* correct field locations. */
/* mask - a number indicating the position of the bits in "value" to be */
/* written. */
/* */
/* Returns - BRD_OK on success, BRD_ERROR on failure. */
/* */
/******************************************************************************/
u16 aic27_write_reg(AIC27Reg reg, u16 value, u16 mask)
{
// If codec closed, just return
if (cdx.state == AIC27_CODEC_CLOSED)
return (u16)BRD_ERROR;
// Mask register and get write value
if (mask != 0xFFFF)
{
value |= (aic27_read_reg(reg) & ~mask);
}
//disable receive DMA interrupt
IER0 &= (u16)(~(1<<AIC27_RXDMA_FLAG));
//assemble cmd addr
//b19 in composite 20-bit word is 0
//aic27Cmd.addrL = ((reg & 0xe) << 12);
//aic27Cmd.addrH = ((reg & 0x70) >> 4);
aic27Cmd.addr = ((u32)((u32)reg & 0x7e) << 12);
//assemble cmd data
aic27Cmd.data = value;
aic27Cmd.data <<= 4;
//set tag to indicate valid addr/data on next frame
aic27Cmd.tag |= (AIC27_VALID_REGADDR_CH | AIC27_VALID_REGDATA_CH);
//clear write flag
writeDone = False;
//enable receive DMA interrupt
IER0 |= (u16)(1<<AIC27_RXDMA_FLAG);
// Wait for write to complete
while (writeDone == False);
return (u16)BRD_OK;
}
/******************************************************************************/
/* aic27_sample_rate() - Set the specified channel sample rate. */
/* */
/* Parameters - */
/* reg - an element of an enumeration indicating the pertinent register. */
/* freq - an element of an enumeration indicating the frequency. */
/* */
/* Returns - BRD_OK on success, BRD_ERROR on failure. */
/* */
/******************************************************************************/
int aic27_sample_rate(AIC27Reg reg, u16 freq)
{
if ((reg == FRONT_DAC_SRATE) ||
(reg == REAR_DAC_SRATE) ||
(reg == LFE_DAC_SRATE) ||
(reg == AUDIO_ADC_RRATE) ||
(reg == LINE1_SRATE) ||
(reg == LINE2_SRATE))
{
return aic27_write_reg(reg, freq, 0xFFFF);
}
return BRD_ERROR;
}
/******************************************************************************/
/* aic27_cont_play() */
/* */
/* This function is used to continuously send data to the codec. */
/* */
/* Parameters - */
/* pingBuf - a buffer containing data to play */
/* pongBuf - a second buffer containing data to play */
/* size - the number of samples in each buffer */
/* pfunc - Pointer to function to run at end of buffer */
/* bufStatus - pointer to transfer status. */
/* 1 = transfer in progress, 0 = transfer complete */
/* */
/* Returns - BRD_OK on success, BRD_ERROR on failure. */
/* */
/******************************************************************************/
int aic27_cont_play(int *pingBuf,
int *pongBuf,
unsigned int size,
Fp pfunc,
int **bufStatus)
{
// Codec must be opened first
if (cdx.state == AIC27_CODEC_CLOSED)
return BRD_ERROR;
//disable receive DMA interrupt
IER0 &= (u16)(~(1<<AIC27_RXDMA_FLAG));
// Setup transmit pack
cdx.txPkt.size = size;
cdx.txPkt.indx = 0;
cdx.txPkt.bufi = (bool)0;
*bufStatus = (int *)&cdx.txPkt.status;
cdx.txPkt.status = 1;
cdx.txPkt.callback = pfunc;
cdx.txPkt.pBuf[0] = pingBuf;
cdx.txPkt.pBuf[1] = pongBuf;
//enable receive DMA interrupt
IER0 |= (u16)(1<<AIC27_RXDMA_FLAG);
return BRD_OK;
}
/******************************************************************************/
/* aic27_cont_capture() */
/* */
/* This function is used to capture data from the codec */
/* */
/* Parameters - */
/* pingBuf - a buffer to contain data read */
/* pongBuf - a second buffer to contain data read */
/* size - the number of samples in each buffer */
/* pfunc - Pointer to function to run at end of buffer */
/* bufStatus - pointer to transfer status. */
/* 1 = transfer in progress, 0 = transfer complete */
/* */
/* Returns - BRD_OK on success, BRD_ERROR on failure. */
/* */
/* */
/******************************************************************************/
int aic27_cont_capture(int *pingBuf,
int *pongBuf,
unsigned int size,
Fp pfunc,
int **bufStatus)
{
// Codec must be opened first
if (cdx.state == AIC27_CODEC_CLOSED)
return BRD_ERROR;
//disable receive DMA interrupt
IER0 &= (u16)(~(1<<AIC27_RXDMA_FLAG));
/* Setup receive packet */
cdx.rxPkt.size = size;
cdx.rxPkt.indx = 0;
cdx.rxPkt.bufi = (bool)0;
*bufStatus = (int *)&cdx.rxPkt.status;
cdx.rxPkt.status = 1;
cdx.rxPkt.callback = pfunc;
cdx.rxPkt.pBuf[0] = pingBuf;
cdx.rxPkt.pBuf[1] = pongBuf;
//enable receive DMA interrupt
IER0 |= (u16)(1<<AIC27_RXDMA_FLAG);
return BRD_OK;
}
/******************************************************************************/
/* aic27_stop_play() - Stops sending data to AIC27 */
/* */
/* Parameters - None */
/* */
/* Returns - None */
/* */
/******************************************************************************/
void aic27_stop_play()
{
cdx.txPkt.callback = 0;
cdx.txPkt.pBuf[0] = NULL;
cdx.txPkt.pBuf[1] = NULL;
}
/******************************************************************************/
/* aic27_stop_capture() - Stops capturing data from AIC27. */
/* */
/* Parameters - None */
/* */
/* Returns - None */
/* */
/******************************************************************************/
void aic27_stop_capture()
{
cdx.rxPkt.status = 1;
cdx.rxPkt.callback = 0;
cdx.rxPkt.pBuf[0] = NULL;
cdx.rxPkt.pBuf[1] = NULL;
}
/******************************************************************************/
/* _reset_aic27_pkts() - reset codec packets */
/******************************************************************************/
static void _reset_aic27_pkts()
{
//reset AIC27 input and output frames
aic27Status.tag = 0;
aic27Cmd.tag = 0;
aic27Status.addr = aic27Cmd.addr = 0;
aic27Status.data = aic27Cmd.data = 0;
// Initialize buffer pointers and callback function
cdx.rxPkt.size = 0;
cdx.rxPkt.indx = 0;
cdx.rxPkt.bufi = (bool)0;
cdx.rxPkt.pBuf[0] = NULL;
cdx.rxPkt.pBuf[1] = NULL;
cdx.rxPkt.callback = NULL;
cdx.txPkt.size = 0;
cdx.txPkt.indx = 0;
cdx.txPkt.bufi = (bool)0;
cdx.txPkt.pBuf[0] = NULL;
cdx.txPkt.pBuf[1] = NULL;
cdx.txPkt.callback = NULL;
dmaTxBuf.tag = dmaRxBuf.tag = 0;
dmaTxBuf.data = dmaRxBuf.data = 0;
dmaTxBuf.addr = dmaRxBuf.addr = 0;
dmaTxBuf.leftCh = dmaRxBuf.leftCh = 0;
dmaTxBuf.rightCh = dmaRxBuf.rightCh = 0;
}
/******************************************************************************/
/* _enable_aic27_interrupt() - RX interrupt for AIC27 codec */
/******************************************************************************/
static void _enable_aic27_interrupt()
{
// Clear any pending interrupt
IFR0 |= (u16)(1<<AIC27_RXDMA_FLAG);
// Hook and enable McBSP receive interrupt
hook_interrupt(AIC27_RXDMA_TRAP, _aic27_rxdma_isr);
IER0 |= (u16)(1<<AIC27_RXDMA_FLAG);
// Make sure global interrupts are enabled
INTR_GLOBAL_ENABLE;
}
/******************************************************************************/
/* _disable_aic27_interrupt() - disable RX interrupt for AIC27 codec */
/******************************************************************************/
static void _disable_aic27_interrupt()
{
// Disable interrupt
IER0 &= (u16)(~(1<<AIC27_RXDMA_FLAG));
// Unhook interrupt handler
unhook_interrupt(AIC27_RXDMA_TRAP);
}
/******************************************************************************/
/* _setup_aic27_dma() - setup DMA ch 4 & 5 for AIC27 codec */
/* TX - Ch 4, RX - Ch 5 */
/******************************************************************************/
static void _setup_aic27_dma()
{
u32 addr = 0;
u16 mSpace = 0;
DMGCR = 0x0000; //initialize gcr
// clear all DMA registers
reset_dma();
/*****************************************************************/
/* Transmit DMA setup */
/*****************************************************************/
DMCCR(AIC27TXCH) = (DM_NOMOD << DM_DST_AMODE) |
(DM_POST_INCR << DM_SRC_AMODE) |
(1 << DM_AUTOINIT) | // Requires ENDPROG
(1 << DM_PRIO) |
(DMSYNC_XEVT2 << DM_SYNC);
// Determine memory type of source data
mSpace = setMemSpace((u32)&dmaTxBuf);
DMCSDP(AIC27TXCH) = (DM_RHEA << DM_DST) |
(mSpace << DM_SRC) |
(DM_DTYPE_32 << DM_DATA_TYPE);
// Transmit interrupt is not used (only receive)
DMCICR(AIC27TXCH) = 0;
// set src address (byte address)
addr = ((u32)&dmaTxBuf) << 1;
DMCSSAL(AIC27TXCH) = (u16)addr;
DMCSSAU(AIC27TXCH) = (u16)((addr & 0xff0000)>>16);
// set dst address (byte address)
addr = ((u32)DXR2_ADDR(AIC27_PORT)) << 1;
DMCDSAL(AIC27TXCH) = (u16)addr;
DMCDSAU(AIC27TXCH) = (u16)((addr & 0xff0000)>>16);
DMCEN(AIC27TXCH) = DMA_BUFSIZE;
DMCFN(AIC27TXCH) = 1;
DMCEI(AIC27TXCH) = 0;
DMCFI(AIC27TXCH) = 0;
/*****************************************************************/
// Receive DMA setup
/*****************************************************************/
DMCCR(AIC27RXCH) = (DM_POST_INCR << DM_DST_AMODE) |
(DM_NOMOD << DM_SRC_AMODE) |
(1 << DM_REPEAT) |
(1 << DM_AUTOINIT) |
(1 << DM_PRIO) |
(DMSYNC_REVT2 << DM_SYNC);
// Determine memory type of destination
mSpace = setMemSpace((u32)&dmaRxBuf);
DMCSDP(AIC27RXCH) = (mSpace << DM_DST) |
(DM_RHEA << DM_SRC) |
(DM_DTYPE_32 << DM_DATA_TYPE);
DMCICR(AIC27RXCH) = (1 << DM_FRAME);
// set src address
addr = ((u32)DRR2_ADDR(AIC27_PORT)) << 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -