This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52 DK GPIOTE interrupt stops working after approx 400ms after startup.

I am using SDK 15.3, SES 4.30 and softdevice 132 with the ble_app_uart_c as the core functionality for my system.

I've read many dev support threads about this issue and most seem to point to using high accuracy with GPIOTE.  I have high accuracy enabled.  Attached is my code:

// GPIOTE is used for D_TEMP_IRQ input to know when a temperature conversion is completed
void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
  nrf_gpio_pin_toggle(LED_1); // Flash the led so we know something's happening
  get_water_temp();
}

/**
 * @brief Function for configuring: PIN_IN pin for input, 
 * and configures GPIOTE to give an interrupt on pin change. */

#define PIN_IN D_TEMP_IRQ

void gpio_init(void) {
  ret_code_t err_code;
  err_code = nrf_drv_gpiote_init();
  APP_ERROR_CHECK(err_code);

  nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);   // true = high accuracy
  in_config.pull = NRF_GPIO_PIN_NOPULL;

  err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
  APP_ERROR_CHECK(err_code);

  d_temp_irq_enable();
}
//  Functions to enable and disable interrupts on d_temp_irq
int d_temp_irq_enable(void) {
  nrf_drv_gpiote_in_event_enable(PIN_IN, true);
//  nrf_gpio_pin_toggle(LED_2); // Flash the led so we know something's happening
  temp_probe_irq = true;
}

uint32_t d_temp_irq_disable(void) {
  nrf_drv_gpiote_in_event_disable(PIN_IN);
//  nrf_gpio_pin_toggle(LED_1); // Flash the led so we know something's happening
  temp_probe_irq = false;
}

I have an external pullup on the d_temp_irq line that is triggering the GPIOTE.  The system is consistently shutting down the GPIOTE interrupts within the approximately 400ms time period.  This is the only GPIOTE interrupt I use.

The GPIOTE is setup early in the startup sequence via gpio_init()  in main(void) code were I immediately configure the Dallas DS18B20 temperature sensor.  The sensor is working up until the 400ms time wherein the interrupt stops working.  I'm thinking that there is other code starting afterwards that is disabling the interrupt function.

Does the soft device, timers, or other BLE functions affect the GPIOTE operation?   Here's my main(void) code:

int main(void) {
  // Initialize.
  log_init();
  app_timers_init();

  uart_init();
  pins_buttons_leds_init();   
  gpio_init();                
//  pwm_init();             

//  saadc_init();               
//  saadc_sampling_event_init(); 
  perfect_shower_init();       

  db_discovery_init();
  power_management_init();
  ble_stack_init();
  gatt_init();
  nus_c_init();
  scan_init();

  // Start execution.
  printf("BLE UART central example started.\r\n");
  NRF_LOG_INFO("BLE UART central example started.");
  scan_start();

  // Enter main loop.
  for (;;) {
    idle_state_handle();
  }
}

/

I've disabled the pwm and saadc code to see if they're causing the problem... They aren't.

Parents Reply Children
  • Hi Kenneth,

    If you look at the first code segment I pasted in my first post, you will see that I have set high accuracy to (true) so I don't understand why I am getting the Port output enabled.

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true); // true = high accuracy

    in_config.pull = NRF_GPIO_PIN_NOPULL;

    Also, your links refer to:

    Tasks and events pin configuration

    Each GPIOTE channel is associated with one physical GPIO pin through the CONFIG.PSEL field.

    When Event mode is selected in CONFIG.MODE, the pin specified by CONFIG.PSEL will be configured as an input, overriding the DIR setting in GPIO. Similarly, when Task mode is selected in CONFIG.MODE, the pin specified by CONFIG.PSEL will be configured as an output overriding the DIR setting and OUT value in GPIO. When Disabled is selected in CONFIG.MODE, the pin specified by CONFIG.PSEL will use its configuration from the PIN[n].CNF registers in GPIO.

    I cannot find any modules that define CONFIG.MODE or CONFIG.PSEL.  How do I make sure that I get high accuracy and that I am set to Event?

  • Hi Kenneth,

    I've traced the GPIOTE port enable setting to be performed by   err_code = nrf_drv_gpiote_init(); in main.c.

    the call to:     nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk); from nrfx_err_t nrfx_gpiote_init(void) in nrfx_gptioe.c sets the GPIOTE port enable bit. 

    My subsequent call to configure the pin PIN_IN:

    nrf_drv_gpiote_in_config_t in_config =
    {
    .sense = NRF_GPIOTE_POLARITY_LOTOHI,
    .pull = NRF_GPIO_PIN_NOPULL ,
    .is_watcher = false,
    .hi_accuracy = true,
    };

    doesn't change the port bit even though I am setting the hi_accuracy bit to true.

  • It is not that I don't believe you, but I am not aware of any issue that may be similar to what you describe. My best suggestion is to take a look at the gpiote example one more time, comment out everything in your project that is not related for gpiote until it works, and then comment in code again until it fails. If you are not able to find the root cause, then I need a project I can unzip to the example folder in the nRF5 SDK and run on a standard nRF52-DK (without any third party hardware attached).

    I don't see any better suggestion, but please share any findings you may have.

    Best regards,
    Kenneth

  • Hi Kenneth,

    Since this code is setting an irq for an external Dallas temperature device, I'm not sure how I can give you a copy of the code that you can run directly.  However, I've setup 4 breakpoints and took 4 screen shots that show the GPIOTE registers after each.  You can see what is going on from these.

      

    What to do next?

  • Kenneth,

    When I setup a GPIOTE interrupt, how do I know what interrupt is being used?  It's looking to me that my GPIOTE interrupt is being disabled by some other module such as: ble_stack_init(),  gatt_init(),  nus_c_init()  or scan_init().  If I run the code continuously before enabling  these functions, the interrupt works fine.  This would account for the 400ms run time at startup.

    If this is the case, how do I specify an interrupt that isn't used by the softdevice or other code?

Related