Hello,
I am trying to use two channels on one timer0, to handle two gpiote tasks to toggle two on-board leds on nRF52840 DK. I am using two ppi channels to handle this.
I have set the timer0_ticks0 and timer0_ticks1 as 250ms and 500ms and used extended compare on both the channels to generate a compare events accordingly.
I could see from the EVENTS_COMPARE[n] register, that only EVENTS_COMPARE[0] is triggered and not the other.
Diggging into it a little bit shown that only the lowest value from CC[n] gets a compare event.
Please find the code here. Any clarification on this is highly appreciated.
KInd regards
/** @file
*
* @ppi_timer_leds main.c
* @{
* @ingroup ppi_timer_leds
* @brief PPI TIMER0 CH0 and CH1 Application main file.
*
* This file contains the source code for a sample application using GPIOTE, TIMER; PPI.
*/
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_gpiote.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "nrfx_timer.h"
#include "nrfx_ppi.h"
#include "nrfx_gpiote.h"
#include "nrf_timer.h"
#include "nrf_gpiote.h"
#include "nrf_ppi.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#define LED1 13
#define LED2 14
#define LED3 15
#define LED4 16
#define B1 11
#define B2 12
#define B3 24
#define B4 25
static uint32_t tep_led1;
static uint32_t tep_led2;
static uint32_t eep0_timer0;
static uint32_t eep1_timer0;
static nrf_ppi_channel_t ppi_channel0; //for timer0_ch0 event and led1 toggle task at 500ms
static nrf_ppi_channel_t ppi_channel1; //for timer0_ch1 event and led2 toggle task at 1000ms
//Function prototypes
void gpiote_init();
void timer0_init();
void dummy_timer0_evnthndlr();
int main(void)
{
uint32_t err_code = NRF_SUCCESS;
gpiote_init();
timer0_init();
//Allocate a PPI channel 0
err_code = nrfx_ppi_channel_alloc(&ppi_channel0);
APP_ERROR_CHECK(err_code);
//Allocate a PPI channel 1
err_code = nrfx_ppi_channel_alloc(&ppi_channel1);
APP_ERROR_CHECK(err_code);
//Assign EEPs and TEPs to the PPI channel0
nrfx_ppi_channel_assign(ppi_channel0, eep0_timer0, tep_led1);
//Assign EEPs and TEPs to the PPI channel1
nrfx_ppi_channel_assign(ppi_channel1, eep1_timer0, tep_led2);
//Enable ppi channel
err_code = nrfx_ppi_channel_enable(ppi_channel0);
APP_ERROR_CHECK(err_code);
err_code = nrfx_ppi_channel_enable(ppi_channel1);
APP_ERROR_CHECK(err_code);
while (true)
{
// Do Nothing - GPIO can be toggled without software intervention.
}
}
void gpiote_init()
{
uint32_t err_code = NRF_SUCCESS;
//configure gpiote out task
nrfx_gpiote_out_config_t out_config1 = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); //out task to toggle the pin state
nrfx_gpiote_out_config_t out_config2 = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); //out task to toggle the pin state
//Initialize gpiote modlue
err_code = nrfx_gpiote_init();
APP_ERROR_CHECK(err_code);
//init gpiote for the desired pin- LED1 pin 13
err_code = nrfx_gpiote_out_init(LED1, &out_config1);
APP_ERROR_CHECK(err_code);
err_code = nrfx_gpiote_out_init(LED2, &out_config2);
APP_ERROR_CHECK(err_code);
//Enable gpiote led1 task
nrfx_gpiote_out_task_enable(LED1);
//Enable gpiote led2 task
nrfx_gpiote_out_task_enable(LED2);
//get the address of the gpiote out toggle task for led1
tep_led1 = nrfx_gpiote_out_task_addr_get(LED1);
//get the address of the gpiote out toggle task for led2
tep_led2 = nrfx_gpiote_out_task_addr_get(LED2);
}
void timer0_init()
{
uint32_t err_code = NRF_SUCCESS;
//Timer0 is instatiated
nrfx_timer_t timer0 = NRFX_TIMER_INSTANCE(0);
//Configure timer 0. Look at the macro for parameter details
nrfx_timer_config_t timer0_cfg = NRFX_TIMER_DEFAULT_CONFIG;
timer0_cfg.frequency = NRF_TIMER_FREQ_1MHz;
timer0_cfg.mode = NRF_TIMER_MODE_TIMER;
timer0_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
timer0_cfg.interrupt_priority = 6;
//from ms to ticks
uint32_t timer0_ticks0 = nrfx_timer_ms_to_ticks(&timer0, 250);
uint32_t timer0_ticks1 = nrfx_timer_ms_to_ticks(&timer0, 500);
//Initialize the timer
err_code = nrfx_timer_init(&timer0, &timer0_cfg, dummy_timer0_evnthndlr);
APP_ERROR_CHECK(err_code);
//setting the timer channel in the extended compare mode.
nrfx_timer_extended_compare(&timer0, NRF_TIMER_CC_CHANNEL0, timer0_ticks0, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
nrfx_timer_extended_compare(&timer0, NRF_TIMER_CC_CHANNEL1, timer0_ticks1, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, false);
//get timer0 event address
eep0_timer0 = nrfx_timer_event_address_get(&timer0, NRF_TIMER_EVENT_COMPARE0);
eep1_timer0 = nrfx_timer_event_address_get(&timer0, NRF_TIMER_EVENT_COMPARE1);
//enable timer0
nrfx_timer_enable(&timer0);
}
void dummy_timer0_evnthndlr()
{
}
/** @} */