Dialog DA14531 - Timers
By: Gowtham Ts
Tags: Tutorial, Electronics, Hardware, Bluetooth Low Energy, Embedded Systems

A timer is a common peripheral found on a microcontroller which stores a value and keeps incrementing with a pulse trigger, which can be the internal clock or an external signal. Timers have a wide variety of use cases, for generating delays, periodically performing an operation etc.

The DA14531 has 3 timers — Timer0, Timer1 and Timer2.

Timer 0 is a 16 bit general purpose timer which can also generate PWM signals on 2 channels.

Timer1 is a 11 bit timer. It does not have the capability to generate PWM signals but it can be used to capture inputs on 2 GPIO pins.

Timer 2 is a 14 bit timer which is a PWM generator with 6 outputs.

In this tutorial, I have used Timer0 to toggle the state of a LED.

Project setup

The project with the code for this tutorial is available on Github at https://github.com/vicara-hq/da14531-tutorials

Download the project and copy it. The project has to be placed inside the Dialog SDK6 folder. Navigate to <SDK6_ROOT>/projects/target_apps/template and paste it in this folder. The project is a modified version of the empty_peripheral_template project provided by Dialog. But to keep this tutorial series as open source as possible, all the following steps will use the SmartSnippets Studio.

Code Overview

Our aim is to toggle a LED using a timer, so we will need to configure the GPIO connected to the LED i.e. P0.09 as an output pin in the user_periph_setup.c file.

void GPIO_reservations(void)

{

RESERVE_GPIO(LED, GPIO_PORT_0, GPIO_PIN_9, PID_GPIO);

} void set_pad_functions(void)

{

GPIO_ConfigurePin(GPIO_PORT_0, GPIO_PIN_9, OUTPUT, PID_GPIO, false);

}

Next, we will configure Timer0 to generate an interrupt every 100ms.

void user_app_on_init() {

timer_init();

default_app_on_init();

} static void timer_irq_handler() {

if (GPIO_GetPinStatus(GPIO_PORT_0, GPIO_PIN_9)) {

GPIO_SetInactive(GPIO_PORT_0, GPIO_PIN_9);

} else {

GPIO_SetActive(GPIO_PORT_0, GPIO_PIN_9);

}

} void timer_init() { static tim0_2_clk_div_config_t clk_div_config = {

.clk_div = TIM0_2_CLK_DIV_8

};

timer0_stop();

timer0_register_callback(timer_irq_handler);

timer0_2_clk_enable();

timer0_2_clk_div_set(&clk_div_config);

timer0_init(TIM0_CLK_FAST, PWM_MODE_ONE, TIM0_CLK_DIV_BY_10); timer0_set_pwm_high_counter(0);

timer0_set_pwm_low_counter(0); timer0_set_pwm_on_counter(20000);

timer0_enable_irq();

timer0_start(); }

To check the steps on linking the custom callback, take a look at my last tutorial on GPIOs, buttons and LEDs.

Before configuring anything, timer0_2_clk_enable needs to be called which will enable Timer0.

Timer0 can use the System Clock or the Low Power Clock as it’s source. We’ll be using the System Clock which runs at 16 MHz by default. We set the prescaler in the clock configuration structure to divide the frequency by 8 i.e. 2MHz. Timer0 also has an internal optional clock divider which divides the frequency by 10. After enabling it, the frequency at the Timer is 200kHz.

To get the LED to toggle every 100ms, we need to load the timer register with 20000.

20,000 * (1/200,000)sec = 1/10 sec = 100 ms

Timer0 also has 2 registers used for PWM which are set to 0 using the timer0_set_pwm_high_counter and timer0_set_pwm_low_counter functions. The timer0_set_pwm_on_counter is used when Timer0 is configured as a general purpose timer.

The timer0_init function takes 3 parameters. The first parameter decides which clock we use as the source. TIM0_CLK_FAST selects the system clock. The second parameter selects the PWM mode but since we are using Timer0 as a general purpose timer, we set it to PWM_MODE_ONE. TIM0_CLK_DIV_BY_10 enabled the internal frequency divider.

Timer0 has an interrupt which is enabled using timer0_enable_irq and we register the callback to the function using timer0_register_callback. To understand the code used in the callback function, take a look at my last blog post on GPIO, buttons and LEDs.

The last thing to do is to start the timer which is done by the timer0_start function.

Build the project and run the debugger. You should observe that the D2 LED on the DA14531 module daughterboard blinks rapidly.