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.

McBSP receive lockup

Other Parts Discussed in Thread: OMAP-L138

Hey all -

I'm using the OMAP-L138 with the C674x DSP. McBSP interfaces to the EDMA through a FIFO. Under normal operation my application is working fine, but recently I have found a lockup that can [very] rarely occur.

The lockup happens when there is a soft reset (power is not removed, but the DSP code is reloaded and restarted). The peripheral feeding into the McBSP is not reset and always spamming data. 

In the locked up state I can read the SPCR register and find that RRST, RRDY, and RFULL are all set. This means the McBSP has overrun, DRR is not read, RBR is full. I have checked the FIFO and EDMA which appear to have read a DRR value and the DMA has put it in memory. On the DSP I set up some code to manually read the DRR when it is in this locked up state to see if it would kick start the McBSP back up and recover. The McBSP does not respond and SPCR still shows RFULL as set. I have also tried to manually trigger the DMA event to see if that would help and again no change in SPCR.

Looking at virtually all the DMA and McBSP registers between a locked up case and a normal operation case the only difference I can find is that in the DMA IPR register the event in question gets set once (and I clear it) in the locked up state and never again. The IPR event gets repeatedly set in the normal case as I would expect.

I've performed all the debug steps described here http://www.ti.com/lit/ug/sprugp9b/sprugp9b.pdf. I'm still not certain if it's a DMA problem or a McBSP problem, but since the RFULL/DRR is not clearing when I manually read the register I suspect McBSP.

So since this only happens during this special reset and very rarely, I feel like there is something wrong with how I shutdown. When I shutdown I just stop the DMA and disable, clear all events and interrupts in the Delete() IOM function.

I hope I've provided enough information (not likely) and posted this in the correct forum - if not please ask. Please and thank you for any help you can provide :)

  • Hi Marshall ,

    I have moved this thread over to the OMAP-L13x forum to get a faster response.

    Thanks.

  • Hi Marshall,

    Thanks for your post.

    I suspect, it could be a DMA issue and I believe  in the locked up state, EDMA controller is not setting up correctly to service the McBSP data automatically upon receiving the XEVT and/or REVT as mentioned in McBSP user guide.

    In the McBSP Rx. locked up state, if you see the EDMA is not being triggered, please check the missed event register (EMR/QEMR) and secondary event register (SER/QSER) to see if the channel bit being set.  The section "A.1 Debug Checklist" in EDMA user guide as shown below has one row item discussing the issue of "The Secondary Event Registers bits are set, not allowing additional transfers to occur on a channel.".

    http://www.ti.com/lit/ug/sprugp9b/sprugp9b.pdf

    You must ensure that the number of events received is limited to the expected number of events for which the parameter set is programmed, or you must ensure that bits corresponding to a particular channel or event are not set in the secondary event registers (SER/QSER) and the event missed registers (EMR/QEMR) before trying to perform subsequent transfers for the event/channel.

     Thanks & regards,

    Sivaraj K

    ------------------------------------------------------------------------------------------------------- 
    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------

  • Thanks for the reply Sivaraj.

    The EMR and SER are both clear (0x0000) indicating no events have been missed or pushed as secondary.

    I have also gone through the other debug steps listed in the user's guide checking to make sure events and interrupts are enabled as expected and the DRAE is set up properly. But this isn't surprising since in general the McBSP and EDMA operate fine.

    We've had an issue before that is sort of related to this. We found a condition during a flush where we would clear the event register before the DMA could process the event. This created another lockup condition because the McBSP does not resend the REVT and the DMA waits idle for the event that was already cleared. In this problem though we could manual trigger the EDMA and it "kick started" itself back up where it processed the event where operation would continue as normal.

    In the lockup described in the original post, manual triggering doesn't seem to have any effect. However, I noticed in our initialization we do not put the McBSP RRST into reset until after we have already performed an EDMA_STOP, which clears the event register. This looks like the same symptoms as before to me, but I have no way to convince myself that this is actually what is going on. It could be possible (very likely) that a set bit in EMR/SER is getting cleared when we shutdown or initialize during startup. I'm going to work on a way to read these registers for the event before we clear them and try to reproduce the issue.

  • I haven't been able to reproduce so I can't say anything more on the EMR or SER, but I wanted to add some more information.

    I can get the processor in a similar state by spamming CPU reads of DRR. I get the same symptoms described in the original inquiry so I hope this is related to the same problem. I'm trying to identify the problem when in this condition so I can find the bug in the code to prevent it. Once in this state performing software resets does not get it out of this state.

    So the important part is I think the DMA is executing once. I see IPR show my event triggered and I see data moving into memory (lets say I see 0x01 moved to memory) and I see SPCR showing RFULL set. At this point I can read DRR (hoping this would reset RRDY, but it does not) and lets say it is a value 0xFF.

    Now I perform another software reset and I see the data moved into memory is 0xFF and the DRR updated with a new value and the locked state continues.

    So apparently each software reset (which resets the McBSP and DMA to its initial state) DRR is indeed being shifted out and grabbed by the FIFO and then the DMA places it in memory, but it immediately locks up after this. No manual DMA trigger kicks off the next read and no read of DRR clears the RFULL/RRDY flags.

    Any ideas what might describe some of these symptoms I have been seeing? Need more info?

    Thanks.

  • I'm going to try to tabulate the initialization of the McBSP/DMA that is currently executing. An IOM driver is written to handle the McBSP so I will be referencing the IOM_Bind, IOM_Create and IOM_Submit functions. Actions will be listed in the order they are executed. This particular problem pertains to McBSP0 receive, but we do use McBSP0 transmit and both McBSP1 receive and transmit.

    Init Procedure:

    • EDMA3 Init
      • Power (PSC Register) to the channel controller, transfer controller 0, transfer controller 1.
      • Set DSP channels 0, 1, 2, 3, 14, 15 to use Queue 0
      • Set channels 0, 1, 2, 3, 14, 15 to be used by the DSP
    • McBSP Power On
      • PSC modules on
    • McBSP Enable Pins
      • Set up the PINMUX (DX, DR, FSX, FSR, CLKX, CLKR) to use McBSP pins.

    Bind

    • EDMA Stop Tx
      • disable event
      • clear event
      • disable interrupt
      • clear interrupt
    • EDMA Stop Rx
      • disable event
      • clear event
      • disable interrupt
      • clear interrupt
    • McBSP Reset All
      • XRST, RRST, FRST, GRST all set to "RESET"
      • RFIFO, WFIFO are disabled
    • McBSP Configure
      • All registers configured in this order:
      • SPCR, RCR, XCR, SRGR, MCR, RCERE0, XCERE0, PCR, RCERE1, XCERE1, RCERE2, XCERE2, RCERE3, XCERE3
     CSL_FMKT(MCBSP_SPCR_FREE,     CLOCKS_RUN)        |
     CSL_FMKT(MCBSP_SPCR_FRST,     RESET)             |
     CSL_FMKT(MCBSP_SPCR_GRST,     RESET)             |
     CSL_FMKT(MCBSP_SPCR_XINTM,    XRDY)              |
     CSL_FMKT(MCBSP_SPCR_XSYNCERR, NO_ERROR)          |
     CSL_FMKT(MCBSP_SPCR_XRST,     RESET)             |
     CSL_FMKT(MCBSP_SPCR_DLB,      DISABLED)          |
     CSL_FMKT(MCBSP_SPCR_RJUST,    RIGHT_SIGN_EXTEND) |
     CSL_FMKT(MCBSP_SPCR_DXENA,    OFF)               |
     CSL_FMKT(MCBSP_SPCR_RINTM,    RRDY)              |
     CSL_FMKT(MCBSP_SPCR_RSYNCERR, NO_ERROR)          |
     CSL_FMKT(MCBSP_SPCR_RRST,     RESET),
    
     CSL_FMKT(MCBSP_RCR_RPHASE,   SINGLE)    |
     CSL_FMKT(MCBSP_RCR_RCOMPAND, MSB_FIRST) |
     CSL_FMKT(MCBSP_RCR_RFIG,     IGNORE)    |
     CSL_FMK( MCBSP_RCR_RDATDLY,  1)         |
     CSL_FMK( MCBSP_RCR_RFRLEN1,  0)         |
     CSL_FMKT(MCBSP_RCR_RWDLEN1,  32_BITS)   |
     CSL_FMKT(MCBSP_RCR_RWDREVRS, MSB_FIRST),
    
     CSL_FMKT(MCBSP_XCR_XPHASE,   SINGLE)    |
     CSL_FMKT(MCBSP_XCR_XCOMPAND, MSB_FIRST) |
     CSL_FMKT(MCBSP_XCR_XFIG,     IGNORE)    |
     CSL_FMK( MCBSP_XCR_XDATDLY,  0)         |
     CSL_FMK( MCBSP_XCR_XFRLEN1,  0)         |
     CSL_FMKT(MCBSP_XCR_XWDLEN1,  32_BITS)   |
     CSL_FMKT(MCBSP_XCR_XWDREVRS, MSB_FIRST),
    
     CSL_FMKT(MCBSP_SRGR_CLKSM,  INTERNAL_OR_CLKX) |
     CSL_FMK( MCBSP_SRGR_CLKGDV, 1),
    
     CSL_FMKT(MCBSP_MCR_RMCM, ALL_CHANNELS_ENABLED) |
     CSL_FMKT(MCBSP_MCR_RMCM, ALL_CHANNELS_ENABLED),
    
     CSL_FMKT(MCBSP_PCR_FSXM,   INPUT)            |
     CSL_FMKT(MCBSP_PCR_FSRM,   INPUT)            |
     CSL_FMKT(MCBSP_PCR_CLKXM,  INPUT)            |
     CSL_FMKT(MCBSP_PCR_CLKRM,  INPUT)            |
     CSL_FMKT(MCBSP_PCR_SCLKME, CLKS_OR_INTERNAL) |
     CSL_FMKT(MCBSP_PCR_FSXP,   ACTIVE_HIGH)      |
     CSL_FMKT(MCBSP_PCR_FSRP,   ACTIVE_HIGH)      |
     CSL_FMKT(MCBSP_PCR_CLKXP,  RISING_EDGE)      |
     CSL_FMKT(MCBSP_PCR_CLKRP,  FALLING_EDGE),

    Create

    • Set IOM callback function
    • Create Queue_new
    • Load channel paramset
    • Load idle paramset

    Peripheral Device Initialization

    • Here we initialize the device feeding our McBSP and perform a software equivalent power on reset (POR) according to its specs.
    • Up to this point, since we are doing a software reset, I assume this has been continually sending data to the McBSP port. It is now reset and continues sending data.

    Submit

    On the first IOM_READ, IOM_WRITE, or IOM_FLUSH we must activate the McBSP receive

    • McBSP Prepare for Rx
      • Wait 2 clock cycles. We have a SLAVE clock and sample generator is OFF.
    • EDMA3 Run
      • Clear missed event
      • clear secondary event
      • enable event
    • McBSP Start Rx
      • Set up RFIFO configuration
        • NUMEVT = 1
        • NUMDMA = 1
        • ENABLED
      • Set SPCR.RRST to ACTIVE

    During this first SUBMIT action is when I see that the IPR has been set for this particular event and the data moved to memory. The second, and for the rest of eternity, time it is called I see RFULL set and the McBSP looks clogged and the DMA looks to be sitting idle. RFIFOSTS reports empty. Manual DMA triggers appear to do nothing, CPU reads on DRR appear to do nothing.

    Hope this might help provide some insight or help ask the right questions :)

  • Hi Marshall,

    Did you ever figure out a recovery mechanism for this lockup?