While using PPI and trying to use the first channel as a clock based PWM running on timer1 I noticed that whenever I use more than 2 PPI channels, the pin that is toggeling on timer1 goes to a much higher frequency (2 Hz to 2kHz). Moreover the LEDs that are on a PPI channel and supposed to react to the first channel toggling from high to low stay off but when measured I get a voltage of 3,3 on the LEDs. But im wondering why the PPI acts this way as I was only using two channels. The code I used to initialize the PPI setup that works when I comment out ppi_set_led2 or 3:
#include "ppi_setup.h"
#define LED1 21
#define LED2 22
#define LED3 23
#define SENSE1 10
#define SENSE2 11
//Declare PPI channels
nrf_ppi_channel_t ppi_channel1;
nrf_ppi_channel_t ppi_channel2;
nrf_ppi_channel_t ppi_channel3;
//Declare Timer
const nrf_drv_timer_t timer1 = NRF_DRV_TIMER_INSTANCE(0);
void ppi_init(void)
{
ppi_set_LED1();
ppi_set_LED2();
//ppi_set_LED3();
nrf_drv_timer_enable(&timer1);
}
void ppi_set_LED1(void)
{
//Declare Variables
uint32_t err_code;
uint32_t led1_task_addr;
//Configure Task & Event
nrf_drv_gpiote_out_config_t led1_output_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
//Initialize peripherals
err_code = nrf_drv_gpiote_out_init(LED1, &led1_output_config);
APP_ERROR_CHECK(err_code);
//Set timer compare trigger
nrf_drv_timer_extended_compare(&timer1, (nrf_timer_cc_channel_t)0, 0x0000F424, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
//Set Task & Event pointers
led1_task_addr = nrf_drv_gpiote_out_task_addr_get(LED1);
//Allocate PPI channel
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel1);
APP_ERROR_CHECK(err_code);
//Assign Event-End-Point (EEP) and Task-Event-Point (TEP)
err_code = nrf_drv_ppi_channel_assign(ppi_channel1, nrf_drv_timer_event_address_get(&timer1, NRF_TIMER_EVENT_COMPARE0), led1_task_addr);
//Enable PPI channel & peripherals
err_code = nrf_drv_ppi_channel_enable(ppi_channel1);
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_out_task_enable(LED1);
}
void ppi_set_LED2(void)
{
//Declare Variables
uint32_t err_code = NRF_SUCCESS;
uint32_t led2_event_addr;
uint32_t led2_task_addr;
//Configure Task & Event
nrf_drv_gpiote_in_config_t led2_event_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
nrf_drv_gpiote_out_config_t led2_task_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
//Initialize peripherals
err_code = nrf_drv_gpiote_in_init(SENSE1, &led2_event_config, false);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_gpiote_out_init(LED2, &led2_task_config);
APP_ERROR_CHECK(err_code);
//Set Task & Event pointers
led2_event_addr = nrf_drv_gpiote_in_event_addr_get(SENSE1);
led2_task_addr = nrf_drv_gpiote_out_task_addr_get(LED2);
//Allocate PPI channel
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel2);
APP_ERROR_CHECK(err_code);
//Assign Event-End-Point (EEP) and Task-Event-Point (TEP)
err_code = nrf_drv_ppi_channel_assign(ppi_channel2, led2_event_addr, led2_task_addr);
//Enable PPI channel & peripherals
err_code = nrf_drv_ppi_channel_enable(ppi_channel2);
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_in_event_enable(SENSE1, false);
nrf_drv_gpiote_out_task_enable(LED2);
}
void ppi_set_LED3(void)
{
//Declare Variables
uint32_t err_code = NRF_SUCCESS;
uint32_t led3_event_addr;
uint32_t led3_task_addr;
//Configure Task & Event
nrf_drv_gpiote_in_config_t led3_event_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
nrf_drv_gpiote_out_config_t led3_task_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
//Initialize peripherals
err_code = nrf_drv_gpiote_in_init(SENSE2, &led3_event_config, false);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_gpiote_out_init(LED3, &led3_task_config);
APP_ERROR_CHECK(err_code);
//Set Task & Event pointers
led3_event_addr = nrf_drv_gpiote_in_event_addr_get(SENSE2);
led3_task_addr = nrf_drv_gpiote_out_task_addr_get(LED3);
//Allocate PPI channel
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel3);
APP_ERROR_CHECK(err_code);
//Assign Event-End-Point (EEP) and Task-Event-Point (TEP)
err_code = nrf_drv_ppi_channel_assign(ppi_channel3, led3_event_addr, led3_task_addr);
//Enable PPI channel & peripherals
err_code = nrf_drv_ppi_channel_enable(ppi_channel3);
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_in_event_enable(SENSE2, false);
nrf_drv_gpiote_out_task_enable(LED3);
}
The main code:
#include "nrf.h"
#include "app_error.h"
#include "bsp.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_gpiote.h"
#include "app_pwm.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "nrf_drv_gpiote.h"
#include "boards.h"
#include "nrf_soc.h"
#include "ppi_setup.h"
static void power_manage(void);
static void power_manage(void)
{
uint32_t err_code = sd_app_evt_wait();
APP_ERROR_CHECK(err_code);
}
int main(void)
{
ret_code_t err_code;
err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);
NRF_POWER->TASKS_CONSTLAT = 1;
NRF_TIMER0->PRESCALER = 8;
NRF_TIMER0->TASKS_CLEAR = 1;
ppi_init();
while(true)
{
power_manage();
}
}