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.

CCS/MSP430I2021: Reset occurs if disabling and then enabling UCRXIE on eUSCI_A peripheral in UART mode

Part Number: MSP430I2021
Other Parts Discussed in Thread: MSP430F2252

Tool/software: Code Composer Studio

I am facing a strange issue on the MSP430I2021 eUSCI_A in UART mode.

In my application I use eUSCI_A in UART mode with RX and TX interrupts.

My UART RX interrupt handler stores the received characters in a static buffer or records a possible receive error condition; in both cases the condition flags are always cleared. In my main loop the following function is called to handle the UART reception:

/*!
** \fn short Uart0_GetBuffer( unsigned char *Buff, unsigned short *Len )
** \brief Get the received packet and the receive condition
** \param Buff The buffer for the received packet
** \param Len The received packet size
** \return UART0_NODATA - no reception
**         UART0_ERROR - reception error (framing, parity, overrun)
**         UART0_SIDATA - received packet
**         UART0_RXDATA - packet reception in progress
**/
short Uart0_GetBuffer( unsigned char *Buff, unsigned short *Len )
{
    short tmp = UART0_NODATA;

    UCA0IE &= ~UCRXIE;   // disable RX interrupt

    // handle the current receive condition:
    // - If a packet was received, store it in the buffer and return UART0_SIDATA.
    // - Else if reception error, return UART0_ERROR.
    // - Else if packet reception in progress, return UART0_RXDATA.

    [...]

    UCA0IE |= UCRXIE;   // enable RX interrupt

    return tmp;
}

My issue:

  • My application starts and runs for a few seconds (random from 10 to 30 sec), the UART is working properly (receives and transmits), but then a reset occurred.

My application does not use the watchdog and no code optimization. The supply voltage VCC on my board is stable and no external reset occurs. I run with DCO clock with external 20K resistor, MCLK = DCO/2 = 8.192MHz, SMCLK = DCO/4 = 4.096MHz. The UART communication handles packets with size until 30 bytes in both RX and TX directions.

After a day of searching, I found the cause is the RX interrupt disable-enable sequence. Also, letting RX interrupt run without handling the serial communication, I get the same issue with the following function in the main loop:

/*!
** \fn short Uart0_GetBuffer( unsigned char *Buff, unsigned short *Len )
** \brief Get the received packet and the receive condition
** \param Buff The buffer for the received packet
** \param Len The received packet size
** \return UART0_NODATA - no reception
**         UART0_ERROR - reception error (framing, parity, overrun)
**         UART0_SIDATA - received packet
**         UART0_RXDATA - packet reception in progress
**/
short Uart0_GetBuffer( unsigned char *Buff, unsigned short *Len )
{
    short tmp = UART0_NODATA;

    UCA0IE &= ~UCRXIE;   // disable RX interrupt

    UCA0IE |= UCRXIE;   // enable RX interrupt

    return tmp;
}

So, it looks like a very frequent write access to the UCRXIE bit in the UCA0IE register may generate a reset condition. Why?

Nothing about that is reported in the device erratasheet.

In the meantime I solved disabling (_DINT()) and re-enabling (_EINT()) all the interrupts in the Uart0_GetBuffer() function, instead of the single UART RX interrupt. But I don't like it!

I don't understand this behavior: the same function is running properly on an old application of mine based on the MSP430F2252 and built with IAR compiler (but in that case the peripheral USCI is a little bit different from the eUSCI).

Any idea?

Thank you all.

  • Hey Vagni,

    Interesting issue.  I'm not sure why the device is reseting but I don't see any errata of USCI resetting the device. 

    Does this still happen while you are debugging the device?  If so, can you check the reset flags as they might lead us toward a cause.  

    Section 6.6 of the datasheet determines the 4 interrupt flags that lead to a device reset.  They are BORIFG, RSTIFG, WDTIFG.  WDTIFG also includes KEYV (Key or memory violation).  These flags reside in the IFG1 register.

    What I would do is at the very start of your code, add an if statement to check these flags and place a breakpoint.  Then, if it resets while debugging, you should be able to see the source.  Then we can go from there. 

    Thanks,

    JD   

  • Hi JD,

    I checked the reset flags while debugging: none of the source reset flags (BORIFG, RSTIFG, WDTIFG) is set when the reset issue occurs. In that case only the OFIFG flag is always set in the IFG1 register: is it correct?

    I confirm: no reset occurs without the very frequent write access to the UCRXIE bit in the UCA0IE register.

    Thanks

  • Hello Vagni,

    I assume there is no oscillator connected to the I2021.  Is that correct?  If so, then it's fine that this bit is always set.  It's used to determine that a stable clock signal is being fed into the oscillator module. 

    Very interesting that there is no reset flag set...  I feel like that shouldn't be possible.  

    How are you determining the device has reset? 

    Thanks,

    JD 

     

  • Hello JD,

    No oscillator connected to the MSP430I2021.

    With the debugger (a breakpoint set in the _system_pre_init() function in the low_level_init.c source file) I see my application suddenly restarts after a random number of seconds.

    Regards

  • The manual doesn't provide a lot of detail on the interrupt system except to show that the modules are chained together and this defines their priorities. Even without circuit details it seems unlikely that this would cause a reset. A NMI perhaps. Do you have a NMI handler? If not, add a simple one so you can see if it gets triggered.

    A spurious NMI is just as nasty a bug as a reset of course.

  • On my board I use RST_NMI_SBWTDIO pin connected to a pushbutton and an RC network for external reset. The pushbutton is used to trigger my NMI handler. In my NMI handler only NMIIFG event (from pushbutton pressed or released event) is handled; the other flags (OFIFG and ACCVIFG) are only cleared, if set, because both ACCVIE and OFIE are set to 0.


    RST_NMI_SBWTDIO and TEST_SBWTCK pins are also used for 2-Wire JTAG (Spy-Bi-Wire) program/debug interface..

    When the reset issue occurs, NMI handler is not triggered.





  • Hi Vagni

    Could you upload the reset check code? I think it should be one of the reset that mentioned by JD.

    Best regards

    Gary

  • Hi Gary,

    With the debugger and a breakpoint set in the _system_pre_init() function in the low_level_init.c source file I see my application suddenly restarts after a random number of seconds. When it happens, IFG1 = 0x02 (see the attached screenshot).

    Thanks,

    Vagni

  • Hi Vagni

    Could you upload a sample test code to reproduce this issue? 

    Best regards

    Gary

  • Hey Vagni,

    Very sorry for the delay from my side.  Are you still having this issue?  Do you have some code that repeats the issue that you can share with me?   

    I also looked back at the system reset sources in the user's guide, and it appears that WDT and Flash PW violations will also directly cause a device PUC.  The WDT flag is in the IFG2 register that you are viewing above, but it actually appears that a Flash violation sets bits in the FCTL3 register.  Specifically the KEYV and ACCVIFG bits.  

    Can you also check these bits to see if the reset is coming from a flash password violation?  

    Thanks,

    JD

**Attention** This is a public forum