8 years, 10 months ago.

Ticker failing/stopping after 72 minutes on LPC1549

I'm running into issues on the LPC1549 where the ticker is stopping after 72 minutes and 30-40 seconds when I run it with a 1 second period.

It doesnt seem to be ticker object related, but perhaps the mbed library still has a bug that is incorrectly handling something. It doesnt matter if I delete the Ticker and then recreate it, it wont begin working again unless I reset the chip.

Here's my quick test code:

LPC1549 Ticker Failure

#include "mbed.h"

Serial pc(USBTX, USBRX);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);

bool led1State = 0;
bool led2State = 0;
bool led3State = 0;

int systime = 0;

time_t lastUpdateData; 

void updateData()
{ 
    time_t systime = time(NULL);
    
    pc.printf("Run Time: %d mins %d secs (%d)\r\n", (systime/60), systime - ((systime/60)*60), time(NULL));
    // blue
    led3 = led3State;
    led3State = !led3State;
    
    lastUpdateData = time(NULL);
}

int main() {
    set_time(0);
    
    pc.baud(57600);
    pc.printf("Boot OK, Timer Test\r\n\r\n");
    
    led1 = 1;
    led2 = 1;
    led3 = 1;
    
    lastUpdateData = time(NULL);
    
    Ticker *tick1s = new Ticker();
    tick1s->attach(&updateData, 1);

    while (true)
    {
        // green        
        led2 = led2State;
        led2State = !led2State;
        wait (0.125);
        
        
        if (time(NULL) - lastUpdateData > 2)
        {
            pc.printf("Ticker stopped, restarting\r\n");
            tick1s->detach();
            delete tick1s;
            
            tick1s = new Ticker();
            
            tick1s->attach(&updateData, 1);
            
            lastUpdateData = time(NULL);
        }
    }
}

I'm running MBED library version 100, which at the time I'm posting is the latest build. I realise that there have been issues from 89 on, however there have been several posts to say that this has been resolved.

When running this code, my last bytes before going into an endless loop of "ticker stopped, restarting" have been: Run Time: 72 mins 31 secs (4351)

Run Time: 72 mins 36 secs (4356)

Run Time: 72 mins 41 secs (4361)

When running my my more complex program, I'm seeing pretty similar, with start/end times of (time is from a GPS, not the RTC):

  • 2015-05-31 17:55:39 to 2015-05-31 19:07:12
  • 2015-05-31 19:09:07 to 2015-05-31 20:20:40
  • 2015-05-31 21:42:28 to 2015-05-31 22:54:01
  • 2015-05-31 23:25:20 to 2015-06-01 00:36:53
  • 2015-06-01 03:17:26 to 2015-06-01 04:28:59
  • 2015-06-05 07:10:21 to 2015-06-05 08:21:54

I'd love some suggestions on keeping the ticker running on the 1549, I need it to be running for at least 4hrs to dump telemetry and do logging, which I don't want in my fairly dumb main loop for simplicity.

I'm hoping not to need to modify the mbed library, as I'm hoping to open source this code in a few months when I'm finished, so I'd like to keep things as standard as possible :)

- Mark

Question relating to:

Running the attach callback at 0.1 seconds doesnt make a difference:

  • Run Time: 72 mins 25 secs (4345)
  • Run Time: 72 mins 26 secs (4346)

I figured out why the run time messages have a more variable time, vs the gps - when running 10hz I can clearly see how the RTC is not very accurate, the GPS time fails on exactly the same second every time. When running at 10hz with just checking time() I can have as few has 6 callbacks for the one second, and as many as 14 or so... these might even themselves out mostly but you can see the variation of over 10 seconds for the timer failure according to the RTC.

posted by Mark Harris 06 Jun 2015

Another test using the code above: NXP Run Time: 72 mins 32 secs (4352) NXP Run Time: 72 mins 33 secs (4353) NXP Run Time: 72 mins 34 secs (4354) NXP Run Time: 72 mins 35 secs (4355) Ticker stopped, restarting

This time I ran the code on a STM32L053 next to it, both started at the same time. When the STM ticked over to 68 minutes, the nxp ticked over to 69 minutes, the NXP was consistently pulling away from the STM32. I find this interesting, as the LPC1549 appears to have an RTC crystal on the dev board, which it also appears to be completely ignoring.

The STM32 is still running after 80 minutes, so this appears to be an issue in the LPC1549 implementation. I dont have any other NXP dev boards here at time, there are a couple back in the office that I can test on monday however.

In short: the NXP LPC1549 stopped working, the STM32L continued on. I'm not going to turn off the STM32 just to see how it goes after a day or two.

Another interesting note, despite running set_time(0) on the STM32, it's time is still a very negative number after doing that.

For example: STM Run Time: 75 mins 21 secs (-1265433175)

The number in brackets is the time(NULL) value.

posted by Mark Harris 06 Jun 2015

The STM should have very inaccurate RTC, unless you fitted a crystal yourself.

Regarding your ticker: This is exactly the 32-bit overflow, and the code of the LPC1549 does not handle it properly indeed. It will require mbed-src modification, but of course when that is done it can be added to the official sources. I however don't have the LPC1549, so hard for me to modify it without having a possibility to debug it afterwards.

posted by Erik - 06 Jun 2015

Any suggestions on where to start modifying the mbed lib?

The STM32 died after:

  • STM Run Time: 526 mins 31 secs (-1265406105)

The STM32 is one of the nucleo boards, it has a 32.768khz on X2, the HSE crystal is unmounted on the nucleo's, however this board happens to have one mounted and in use as well.

I havent actually looked at the schematics yet, but Y1 on the NXP board next to the 12mhz Y2 sure looks like a 32.768khz RTC crystal, but based on the timings coming out of the board it doesn't appear to be used at all for the time functions.

posted by Mark Harris 06 Jun 2015

Thanks for the link to the ticker code. I'll see if I can get some time to look at it over the next week or so. If you have any suggestions for specific changes, I'd be happy to test them.

NXP dev board does indeed have Y1 as the RTC: http://www.embeddedartists.com/sites/default/files/support/xpr/LPC1549_LPCXpresso%20v2_schem_Rev_B2.pdf

Doesn't appear to be making use of it though.

I have restarted my STM32L053 test to see what happens over night :)

posted by Mark Harris 07 Jun 2015

STM finally dropped out again at: STM Run Time: 1658 mins 39 secs (-1265338177) BYE!

posted by Mark Harris 09 Jun 2015

Just want to confirm that this issue is not present on the LPC812 or the LPC11U68. They are both at: NXP Run Time: 149 mins 40 secs (8980)

posted by Mark Harris 09 Jun 2015

2 Answers

8 years, 5 months ago.

The problem here is the implementation of the ticker based on the LPC1549's Repetitive Interrupt Timer (RIT). The RIT runs on a fixed clock rate (core clock) and has a 48-bit counter register. The ticker itself uses a 32-bit timestamp in microseconds. There is an overrun in the ticker at 2^32 microsecs (72 minutes). Due to this overrun the newly calculated compare value for the RIT lies below its counter value preventing further compare interrupts. As a result the ticker stops working. The overrun itself would not be a problem if the RIT would run on a 1MHz clock rate and use a 32-bit counter register. In my opinion the RIT is not suitable for this functionality.

8 years, 5 months ago.

Maybe the code used for the LPC812/824 can provide some inspiration. It uses the 31bit Multirate Timer (MRT) which also runs at SystemCoreClock. At the expense of some additional computations and admin it should be possible to fix the RIT issue.