This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6747 - how to detect McASP AFIFO overrun / underrun

Other Parts Discussed in Thread: TMS320C6747

Hi,

we are using McASP for communication between a DM648 and
several C6747 DSPs. Every now and then, we run into
trouble with corrupted data.

On C6747 we use McASP 0 with AFIFO driven by DMA, using
one serial data pin towards the C6747 and two serial data
pins towards the DM648, using a 24 MHz McASP clock plus
FSYNC generated by the DM648.

Modifying the C6747 code alters the error frequency so
we think the source of trouble lies within the C6747.

Sometimes the corrupted data towards DM648 looks like
a 32-Bit word (or a fraction thereof) is sent twice instead
of once, so we speculate about a problem with feeding data
into the McASP.
Maybe DMA getting too slow because it is blocked by other
resources and thus the AFIFO may run empty.

We have monitored all error registers that we could find,
checking McASP registers RSTAT and XSTAT, DSP registers
FLTSTAT, BUSERR, and INTXSTAT, EDMA3 registers EMR, QEMR
and CCERR, and EDMA3TC registers ERRSTAT.
None of these gives us an indication of anything going wrong.

However we could not find any register reporting possible
overrun or underrun of the AFIFO. The WFIFOSTS and RFIFOSTS
registers don't report FIFO overrun/underrun, and the McASP
registers RSTAT and XSTAT will probably never report RDMAERR
or ROVRN (or XDMAERR or XUNDRN) when the AFIFO is in use.

So how can we detect/diagnose an overrun/underun condition
inside the AFIFO ?

Thank you,

Christoph

  • Christoph,

    Welcome to the TI E2E forum. I hope you will find many good answers here and in the TI.com documents and in the TI Wiki Pages. Be sure to search those for helpful information and to browse for the questions others may have asked on similar topics.

    When the FIFO runs out of transmit data, it will no longer send data to the transmitter and the transmitter will then report a underrun condition. Try this by stopping the DMA channel that is supposed to be servicing the transmitters and check XSTAT to see if the underrun status is set.

    Regards,
    RandyP

  • RandyP,

    thanks for your reply and your suggestion.

    I followed your suggestion, stopped the DMA, watched the effect on XSTAT register at 0x01D000C0, and found that XSTAT changes into 0x20 after stopping the DMA. So only the XDATA bit is set, indicating that new data is required, but none of the error bits XERR or XUNDRN or  XSYNCERR or XCKFAIL or XDMAERR is set.

    In my understanding the XDATA bit is non-permanent and would vanish again when the DMA continues to feed data into the AFIFO. And since none of the error bits get set, the XSTAT register does not help in detecting the problem.

    Any other suggestions?

    Thanks and best regards,

    Christoph

  • Christoph,

    If you have a I/O Peripheral that is not transmitting/receiving in a consistent manner, there are several steps you can make
    Step 1: Are the clocks to the peripheral correctly set up
    Step 2: Are the buffers properly being serviced in time. Some peripherals (such as McASP) have a limited time window in which you need to service the buffers before a transmit overrun, or underrun condition will cause the state machines to generate an error. You can then use this information to back track and determine why the buffers are not being serviced in time by the CPU or DMAs


    On creation of McASP device driver, the High Clock, Bit Clock and Frame Sync signals are configured.
    On edge of the Frame Sync the EDMA events are generated.
    With every Frame Sync either data is to be written/read from,
    failing which under run/overrun error conditions are reported.
    The only way to recover from this error condition would be to re-set the peripheral.
    The McASP driver configures the EDMA to service the events raised by McASP before configuring the peripheral.

  • Christoph,

    Some more details for Overrun and Underrun errors.
    Kindly refer the sections "24.2.4.7.2 Buffer Underrun Error" - Transmitter and "24.2.4.7.3 Buffer Overrun Error - Receiver" in TMS320C6747 TRM (spruh91).

  • Pubesh,

    thanks for your hints. Yes, I know these sections, but in my experience this is not true when the AFIFO is in use. So when the AFIFO is in use, the XUNDRN and ROVRN bits will never ever get set.

    I speculate that the AFIFO feeds the McASP with data even when it has run empty, and that this prevents the XUNDRN and ROVRN bits from getting set.

    And on the other hand, I did not find any UNDRN or OVRN bits for the AFIFO itself, so I think an overrun/underrun of the AFIFO itself is not reported.

    Do you agree to this analysis ?

    Any idea on how to get around this ?

    Thanks and best regards,

    Christoph

  • Christoph,

    Could you try the XBUFn and RBUFn registers are make to null for overcome underrun/overrun error.
    For example, (The below calls are done before the state machine rountines)  
    /* Write a 0, so that no underrun occurs after releasing the state machine */
    mcasp->regs->XBUF5 = 0;
    mcasp->regs->RBUF0 = 0;

  • Pubesh said:

    /* Write a 0, so that no underrun occurs after releasing the state machine */

    mcasp->regs->XBUF5 = 0;
    mcasp->regs->RBUF0 = 0;

    I don't quite understand what you ask from me. These registers are zero already, as our application doesn't use them.

    You say I should do an additional write onto these, but when? Once at init time, before setting up the ping-pong DMA that transports data from/to 0x01D02000 = RBUF/XBUF? How could that cure a problem that appears somewhere in the middle of run?

  • Christoph,

    Refer this file, it may help you
    evmc6747_v1\dsp\tests\aic3106\aic3106_loop_linein.c

     

    /*
     *  Copyright 2008 by Spectrum Digital Incorporated.
     *  All rights reserved. Property of Spectrum Digital Incorporated.
     */
    
    /*
     *  AIC3106 Loop Linein
     *
     */
    
    #include "evmc6747.h"
    #include "evmc6747_mcasp.h"
    #include "aic3106.h"
    
    static MCASP_Handle mcasp;
    
    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  AIC3106 Tone                                                            *
     *      Output a 1 kHz tone through the HEADPHONE/LINEOUT jacks             *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 aic3106_loop_linein( )
    {
        Int16 msec, sec;
        Int16 sample;
        Int32 sample_data = 0;
            
        /* Configure AIC3106 */
        EVMC6747_AIC3106_rset(  AIC3106_PAGESELECT, 0 );       // Select page 0
        EVMC6747_AIC3106_rset(  AIC3106_RESET, 0x80 );         // Reset AIC3106
        /* ------------------------------------------------------------------------ *
         *                                                                          *
         *  AIC3106 Setup                                                           *
         *                                                                          *
         *      AIC3106.MCLK = PLL1705.SCK02                                        *
         *      FS = ( AIC3106.MCLK * K ) / ( 2048 * P )                            *
         *                                                                          *
         *      For a FS=[48 kHz] & MCLK=[22.5792 MHz]                              *
         *          : 48kHz = ( 22.5792 MHz * K ) / ( 2048 * P )                    *
         *          : P = 2, K[J.D] = 8.7075                                        *
         *                                                                          *
         * ------------------------------------------------------------------------ */
        /* Configure AIC3106 registers */
    
        EVMC6747_AIC3106_rset(  3, 0x22 );  // 5 PLL A                            <- [PLL=OFF][Q=4][P=2]
        EVMC6747_AIC3106_rset(  4, 0x20 );  // 4 PLL B                            <- [J=8]
        EVMC6747_AIC3106_rset(  5, 0x6E );  // 5 PLL C                            <- [D=7075]
        EVMC6747_AIC3106_rset(  6, 0x23 );  // 6 PLL D                            <- [D=7075]
        EVMC6747_AIC3106_rset(  7, 0x0A );  // 7 Codec Datapath Setup             <- [FS=48 kHz][LeftDAC=LEFT][RightDAC=RIGHT]
        EVMC6747_AIC3106_rset(  8, 0x00 );  // 8  Audio Interface Control A       <- [BCLK=Slave][MCLK=Slave]
        EVMC6747_AIC3106_rset(  9, 0x00 );  // 9  Audio Interface Control B       <- [I2S mode][16 bit]
        EVMC6747_AIC3106_rset(  10, 0x00);  // 10 Audio Interface Control C       <- [Data offset=0]
        EVMC6747_AIC3106_rset(  15, 0 );    // 15  Left ADC PGA Gain              <- [Mute=OFF]
        EVMC6747_AIC3106_rset(  16, 0 );    // 16 Right ADC PGA Gain              <- [Mute=OFF]
        EVMC6747_AIC3106_rset(  19, 0x04 ); // 19  LINE1L to  Left ADC            <- [SingleEnd][Gain=0dB][Power=ON][SoftStep=OncePerFS]
        EVMC6747_AIC3106_rset(  22, 0x04 ); // 22  LINE1R to Right ADC            <- [SingleEnd][Gain=0dB][Power=ON][SoftStep=OncePerFS]
        EVMC6747_AIC3106_rset(  27, 0 );    // 27  Left AGC B                     <- [OFF]
        EVMC6747_AIC3106_rset(  30, 0 );    // 30 Right AGC B                     <- [OFF]
        EVMC6747_AIC3106_rset(  37, 0xE0 ); // 37 DAC Power & Output Dvr          <- [LeftDAC=ON][RightDAC=ON][HPLCOM=SingleEnd]
        EVMC6747_AIC3106_rset(  38, 0x10 ); // 38 High Power Output Dvr           <- [HPRCOM=SingleEnd][ShortCircuit=OFF]
        EVMC6747_AIC3106_rset(  43, 0 );    // 43  Left DAC Digital Volume        <- [Mute=OFF][Gain=0dB]
        EVMC6747_AIC3106_rset(  44, 0 );    // 44 Right DAC Digital Volume        <- [Mute=OFF][Gain=0dB]
        EVMC6747_AIC3106_rset(  47, 0x80 ); // 47 DAC_L1 to HPLOUT Volume         <- [Routed]
        EVMC6747_AIC3106_rset(  51, 0x09 ); // 51           HPLOUT Output         <- [Mute=OFF][Power=ON]
        EVMC6747_AIC3106_rset(  58, 0 );    // 58           HPLCOM Output         <- []
        EVMC6747_AIC3106_rset(  64, 0x80 ); // 64 DAC_R1 to HPROUT Volume         <- [Routed]
        EVMC6747_AIC3106_rset(  65, 0x09 ); // 65           HPROUT Output         <- [Mute=OFF][Power=ON]
        EVMC6747_AIC3106_rset(  72, 0 );    // 72           HPRCOM Output         <- []
        EVMC6747_AIC3106_rset(  82, 0x80 ); // 82 DAC_L1 to LEFT_LOP/M Volume     <- [Routed]
        EVMC6747_AIC3106_rset(  86, 0x09 ); // 83 LINE2R to LEFT_LOP/M Volume     <- []
        EVMC6747_AIC3106_rset(  92, 0x80 ); // 92 DAC_R1 to RIGHT_LOP/M Volume    <- [Routed]
        EVMC6747_AIC3106_rset(  93, 0x09 ); // 93           RIGHT_LOP/M Output    <- [Mute=OFF][Power=ON]
        EVMC6747_AIC3106_rset( 101, 0x01 ); // 101 GPIO Control Register B        <- [CODEC_CLKIN = CLKDIV_OUT]
        EVMC6747_AIC3106_rset( 102, 0 );    // 102 Clock Generation Control       <- [PLLCLK_IN and CLKDIV_IN use MCLK]
    
        /* Initialize MCASP1 */
        mcasp = &MCASP_MODULE_1;
        /* ---------------------------------------------------------------- *
         *                                                                  *
         *  McASP1 is in MASTER mode.                                       *
         *      BCLK & WCLK come from McASP1                                *
         *      DIN is used by write16/write32                              *
         *      DOUT is usec by read16/read32                               *
         *                                                                  *
         * ---------------------------------------------------------------- */
        mcasp->regs->GBLCTL  = 0;       // Reset
        mcasp->regs->RGBLCTL = 0;       // Reset RX
        mcasp->regs->XGBLCTL = 0;       // Reset TX
        mcasp->regs->PWRDEMU = 1;       // Free-running
    
          /* RX */
        mcasp->regs->RMASK      = 0xffffffff; // No padding used
        mcasp->regs->RFMT       = 0x00008078; // MSB 16bit, 1-delay, no pad, CFGBus
        mcasp->regs->AFSRCTL    = 0x00000112; // 2TDM, 1bit Rising, INTERNAL FS, word
        mcasp->regs->ACLKRCTL   = 0x000000AF; // Rising INTERNAL CLK,(from tx side)
        mcasp->regs->AHCLKRCTL  = 0x00000000; // INT CLK (from tx side)
        mcasp->regs->RTDM       = 0x00000003; // Slots 0,1
        mcasp->regs->RINTCTL    = 0x00000000; // Not used
        mcasp->regs->RCLKCHK    = 0x00FF0008; // 255-MAX 0-MIN, div-by-256
    
        /* TX */
        mcasp->regs->XMASK      = 0xffffffff; // No padding used
        mcasp->regs->XFMT       = 0x00008078; // MSB 16bit, 1-delay, no pad, CFGBus
        mcasp->regs->AFSXCTL    = 0x00000112; // 2TDM, 1bit Rising edge INTERNAL FS, word
        mcasp->regs->ACLKXCTL   = 0x000000AF; // ASYNC, Rising INTERNAL CLK, div-by-16
        mcasp->regs->AHCLKXCTL  = 0x00000000; // EXT CLK
        mcasp->regs->XTDM       = 0x00000003; // Slots 0,1
        mcasp->regs->XINTCTL    = 0x00000000; // Not used
        mcasp->regs->XCLKCHK    = 0x00FF0008; // 255-MAX 0-MIN, div-by-256
    
        mcasp->regs->SRCTL5     = 0x000D;     // MCASP1.AXR1[5] --> DIN
        mcasp->regs->SRCTL0     = 0x000E;     // MCASP1.AXR1[0] <-- DOUT
        mcasp->regs->PFUNC      = 0;          // All MCASPs
        mcasp->regs->PDIR       = 0x14000020; // All inputs except AXR0[5], ACLKX1, AFSX1
    
        mcasp->regs->DITCTL     = 0x00000000; // Not used
        mcasp->regs->DLBCTL     = 0x00000000; // Not used
        mcasp->regs->AMUTE      = 0x00000000; // Not used
    
        /* Starting sections of the McASP*/
        mcasp->regs->XGBLCTL |= GBLCTL_XHCLKRST_ON;                                    // HS Clk
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XHCLKRST_ON ) != GBLCTL_XHCLKRST_ON );  
        mcasp->regs->RGBLCTL |= GBLCTL_RHCLKRST_ON;                                    // HS Clk
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RHCLKRST_ON ) != GBLCTL_RHCLKRST_ON );
       
        mcasp->regs->XGBLCTL |= GBLCTL_XCLKRST_ON;                                     // Clk
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XCLKRST_ON ) != GBLCTL_XCLKRST_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RCLKRST_ON;                                     // Clk
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RCLKRST_ON ) != GBLCTL_RCLKRST_ON );
    
        mcasp->regs->XSTAT = 0x0000ffff;        // Clear all
        mcasp->regs->RSTAT = 0x0000ffff;        // Clear all
    
        mcasp->regs->XGBLCTL |= GBLCTL_XSRCLR_ON;                                      // Serialize
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XSRCLR_ON ) != GBLCTL_XSRCLR_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RSRCLR_ON;                                      // Serialize
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RSRCLR_ON ) != GBLCTL_RSRCLR_ON );
    
        /* Write a 0, so that no underrun occurs after releasing the state machine */
        mcasp->regs->XBUF5 = 0;
        mcasp->regs->RBUF0 = 0;
    
        mcasp->regs->XGBLCTL |= GBLCTL_XSMRST_ON;                                       // State Machine
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XSMRST_ON ) != GBLCTL_XSMRST_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RSMRST_ON;                                       // State Machine
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RSMRST_ON ) != GBLCTL_RSMRST_ON );
    
        mcasp->regs->XGBLCTL |= GBLCTL_XFRST_ON;                                        // Frame Sync
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XFRST_ON ) != GBLCTL_XFRST_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RFRST_ON;                                        // Frame Sync
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RFRST_ON ) != GBLCTL_RFRST_ON );
    
      
        /* Start by sending a dummy write */
        while( ! ( mcasp->regs->SRCTL5 & 0x10 ) );  // Check for Tx ready
        mcasp->regs->XBUF5 = 0;
    
        /* Play Tone */
        for ( sec = 0 ; sec < 5 ; sec++ )
        {
            for ( msec = 0 ; msec < 1000 ; msec++ )
            {
                for ( sample = 0 ; sample < 48 ; sample++ )
                {
                    /* Read then write the left sample */
                    while ( ! ( MCASP1_SRCTL0 & 0x20 ) );
                        sample_data = MCASP1_RBUF0_32BIT;
                    while ( ! ( MCASP1_SRCTL5 & 0x10 ) );
                        MCASP1_XBUF5_32BIT =  sample_data; 
    
                    /* Read then write the left sample */
                    while ( ! ( MCASP1_SRCTL0 & 0x20 ) );
                        sample_data = MCASP1_RBUF0_32BIT;
                    while ( ! ( MCASP1_SRCTL5 & 0x10 ) );
                        MCASP1_XBUF5_32BIT = sample_data; 
                }
            }
        }
    
        /* Close Codec */ 
        EVMC6747_AIC3106_rset( AIC3106_PAGESELECT, 0 ); // Select Page 0
        EVMC6747_AIC3106_rset( AIC3106_RESET, 0x80 );   // Reset the AIC3106
        
        /* Close McASP */
        mcasp->regs->SRCTL0 = 0; // Serializers
        mcasp->regs->SRCTL1 = 0;
        mcasp->regs->SRCTL2 = 0;
        mcasp->regs->SRCTL3 = 0;
        mcasp->regs->GBLCTL = 0;  // Global Reset
        return 0;
    }
    

  • Pubesh said:

    Refer this file, it may help you

    evmc6747_v1\dsp\tests\aic3106\aic3106_loop_linein.c

     

    /*
     *  Copyright 2008 by Spectrum Digital Incorporated.
     *  All rights reserved. Property of Spectrum Digital Incorporated.
     */
    
    /*
     *  AIC3106 Loop Linein
     *
     */
    
    #include "evmc6747.h"
    #include "evmc6747_mcasp.h"
    #include "aic3106.h"
    
    static MCASP_Handle mcasp;
    
    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  AIC3106 Tone                                                            *
     *      Output a 1 kHz tone through the HEADPHONE/LINEOUT jacks             *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 aic3106_loop_linein( )
    {
        Int16 msec, sec;
        Int16 sample;
        Int32 sample_data = 0;
            
        /* Configure AIC3106 */
        EVMC6747_AIC3106_rset(  AIC3106_PAGESELECT, 0 );       // Select page 0
        EVMC6747_AIC3106_rset(  AIC3106_RESET, 0x80 );         // Reset AIC3106
        /* ------------------------------------------------------------------------ *
         *                                                                          *
         *  AIC3106 Setup                                                           *
         *                                                                          *
         *      AIC3106.MCLK = PLL1705.SCK02                                        *
         *      FS = ( AIC3106.MCLK * K ) / ( 2048 * P )                            *
         *                                                                          *
         *      For a FS=[48 kHz] & MCLK=[22.5792 MHz]                              *
         *          : 48kHz = ( 22.5792 MHz * K ) / ( 2048 * P )                    *
         *          : P = 2, K[J.D] = 8.7075                                        *
         *                                                                          *
         * ------------------------------------------------------------------------ */
        /* Configure AIC3106 registers */
    
        EVMC6747_AIC3106_rset(  3, 0x22 );  // 5 PLL A                            <- [PLL=OFF][Q=4][P=2]
        EVMC6747_AIC3106_rset(  4, 0x20 );  // 4 PLL B                            <- [J=8]
        EVMC6747_AIC3106_rset(  5, 0x6E );  // 5 PLL C                            <- [D=7075]
        EVMC6747_AIC3106_rset(  6, 0x23 );  // 6 PLL D                            <- [D=7075]
        EVMC6747_AIC3106_rset(  7, 0x0A );  // 7 Codec Datapath Setup             <- [FS=48 kHz][LeftDAC=LEFT][RightDAC=RIGHT]
        EVMC6747_AIC3106_rset(  8, 0x00 );  // 8  Audio Interface Control A       <- [BCLK=Slave][MCLK=Slave]
        EVMC6747_AIC3106_rset(  9, 0x00 );  // 9  Audio Interface Control B       <- [I2S mode][16 bit]
        EVMC6747_AIC3106_rset(  10, 0x00);  // 10 Audio Interface Control C       <- [Data offset=0]
        EVMC6747_AIC3106_rset(  15, 0 );    // 15  Left ADC PGA Gain              <- [Mute=OFF]
        EVMC6747_AIC3106_rset(  16, 0 );    // 16 Right ADC PGA Gain              <- [Mute=OFF]
        EVMC6747_AIC3106_rset(  19, 0x04 ); // 19  LINE1L to  Left ADC            <- [SingleEnd][Gain=0dB][Power=ON][SoftStep=OncePerFS]
        EVMC6747_AIC3106_rset(  22, 0x04 ); // 22  LINE1R to Right ADC            <- [SingleEnd][Gain=0dB][Power=ON][SoftStep=OncePerFS]
        EVMC6747_AIC3106_rset(  27, 0 );    // 27  Left AGC B                     <- [OFF]
        EVMC6747_AIC3106_rset(  30, 0 );    // 30 Right AGC B                     <- [OFF]
        EVMC6747_AIC3106_rset(  37, 0xE0 ); // 37 DAC Power & Output Dvr          <- [LeftDAC=ON][RightDAC=ON][HPLCOM=SingleEnd]
        EVMC6747_AIC3106_rset(  38, 0x10 ); // 38 High Power Output Dvr           <- [HPRCOM=SingleEnd][ShortCircuit=OFF]
        EVMC6747_AIC3106_rset(  43, 0 );    // 43  Left DAC Digital Volume        <- [Mute=OFF][Gain=0dB]
        EVMC6747_AIC3106_rset(  44, 0 );    // 44 Right DAC Digital Volume        <- [Mute=OFF][Gain=0dB]
        EVMC6747_AIC3106_rset(  47, 0x80 ); // 47 DAC_L1 to HPLOUT Volume         <- [Routed]
        EVMC6747_AIC3106_rset(  51, 0x09 ); // 51           HPLOUT Output         <- [Mute=OFF][Power=ON]
        EVMC6747_AIC3106_rset(  58, 0 );    // 58           HPLCOM Output         <- []
        EVMC6747_AIC3106_rset(  64, 0x80 ); // 64 DAC_R1 to HPROUT Volume         <- [Routed]
        EVMC6747_AIC3106_rset(  65, 0x09 ); // 65           HPROUT Output         <- [Mute=OFF][Power=ON]
        EVMC6747_AIC3106_rset(  72, 0 );    // 72           HPRCOM Output         <- []
        EVMC6747_AIC3106_rset(  82, 0x80 ); // 82 DAC_L1 to LEFT_LOP/M Volume     <- [Routed]
        EVMC6747_AIC3106_rset(  86, 0x09 ); // 83 LINE2R to LEFT_LOP/M Volume     <- []
        EVMC6747_AIC3106_rset(  92, 0x80 ); // 92 DAC_R1 to RIGHT_LOP/M Volume    <- [Routed]
        EVMC6747_AIC3106_rset(  93, 0x09 ); // 93           RIGHT_LOP/M Output    <- [Mute=OFF][Power=ON]
        EVMC6747_AIC3106_rset( 101, 0x01 ); // 101 GPIO Control Register B        <- [CODEC_CLKIN = CLKDIV_OUT]
        EVMC6747_AIC3106_rset( 102, 0 );    // 102 Clock Generation Control       <- [PLLCLK_IN and CLKDIV_IN use MCLK]
    
        /* Initialize MCASP1 */
        mcasp = &MCASP_MODULE_1;
        /* ---------------------------------------------------------------- *
         *                                                                  *
         *  McASP1 is in MASTER mode.                                       *
         *      BCLK & WCLK come from McASP1                                *
         *      DIN is used by write16/write32                              *
         *      DOUT is usec by read16/read32                               *
         *                                                                  *
         * ---------------------------------------------------------------- */
        mcasp->regs->GBLCTL  = 0;       // Reset
        mcasp->regs->RGBLCTL = 0;       // Reset RX
        mcasp->regs->XGBLCTL = 0;       // Reset TX
        mcasp->regs->PWRDEMU = 1;       // Free-running
    
          /* RX */
        mcasp->regs->RMASK      = 0xffffffff; // No padding used
        mcasp->regs->RFMT       = 0x00008078; // MSB 16bit, 1-delay, no pad, CFGBus
        mcasp->regs->AFSRCTL    = 0x00000112; // 2TDM, 1bit Rising, INTERNAL FS, word
        mcasp->regs->ACLKRCTL   = 0x000000AF; // Rising INTERNAL CLK,(from tx side)
        mcasp->regs->AHCLKRCTL  = 0x00000000; // INT CLK (from tx side)
        mcasp->regs->RTDM       = 0x00000003; // Slots 0,1
        mcasp->regs->RINTCTL    = 0x00000000; // Not used
        mcasp->regs->RCLKCHK    = 0x00FF0008; // 255-MAX 0-MIN, div-by-256
    
        /* TX */
        mcasp->regs->XMASK      = 0xffffffff; // No padding used
        mcasp->regs->XFMT       = 0x00008078; // MSB 16bit, 1-delay, no pad, CFGBus
        mcasp->regs->AFSXCTL    = 0x00000112; // 2TDM, 1bit Rising edge INTERNAL FS, word
        mcasp->regs->ACLKXCTL   = 0x000000AF; // ASYNC, Rising INTERNAL CLK, div-by-16
        mcasp->regs->AHCLKXCTL  = 0x00000000; // EXT CLK
        mcasp->regs->XTDM       = 0x00000003; // Slots 0,1
        mcasp->regs->XINTCTL    = 0x00000000; // Not used
        mcasp->regs->XCLKCHK    = 0x00FF0008; // 255-MAX 0-MIN, div-by-256
    
        mcasp->regs->SRCTL5     = 0x000D;     // MCASP1.AXR1[5] --> DIN
        mcasp->regs->SRCTL0     = 0x000E;     // MCASP1.AXR1[0] <-- DOUT
        mcasp->regs->PFUNC      = 0;          // All MCASPs
        mcasp->regs->PDIR       = 0x14000020; // All inputs except AXR0[5], ACLKX1, AFSX1
    
        mcasp->regs->DITCTL     = 0x00000000; // Not used
        mcasp->regs->DLBCTL     = 0x00000000; // Not used
        mcasp->regs->AMUTE      = 0x00000000; // Not used
    
        /* Starting sections of the McASP*/
        mcasp->regs->XGBLCTL |= GBLCTL_XHCLKRST_ON;                                    // HS Clk
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XHCLKRST_ON ) != GBLCTL_XHCLKRST_ON );  
        mcasp->regs->RGBLCTL |= GBLCTL_RHCLKRST_ON;                                    // HS Clk
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RHCLKRST_ON ) != GBLCTL_RHCLKRST_ON );
       
        mcasp->regs->XGBLCTL |= GBLCTL_XCLKRST_ON;                                     // Clk
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XCLKRST_ON ) != GBLCTL_XCLKRST_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RCLKRST_ON;                                     // Clk
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RCLKRST_ON ) != GBLCTL_RCLKRST_ON );
    
        mcasp->regs->XSTAT = 0x0000ffff;        // Clear all
        mcasp->regs->RSTAT = 0x0000ffff;        // Clear all
    
        mcasp->regs->XGBLCTL |= GBLCTL_XSRCLR_ON;                                      // Serialize
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XSRCLR_ON ) != GBLCTL_XSRCLR_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RSRCLR_ON;                                      // Serialize
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RSRCLR_ON ) != GBLCTL_RSRCLR_ON );
    
        /* Write a 0, so that no underrun occurs after releasing the state machine */
        mcasp->regs->XBUF5 = 0;
        mcasp->regs->RBUF0 = 0;
    
        mcasp->regs->XGBLCTL |= GBLCTL_XSMRST_ON;                                       // State Machine
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XSMRST_ON ) != GBLCTL_XSMRST_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RSMRST_ON;                                       // State Machine
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RSMRST_ON ) != GBLCTL_RSMRST_ON );
    
        mcasp->regs->XGBLCTL |= GBLCTL_XFRST_ON;                                        // Frame Sync
        while ( ( mcasp->regs->XGBLCTL & GBLCTL_XFRST_ON ) != GBLCTL_XFRST_ON );
        mcasp->regs->RGBLCTL |= GBLCTL_RFRST_ON;                                        // Frame Sync
        while ( ( mcasp->regs->RGBLCTL & GBLCTL_RFRST_ON ) != GBLCTL_RFRST_ON );
    
      
        /* Start by sending a dummy write */
        while( ! ( mcasp->regs->SRCTL5 & 0x10 ) );  // Check for Tx ready
        mcasp->regs->XBUF5 = 0;
    
        /* Play Tone */
        for ( sec = 0 ; sec < 5 ; sec++ )
        {
            for ( msec = 0 ; msec < 1000 ; msec++ )
            {
                for ( sample = 0 ; sample < 48 ; sample++ )
                {
                    /* Read then write the left sample */
                    while ( ! ( MCASP1_SRCTL0 & 0x20 ) );
                        sample_data = MCASP1_RBUF0_32BIT;
                    while ( ! ( MCASP1_SRCTL5 & 0x10 ) );
                        MCASP1_XBUF5_32BIT =  sample_data; 
    
                    /* Read then write the left sample */
                    while ( ! ( MCASP1_SRCTL0 & 0x20 ) );
                        sample_data = MCASP1_RBUF0_32BIT;
                    while ( ! ( MCASP1_SRCTL5 & 0x10 ) );
                        MCASP1_XBUF5_32BIT = sample_data; 
                }
            }
        }
    
        /* Close Codec */ 
        EVMC6747_AIC3106_rset( AIC3106_PAGESELECT, 0 ); // Select Page 0
        EVMC6747_AIC3106_rset( AIC3106_RESET, 0x80 );   // Reset the AIC3106
        
        /* Close McASP */
        mcasp->regs->SRCTL0 = 0; // Serializers
        mcasp->regs->SRCTL1 = 0;
        mcasp->regs->SRCTL2 = 0;
        mcasp->regs->SRCTL3 = 0;
        mcasp->regs->GBLCTL = 0;  // Global Reset
        return 0;
    }
    

    Hi Pubesh,

    no, this file does not help, because it only uses the (slow) single word CPU access to the McASP.

    This example uses neither AFIFO nor EDMA, so it does not help in tracking down this AFIFO / EDMA issue.

  • I have suggested whatever I known about the MCASP and EDMA. Mean time I will try and share some details, Probably you will get some more detailed support from someone better able to help.

  • Pubesh,

    thanks for your efforts.

    In the mean time I am wondering if this might be a design flaw of C6747, that someone just forgot to make the AFIFO overrun/underrun status visible to the DSP.

    So if the C6747 does not give me that info, I will now try to detect this error condition on the other side of the McASP wires, that's the DM648 side in my hardware setup.

    Best regards,

    Christoph

  • Christoph,

    Did you try to detect the error condition on the other side(DM648) of the McASP wires?
    Is there any update from your side and Please let us know, if your problem got fixed.

  • Pubesh,

    yes, I am now sending test data blocks with known contents over the McASP and then check on the other side if they are still intact or if they contain errors in the data.

    Still I don't see any error flags rise on C6747, but the data consistency check on the other side allows me to detect errors there and thus serves as a replacement for the missing error flags on C6747.

    So from my point of view the problem is solved.

    However generally speaking, it would be nice for a future revision of C6747 DSP to add error flags for AFIFO overrun/underrun somewhere in the error registers. There are plenty of "reserved" bits e. g. in RSTAT and XSTAT where such error flags for the AFIFO could easily be added.

  • Christoph,

     Thanks for your kind reply.
     If you are correct as it appears you are then thank you for bringing this to our attention.