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

Why does the GPIOTE event not link to the GPIOTE task via PPI though the event handler works?

I was learning GPIOTE using the example provided in SDK 9.0.0. (examples\peripheral\gpiote). The example only uses GPIOTE task and a timer to drive the task through PPI.

So I created a similar function (pasted below) that is meant to link a GPIOTE event to a GPIOTE task through PPI. The GPIOTE event corresponds to button 2 (BSP_Button_1) of the nRF51 DK board. The GPIOTE task corresponds to LED 2 (BSP_LED_1).

The GPIOTE event's handler also toggles LED 3 (for verification purposes).

LED 3 toggled when button 2 was pressed, confirming that the GPIOTE event was working. But LED 2 was always on. So either PPI or GPIOTE task, or both was not working.

#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_gpiote.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#include "nrf_delay.h"

#ifdef BSP_LED_0
    #define GPIO_OUTPUT_PIN_NUMBER BSP_LED_0  /**< Pin number for output. */
#endif

#ifndef GPIO_OUTPUT_PIN_NUMBER
    #error "Please indicate output pin"
#endif


static nrf_drv_timer_t timer = NRF_DRV_TIMER_INSTANCE(0);

void timer_dummy_handler(nrf_timer_event_t event_type, void * p_context){}

	
#define GPIO_LED_PIN 			BSP_LED_1
#define GPIO_LED2_PIN			BSP_LED_2
#define GPIO_BUTTON_PIN   BSP_BUTTON_1

void button_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) 
{
	nrf_gpio_pin_toggle(GPIO_LED2_PIN);
	nrf_delay_ms(1000);
}
	
static void led_button_setup()
{
  uint32_t gpiote_event_addr;
  uint32_t gpiote_task_addr;
  nrf_ppi_channel_t ppi_channel;
  ret_code_t err_code;
	
	// Initialise the LED task GPIOTE
  nrf_drv_gpiote_out_config_t task_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);

  err_code = nrf_drv_gpiote_out_init(GPIO_LED_PIN, &task_config);
  APP_ERROR_CHECK(err_code);

  gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_LED_PIN);

  nrf_drv_gpiote_out_task_enable(GPIO_LED_PIN);

	// Initialise LED 2 as an output
	nrf_gpio_cfg_output(GPIO_LED2_PIN);
	
	// Initialise the button event GPIOTE
  nrf_drv_gpiote_in_config_t event_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);

  err_code = nrf_drv_gpiote_in_init(GPIO_BUTTON_PIN, &event_config, button_handler);
  APP_ERROR_CHECK(err_code);

  gpiote_event_addr = nrf_drv_gpiote_in_event_addr_get(GPIO_BUTTON_PIN);
	
  nrf_drv_gpiote_in_event_enable(GPIO_BUTTON_PIN, true);

  // Initialise the ppi channel
  err_code = nrf_drv_ppi_channel_alloc(&ppi_channel);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_assign(ppi_channel, gpiote_event_addr, gpiote_task_addr);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_enable(ppi_channel);
  APP_ERROR_CHECK(err_code);

	
}

static void led_blinking_setup()
{
    uint32_t compare_evt_addr;
    uint32_t gpiote_task_addr;
    nrf_ppi_channel_t ppi_channel;
    ret_code_t err_code;
    nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);

    err_code = nrf_drv_gpiote_out_init(GPIO_OUTPUT_PIN_NUMBER, &config);
    APP_ERROR_CHECK(err_code);


    nrf_drv_timer_extended_compare(&timer, (nrf_timer_cc_channel_t)0, 200*1000UL, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);

    err_code = nrf_drv_ppi_channel_alloc(&ppi_channel);
    APP_ERROR_CHECK(err_code);

    compare_evt_addr = nrf_drv_timer_event_address_get(&timer, NRF_TIMER_EVENT_COMPARE0);
    gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_OUTPUT_PIN_NUMBER);

    err_code = nrf_drv_ppi_channel_assign(ppi_channel, compare_evt_addr, gpiote_task_addr);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_enable(ppi_channel);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_out_task_enable(GPIO_OUTPUT_PIN_NUMBER);
}

/**
 * @brief Function for application main entry.
 */
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);

    err_code = nrf_drv_timer_init(&timer, NULL, timer_dummy_handler);
    APP_ERROR_CHECK(err_code);
    *(uint32_t *)0x40008C0C = 1;

    // Setup PPI channel with event from TIMER compare and task GPIOTE pin toggle.
//    led_blinking_setup();

	  led_button_setup();
	
    // Enable timer
//    nrf_drv_timer_enable(&timer);

    while (true)
    {
        // Do Nothing - GPIO can be toggled without software intervention.
    }
}
Parents
  • Hmm, it worked after I set the GPIOTE event to high accuracy.

      nrf_drv_gpiote_in_config_t event_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    

    Also it seemed that the button is not as responsive as it should be in either case.

    Is there anything wrong in the code that makes the button randomly unresponsive?

Reply
  • Hmm, it worked after I set the GPIOTE event to high accuracy.

      nrf_drv_gpiote_in_config_t event_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    

    Also it seemed that the button is not as responsive as it should be in either case.

    Is there anything wrong in the code that makes the button randomly unresponsive?

Children
No Data
Related