ARM Cortex-M0 SysTick learning notes





























UM10398 User Manual Chapter 24: LPC111x/LPC11Cxx System tick timer (SysTick)

24 September 2012 User manual page 396 of 538

The system tick timer (SysTick timer) is part of the ARM Cortex-M0 core and is identical
for all LPC111x, LPC11D14, and LPC11Cxx parts.

24.2 Basic configuration

The system tick timer is configured using the following registers:

1. Pins: The system tick timer uses no external pins.

2. Power: The system tick timer is enabled through the SysTick control register
(Section 28.6.4.1). The system tick timer clock is fixed to half the frequency of the
system clock.

3. Enable the clock source for the SysTick timer in the SYST_CSR register (Table 357).


24.3 Features

• Simple 24-bit timer.

• Uses dedicated exception vector.

• Clocked internally by the system clock or the system clock/2.


24.4 General description

The SysTick timer is an integral part of the Cortex-M0. The SysTick timer is intended to
generate a fixed 10 millisecond interrupt for use by an operating system or other system
management software.

Since the SysTick timer is a part of the Cortex-M0, it facilitates porting of software by
providing a standard timer that is available on Cortex-M0 based devices. The SysTick
timer can be used for:

• An RTOS tick timer which fires at a programmable rate (for example 100 Hz) and
invokes a SysTick routine.

• A high-speed alarm timer using the core clock.

• A simple counter. Software can use this to measure time to completion and time used.

• An internal clock source control based on missing/meeting durations. The
COUNTFLAG bit-field in the control and status register can be used to determine if an
action completed within a set duration, as part of a dynamic clock management
control loop.


24.5 Register description

The systick timer registers are located on the ARM Cortex-M0 private peripheral bus (see
Figure 97), and are part of the ARM Cortex-M0 core peripherals. For details, see
Section 28.6.4.

[1] Reset Value reflects the data stored in used bits only. It does not include content of reserved bits.

Table 356. Register overview: SysTick timer (base address 0xE000 E000)

Name Access Address offset Description Reset value[1]

SYST_CSR R/W 0x010 System Timer Control and status register 0x000 0000

SYST_RVR R/W 0x014 System Timer Reload value register 0

SYST_CVR R/W 0x018 System Timer Current value register 0

SYST_CALIB R/W 0x01C System Timer Calibration value register 0x4


24.5.1 System Timer Control and status register

The SYST_CSR register contains control information for the SysTick timer and provides a
status flag. This register is part of the ARM Cortex-M0 core system timer register block.
For a bit description of this register, see Section 28.6.4 “System timer, SysTick”.
This register determines the clock source for the system tick timer.

Table 357. SysTick Timer Control and status register (SYST_CSR - 0xE000 E010) bit
description

Bit Symbol Description Reset value

0 ENABLE System Tick counter enable. When 1, the counter is enabled.
When 0, the counter is disabled.
0

1 TICKINT System Tick interrupt enable. When 1, the System Tick interrupt
is enabled. When 0, the System Tick interrupt is disabled. When
enabled, the interrupt is generated when the System Tick counter
counts down to 0.
0

2 CLKSOURCE System Tick clock source selection. When 1, the system clock
(CPU) clock is selected. When 0, the system clock/2 is selected
as the reference clock.
0

15:3 - Reserved, user software should not write ones to reserved bits.
The value read from a reserved bit is not defined.
NA

16 COUNTFLAG Returns 1 if the SysTick timer counted to 0 since the last read of
this register.
0

31:17 - Reserved, user software should not write ones to reserved bits.
The value read from a reserved bit is not defined.

NA

24.5.1 System Timer Control and status register
The SYST_CSR register contains control information for the SysTick timer and provides a
status flag. This register is part of the ARM Cortex-M0 core system timer register block.
For a bit description of this register, see Section 28.6.4 “System timer, SysTick”.
This register determines the clock source for the system tick timer.
Table 356. Register overview: SysTick timer (base address 0xE000 E000)
Name Access Address
offset
Description Reset value[1]
SYST_CSR R/W 0x010 System Timer Control and status register 0x000 0000
SYST_RVR R/W 0x014 System Timer Reload value register 0
SYST_CVR R/W 0x018 System Timer Current value register 0
SYST_CALIB R/W 0x01C System Timer Calibration value register 0x4
UM10398 All information provided in this document is subject to legal disclaimers. © NXP B.V. 2012. All rights reserved.
User manual Rev. 12 — 24 September 2012 398 of 538
NXP Semiconductors UM10398
Chapter 24: LPC111x/LPC11Cxx System tick timer (SysTick)
24.5.2 System Timer Reload value register
The SYST_RVR register is set to the value that will be loaded into the SysTick timer
whenever it counts down to zero. This register is loaded by software as part of timer
initialization. The SYST_CALIB register may be read and used as the value for
SYST_RVR register if the CPU is running at the frequency intended for use with the
SYST_CALIB value.
24.5.3 System Timer Current value register
The SYST_CVR register returns the current count from the System Tick counter when it is
read by software.
Table 357. SysTick Timer Control and status register (SYST_CSR - 0xE000 E010) bit
description
Bit Symbol Description Reset
value
0 ENABLE System Tick counter enable. When 1, the counter is enabled.
When 0, the counter is disabled.
0
1 TICKINT System Tick interrupt enable. When 1, the System Tick interrupt
is enabled. When 0, the System Tick interrupt is disabled. When
enabled, the interrupt is generated when the System Tick counter
counts down to 0.
0
2 CLKSOURCE System Tick clock source selection. When 1, the system clock
(CPU) clock is selected. When 0, the system clock/2 is selected
as the reference clock.
0
15:3 - Reserved, user software should not write ones to reserved bits.
The value read from a reserved bit is not defined.
NA
16 COUNTFLAG Returns 1 if the SysTick timer counted to 0 since the last read of
this register.
0
31:17 - Reserved, user software should not write ones to reserved bits.
The value read from a reserved bit is not defined.
NA
Table 358. System Timer Reload value register (SYST_RVR - 0xE000 E014) bit description
Bit Symbol Description Reset
value
23:0 RELOAD This is the value that is loaded into the System Tick counter when it
counts down to 0.
0
31:24 - Reserved, user software should not write ones to reserved bits.
The value read from a reserved bit is not defined.
NA
Table 359. System Timer Current value register (SYST_CVR - 0xE000 E018) bit description
Bit Symbol Description Reset
value
23:0 CURRENT Reading this register returns the current value of the System Tick
counter. Writing any value clears the System Tick counter and the
COUNTFLAG bit in STCTRL.
0
31:24 - Reserved, user software should not write ones to reserved bits. The
value read from a reserved bit is not defined.
NA

24.5.4 System Timer Calibration value register (SYST_CALIB - 0xE000 E01C)
The value of the SYST_CALIB register is driven by the value of the SYSTCKCAL register
in the system configuration block (see Table 34).

24.6 Functional description

The SysTick timer is a 24-bit timer that counts down to zero and generates an interrupt.
The intent is to provide a fixed 10 millisecond time interval between interrupts. The
SysTick timer is clocked from the CPU clock (the system clock, see Figure 8) or from the
reference clock, which is fixed to half the frequency of the CPU clock. In order to generate
recurring interrupts at a specific interval, the SYST_RVR register must be initialized with
the correct value for the desired interval. A default value is provided in the SYST_CALIB
register and may be changed by software. The default value gives a 10 millisecond
interrupt rate if the CPU clock is set to 50 MHz.

24.7 Example timer calculations

To use the system tick timer, do the following:

1. Program the SYST_RVR register with the reload value RELOAD to obtain the desired
time interval.

2. Clear the SYST_CVR register by writing to it. This ensures that the timer will count
from the SYST_RVR value rather than an arbitrary value when the timer is enabled.

3. Program the SYST_SCR register with the value 0x7 which enables the SysTick timer
and the SysTick timer interrupt.

The following example illustrates selecting the SysTick timer reload value to obtain a
10 ms time interval with the LPC111x/LPC11Cxx system clock set to 50 MHz.

Example (system clock = 50 MHz)

The system tick clock = system clock = 50 MHz. Bit CLKSOURCE in the SYST_CSR
register set to 1 (system clock).

RELOAD = (system tick clock frequency  10 ms) 1 = (50 MHz  10 ms) 1 = 5000001
= 499999 = 0x0007A11F.

Table 360. System Timer Calibration value register (SYST_CALIB - 0xE000 E01C) bit
description

Bit Symbol Value Description Reset

value

23:0 TENMS See Table 461. 0x4

29:24 - Reserved, user software should not write ones to
reserved bits. The value read from a reserved bit is not
defined.

NA

30 SKEW See Table 461. 0

31 NOREF See Table 461. 0



.END




Programming the LPC1114FN28 - Created 19 Dec 2012, last modified: 14 May 2013

http://vilaca.eu/lpc1114/vilaca.eu.lpc1114_102_led_blink.zip

#include <LPC11xx.h> /* LPC11xx Peripheral Registers */
#include "system_LPC11xx.h"

#define LED       (1<<9)      /* LED D1 connect to PIO1_9 */

int main(void)
{

LPC_SYSCON ->SYSAHBCLKCTRL |= (1 << 8); // Enable Clock for TMR1

LPC_IOCON ->PIO1_9 |= (1 << 0); // PIN1_9 = CT16B1_MAT0

LPC_TMR16B1 ->MR0 = 2000; // 50% Duty Cycle
LPC_TMR16B1 ->PR = 12000;
LPC_TMR16B1 ->MR3 = 4000; // Cycle Length

LPC_TMR16B1 ->MCR |= (1 << 10); // TC Reset on MR3 Match

LPC_TMR16B1 ->PWMC |= (1 << 0); // PWM Mode

LPC_TMR16B1 ->TCR |= (1 << 0); // GO

while (1);
// unreachable
return 0;
}


Code Samples for NXP's LPC1114FN28/102 Microprocessor

https://github.com/engineergorman/lpc1114fn28

// LPC_IOCON->PIO0_8
    // I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 (R/W)
    struct _PIO0_8
    {
        uint32_t FUNC : 3;  // pin function
        uint32_t MODE : 2;  // pull up/down resistor mode
        uint32_t HYS : 1;       // Hysteresis.
        uint32_t reserved0 : 4;
        uint32_t OD : 1;        // Selects pseudo open-drain mode
        uint32_t reserved1 : 21;
    };

I then use inline functions to cast the ptr to register to the structure and then set/get the bit field values.

    #define PIO0_8_FUNC_GPIO 0x0
    #define PIO0_8_FUNC_MISO 0x1
    #define PIO0_8_FUNC_TIMER 0x2
    inline void IOCON_PIO0_8_FUNC(uint32_t val)
    {
        ((_PIO0_8*)&LPC_IOCON->PIO0_8)->FUNC = val;
    }

And best of all I let the compiler figure out all of the masks and bit shifts for me.

Here is what programming the 16-bit timer for PWM looks like with these inline functions:

    void SetupPWM()
    {
        // Enables clock for 16-bit counter/timer 0
        SYSCON_SYSAHBCLKCTRL_CT16B0(SYSAHBCLKCTRL_ENABLE);
        // setup pin 1 for PWM output
        IOCON_PIO0_8_FUNC(PIO0_8_FUNC_TIMER);
        // disable pullup resistor pin 1
        IOCON_PIO0_8_MODE(PIO0_8_MODE_NO_RESISTOR);
        // set timer prescaler
        TMR16B0_PR_Set(SystemFrequency/10000);  // TC = 10Khz
        // set match register 3 to reset TC
        TMR16B0_MCR_MR3R(MCR_ENABLE);
        // set PWM duty cycle
        TMR16B0_MR3_Set(100);   // 100Hz
        // set pulse width
        TMR16B0_MR0_Set(0); // 0%
        // enable PWM mode on match register 0 (MR0)
        TMR16B0_PWMC_PWMEN0(PWMC_ENABLE);
        // enable counter
        TMR16B0_TCR_CEn(TCR_ENABLE);
        // reset timers
        //TMR16B0_TCR_CRst(TCR_RESET);
    }


*** Delay using Systick ***

#include <LPC11xx.h>
#include "../core/core.h"

uint32_t SystemFrequency;


extern "C" void SystemInit(void)
{
// if you initialize clock here beware that the C++ runtime 
// initialization code runs next...  and writes to globals
// do not persist.  so the SystemFrequency needs to be set
// in the main() function, or just initialize the clock there
// for simplicity.
}


volatile unsigned long SysTickCnt;      // SysTick Counter

// SysTick Interrupt Handler (1ms)
extern "C" void SysTick_Handler(void) 
{           
  SysTickCnt++;
}

void Delay(unsigned long tick)
{
  unsigned long systickcnt;

  systickcnt = SysTickCnt;
// TODO: handle when SysTickCnt overflows
  while ((SysTickCnt - systickcnt) < tick);
}


int main(void)
{
// Set system frequency to 48MHz
SystemFrequency = ConfigurePLL(12000000UL, 48000000UL);

// Enable clock to IO Configuration block.  Needed for UART, SPI, I2C, etc...
SYSCON_SYSAHBCLKCTRL_IOCON(SYSAHBCLKCTRL_ENABLE);

  SysTick_Config(SystemFrequency/1000 - 1); // Generate interrupt each 1 ms

// set direction on port 0_7 (pin 28) to output
GPIO0_DIR(7, GPIO_OUTPUT);

while (1)
{
int j;
for (j = 0; j < 10; ++j)
{
Delay(50);

GPIO0_DATA(7, 1); // turn on LED on pin 28

Delay(50);

GPIO0_DATA(7, 0); // turn off LED
}

Delay(1000);
}
}

.END

No comments:

Post a Comment