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

nRFX lib - Problem with interupt and timer

Hi,

I use a mcu nRF52840 on a personal card for a project and we are stuck on interruptions: hardware pin and timer. I use the lib "nrfx" for future accounting purposes. I took the example code from the library "nrf" located at

*nRF5_SDK_15.3.0_59ac345\examples\peripheral\pin_change_int*

and I converted it with the nrfx library.

 

//-----------------------------------------CODE--------------------------------------------------------------
#include <nrfx.h>
#include <nrfx_gpiote.h>
#include "bsp.h"
#include "system_nrf52840.h"

void interuptTest(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action);

void main(void)
{
  SystemInit();
  bsp_init();
  // Configure the interupt on button 0
  nrfx_gpiote_init();
  nrfx_gpiote_in_config_t button_0_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO( true );
  nrfx_err_t test = nrfx_gpiote_in_init( BUTTON_0_PIN , &button_0_config, interuptTest );
  nrfx_gpiote_in_event_enable( BUTTON_0_PIN , true );

  while ( true )
  {
    // Make sure that the button is detected
    if( nrfx_gpiote_in_is_set( BUTTON_0_PIN ) )
    {
      nrfx_gpiote_out_clear( LED_2_PIN );
    } else
    {
      nrfx_gpiote_out_set( LED_2_PIN );
    }
  }
}

void interuptTest(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
  nrfx_gpiote_out_toggle( LED_1_PIN );
}
//-------------------------------------------------------------------------------------------------------------------

 

The execution of this code does not cause any interruption, however, LED number 2 changes state when button 0 is pressed, which attests to the change in the state.

Given the problems I have with both the hardware and timer interruptions, we must have missed a step in the configuration of the mcu. Can you enlighten me on this subject? What more needs to be done to allow interruptions?

Another question: I can't find an example with the nrfx library. Is that normal? Do you have a link to "official" examples using this library?

Thank you very much!

Parents
  • Hi,

    Are you configuring any of the buttons or leds in bsp_init() ?

    You are not configuring LED_1 as output with nrfx_gpiote_out_init(). Is it being configured in bsp_init()?

    In SDK 15.3 nrfx is being used, there is a glue layer converting the old api to the new nrfx api. See this link.

  • Hi,
    thank you for answering.
    Yes, LED_1, LED_2 and buttons are configured in bsp_init().
    The problem is when the button is pressed on the PCB, the LED_2 changes state (line 22-28) but we don't enter into the interrupt. Do you have any idea why the interrupt may not be active?

  • I then assume the buttons are not configured in bsp_init().

    Could you check the return values of nrfx_gpiote_in_init() and nrfx_gpiote_init() ? It's good practice to check the return values with APP_ERROR_CHECK()

    nrfx_err_t test = nrfx_gpiote_in_init( BUTTON_0_PIN , &button_0_config, interuptTest );
    APP_ERROR_CHECK(test);

  • Hi,


    Buttons were configured in bsp_init(). But to make it more clear, I moved them into this code. The result is the same. LED_2 change state when button 0 change state, we obtain 2 NRFX_SUCCESS but we never enter the interrupt.

    //----------------------------------------------------------------------------Code---------------------------------------------------
    #include <nrfx.h>
    #include <nrfx_gpiote.h>
    #include "bsp.h"
    #include "system_nrf52840.h"
    
    void interuptTest( nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action );
    void check_error( nrfx_err_t err_code );
    
    void main(void)
    {
      SystemInit();
      // Configure bouton and LEDs
      // LEDs need output direction
      nrf_gpio_cfg_output( LED_0_PIN );
      nrf_gpio_cfg_output( LED_1_PIN );
      nrf_gpio_cfg_output( LED_2_PIN );
    
      // Buttons need input direction, pull up are in hardware
      nrf_gpio_cfg_input( BUTTON_0_PIN, NRF_GPIO_PIN_NOPULL ); 
      nrf_gpio_cfg_input( BUTTON_1_PIN, NRF_GPIO_PIN_NOPULL ); 
      nrf_gpio_cfg_input( BUTTON_2_PIN, NRF_GPIO_PIN_NOPULL ); 
    
      // Configure the interupt on button 0
      nrfx_err_t err_code = nrfx_gpiote_init();
      check_error( err_code );
      nrfx_gpiote_in_config_t button_0_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO( true );
      err_code = nrfx_gpiote_in_init( BUTTON_0_PIN , &button_0_config, interuptTest );
      check_error( err_code );
    
      nrfx_gpiote_in_event_enable( BUTTON_0_PIN , true );
    
      while ( true )
      {
        // Make sure that the button is detected
        if( nrfx_gpiote_in_is_set( BUTTON_0_PIN ) )
        {
          nrfx_gpiote_out_clear( LED_2_PIN );
        } else
        {
          nrfx_gpiote_out_set( LED_2_PIN );
        }
      }
    }
    
    void interuptTest(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
      nrfx_gpiote_out_toggle( LED_1_PIN );
    }
    void check_error( nrfx_err_t err_code )
    {
      if (NRFX_SUCCESS == err_code)
       {
         debug_printf("Configuration success!\r\n");
       } else 
       {
         debug_printf("Error code : %i \r\n", err_code);
       }
    }
    //--------------------------------------------------------------------------------------------------------------------------------------

    Regarding the APP_ERROR_CHECK(test), I'm aware of the practice but as we are using NRFX, how can we include "app_error.h"? I'm missing a step on this. However, I managed to make something functional and I received the Configuration Sucess message twice.

  • Hi,

    The reset_handler will call SystemInit() before jumping to main() as part of the startup, so you don't have have to call it again in main().

    You should not read the pin status in the main while loop, it will consume alot of power. Use interrupts instead. This code here works fine when I test it on a DK.

    //----------------------------------------------------------------------------Code---------------------------------------------------
    #include <nrfx.h>
    #include <nrfx_gpiote.h>
    #include "bsp.h"
    #include "system_nrf52840.h"
    #include "boards.h"
    
    void interuptTest( nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action );
    void check_error( nrfx_err_t err_code );
    
    void main(void)
    {
      //SystemInit();
      // Configure bouton and LEDs
      // LEDs need output direction
      nrf_gpio_cfg_output( BSP_LED_0 );
      nrf_gpio_cfg_output( BSP_LED_1 );
      nrf_gpio_cfg_output( BSP_LED_2 );
    
      // Buttons need input direction, pull up are in hardware
      nrf_gpio_cfg_input( BSP_BUTTON_0, NRF_GPIO_PIN_PULLUP ); 
      nrf_gpio_cfg_input( BSP_BUTTON_1, NRF_GPIO_PIN_PULLUP ); 
      nrf_gpio_cfg_input( BSP_BUTTON_2, NRF_GPIO_PIN_PULLUP ); 
    
      // Configure the interupt on button 0
      nrfx_err_t err_code = nrfx_gpiote_init();
      check_error( err_code );
      nrfx_gpiote_in_config_t button_0_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO( true );
      button_0_config.pull = NRF_GPIO_PIN_PULLUP;
    
      err_code = nrfx_gpiote_in_init( BSP_BUTTON_0 , &button_0_config, interuptTest );
      check_error( err_code );
    
      nrfx_gpiote_in_event_enable( BSP_BUTTON_0 , true );
    
      while ( true )
      {
          // Wait for an event.
        #ifdef SOFTDEVICE_PRESENT
            if (nrf_sdh_is_enabled())
            {
                ret_code_t ret_code = sd_app_evt_wait();
                ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
                UNUSED_VARIABLE(ret_code);
            }
            else
        #endif // SOFTDEVICE_PRESENT
        {
            // Wait for an event.
            __WFE();
            // Clear the internal event register.
            __SEV();
            __WFE();
        }
    
    
      }
    }
    
    void interuptTest(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
      nrfx_gpiote_out_toggle( BSP_LED_1 );
    }
    void check_error( nrfx_err_t err_code )
    {
      if (NRFX_SUCCESS == err_code)
       {
         debug_printf("Configuration success!\r\n");
       } else 
       {
         debug_printf("Error code : %i \r\n", err_code);
       }
    }
    //--------------------------------------------------------------------------------------------------------------------------------------

    how can we include "app_error.h"?

    Just add this at top of main.c

    #include "app_error.h"

Reply
  • Hi,

    The reset_handler will call SystemInit() before jumping to main() as part of the startup, so you don't have have to call it again in main().

    You should not read the pin status in the main while loop, it will consume alot of power. Use interrupts instead. This code here works fine when I test it on a DK.

    //----------------------------------------------------------------------------Code---------------------------------------------------
    #include <nrfx.h>
    #include <nrfx_gpiote.h>
    #include "bsp.h"
    #include "system_nrf52840.h"
    #include "boards.h"
    
    void interuptTest( nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action );
    void check_error( nrfx_err_t err_code );
    
    void main(void)
    {
      //SystemInit();
      // Configure bouton and LEDs
      // LEDs need output direction
      nrf_gpio_cfg_output( BSP_LED_0 );
      nrf_gpio_cfg_output( BSP_LED_1 );
      nrf_gpio_cfg_output( BSP_LED_2 );
    
      // Buttons need input direction, pull up are in hardware
      nrf_gpio_cfg_input( BSP_BUTTON_0, NRF_GPIO_PIN_PULLUP ); 
      nrf_gpio_cfg_input( BSP_BUTTON_1, NRF_GPIO_PIN_PULLUP ); 
      nrf_gpio_cfg_input( BSP_BUTTON_2, NRF_GPIO_PIN_PULLUP ); 
    
      // Configure the interupt on button 0
      nrfx_err_t err_code = nrfx_gpiote_init();
      check_error( err_code );
      nrfx_gpiote_in_config_t button_0_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO( true );
      button_0_config.pull = NRF_GPIO_PIN_PULLUP;
    
      err_code = nrfx_gpiote_in_init( BSP_BUTTON_0 , &button_0_config, interuptTest );
      check_error( err_code );
    
      nrfx_gpiote_in_event_enable( BSP_BUTTON_0 , true );
    
      while ( true )
      {
          // Wait for an event.
        #ifdef SOFTDEVICE_PRESENT
            if (nrf_sdh_is_enabled())
            {
                ret_code_t ret_code = sd_app_evt_wait();
                ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
                UNUSED_VARIABLE(ret_code);
            }
            else
        #endif // SOFTDEVICE_PRESENT
        {
            // Wait for an event.
            __WFE();
            // Clear the internal event register.
            __SEV();
            __WFE();
        }
    
    
      }
    }
    
    void interuptTest(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
      nrfx_gpiote_out_toggle( BSP_LED_1 );
    }
    void check_error( nrfx_err_t err_code )
    {
      if (NRFX_SUCCESS == err_code)
       {
         debug_printf("Configuration success!\r\n");
       } else 
       {
         debug_printf("Error code : %i \r\n", err_code);
       }
    }
    //--------------------------------------------------------------------------------------------------------------------------------------

    how can we include "app_error.h"?

    Just add this at top of main.c

    #include "app_error.h"

Children
Related