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.

omap-l138 mcbsp events stop

Other Parts Discussed in Thread: OMAP-L138

I am experiencing an issue where the mcbsp1 transmit stops functioning.  I am using DSP/BIOS 5, with pspdrivers 01_30_01.  This does not appear to be a BIOS specific issue, so I'll post here to the omap-l138 forum.

So, here's what is happening.  The system is humming along, streaming audio data in/out using the mcbsp and the data goes elsewhere in the system.  Eventually, given a long enough run time (5 minutes? -- used to be less, I think), I start getting a timeout error on the SIO_reclaim, essentially, my packet was not transmitted before a timer went off and said something is wrong.  I hunted through the PaRAM for this channel, and everything looks normal.  The PaRAM entry for the channel is identical to one of the two linked PaRAM ping-pongs, and is not changing, so something happened when that particular PaRAM entry was loaded.

I then looked at the McBSP FIFO for this channel.  The write FIFO level was zero!  That is definitely a problem.  I disabled the write FIFO and re-enabled it, instantly seeing if fill up to 0x40, and also saw the proper decrease in the cCnt of the PaRAM entry -- hence DMA was working just fine.  Again though, everything looked static, and so the fifo was not being used.

Note that the transmit bit clock and frame clock (omap-l138 is master) were moving the entire time.

Now, I tried writing a word to the DXR.  This had the effect of bringing the mcbsp back into working order.  DMA requests are being served and data is again flowing.

The question is, how can this occur?  How can the fifo be empty and yet have the dma sitting there waiting to fill it?  And, once the fifo is full, how is it possible that the mcbsp was not removing items from the fifo?

  • Mike,

      Did the system detect a McBSP overrun / underun condition? This might be causing the McBSP to shut down if the software is configured to do so.

    Is the thread that services the EDMA3 preempted somehow? You could check to see if this is a McBSP issue by disabling all other threads, and simple stream data to and from the McBSP and see if you can get it to break again.

     

  • Drew,

    I will look into that.  I do not think the software is intentionally shutting anything down.  I did all of this debugging over JTAG and all I had to do to get it up and running again was to touch the two registers mentioned above (meaning it was already setup and ready to go, just needed a kick).

    Is either the mcbsp fifo or the DMA edge triggered?  It seems to be the case, based on the code TI wrote relating to the mcbsp fifo, that an event generated by the mcbsp fifo gets lost unless the DMA is armed, hence the code disables/reenables the fifo in order to get the event again.

    Mike

  • Drew,

    The McBSP is reporting XEMPTY=0x0, but there is no code looking for that.  If I only attempt writing to the DXR register, nothing really noticeable happens (it is probably transmitted, but I wasn't watching).  It looks like I must first reset the McBSP FIFO (disable and then re-enable).  Even if I had written to the DXR while the problem was occurring but before resetting the FIFO, the operation does not continue.  I must write a word to DXR after resetting the FIFO for everything to continue.

    I tested a simple audio loopback on the McBSP (so incoming data is rerouted to be the outgoing data).  I have not yet seen that cause an issue.

    What does cause an issue is this setup:  incoming audio data from the McBSP is processed and transmitted out the McASP (operating in more of a SPI-like mode, not continuous data).  At the same time data is being transmitted out the McASP, a similar amount is being received.  When a full packet is received, it is decoded into a buffer that is transmitted back out the McBSP.  If decoding fails or there was no data, then no buffer is given to the McBSP driver (which already would have inserted a dummy dma transfer to keep the McBSP happy).

    Mike

  • The threads that are running are thus:

    - mcbsp input

    - mcbsp output

    - tx task (handles mcasp input and output)

    - There are 3 other tasks, but they are generally blocked on a semaphore or similar (such as a dsplink task)

    I would not think this is taxing the DSP much at all.

    In addition, I tested disabling the McBSP FIFO.  I still run into the issue, but to fix it I need only to write a word to DXR and then the DMA requests resumed.

  • Mike,

      First of all, that's for the additional information in regards to your system. I was not aware that you were using both the McBSP and the McASP.

     

    The XEMPTY bit is interesting. It is only set under two conditions

    [1] Initially once the state machines are taken out of reset

    [2] If all the data is shifted from the XSR before another word is written to the DXR.

     

    I copied an except from the McBSP User's Guide

    During an underflow condition, the transmitter continues to transmit the old data in DXR for every new
    frame sync signal FSX (generated by an external device, or by the internal sample rate generator) until a
    new element is loaded into DXR by the CPU or the EDMA controller.

    XEMPTY is deactivated (XEMPTY = 1) when this new element in DXR is transferred to XSR. In the case when the FSX is generated by a
    DXR-to-XSR copy (FSXM = 1 in PCR and FSGM = 0 in SRGR), the McBSP does not generate any new
    frame sync until new data is written to the DXR and a DXR-to-XSR copy occurs.


    Since you have tested an audio loopback through the McBSP without an apparent issue, it doesn't seem like the McBSP is the suspect here. I'm not sure how you trigger the EDMA3 from the McBSP, however if the frame sync generator gets disabled from the XEMPTY condition, your EDMA3 McBSP event might not be getting generated. Which would eventually cause the McBSP FIFO to empty out.

    If you can prove that the EDMA3 transfers are always being submitted to the McBSP FIFO then I'm wrong, but that's where I would focus given the results of some of your experiments.

     

     

     

  • Drew,

    FSGM=1, so the frame sync never stops.  The EDMA3 transfer is primed and ready, as shown by the ability to give it a kick from the mcbsp side.  I'm going to hunt around and see if there is any code that could have cleared the edma3 Event Register.

    Mike

  • I set the bit for event 5 in the edma3 Event Set Register.  This also gets the transfer going again.  It seems very plausible that something hit the ECR before the DMA saw it, but I have yet to confirm that.

  • I added hardware watchpoints on edma3 ECR register (0x01C02208 for DSP and 0x01C02008 for ARM).  The DSP side was able to add a further condition that the write be something involving 0x20, which should be event 5.  I have not seen these hit before the dma stops.  I'm not sure now what could then cause the DMA to stop, especially to have it start on a fresh new request (the PaRAM for channel 5 is identical to one of the PaRAM entries as part of the ping-pong).

  • Mike,

    Thanks for the info. From above, you were able to  get the McBSP going by itself via a loopback right?Does this within the device, or does the data go off the device through some other IC and then back in?

    You could try to start with that setup, and then add back all the other variables (one at a time) until it breaks again. That way you'd at least have some help narrowing down the sequence of events that leads up to the McBSP transfers stopping after some time.

     

  • For the loopback configuration, 1024 audio samples are read in (I2S bus) before they are then redirected towards the output.  So there's an audio codec involved, but that just changes what data is read in.  The data otherwise sits in DDR until it is transmitted.

    I'll try adding back in some of the pieces and see what happens.  I put breakpoints on the CC/TC error interrupts, and I'm not getting any hits.  Also, the ARM side is masked off of this particular dma channel, so it shouldn't be able affect it.

  • I added back everything except that I made one change.  There is not always a valid packet received back over the mcasp and in that instance, I do not pass a buffer to the mcbsp.  There is a "loopjob" that gets linked into the edma transfer if there is no buffer, so the mcbsp will still constantly receive data.  The loopjob is a PaRAM entry that transfers both a left word and a right word (remember, audio) and then switches to the next edma link (which could be another loopjob buffer).

    I made a change so that there is always a buffer being handed off to the mcbsp, hence the loopjob should be used very minimally.  I have not yet encountered a problem.  The problem is that this does not solve why the edma failed before.  Just shows that the rest of the code seems to be doing everything it is supposed to, and not wandering off into random memory.

  • Robert,

     

    Mike Brudevold said:
    The problem is that this does not solve why the edma failed before. 

    No - but it does give you a critical piece of information. The McBSP functions correctly when you pass it a buffer of data. This rules out the McBSP as the root cause of the problem. You can therefore eliminate the McBSP FIFO hardware from the equation.

    When you say the McASP packet is not always valid - do you mean that you do not always receive a packet, or do you mean that you receive a packet, but the data is not valid?. (i.e. it is corrupted in some manner).

     

    If you are not receiving -anything- from MCASP that sounds like there is some setup issue in the McASP that is preventing the EDMA transfer from being send to the McBSP. You loopjob is obviously a suitable workaround for now.

     

     

  • The McASP is talking to a radio chip, so the data is subject to interference and other problems associated with being wireless.  Hence, there is not always valid data.

    I created a mock version of the problems that can happen in the McASP, by looping back the McBSP input to the output, but occasionally dropping data.  I had no problems.  This is what leads me to believe there may be some sort of timing dependency that breaks it.

  • I have analyzed the code, and as far as I can tell, there is no period of time in which a valid edma PaRAM entry does not exist.  The edma channel is never stopped.  It likely either has two ping-pong PaRAM entries, or has the loopjob linked to itself.  This is what confuses me about how it could ever fail.  Are there ways to modify PaRAM entries such that a transfer fails?

  • Mike,

    There are different types of Parameter RAM (PaRAM) set entries that are defined in the EDMA3 User's Guide. One set is a Null PaRAM set which will appear to be an active entry, but will set an error condition. Another is a dummy PaRAM set, which is a legal transfer of 0 bytes. All others are typically user defined PaRAM entries.

     

  • I am not seeing anything in the EMR, so that would rule out NULL PaRAM sets.  I'll double-check that it is not possible that a dummy PaRAM set is added.  But the PaRAM set that gets left when everything fails is neither a dummy nor a NULL.  Since I can't catch the PaRAM entry that occurred before the failure, I only know that the latest PaRAM entry was linked in either by modifying one of the ping-pong entries to make the link, or by modifying the channel's PaRAM entry, in the case that the former PaRAM entry is linked to itself.

  • I played around with a test case from Mike for a LONG time and got things working again by making the following changes in edma3resmgr.c:

     

     

     

     

     

     

    /* Local MemCopy function */

    void

     

     

    edma3MemCpy(void *dst, const void *src, unsigned int len)

    {

     

     

    unsigned int i=0u;

     

     

    const unsigned int *sr;

     

     

    unsigned int *ds;

     

    assert ((src != NULL) && (dst != NULL));

     

     

     

    len = len >> 2;

     

    // convert "len" from bytes to words

     

    sr = (

    const unsigned int *)src;

    ds = (

    unsigned int *)dst;

     

     

     

    for( i=0;i<len;i++)

    {

    *ds=*sr;

    ds++;

    sr++;

    }

     

     

     

    return;

    In a nutshell I made that function do 32-bit accesses rather than 8-bit accesses.  Now fundamentally there is nothing illegal about doing 8-bit accesses to the Parameter RAM.  However, my theory is that a link was occuring in the midst of these 8-bit accesses causing the EDMA to send data to the wrong address.  When this happens the data would never land in the McBSP FIFO and so the FIFO would not ever send another event, hence the deadlock.  On my end the code ran over night without any failures and it has been running successfully for Mike as well.

    I think we're calling this one closed!

    Brad