I am trying to use PPI to control an output pin. I am successfully using 2 PPI channels at the moment to use the COMP to do freq counting over a 10mS time period. I have added a 3rd PPI channel to turn an output off in below code.
static void ppi_init(void) { uint32_t err_code = NRF_SUCCESS; err_code = nrf_drv_ppi_init(); error_check(err_code); err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); //Configure GPIOTE nrf_drv_gpiote_out_config_t config = NRFX_GPIOTE_CONFIG_OUT_TASK_LOW; //TOGGLE(NRF_GPIOTE_INITIAL_VALUE_HIGH);// err_code = nrf_drv_gpiote_out_init(MI_EN, &config); APP_ERROR_CHECK(err_code); uint32_t gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(MI_EN); nrf_drv_gpiote_out_task_enable(MI_EN); /* Configure 1st available PPI channel to count timer1 when comp has UP event */ err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel1); error_check(err_code); err_code = nrf_drv_ppi_channel_assign(m_ppi_channel1, 0x40013108, 0x40009008); error_check(err_code); //0x40013108 = Comp UP event //0x40009008 = Timer 1 Count /* Configure 2nd available PPI channel to stop TIMER1 (counter) counting when timer 2 ticks */ err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel2); error_check(err_code); err_code = nrf_drv_ppi_channel_assign(m_ppi_channel2, nrf_drv_timer_event_address_get(&m_timer4, NRF_TIMER_EVENT_COMPARE0), nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_STOP)); error_check(err_code); /* Configure 3rd available PPI channel to set MI-EN low after compare event */ err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel3); error_check(err_code); err_code = nrf_drv_ppi_channel_assign(m_ppi_channel3, nrf_drv_timer_event_address_get(&m_timer4, NRF_TIMER_EVENT_COMPARE0), gpiote_task_addr); error_check(err_code); // Enable both configured PPI channels err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1); error_check(err_code); err_code = nrf_drv_ppi_channel_enable(m_ppi_channel2); error_check(err_code); err_code = nrf_drv_ppi_channel_enable(m_ppi_channel3); error_check(err_code); } /** @brief Function for Timer 1 initialization. * setup as a counter */ static void timer1_init(void) { // Check TIMER1 configuration for details. nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; timer_cfg.frequency = NRF_TIMER_FREQ_31250Hz; timer_cfg.mode = NRF_TIMER_MODE_COUNTER; ret_code_t err_code = nrf_drv_timer_init(&m_timer1, &timer_cfg, NULL); error_check(err_code); }
Then I have a seperate RTC timer at 32Hz, that resets the timers and sets the output pin high.
//capture the counter value MI_freq = nrf_drv_timer_capture(&m_timer1, 0); //Restart the timers for the PPI MI capture nrf_drv_timer_enable(&m_timer1); nrf_drv_timer_enable(&m_timer4); nrf_drv_timer_clear(&m_timer1); nrf_drv_timer_clear(&m_timer4); //Set the output high nrf_drv_gpiote_out_set(MI_EN);
The output is always off. If I set the task type to GPIOTE TASK_HIGH then the output is always on.
Is there anything obviously wrong in the code? My timers / counter and PPI channel 1 and 2 are all working as expected.
It appears as if the GPIOTE task is always running, i.e. holding the output low all the time and not just triggering on the PPI timer compare.
Thanks