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.

Dropping audio samples with EDMA and McASP



4721.edma3_audio_testr.zip

Attached are 4 files of for a test case to try to make edma with the McASP work on our hardware, and Logic PD zoom OMAP_L138 EVM

This is a modification of the source found at 

http://software-dl.ti.com/dsps/dsps_public_sw/c6000/web/c6747_audio_edma_app/latest/index_FDS.html

c6747_audio_edma_v4.zip


There are 4 test cases that can be activated at compile time with the following 3 defines
_OMAP_L138  tells the #defines to use the codecs and hardware for the Logic PD zoom OMAP_L138 EVM
_NORGE_CODECS tells the #defines to use the codecs and hardware of our design
_DO_AUDIO_EDMA tells the defines to use edma with McASP instead of a simple polling loop to transfer the audio from rec to transmit.


Observation:
When using _OMAP_L138 alone on evm works fine i.e the simple polling loop.
When using _NORGE_CODECS alone works fine i.e the simple polling loop.
When using _OMAP_L138 with _DO_AUDIO_EDMA on evm works fine.
When using _NORGE_CODECS with _DO_AUDIO_EDMA on our hardware I am missing / dropping samples... etc.

The only real changes I can see, other the using different ports / clocks / pins etc., on the hardware,
is we are using a 24 bit converter and the evm is using 16 bit converters, hence the change to
MCASP->XFMT and MCASP->XFMT in local_OMALP_L138_MCASP_init().


Note:
The audio_edma_c6747.tcf file has not been modified

Changes to mcasp.c
#ifdef _OMAP_L138
void *mcasp_xmt0_register = (void *)(MCASP_REG_BASE + 0x022C);  // mcasp->XBUF11  xmit on 11
void *mcasp_rcv0_register = (void *)(MCASP_REG_BASE + 0x02B0);  // mcasp->RBUF12  rec on 12
#else

#ifdef _NORGE_CODECS
void *mcasp_xmt0_register = (void *)(MCASP_REG_BASE + 0x0220); // mcasp->XBUF8  xmit on 8

#ifdef _NO_AUX9_XMIT
#else
void *mcasp_xmt1_register = (void *)(MCASP_REG_BASE + 0x0224); // mcasp->XBUF9 xmit on 9 
#endif

void *mcasp_rcv0_register = (void *)(MCASP_REG_BASE + 0x0280); // mcasp->RBUF0 rec on 0
#endif
#endif

Changes when using _NORGE_CODECS

in local_OMALP_L138_MCASP_init();

MCASP->RFMT = 0x000080F8;  //is 32 bit
MCASP->AFSRCTL = 0x00000000;  // Not using reciever for frame sync generation
MCASP->ACLKRCTL   = 0x00000000;  // Not using the Reciever Clock for any clock generation although the OMAP_MCLK is connected to AHCLKR
MCASP->RCLKCHK    = 0x00000000; // Not doing any clock checking or McASP AMUTE control so safe to ignore and use defualt for RCLKCHK  NOTE: Makes no difference if it's set like _OMAP_L138 or not.
MCASP->XFMT  = 0x000080F8; //is 32 bit
MCASP->ACLKXCTL   = 0x000000A7;  // divide by 8 for NORGE
MCASP->XCLKCHK    = 0x00000000;  // Not doing any clock checking or McASP AMUTE control so safe to ignore and use defualt for RCLKCHK  NOTE: Makes no difference if it's set like _OMAP_L138 or not.
MCASP->SRCTL8    = 0x000D; //  8 = xmit
MCASP->SRCTL0    = 0x000E; // 0 = rec
MCASP->PDIR       = 0x14000100; // aux 8 out NO aux9 //

see changes in mcasp_open() when _NORGE_CODECS is actave

There are no changes in audio.c
There are no changes in edma3.c

Changes to edma.h
#ifdef _OMAP_L137
#define EDMA_MCASPTXCH       3   // EDMA channel for McASP1 TX
#define EDMA_MCASPRXCH       2   // EDMA channel for McASP1 RX
#endif

#ifdef _OMAP_L138
#define EDMA_MCASPTXCH       1   // EDMA channel for McASP0 TX
#define EDMA_MCASPRXCH       0   // EDMA channel for McASP0 RX
#endif

#ifdef _NORGE_CODECS
#define EDMA_MCASPTXCH       1   // EDMA channel for McASP0 TX
#define EDMA_MCASPRXCH       0   // EDMA channel for McASP0 RX
#endif

I am at a loss of where to look to address or fix this problem. i.e. missing / dropping samples... etc. with edma on our hardware.

I have observed that RDMAERR bit in RSTAT is not set and
no XDMAERR bit set in XSTAT.

Please help !

Thanks

  • Brian,

       If assuming an I2S protocol to transfer the audio, then there will be no difference in the clocking scheme at all between a 16-bit and 24 bit codec, since I2S format requires 32 bit clocks (ACLK) per sample regardless of the bit depth. The codec difference shouldn't contribute to the sample dropping.

       I'm not exactly sure how the EDMA is set up for transfers in the above program, but since audio is time sensitive, I would recommend using a Ping-Pong buffer with regards to the EDMA so that while the DSP is processing one set of  audio samples, the McASP can fill up the other buffer.

    Also, I would highly recommend that you switch from polling to interrupt driven McASP capture to guarantee that you don't miss any samples since the captured data is time-sensitive.

  • It is a Ping-Pong buffer from audio.c file... !!

    It is interrupt driven based on edma see void edma3ccIsr() below from edma3.c !

    Please have a look at the code !  If not my code then---

    http://software-dl.ti.com/dsps/dsps_public_sw/c6000/web/c6747_audio_edma_app/latest/index_FDS.html

    c6747_audio_edma_v4.zip

    Same thing, same structure.....

    --------------------------------------------------------------------------------------------------------------------------

    Regarding   >"I would highly recommend that you switch from polling to interrupt driven McASP capture to guarantee that you don't miss any samples since the captured data is time-sensitive".

    Please "carefully" re-read the original post regarding compile time #defines and there use case.... i.e. the difference between the polling and edma use.

    I added a sign table in order to generated a sign wave for the xmit data to try to isolate if the missing sample issue, using edma, is related to the input / rec data, or the transmit / xmt data. 
    Using the sine data the output signal is NOT Missing samples, i.e. transmit side is working.

    --------------------------------------------------------------------------------

    static void process(void *in_buf, void *out_buf)
    {
     
      int16_t sample;
      Int32  dataIn[48];
     
        // process data from in_buf and but result in out_buf

        for (sample = 0; sample < 48; sample++)
            ((Int32 *)out_buf)[sample] = (sinetable[sample] << 15) | 0x00000000;  <-----------------  USE Sine table to output sign wave...

    OR for audio in to audio out----
            ((Int32 *)out_buf)[sample] = ((Int32 *)in_buf)[sample];  <--------------------- Pass in to out.
    }

    //-----------------------------------------------------------------------------

    static void audio_run(void)
    {
        while (1)
        {
            // ping
            SEM_pend(&rcv_ping_sem, SYS_FOREVER);
            SEM_pend(&xmt_ping_sem, SYS_FOREVER);
            process(rcv_ping_L, xmt_ping_L);
            process(rcv_ping_R, xmt_ping_R);

            // pong
            SEM_pend(&rcv_pong_sem, SYS_FOREVER);
            SEM_pend(&xmt_pong_sem, SYS_FOREVER);
            process(rcv_pong_L, xmt_pong_L);
            process(rcv_pong_R, xmt_pong_R);
        }
    }

    --------------------------------------------------------------

    and from edma3.c

    void edma3ccIsr()
    {
        while(edmaCcRegs->IPR)
        {
            if (edmaCcRegs->IPR & (1 << EDMA_RCV_PING_TCC))    // receive channel (ping)
            {
                EdmaIntClear(EDMA_RCV_PING_TCC);
                SEM_post(&rcv_ping_sem);
            }

            if (edmaCcRegs->IPR & (1 << EDMA_RCV_PONG_TCC))    // receive channel (pong)
            {
                EdmaIntClear(EDMA_RCV_PONG_TCC);
                SEM_post(&rcv_pong_sem);
            }

            if (edmaCcRegs->IPR & (1 << EDMA_XMT_PING_TCC))    // transmit channel (ping)
            {
                EdmaIntClear(EDMA_XMT_PING_TCC);
                SEM_post(&xmt_ping_sem);
            }

            if (edmaCcRegs->IPR & (1 << EDMA_XMT_PONG_TCC))    // transmit channel (pong)
            {
                EdmaIntClear(EDMA_XMT_PONG_TCC);
                SEM_post(&xmt_pong_sem);
            }
        }

        return;
    }

    -------------------------------------------------------------------------------------

    NOTE: I have also been made aware of

    Advisory 2.1.1 DMA Access to L2 RAM Can Stall When DMA and C674x CPU Command Priorities

    Are Equal

    http://www.ti.com/general/docs/lit/getliterature.tsp?literatureNumber=sprz301f&fileType=pdf

    Reference to the errata I don't see any Device Revision Codes on the physical part as shown in Fig 1 ether on our hardware nor the Logic PD SOM part.  It says
    Additionally the ROM ID code may be used to
    distinguish Revision 2.1 from Revision 2.0

    How do I do that ? I do know that 0xFFFD0000 has d800k006 at that location.... Perhaps that's not what the above is referring to ?

    Further I have read Advisory 2.1.1 several times and don't understand...
    I'm going to have to have (TI's) or ? help in trying to "decode" if I have this problem, and, if so what the proper work around should be....

    Thanks  Brian

     

     

  • Are the shared data buffers in L1 or L2 memory?  If not, you will need to perform some manual cache operations to maintain coherence.

    Can you provide more detail related to the data loss?  How much data and how often? Is it periodic?  Is it correlated to anything else in the system?

    Here are some other thoughts:

    • Turn on the audio FIFO for the McASP (even with theshold=1 if you're concerned about latency).  Reading from the FIFO rather than config bus will also give a performance improvement.
    • Take a look at your EDMA assignments
      • What other EDMA traffic is being assigned to the same queue?  For best latency, make this the only transfer happening on the associated TC.
      • What priority is the TC on the SCR interconnect?  Make it the highest priority.

     

  •  

    >Are the shared data buffers in L1 or L2 memory?  If not, you will need to perform some manual cache operations to maintain coherence.

    Everything is in internal memory.  External or other memory is not involved in this example.

    >Can you provide more detail related to the data loss? 

    Attached is a snapshot of a animated graph /probe point for rcv_ping_L of audio.c
    As you can see it is doping samples on the input.  (As long as the animated brake point is not messing up the actual rec ? could be ?)

    >How much data and how often?    See attached (if that helps) ?

    Actuall view of DtoA out with a sign wave in to AtoD.

    >Is it periodic?   (? see above)

    >Is it correlated to anything else in the system?  Not that I can tell....

    Here are some other thoughts:

    • Turn on the audio FIFO for the McASP (even with theshold=1 if you're concerned about latency).  Reading from the FIFO rather than config bus will also give a performance improvement.

    FIFO on both rec and transmit does not change the problem.

    >Take a look at your EDMA assignments

    >What other EDMA traffic is being assigned to the same queue?  For best latency, make this the only transfer happening on the associated TC

    It is the only traffic and the only thing going on that I am aware of except for DSP/BIOS running...

    >What priority is the TC on the SCR interconnect?  Make it the highest priority.

    edma3ccIsr is on HWI_INT8 have not changed any of this from what is in

    http://software-dl.ti.com/dsps/dsps_public_sw/c6000/web/c6747_audio_edma_app/latest/index_FDS.html

    c6747_audio_edma_v4.zip

     

    Please note the problem has, (I think) been isolated to the receive side as a sign wave table sending to the transmitter does work.

    Also all this code works on the EVM, out hardware is "very similar to the EVM" with these changes.... The converters are on McASP AUX8 for transmit and AUX0 for receive, plus we use 24 bit converters, not 16 bit.  On our hardware we also generate all the clocks for the converters so the converters act as slaves... 

    Again all the McASP (I believe is set up correctly, because it works fine with polling etc.).....

    There is also this erata that I have yet to understand etc....

    ------------------------------------------------------

    Advisory 2.1.1 DMA Access to L2 RAM Can Stall When DMA and C674x CPU Command Priorities

    Are Equal

     http://www.ti.com/general/docs/lit/getliterature.tsp?literatureNumber=sprz301f&fileType=pdf

    ------------------------------------------------------

    I'm going to have to have  help in trying to "decode" if I have this problem, and, if so what the proper work around should be....

    Thanks All

    Brian

     

     

     

     

     

  • (From my phone)

    The priorities I was referring to are in the MSTPRI registers. Please check. 

    That errata has a very simple solution (if I'm thinking of the right one).  The registers it references can be found in the Megamodule guide. 

  • Brian was able to get this one figured out himself.  Here's a summary of the steps he missed from the initialization procedure in Section 25.2.4.1.2 “Transmit/Receive Section Initialization” of the TRM:

    • Step 4 says, “Start the respective high-frequency serial clocks AHCLKX and/or AHCLKR. This step is necessary even if external high-frequency serial clocks are used
    • Step 10 says, “Release frame sync generators from reset. Note that it is necessary to release the internal frame sync generators from reset, even if an external frame sync is being used, because the frame sync error detection logic is built into the frame sync generator”