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.

DMA McBSP stall problem in Delfino

Other Parts Discussed in Thread: ADS1216

I'm putting the polish on a Delfino-based measurement system developed under CCS and SYS/BIOS, and have come up with an unexplained DMA stall when linking the McBSP (configured as a clock-stop SPI provider) to Channel 1 (McBSP TX) and Channel 2 (McBSP RX)). I queue up a SPI TX/RX by configuring both channels and their DMA buffers, then forcing the  DMA via software start the transfer process. I repost the SPI service routine when the RX channel interrupts the CPU (the SPI transaction is guaranteed through if the McBSP intakes the SPI frame). There are maybe 10 - 20 SPI transactions per second. Anywhere between 10 seconds and a minute, the DMA and McBSP experience a stall in the RX path--that is, there are still bytes to be read from the McBSP RX channel, and the status of the DMA channel indicates there are still pending transfer counts, and the RUNSTS for the channel is still logic high. PERINT flag is also asserted.  A logic analyzer says the SPI packet made it out on the transmit side and also made it into the RX side. I've looked at the SPI signals, and all timing relationships and waveforms are good. The SPI BRG is only operating at 1 MHz, and the bus length is about an inch, so I really don't think I'm looking at spurious noise as the cause. There are no errors posted in the McBSP either, that indicate an overrun.


It is like the DMA channel just decided not to service the McBSP RX side anymore, mid-transaction. The PERINT flag is set, like the McBSP is requesting service, but the DMA just forgot about it.

I've combed the errata for the chip, and found nothing that would explain this throttling. Any ideas?

  • David,

      I queue up a SPI TX/RX by configuring both channels and their DMA buffers, then forcing the  DMA via software start the transfer process.

    Generaly for communication peripheral one should use the peripheral event to trigger the DMA. How are you triggering the DMA using SW in this case? What is the synchronization mechanism used between DMA and McBSP? Or am I missing something here?

    Regards,

    Vivek Singh

  • Let me explain, again, clearer, how my system is set up. I have DMA Channel 1 feeding the TX side of McBSP B. I have DMA Channel 2 receiving from the RX side of McBSP B. The respective DMA channels have their trigger events coming from the respective McBSP TX and RX sides, and McBSP B haa generation of peripheral service events enabled.  I have the McBSP B set up as a SPI interface (using stopclock mode). The SPI target is an TI ADS1216, although that is immaterial to my issue To trigger a SPI packet, I first load the memory buffers for DMA1 to transmit and set up the DMA 1 channel itself, however transmission does not start because the McBSP TX CANNOT generate a peripheral service request to *start* a transaction by itself just because there are bytes waiting in the TX DMA buffer. I start the transaction by doing a software force of DMA 1 by setting the PERINTFRC flag in DMA 1's CONTROL register. This is a perfectly valid way to start a DMA sequence, and matter of fact, the transmit side runs fine runs fine without stalling. The problem is that DMA 2 (the receive side) stalls after transferring a byte or two, out of about every 100 to 10,000 SPI packets sent. When stalled, the McBSP says that it has a byte ready to be read (and thus should've generated a peripheral event to the DMA, just as it did for the previous received bytes in the SPI packet), but the DMA stalls and does not transfer subsequent bytes from the McBSP RX as it should. The McBSP/DMA SPI interface DOES work tens, hundreds, or thousands of times before stalling. At a rate of 10 SPI packets a second, a stall may take from a second to a minute or more to occur. I've written code to trap the stall and as a crude workaround. In 24 hours, 1792 DMA stalls have occurred. To summarize, there appears to be a mechanism by which McBSP B either doesn't issue a peripheral service request to the DMA as it should, or it does issue a request and  the DMA does not act on it, producing a permanent stall. When stalled, McBSP says it has data in its read buffer waiting to be transferred out. The DMA 2 status says that there are still bytes remaining to transfer (its transfer count is not zero) before the DMA sequence is complete, and the channel RUNSTS is 1.  My SPI transmit and reading routine, which operates as a SWI, is completely synchronous with the DMA 2 transfer complete interrupt. That is, to say, no other routine in my code is tinkering with the McBSP nor DMA while a SPI transmit/receive is ongoing. This leads me to firmly believe there is an errata in the processor here between McBSP B RX and DMA channel 2, which is why I wish to report it. My stall trap is not ideal as it forces me to lose a reading and restart the reading sequence before the point of stall. I haven't tried different combos of DMA channels to see if the problem is only unique to Channel 2 or not. Is my situation a bit more clear, now? By the way, to make sure this was not an emulation artifact, I am free-running the processor platform alone, and the problem still occurs. The target has 6 processes running doing other things through the eCap, native SPI, and I2C, but none of these other processes utilize DMA at all, and none are having issues. I'd be happy to discuss design specifics with a TI representative directly in investigating this event. Thanks.

  • Vivek, Any thoughts/news on this potential errata? Thanks.

  • David,

    I agree that problem is not on TX side but I am not able to understand following statement.

    however transmission does not start because the McBSP TX CANNOT generate a peripheral service request to *start* a transaction by itself just because there are bytes waiting in the TX DMA buffer.

    After McBSP configuration is done and it's been setup for TX, it should generate the TX event because it's buffer is empty so you don't need SW trigger to start the transfer.

    Can you post your McBSP code/DMA code. We'll have our McBSP expert to look into this.

    Regards,

     Vivek Singh

  • The TX side is really not a question, here, Vivek--the RX side is where the problem occurs and where sole focus should be placed. My code for the TX side is fine, and it works just as I want, as I don't want the TX suddenly taking off just because I have started loading buffers into DMA (even if it worked that way, which it doesn't). As far as the TX side is concerned, the peripheral event for DMA service is generated as the TX buffer changes state from full to empty. It is a state-change-driven situation, so my code needs to take action to initially change that state. I could load the first SPI byte into the TX buffer manually after I've got the 2nd through nth byte loaded into the TX DMA buffer, but why? The software force bit is there, so why not use it after I've loaded ALL TX bytes in the DMA buffer. As I said, the TX side works just fine and ALL TX data makes it out on the wire, so let's look at the RX side and only the RX side to characterize this (unless there is some undocumented interaction between the DMA channels or McBSP TX/RX). I don't want to dilute or distract our attention from the RX problem in the process of "solving" a problem that isn't.

    When there is a problem, the TX DMA channel has a RUNSTS of 0--in other words it completed its transfer just fine. There shouldn't be any interaction unless the TX DMA locks up the DMA state machine and won't let the RX channel finish. I would expect that the TX channel RUNSTS would not be zero, though, if that was the case. But, I can imagine some priority lockup bug existing, but I'd expect TI would've already seen this long before. My suspicion is that this bug is McBSP B/DMA related timing bug with the peripheral event flag.

    Why does the RX side sometimes work fine, and other times when the stall occurs, the McBSP has its RX peripheral service flag set, the flag indicating the RX buffer and the hidden buffer are both full is set, and the DMA tied to McBSP's RX side has its RUNSTS set to 1 with transfer counts remaining, but yet it is not pulling data from the McBSP. NOTHING is messing with the McBSP nor DMA until both the TX and RX are complete. As said before, this problem occurs at any rate between a couple seconds to a couple of minutes. The RX DMA transfers a byte from the McBSP RX buffer and then inexplicably stops.

    I'd be willing to PM the code to TI, but don't wish to post it publicly, as it is a commercial, not academic, project. I'm trying to figure out how to do that. Thanks.
  • Is my report still on the burner, even if the back burner? I'd submit code snippets to TI, but it appears the ability to do on this web site that has changed (I can't find the button that allows code attachments). I can't post them publicly as they are commercial code. Thanks.
  • Hi David,

    While replying if you click on "Use rich formatting " option then it'll provide you different menu items. In that you can use "Insert File" for attatchment. I assume you are not looking for a secure option to attach the code.

    Regards,

    Vivek Singh