MicroTick (UTICK) Timer Tutorial with OKdo E1 board

I want to share with you a little embedded trick that I use to improve the reliability of my code. And in addition to improving reliability, the technique can be used to schedule any event to occur ‘sometime in the future’. It uses the MicroTick (UTICK) timer found on the NXP LPC55S69 microcontroller, and could be applied to any device with a simple timer.

The MicroTick timer is an elegant, thing of beauty. But there is not a driver example built into the lpcxpresso55s69 SDK, and I believe that the timer is not widely used. That means we need a tutorial!

Let’s say that you want to turn on an LED for 1 second, or create a delay for 200ms whilst an eInk display initialises. Or you know that the PLL on your microcontroller should lock within 100us and want to guard the inevitable while(PLL_hasnt_locked) loop of code. This is where a simple timer should be used, instead of a delay() function. The while() loop is so widely used in embedded applications, and is often used to test a flag in a status register. You’ll find it all over the lpcxpress55s69 SDK… in the CMSIS code-base, the PLL configuration code, in the I2C driver, the USART and SPI drivers…

Now, I don’t have a philosophical problem with the while() and do…while() constructs, but they can be very dangerous in real-world applications. Consider this:

Snippet>> i2c driver from lpcxpresso55s69 SDK

The I2C STAT register is read at line 1124, inside the do{}, and the loop is executed until the SLVPENDING flag is set true by the hardware. This condition is tested at line 1133 with the test against I2C_STAT_SLV_PENDING_MASK. Any electrical noise, hardware fault or other real-world disturbance can upset the I2C state machine and cause the software to hang permanently inside this loop, with SLVPENDING never getting set. We might get rescued by the watchdog at some point in the future (if it is enabled) but by then we won’t know what caused the hang. It could be preferable to enable the define I2C_RETRY_TIMES, but since I am using the UTICK timer for all kinds of non-RTOS applications (switch debouncing, general delays in the display driver, LED blinking, as a replacement for delay_ms()…) I prefer to guard the while() loops with this UTICK timer.

MicroTick timer

block diagram of utick timer (LPC55S69)

It’s a very simple timer! A dedicated 1MHz free-running oscillator fro_1m is the clock source, and the timer can be loaded with a 31-bit count value. The clock decrements the timer, and at Count = 0, an interrupt is asserted to the NVIC. There is a repeat mode, so that the timer generates a periodic interrupt, but I prefer to use the timer in “Onetime” mode… I simply configure the timer to generate an interrupt in ‘X’ microseconds, and the UTICK driver sends my code into the callback function that I assigned to the driver.

Two other points to note… 2^31 / (1,000,000) gives a maximum delay of approximately 35 minutes (actually, 00:35:47) and a minimum delay of a few microseconds. Since the reference clock comes from a free-running 1MHz oscillator, the UTICK timer is not intended for accurate time-keeping. Secondly, note that the UTICK timer has 4 capture inputs… these allow us to latch the counter value into one of 4 capture registers when a programmed edge detect occurs on the capture pins. And simple means a low gate count and a low gate count means very low power… LPC55S69 datasheet quotes 200nA for the utick and 3.5uA for the fro_1m.

Using UTICK timer driver

In the video accompanying this tutorial I show how the UTICK timer is configured and used. It really is simple. As my example runs on the OKdo E1 board, it is necessary for me to configure the clocks so that we don’t use the external crystal and PLL0 (otherwise the code hangs in a while () loop….. you see what I mean about while() loops 😉 ). I chose to use the BOARD_BootClockFRO12M() functional group; then enabled the fro_1m; and then attached the fro_1m to the utick timer:

enabling fro_1m
attach fro_1m to UTICK timer

The software required to use the UTICK driver takes just 3 steps:

  • Declare the driver;
  • Initialise and configure the UTICK timer;
  • Write the user callback function.

In this code snippet, I #include the driver fsl_utick.h (line 43), then I initialise (line 63) and configure the UTICK0 to give me a onetime interrupt after 2,000,000 microseconds that will call the registered utick_callback function (line 67). Lastly, the callback function is declared at line 48.

UTICK driver in action (volatile qualifier on gbTick – thankyou Robert Poor)

Without the utick timer, the code will hang at line 69 in the while() loop. The escape clause happens in the callback function… setting the global boolean variable gbTick = true. It is so simple and easy to use I’m finding uses for the UTICK timer in all of my projects.

You can see the full details of the project on the embeddedpro YouTube channel, where I create a new project in MCUXpresso IDE v11.1.x with the New Project Wizard, use the Clocks config tool to set up the fro_1m, write the software and run it on my OKdo E1 board.

We all have our preferred strategies for managing real-world embedded problems. Maybe you manage timing and delays with an RTOS – for example FreeRTOS – or perhaps you are more comfortable with software-timed ‘for() loop’ delays. I meet in the middle – low level code, but using a simple-but-robust timer to schedule something to happen in the near future. I must admit that I really like the simplicity of the MicroTick timer. Why not give it a test and then let me know how you got on??

3 thoughts on “MicroTick (UTICK) Timer Tutorial with OKdo E1 board

  1. Mark: Good stuff! Quick question: It seems like the compiler might optimize `gbTick` out unless you declare it volatile. Can you guarantee that it won’t?

    Liked by 1 person

    • Well yes, of course gbTick is at risk of optimisation without the volatile qualifier. Indeed, when building the project with -O3 gbTick is promoted to internal register R2 and never has an address in RAM. The example then breaks: the callback is executed but the code remains hung in while(). “Shoots self in foot” 😦
      I’ve updated the code example with volatile: thankyou for your input.

      Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.