This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problems when counting pulses using GPIOTE and TIMER via PPI in the presence of SoftDevice

I am trying to implement frequency counting on nRF51822 by counting number of pulses in a given period. I create a PPI channel with a GPIOTE event on rising edge linked to TIMER counting task. The relevant code is as follows:

#define USE_WITH_SOFTDEVICE     1

#define FC_GPIO   2
#define FC_TIMER  NRF_TIMER0 
#define FC_GPIOTE_CH  0 
#define FC_PPI_CH  0

static void ppi_enable_channel(uint32_t ch_num, volatile uint32_t *event_ptr, volatile uint32_t *task_ptr)
{
    if(ch_num >= 16) return;
    else
    {
#if(USE_WITH_SOFTDEVICE == 1)
        sd_ppi_channel_assign(ch_num, event_ptr, task_ptr);
        sd_ppi_channel_enable_set(1 << ch_num);
#else
        // Otherwise we configure the channel and return the channel number
        NRF_PPI->CH[ch_num].EEP = (uint32_t)event_ptr;
        NRF_PPI->CH[ch_num].TEP = (uint32_t)task_ptr;    
        NRF_PPI->CHENSET = (1 << ch_num);   
#endif
    }
}


// Create a PPI channel: GPIOTE event from low to high --> FC_TIMER count up by 1 
static void counting_init(void)
{ 
	nrf_gpio_cfg_input(FC_GPIO, NRF_GPIO_PIN_NOPULL);   // frequency counting input
	
	// Init timer
  FC_TIMER->TASKS_CLEAR = 1;
  FC_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
	FC_TIMER->MODE = TIMER_MODE_MODE_Counter;
	FC_TIMER->PRESCALER = 0; 
	FC_TIMER->TASKS_CAPTURE[0] = 0;
	
	// Init GPIOTE
	nrf_gpiote_event_config(FC_GPIOTE_CH, FC_GPIO, NRF_GPIOTE_POLARITY_LOTOHI);
	
	// enable PPI
	ppi_enable_channel(FC_PPI_CH, &NRF_GPIOTE->EVENTS_IN[FC_GPIOTE_CH], &FC_TIMER->TASKS_COUNT);
	
}

// Destructor 
static void counting_deinit(void)
{
	FC_TIMER->TASKS_STOP = 1;
	FC_TIMER->TASKS_SHUTDOWN = 1;
	nrf_gpiote_unconfig(FC_GPIOTE_CH);
	nrf_gpio_cfg_output(FC_GPIO);
	nrf_gpio_pin_clear(FC_GPIO);
}

static uint16_t count_get(void)
{
	uint16_t count;
	counting_init();
	FC_TIMER->TASKS_START = 1;
	nrf_delay_ms(1);  // try busy wait
	FC_TIMER->TASKS_CAPTURE[0] = 1;
  count = FC_TIMER->CC[0];
	counting_deinit();
	return count;
}

The last function count_get() returns the number of counts. However, when I call the function in the code, the program results in hard default. If I don't call the function, the code runs fine. So there should be something wrong with the way I implement in. Please advise.

Parents Reply Children
No Data
Related