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.

Errors when receiving bytes via UART when in low power mode.

Other Parts Discussed in Thread: MSP430F5419A, MSP430F5529

Hi Everyone,

I am currently having an issue when using UART in LPM3 on the MSP430F5419A. If i send a burst amount of characters (from Hyperterminal) to the MSP, and have the MSP reflect the characters, it only reflects them for a small amount of time (usually around 10 characters are reflected) before the MSP no longer returns the characters to Hyperterminal. From what I can tell, the MSP undergoes some sort of framing error as several bits (UCFE, UCOE and UCRXERR) in the UCA0STAT register are set, when using the MSP430-FET430UIF to debug. This seems to prevent the MSP from receiving anymore characters, making the RX unusable until it is reprogrammed.

I have used a logic analyzer to ensure all the data being sent to the MSP is intact (which it is).

I noticed in the errata sheet there is a potential problem "SMCLK comes up fast on exit from LPM3 and LPM4". However I do not believe this is the problem since the same issue occurs in LPM1 and LPM2 as well.

The only methods of preventing these errors I have found (so far) is to never enter any Low Power Mode or to reduce the clock frequency from 20MHz to 8MHz, both are extremely undesirable for this project.

Other information:

     Board rate: 115200

    Core voltage: PMM Core Voltage 2 (1.75V) 

If anyone has any insight as to why this UART RX problem is occurring, it would be much appreciated.

Kind Regards,
 Jake

  • Jake Verry said:
    The only methods of preventing these errors I have found (so far) is to never enter any Low Power Mode or to reduce the clock frequency from 20MHz to 8MHz, both are extremely undesirable for this project.

    This wont help you in saving power.

    Is the data missing at the beginning of the frame, I mean if you are sending "ABCDEF", are u missing the few first bytes like "AB" and receiving only "CDEF"?

  • chethu gowda said:
    Is the data missing at the beginning of the frame, I mean if you are sending "ABCDEF", are u missing the few first bytes like "AB" and receiving only "CDEF"?

    It's more like if I press "ABCDEFGHIJKLMNO" (quickly) i'll get back something like "ABCDEFŠ"  then it cuts out.

     Jake

  • Jake Verry said:
    It's more like if I press "ABCDEFGHIJKLMNO" (quickly) i'll get back something like "ABCDEFŠ"  then it cuts out.

    The problem is not with the LPM mode exit delay.

    can u post your code where you are echoing the rxbuf data?

    or is this just what you are doing?

    while (!(UCA0IFG&UCTXIFG);

    UCA0TXBUF = UCA0RXBUF;

  • No, that is not the  method I am using, I am using a circular buffer. Inside the rx interrupt a check is done too see if the buffer is full, if it is not, rxbuf is written to the circular buffer. Then in the main while loop, the buffer is polled, if it is not empty it returns a character.

    Kind Regards,
    Jake 

  • what is the size of your circular buffer? It will be difficult to analyze the issue unless you post the part of your code which takes care of circular buffer,

    make sure your ISR is not doing too much operation on circular buffer and thereby loosing any incoming data.

    Also try sending data from some tool other than hyperterminal, sometimes hyperterminal behaves weird (but anyways this should not cause any overrun or frame error, however just give a try)

  • chethu gowda said:
    what is the size of your circular buffer?

    I have tried several different sizes ranging from 16-128, size does not seem to matter. 

    Unfortunately I am unable to post the code since it is the company's. However the interrupt is relatively small.

    chethu gowda said:
    Also try sending data from some tool other than hyperterminal

    I have tried using putty which has the same effect. The data analyzer seemed to confirm the outgoing data (from the computer) was behaving correctly.

    Also i don't think any of these could be a problem since the UART behaves perfectly when the device is not in Low Power Mode.

    Kind Regards,
    Jake 

  • Jake Verry said:
    Also i don't think any of these could be a problem since the UART behaves perfectly when the device is not in Low Power Mode.

    The LPM mode should not interfere with the UART ISR, and tell me one more thing, does your MSP430 stop receving the data forever until power reset or it recovers after some time and starts echoing the data?

  • Do you mind telling the size of your circular buffer? It will be difficult to analyze the issue unless you post the part of your code which takes care of circular buffer.

  • Aurea Henry said:
    Do you mind telling the size of your circular buffer?

    The size of the buffer is 32 bytes at the moment, however, I have attempted changing the size of the buffer many times (to a max of 128 bytes). 
    I have also tried testing other (more basic) buffers which was also unsuccessful. If you have any code for a basic UART buffer I would be happy to try it. 

    Kind Regards, 
    Jake 

  • chethu gowda said:
    oes your MSP430 stop receving the data forever until power reset or it recovers after some time and starts echoing the data?

    It does not recover after time, the MSP430 must have a power reset in order for the UART to function again.

    Kind Regards, 

    Jake

  • Jake Verry said:

    If you have any code for a basic UART buffer I would be happy to try it. 

    we would be happier to check your circular buffer algorithm and try to find out what could be wrong in your logic.

    you can find out lot of links about circular buffer algorithms with code on web, just google it.

  • Jake Verry said:
    It does not recover after time, the MSP430 must have a power reset in order for the UART to function again.

    This would conclude that the problem is with your logic, check if you are disabling the UART ISR somewhere and not enabling the same.

    also the LPM entry and exits are balanced, I mean the LPM mode being exited properly, It should not happen that while your circular buffer logic is handling the data the UART interrupt is disabled and at the same time you have entered the LPM mode but there is no interrupt to exit the LPM mode.

  • Jake Verry said:
    It does not recover after time, the MSP430 must have a power reset in order for the UART to function again.

    Jake,

    The reason the UART does not recover is because you still need to read the UART RX buffer in the event one of the error flags is set.  We found this early in our work with the MSP430. 

                    /* Clear all error flags that are USCI controlled */
                    UCA0STAT &= ~(UCFE | UCPE | UCBRK | UCRXERR);

                    /*
                     * if an error occurred, it is vital that RXBUF be read.
                     * Without a read, the next received character will also
                     * cause an overrun error, and the UART will appear to
                     * stop responding!
                     */
                    UCA0RXBUF;
    If you are using the DCO as the clock source for the UART then it is likely drifting like ours was. If the system wakes up in your main loop and goes back to sleep before three clock cycles of the DCO reference clock then the FLL will incorrectly set the DCO.

    Cheers,
    Darren

  • chethu gowda said:
    This would conclude that the problem is with your logic, check if you are disabling the UART ISR somewhere and not enabling the same.

    I do not disable the RX interrupt at any point in the code, only the TX interrupt is disabled and re-enabled at certain points.

    chethu gowda said:
    It should not happen that while your circular buffer logic is handling the data the UART interrupt is disabled and at the same time you have entered the LPM mode but there is no interrupt to exit the LPM mode.

    I'm not sure I understand this part?

    Kind Regards, 
    Jake 

  • Darren Beckwith said:
    The reason the UART does not recover is because you still need to read the UART RX buffer in the event one of the error flags is set.  We found this early in our work with the MSP430. 

    I have tried reading the UART RX buffer every single time the interrupt fires, the problem still persists. After the flags are cleared and the RX buffer is read, the interrupt will fire on the next received character with the same error flags set again.

    I also tried adding additional clock cycles to the main loop using __delay_cycles(); This also proved ineffective.

    Kind regards, 
    Jake 

  • Jake,

    OK, you said in the beginning of your post that you tried different LPM modes and system clock settings.  Have you tried running it with your desired system clock rate and not entering any LPM mode?

    Cheers,

    Darren

  • Darren Beckwith said:
    If the system wakes up in your main loop and goes back to sleep before three clock cycles of the DCO reference clock then the FLL will incorrectly set the DCO.

    Turns out this was the problem. Once I moved the delay to the ISR, and had it at 3 times the reference clock, everything started behaving correctly.

    Thank you very much for your help!

    Kind Regards,
    Jake 

  • Hi all,

    I am also investigating UART RX operation in combination with LPM. What I have found based on info from this thread and other places is that I should set up fast wake up, i.e. set SVSLFP=1 in SVSMCTL, otherwise wake up from LPM2,3 and 4 takes ~150us instead of 3.5-4.5us. Then, I also have to add a delay either in the USCI ISR or the main loop right after the CPU wakes from LPM to allow the FLL 3 FLLREF cycles to avoid drifting.

    After many tries I have not been able to make it work with 25MHz CPU clock and 115200bps on the MSP430F5529 Launchpad. I am testing with a burst of 200 bytes, depending on the configuration I receive from 3 to ~195 each time. This is with the debugger disconnected, when running through CCS all 200 bytes are received. I suspect a couple of things:

    1. At 115200 bps 1 baud is 8.68us and the maximum wake up time for MCLK>4Mhz is 7.5us according to the datasheet. It seems probable that the time available for the clock to start is marginal.
    2. The FLL ref is XT1 at 32768Hz, so 3 XT1 clocks are 91.5us, while 1 UART byte (10bauds) is 86.8us. Thus the delay in the ISR can cause bytes to be missed. Moving the delay to the main loop right after LPM is entered did not make a difference though.

    What I have not tried yet is making the delay int the ISR incremental, i.e. instead of delaying 91.5s at once, delay 5us, then check if a new byte has arrived and store it in the buffer, etc. I also havent tried yet using the REF instead of XT1 for the FLL reference, in case it starts up faster than the crystal.

    However, I do not know if there is any significant consumption gains to be obtained compared to just using LPM1 where UART RX works without any tweaks consuming about 550uA without any UART activity at 25MHz.

  • When entering any LPM>0, you should also disable the FLL, as this will cause the DCO to go off (and therefore makes the FLL thinking that the DCO frequency is too low). When an ISR is called, the FLL is not re-enabled, so it remains off during ISR. When exiting LPM, FLL should also remain off (don’t clear the bit the _exit code you use inside the ISR) and main should decide whether to re-enable the FLL (and then not go into LPM again until at least one reference cycle has passed) or keep it off (and go back into LPM soon)

    Regarding the receive problems: having the debugger attached will partly prevent deeper LPMs. So probably, the DCO remains active even in LPM>0 -> no wakeup time.
    Also, the time between start bit edge and re-appearance of the clock that drives the USCI (SMCLK or ACLK) must be smaller than 1/2 bit length or else the first byte(s) cannot be received, as the first data bit is not detected properly after the (ultra-short) start bit. This is not necessarily the startup time, as this timing (until DCOCLK has settled) applies only to MCLK (at least AFAIK). SMCLK and ACLK, when driven by DCO, are probably active earlier, yet with a wrong frequency.

    If the USCI is clocked from the DCO, the FLL reference clock frequency is rather unimportant.

  • Hi Jens,

    so what you are saying is that the FLL cannot be used in an application that is always sleeping and waiting for UART input? If yes, what are the effects on the clock accuracy, which is important for UART operation?

    About the relation between the wake-up time and the bit duration, as I wrote before at the 115200bps that I am testing one byte is ~85% of the MCLK wake-up time, which is obviously too close to be safe. If SMCLK starts sooner and at what frequency I do not know, the results though probably show that it does not start fast and/or accurately enough.

    The most effective thing I did to lower the currect consumption while still being able to reliably receive UART data at 115200bps was to drop the CPU clock to 2MHz (from 25MHz) and VCore from 3 to 0. If I remember correctly this dropped the current from ~500uA (LPM1, no UART activity) to ~150uA, which is about what I got with LPM2/3 at 25MHz

  • Giannis Roussos said:
    so what you are saying is that the FLL cannot be used in an application that is always sleeping and waiting for UART input?

    I didn’t say or mean that. But you can’t expect the FLL to work if you switch the DCO on and off. After all, the FLL is counting DCO pulses against reference pulses. If you switch the DCO off in LPM>0, this means the FLL sees less pulses than there should be, and adjusts the DCO up.
    When going into LPM, you should switch the FLL off, and when returning from LPM, you need to leave the FL off unless you are longer than at least two reference periods in active mode or LPM0.

    If you have regular timer interrupts, you can every now and then switch from LPM1..4 to LPM0 and go back to higher LPMs after a sufficient amount of time, leaving the FLL on during this period, so it can adjust the DCO. After all, in a stable system, the FLL is mostly not doing anything. After initial settling, its job is mainly to compensate for long-time drift

**Attention** This is a public forum