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.

MSP432P4111: Missing UART Receive interrupts

Part Number: MSP432P4111


We're having comm issues on our UART, and after setting a signal output that toggles every receive interrupt I can look at the stream of characters on a scope, sometimes I notice missed received interrupts on the input stream, resulting in comm failures.

What can I do to eliminate this problem?  Is there a way to elevate the receive interrupt priority above all the rest of the interrupts?  There are also critical places in the code where interrupts are globally disabled, so I'll need to look at those as well.

Thanks

  • Hi Bit_Banger,

    Cool name BTW :)

    What other interrupts do you running? 

    I'm not sure why you are missing the interrupt event.  Even if higher priority is being serviced, when complete the lower (UART) handler should be called.  Of course if the higher priority takes too long, you could miss characters.  Is that what is happening? 

    For reference, check out section 1.5.5 the users guide.

  • You didn't post any code, so I'll just throw this in as a "random tip": Clear the RXIFG only by reading RXBUF, not by writing to the IFG register. Similarly for the TXIFG/TXBUF (if you're not interested, clear the TXIE). UART_clearInterruptFlag() writes to the IFG.

    Apparently on the MSP430 explicitly clearing an IFG is atomic (I don't know, since I avoid it) but on the MSP432 it's not, and the read/modify/write on the IFG could (did) clear a nascent IFG -> lost interrupt. It's worse when running at high speed, but it's always possible.

    A year or two ago we had some number of people who were doing that, thus my suggestion.

    As a diagnostic, it would probably be useful to see if you're getting (Rx) overruns.

  • Thanks for the replies.  I wish we were clearing the IFG explicitly in the interrupt using UART_clearInterruptFlag(), because that would be a smoking gun, but we're not.  All we do is read each in-coming character into a buffer using the UART_receiveData() function, and we are not using dormant mode.  However, I will add a call to UART_queryStatusFlags() to see if we're getting over-runs or other issues.

    We are using DMA to transmit data through the UART, but we are not using DMA to receive data, since the incoming messages have variable length.

    We are also looking at areas where we're blocking interrupts to see if we can improve the timing, and we may be able to get away with blocking everything but the character receive interrupt if that's what it takes, but the blocking operations involve SPI interfaces at high data rates, so that may be easier said than done.

    The thing that surprises me is this code I'm working on is a port from the MSP-430, which ran fine before, so I would've expected the code to run more smoothly on the MSP-432, yet now I'm at the eleventh hour of having something we can sell based on the new architecture, with this show-stopper issue in our way.

    We are also struggling to provide the capability to communicate with two UART ports simultaneously, which I think is a problem that is based in the same root cause.

  • We have made progress in streamlining the software such that our overruns are reduced dramatically, but simultaneous UART port communications still times out sometimes, so we need to do better.

    I think we're missing characters when we enter sections of code that require blocking, and in our case most if not all of those routines that require blocking are interfacing with external sensors via SPI.

    If a character comes in while it's blocking that character won't be read until interrupts are re-enabled, but I might be able to ensure the character receive interrupts are serviced first by escalating their priority relative to the other peripherals using calls to Interupt_setPriority().  

    I assume interrupts are not pre-emptive, in the sense that a higher priority interrupt that is triggered after a lower priority interrupt won't interrupt the lower priority interrupt, but will wait until the lower priority interrupt is finished executing, is this true?

    The only other thing I can think of is to increase the clock frequency, but that could be risky, and it may not buy us much, since it won't speed up the data transfer of the SPI, which accounts for the majority of the time spent blocking.

  • Interrupts are pre-emptive (based on priority) on the Cortex-M. At reset, all priorities are the same, so if you don't mess with them there's no pre-emption.

    You need to assure mutual exclusion, and/or tighten the "sandbox" boundaries so tight that it doesn't matter. 

  • So interrupts are pre-emptive (will interrupt each other) if the priorities are set differently, interesting.

    If I understand you correctly, the "sandbox" boundaries are defined by the time spent blocking, which in turn is defined by the time spent servicing the SPI ports, so if I can minimize that time by speeding up the SPI or by breaking the SPI interface functions into shorter, more atomic operations to allow receive interrupts to fire in between, then I might be able to get those boundaries tightened sufficiently to avoid overrun issues.

    Thanks.

  • Sorry, my terminology was sloppy. By "sandbox" I meant "the pool of data touched by a given ISR". If e.g. your UART ISR works only with its private data (that includes peripheral registers), it's probably pretty safe to let it break in by giving it a high priority. This may already be true of your UART ISR.

    Keeping ISRs short is of course also a good idea, but I recognize that this is something that's difficult to retrofit at the last minute.

  • Sure, we have been disciplined in encapsulating our data and keeping the interrupts as short as possible so that our UART interrupt, for example, just takes the contents of the receive register and stuffs it into a buffer, which is later processed by a background task.

    Prioritizing the interrupts and minimizing the time spent blocking, possibly by breaking the routines that interface with SPI (and are therefore blocking) into smaller routines that would allow the receive interrupts to fire in between, might get the job done.

    Thanks.

  • Hi Bit_Banger,

    It's been a few days since I have heard from you so I’m assuming your question has been answered.
    If this isn’t the case, please click the "This did NOT resolve my issue" button and reply to this thread with more information.
    If this thread locks, please click the "Ask a related question" button and in the new thread describe the current status of your issue and any additional details you may have to assist us in helping to solve your issues.


**Attention** This is a public forum