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.

MSP430F67471: DMA stuck/hangs in UART reception

Part Number: MSP430F67471

We employ DMA transfers from UART to RAM, incl. Workaround for DMA9 problem according to the Erratasheet of the MSP430f67471.
This works around 99.99% of the transfers very well.
Then the DMA transfer sometimes stops at any point when receiving a message.
Accordingly, you can see overrun errors in the UART status register, DMA is still enabled and the DMA size register shows incomplete transfer size.
This behavior does not seem to occur when GIE is disabled.
Now you might think that an ISR is somehow disturbing, but how should that be possible?
DMA access has priority over interrupts and stopping the DMA by NMI is not configured (there is an extra bit).
We do not use DMA Interrupts in this reception processing at all.
UART clock is configured as divided SMCLK, i.e. it is synchronous to DMA module clock.

Any ideas about this issue are highly appreciated...

KR
Matthias

  • Are you using the UART interrupt along with the DMA? These can interfere with one another. [Ref User Guide (SLAU208Q) Sec 36.3.16] 

  • No, Bruce, also no UART interrupts used (not on that UART HW instance).

  • Hello,

    Have you reviewed errata DMA4 and DMA7? Perhaps one of these is causing the issue.

    Regards,

    James

  • Sorry for the late reply, I was ill.

    Yes, I checked also errata DMA4 and DMA7. 

    Both are not applicable, since UART interrupts are disabled and DISRMWDIS is set.

  • Hi Matthias,

    What transfer mode are you using?

    Regards,

    James

  • Matthias Voss1 said:
    Then the DMA transfer sometimes stops at any point when receiving a message.
    Accordingly, you can see overrun errors in the UART status register, DMA is still enabled and the DMA size register shows incomplete transfer size.
    This behavior does not seem to occur when GIE is disabled.

    If the behavior doesn't happen with GIE is disabled, then it sounds like a peripheral interrupt is getting requested. But, that shouldn't happen. 

    1.3.4 Interrupt Processing in SLAU208

    When an interrupt is requested from a peripheral and the peripheral interrupt enable bit and GIE bit are
    set, the interrupt service routine is requested. Only the individual enable bit must be set for (non)-
    maskable interrupts (NMI) to be requested.

    Matthias Voss1 said:
    Now you might think that an ISR is somehow disturbing, but how should that be possible?
    DMA access has priority over interrupts and stopping the DMA by NMI is not configured (there is an extra bit).
    We do not use DMA Interrupts in this reception processing at all.

    That's correct. As you can see from this section in the user's guide, system interrupts can't interrupt DMA transfers.

    11.2.8 Using DMA With System Interrupts in SLAU208

    DMA transfers are not interruptible by system interrupts. System interrupts remain pending until the
    completion of the transfer. NMIs can interrupt the DMA controller if the ENNMI bit is set.
    System interrupt service routines are interrupted by DMA transfers. If an interrupt service routine or other
    routine must execute with no interruptions, the DMA controller should be disabled prior to executing the
    routine.

    Make sure the ENNMI bit is not set. Also, as you can see, the DMA transfer can interrupt system ISRs. Please check if there's a time-crucial or important process that the DMA transfer is interrupting. Perhaps that interruption is causing the issue.

    Regards,

    James

  • James Evans said:
    Make sure the ENNMI bit is not set. Also, as you can see, the DMA transfer can interrupt system ISRs. Please check if there's a time-crucial or important process that the DMA transfer is interrupting. Perhaps that interruption is causing the issue.

    Thanks, James, NMI is disabled and you are right in principle interrupting ISR by DMA could lead to  unwanted effects, but for the ISRs on my system I cannot see what should lead to stopping the DMA or UART (UART ISR also not active/enabled when DMA is used).

  • Transfer mode is block mode, single or repeated (has no influence on this effect), no interrupt,

    level triggered, trigger is UART reception on DMA0. This goes in conjunction with same trigger for DMA9 errata workaround on DMA channel 2 (low prio, reg to reg dummy transfer).

    I noted one strange thing about DMA egde trigger: It leads to multiple DMA transmission of the same byte into memory. Not sure what may cause this... This was initially the reason to setup for level trigger.

  • Matthias Voss1 said:
    ISRs on my system I cannot see what should lead to stopping the DMA or UART (UART ISR also not active/enabled when DMA is used).

    Strange indeed. Is there a way to check if the behavior happens if DMA is disabled/enabled at start/finish of the other ISRs?

    Are you reading UCRXIFG anywhere else in your code?

    I also found this recommendation in the UG.

    The DMAxTSEL bits should be modified only when the DMAxCTL DMAEN bit is 0. Otherwise, unpredictable DMA triggers may occur.

    Also, since you're not enabling NMI, the DMAABORT bit should not be set in the DMAxCTL register when this issue occurs.

    Regards,

    James

  • James Evans said:
    Is there a way to check if the behavior happens if DMA is disabled/enabled at start/finish of the other ISRs?

    Good point. The DMA resource is indeed shared, but there is a mechanism in place to securely claim this resource - plus I can see that DMA is still enabled when it is stuck.

    James Evans said:
    Are you reading UCRXIFG anywhere else in your code?

    No.

    James Evans said:
    The DMAxTSEL bits should be modified only when the DMAxCTL DMAEN bit is 0.

    Right, this is the case.

  • Hi Matthias,

    Could you try removing the other non-essential parts of your code including the related ISRs? Then, if the issue goes away, I think it'll indicate what's causing the issue. Then, you could add your code piece-by-piece and monitor when the issue happens.

    Regards,

    James

**Attention** This is a public forum