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

gpio button interrupt is not triggering?

Hi all,

I am using pca10040 board. My requirement is when i press the button led should turn on after repress the button led should turn off.

For that i tried below code :

#include <stdbool.h>
#include <stdint.h>
#include "pca10040.h"
#include "bsp.h"
#include "nordic_common.h"
#include "nrf_gpio.h"
#include "nrf_drv_clock.h"
#include "sdk_errors.h"
#include "app_error.h"
#include "app_uart.h"
#include "app_fifo.h"
#include "app_button.h"
#include "app_timer.h"
#include "nrf_delay.h"
#include "nrf_error.h"

#define APP_TIMER_PRESCALER 0
#define  APP_TIMER_OP_QUEUE_SIZE 6
#define BUTTON_DETECTION_DELAY        APP_TIMER_TICKS(500u, APP_TIMER_PRESCALER)
#define MAX_TEST_DATA_BYTES     (15U)                /**< max number of test bytes to be used for tx and rx. */
#define UART_TX_BUF_SIZE 256                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 1                           /**< UART RX buffer size. */

void button_handler(uint8_t pin_no, uint8_t button_action)
{
    UNUSED_VARIABLE(puts("Enter \r\n"));
    nrf_gpio_pin_toggle(BSP_LED_1);
    if (button_action == APP_BUTTON_PUSH)
    {
        switch (pin_no)
        {
            case BSP_BUTTON_0:
                    UNUSED_VARIABLE(puts(" Buttons 0 \r\n"));
                    nrf_gpio_pin_toggle(BSP_LED_0);
                break;
          }
     }
}

void leds_init(void)
{
        UNUSED_VARIABLE(puts("LEDS Initialized \r\n"));
// Configure LED-pins as outputs
    nrf_gpio_cfg_output(BSP_LED_0);
    nrf_gpio_cfg_output(BSP_LED_1);
    nrf_gpio_cfg_output(BSP_LED_2);
    nrf_gpio_cfg_output(BSP_LED_3);
    nrf_gpio_pin_set(BSP_LED_0);
    nrf_gpio_pin_set(BSP_LED_1);
    nrf_gpio_pin_set(BSP_LED_2);
    nrf_gpio_pin_set(BSP_LED_3);
}

void uart_error_handle(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_communication);
    }
    else if (p_event->evt_type == APP_UART_FIFO_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_code);
    }
}

void uart_init(void)
{
    ret_code_t err_code;
    const app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_ENABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud38400
    };

    APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_error_handle,
                       APP_IRQ_PRIORITY_LOW,
                       err_code);

    APP_ERROR_CHECK(err_code);

    UNUSED_VARIABLE(puts(" UART Initialized \r\n"));
}
int main(void)
{
        ret_code_t err_code;
        err_code = nrf_drv_clock_init();
        APP_ERROR_CHECK(err_code);
        uart_init();
        leds_init();
        UNUSED_VARIABLE(puts(" Buttons Initialized \r\n"));
        app_button_cfg_t p_button[] = {{BUTTON_1, false, BUTTON_PULL, button_handler}};
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);
        // Initializing the buttons.
        err_code = app_button_init(p_button,1, BUTTON_DETECTION_DELAY);
        APP_ERROR_CHECK(err_code);
        // Enabling the buttons.
        err_code = app_button_enable();
        APP_ERROR_CHECK(err_code);
        while(1) {
            __WFE();
            __SEV();
            __WFE();
     }
}

Buttons Initialization is done. But button handler is not calling. In my console i'm getting prints like this :

 UART Initialized                       
                                        
LEDS Initialized                        
                                        
 Buttons Initialized 

After that its hanging there itself.

Why button handler is not called?

Im a newbie on this. Can anyone help me to fix this issue?

Thank you,

  • You need to start the LFCLK with nrf_drv_clock_lfclk_request() or else app_timer will not work (which app_button depends on). Here is a similar example that uses app_button.

  • How to use the same code in FreeRTOS?

  • Hi Ole Bauck, Thanks for your support, After adding nrf_drv_clock_lfclk_request() the above program is handling fine.

    That same code i had implemented in FreeRTOS. There i created 3 tasks , those tasks are running parallely but there my button handler is not handling. Code is below :

    #include <stdbool.h>
    #include <stdint.h>
    #include "FreeRTOS.h"
    #include "task.h"
    #include "timers.h"
    #include "bsp.h"
    #include "nordic_common.h"
    #include "nrf_gpio.h"
    #include "nrf_drv_clock.h"
    #include "sdk_errors.h"
    #include "app_error.h"
    #include "app_uart.h"
    #include "app_fifo.h"
    #include "pca10040.h"
    #include "app_button.h"
    #include "app_timer.h"
    #include "nrf_delay.h"
    #include "nrf_error.h"
    
    #define TASK_DELAY 1000
    #define MAX_TEST_DATA_BYTES     (15U)                /**< max number of test bytes to be used for tx and rx. */
    #define UART_TX_BUF_SIZE 256                         /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE 1                           /**< UART RX buffer size. */
    
    #define APP_TIMER_PRESCALER 0
    #define  APP_TIMER_OP_QUEUE_SIZE 6
    #define BUTTON_DETECTION_DELAY        APP_TIMER_TICKS(500u, APP_TIMER_PRESCALER)
    
    static void vLed0Function (void *pvParameter)
    {
        UNUSED_PARAMETER(pvParameter);
        for( ;; )
        {
                    printf("LED 1 Toggle \r\n");
                    nrf_gpio_pin_toggle(BSP_LED_0);
                    vTaskDelay(TASK_DELAY); // Delay a task for a given number of ticks
        }
    }
    
    static void vLed1Function (void *pvParameter)
    {
        UNUSED_PARAMETER(pvParameter);
        for( ;; )
        {
                    printf("LED 2 Toggle \r\n");
                    nrf_gpio_pin_toggle(BSP_LED_1);
                    vTaskDelay(TASK_DELAY); // Delay a task for a given number of ticks
        }
    }
    
    static void vLed2Function (void *pvParameter)
    {
        UNUSED_PARAMETER(pvParameter);
        for( ;; )
        {
                    printf("LED 3 Toggle \r\n");
                    nrf_gpio_pin_toggle(BSP_LED_2);
                    vTaskDelay(TASK_DELAY); // Delay a task for a given number of ticks
        }
    }
    
    static void leds_init(void)
    {
        printf("LEDS Initialized \r\n");
        // Configure LED-pins as outputs
        nrf_gpio_cfg_output(BSP_LED_0);
        nrf_gpio_cfg_output(BSP_LED_1);
        nrf_gpio_cfg_output(BSP_LED_2);
        nrf_gpio_cfg_output(BSP_LED_3);
        nrf_gpio_pin_set(BSP_LED_0);
        nrf_gpio_pin_set(BSP_LED_1);
        nrf_gpio_pin_set(BSP_LED_2);
        nrf_gpio_pin_set(BSP_LED_3);
    }
    
    static void uart_error_handle(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_communication);
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_code);
        }
    }
    
    static void uart_init(void)
    {
        ret_code_t err_code;
        const app_uart_comm_params_t comm_params =
        {
            RX_PIN_NUMBER,
            TX_PIN_NUMBER,
            RTS_PIN_NUMBER,
            CTS_PIN_NUMBER,
            APP_UART_FLOW_CONTROL_ENABLED,
            false,
            UART_BAUDRATE_BAUDRATE_Baud38400
        };
    
        APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_error_handle,
                           APP_IRQ_PRIORITY_LOW,
                           err_code);
    
        APP_ERROR_CHECK(err_code);
    
        UNUSED_VARIABLE(puts(" UART Initialized \r\n"));
    }
    
    void button_handler(uint8_t pin_no, uint8_t button_action)
    {
        UNUSED_VARIABLE(puts("Enter \r\n"));
        nrf_gpio_pin_toggle(BSP_LED_3);
        if (button_action == APP_BUTTON_PUSH)
        {
            switch (pin_no)
            {
                case BSP_BUTTON_0:
                        UNUSED_VARIABLE(puts("Buttons 0 \r\n"));
                        nrf_gpio_pin_toggle(BSP_LED_3);
                    break;
              }
         }
    }
    int main(void)
    {
        uart_init();
        leds_init();
    
        ret_code_t err_code;
        err_code = nrf_drv_clock_init();
        APP_ERROR_CHECK(err_code);
        nrf_drv_clock_lfclk_request(NULL);
    
            UNUSED_VARIABLE(puts(" Buttons Initialized \r\n"));
            app_button_cfg_t p_button[] = {{BUTTON_1, false, BUTTON_PULL, button_handler}};
            APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);
            // Initializing the buttons.
            err_code = app_button_init(p_button,1, BUTTON_DETECTION_DELAY);
            APP_ERROR_CHECK(err_code);
            // Enabling the buttons.
            err_code = app_button_enable();
            APP_ERROR_CHECK(err_code);
    
        TaskHandle_t  xLed0Handle;       /**< Reference to LED0 toggling FreeRTOS task. */
        TaskHandle_t  xLed1Handle;       /**< Reference to LED1 toggling FreeRTOS task. */
        TaskHandle_t  xLed2Handle;       /**< Reference to LED2 toggling FreeRTOS task. */
    
        UNUSED_VARIABLE(xTaskCreate( vLed0Function, "L0", configMINIMAL_STACK_SIZE + 50, NULL, 1, &xLed0Handle ));    // LED0 task creation
        UNUSED_VARIABLE(xTaskCreate( vLed1Function, "L1", configMINIMAL_STACK_SIZE + 50, NULL, 2, &xLed1Handle ));    // LED1 task creation
        UNUSED_VARIABLE(xTaskCreate( vLed2Function, "L2", configMINIMAL_STACK_SIZE + 50, NULL, 0, &xLed2Handle ));    // LED2 task creation
        /* Activate deep sleep mode */
        SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    
    uint8_t ch;
    while(app_uart_get(&ch) != NRF_SUCCESS);
        // Start FreeRTOS scheduler.
        vTaskStartScheduler();
    
        while (true)
        {
            // FreeRTOS should not be here...
        }
    }
    
    /* Used in debug mode for assertions */
    void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name)
    {
      while(1)
      {
        /* Loop forever */
      }
    }
    

    Is there anything we need to enable or disable for using FreeRTOS,

    Can you please guide me on this?

    Thank you

  • You need to define app_button_cfg_t p_button[] = {{BUTTON_1, false, BUTTON_PULL, button_handler}} as static or move it outside of main(). Or else it will be placed on the stack and removed when it is not used anymore. You are also toggling the led twice inside button_handler, remove one of the toggle functions.

  • Hi Ole Bauck, Thanks for your awesome responses, Its really helpful for us. And may i know how to set the priority of gpio interrupts? Thank you,

Related