⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aic27.c

📁 Real-Time Digital Signal Processing Implementations, Applications, and Experiments with the TMS320C
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -