Skip to main content Skip to local navigation

Wakeup Timer on the LPC804

Here is an example of running a timer on the LPC804, originally written in C and then modified to work in C++14 on MCUXpresso 11.1.

Checking LED blinking frequency against a known good clock (NIST).

Checking LED blinking frequency against a known good clock (NIST and my computer's clock)

Here we're using the 1MHz Low Power Oscillator to drive the Wakeup Timer on the LPC804. The same code would work as a C++ project on the LPC802 (OM40000 board) if we swapped out the LPC804.h header for LPC802.h.  As well, LED_USER1 (20) would have to be LED_USER1 (9) since there are different GPIO connections to LEDs on the OM40000 (LPC802) board versus the OM400001 (LPC804) board.

To adjust the frequency, modify the WKT_RELOAD value.  Note that this adjusts the interrupt request frequency.  The actual LED flashing frequency will always be half that because the interrupt service routine (function) uses a toggle ("NOT") that has to run twice to make the LED blink completely.

// LPC804_Project_WKT_CPP14.c
//
// based on NXP sample code.
//
// -----------------------------------------------

#define WKT_FREQ 1000000    // Use if the WKT is clocked by the Low PWR Oscillator

//#define WKT_FREQ 937500   // Use if the WKT is clocked by the 15 MHz FRO,

// via the div-by-16 WKT divider
#define WKT_RELOAD 500000    // Reload value for the WKT down counter
#define WKT_INT_FREQ (WKT_FREQ/WKT_RELOAD)  // Interrupt frequency of the WKT.
#define LED_USER1 (20) // GPIO #20 (PIO0_20) is connected to the LED

#include "LPC804.h"
// prototypes
void WKT_Config();
// main routine
//
int main(void) {
  // WKT: Wake Timer configuration
  WKT_Config();
  // do nothing in the main loop.
  while(1) {
  asm("NOP");
  } // end of loop.
} // end of main

// Function name: WKT_Config
// Description:   Initialize a GPIO output pin and the WKT, then start it.
// Parameters:    None
// Returns:       Void
// Source: Ch. 18 of the User Manual (UM11045)
void WKT_Config(void)
{
// -----------------------------------------------------
// Step 1.  Make an LED turn on.  Checks that board is up and running.
// Enable GPIO for the LED.
SYSCON->SYSAHBCLKCTRL0 |= (SYSCON_SYSAHBCLKCTRL0_GPIO0_MASK);

// GPIO to Output.
GPIO->DIRSET[0] = (1UL<<LED_USER1);
// Turn on the LED.
GPIO->CLR[0] = (1UL<<LED_USER1);
// --------------------------------------------------------

// Step 2: turn on the Wake-up Timer (WKT) enabling clock.
SYSCON->SYSAHBCLKCTRL0 |= (SYSCON_SYSAHBCLKCTRL0_WKT_MASK);
// --------------------------------------------------------
// Step 3: disable the vector lookup for WKT.
NVIC_DisableIRQ(WKT_IRQn); // turn off the WKT interrupt.
// --------------------------------------------------------
// Step 4: Turn on the Low Power Oscillator's power supply.
// bit 6 to 0 in order to turn it ON. (Active low)
SYSCON->PDRUNCFG &= ~(SYSCON_PDRUNCFG_LPOSC_PD_MASK);

// ----------------------------------------------------
// Step 5: Enable the LPOSC clock to the WKT.  (Bit 1 to 1)

SYSCON->LPOSCCLKEN |= (SYSCON_LPOSCCLKEN_WKT_MASK);

// --------------------------------------------------------

// Step 6: Reset the WKT.
//    Set bit 9 to 0: assert (i.e. "make") the WKT reset
//  Set bit 9 to 1: clear the WKT reset (i.e. "remove" reset)
SYSCON->PRESETCTRL0 &= ~(SYSCON_PRESETCTRL0_WKT_RST_N_MASK);   // Reset the WKT
SYSCON->PRESETCTRL0 |= (SYSCON_PRESETCTRL0_WKT_RST_N_MASK);// clear the reset.

// -------------------------------------------------------
// Step 7: Load the timer
// --------------------------------------------------------
// Select the LPOSC as the WKT clock source (0b0001)
// Bit 0 (CLKSEL) to 1 for Low Power Clock
// Bit 1 (ALARMFLAG) read flag.  If 1, an interrupt has happened. if 0, then no timeout.
// Bit 2 (CLEARCTR).  Set to 1 to clear the counter.
// Bit 3 (SEL_EXTCLK).  Set to 0 for internal clock source.
WKT->CTRL = WKT_CTRL_CLKSEL_MASK; // (Choose Low Power Clock using Bit 0)
// load the timer count-down value. (The "Timeout value")
WKT->COUNT = WKT_RELOAD;// Start WKT, counts down from WKT_RELOAD and then interrupt
// Enable the IRQ
NVIC_EnableIRQ(WKT_IRQn);                 // Enable the WKT interrupt in the NVIC
}

// Function name: WKT_IRQHandler (interrupt service routine)
// Description:   WKT interrupt service routine.
//                Toggles an LED & restarts the WKT.
// Parameters:    None
// Returns:       Void
extern "C" // wrap in an extern for C++
{
void WKT_IRQHandler(void)
{
  WKT->CTRL |= WKT_CTRL_ALARMFLAG_MASK; // Clear the interrupt flag
  WKT->COUNT = WKT_RELOAD;              // Restart the WKT (fill it again)
  // Toggle the LED
  GPIO->NOT[0] = (1UL<<LED_USER1);
  return;  // return nothing.
}
}