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

Button handling not working using bsp

Hi. I have a problem with my NRF52840 Dongle. When using BSP driven button. I've tried to use some SDK precompiled examples - it doesn't work. Neither with ble_peripheral, nor ZigBee or Thread examples. Then I tried this code:

#include "boards.h"

int main(){
    bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
    while (true)
    {
        if (bsp_board_button_state_get(BSP_BUTTON_0)){
            bsp_board_led_invert(BSP_BOARD_LED_2);
        }
    }
    
}
 and it worked as expected.

But the following code, which is intended to perform the same action:

#include "boards.h"
#include "app_timer.h"
#include "app_button.h"

static void buttons_handler(uint8_t pin, uint8_t action)
{
    if (pin == BSP_BOARD_BUTTON_0){
        if (action == APP_BUTTON_PUSH){
            bsp_board_led_invert(BSP_BOARD_LED_0);
        }
    }
}

int main(void)
{
    bsp_board_init(BSP_INIT_LEDS);
    app_timer_init();
    static app_button_cfg_t buttons [] = {
        {BSP_BOARD_BUTTON_0, false, BUTTON_PULL, buttons_handler}
    };
    app_button_init(buttons, ARRAY_SIZE(buttons), APP_TIMER_TICKS(50));
    app_button_enable();
}
 doesn't work.

This code works well:

#include <stdbool.h>
#include <stdint.h>
#include "boards.h"
#include "bsp.h"
#include "app_timer.h"
#include "nordic_common.h"

void bsp_evt_handler(bsp_event_t evt)
{
    switch (evt)
    {
        case BSP_EVENT_KEY_0:
            bsp_board_led_invert(BSP_BOARD_LED_0);
            break;

        default:
            return;
    }
}

int main(void){
    NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_LFCLKSTART    = 1;

    app_timer_init();
    bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_evt_handler);
    while (true)
    {

    }
}

But the same construction in examples doesn't work (Ble blinky, for example).

I need some help because I don't know, where to look for some kind of solution.

Parents
  • Hi,

    You cannot use the BSP_BOARD_BUTTON_x defines with app_button. App_button expects the GPIO pin number as input, while the BSP_BOARD_BUTTON_x defines are defined from 0-7:

    #define BSP_BOARD_BUTTON_0 0
    #define BSP_BOARD_BUTTON_1 1
    #define BSP_BOARD_BUTTON_2 2
    #define BSP_BOARD_BUTTON_3 3
    #define BSP_BOARD_BUTTON_4 4
    #define BSP_BOARD_BUTTON_5 5
    #define BSP_BOARD_BUTTON_6 6
    #define BSP_BOARD_BUTTON_7 7

    You can use the BUTTON_x or the BSP_BUTTON_x defines from the board header file (these are taken from pca10056.h):

    #define BUTTON_1       11
    #define BUTTON_2       12
    #define BUTTON_3       24
    #define BUTTON_4       25
    
    #define BSP_BUTTON_0   BUTTON_1
    #define BSP_BUTTON_1   BUTTON_2
    #define BSP_BUTTON_2   BUTTON_3
    #define BSP_BUTTON_3   BUTTON_4

    Best regards,
    Jørgen

  • Hi! Thanks. That helped to fix the issue with small parts of code above. But, unfortunately, I still don't know what should I do with Zigbee example. Here are some parts of init code from my modified light_switch. But the same situation is with other examples.

    #include "zboss_api.h"
    #include "zb_mem_config_custom.h"
    #include "zb_error_handler.h"
    #include "zigbee_helpers.h"
    
    #include "app_timer.h"
    #include "bsp.h"
    #include "boards.h"
    #include "nordic_common.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    static void buttons_handler(bsp_event_t evt)
    {
        zb_ret_t zb_err_code;
        zb_uint32_t button;
        bsp_board_led_invert(BSP_BOARD_LED_1);
        if (m_device_ctx.bulb_params.short_addr == 0xFFFF)
        {
            /* No bulb found yet. */
            bsp_board_led_off(BULB_FOUND_LED);
            return;
        }
    
        switch(evt)
        {
            case BSP_EVENT_KEY_0:
                zb_err_code = zb_buf_get_out_delayed_ext(light_switch_send_on_off, ZB_FALSE, 0);
                bsp_board_led_invert(BSP_BOARD_LED_2);
                button = BSP_BUTTON_0;
                break;
    
            default:
                NRF_LOG_INFO("Unhandled BSP Event received: %d", evt);
                return;
        }
    
    }
    
    /**@brief Function for initializing LEDs and buttons.
     */
    static zb_void_t leds_buttons_init(void)
    {
        ret_code_t error_code;
    
        /* Initialize LEDs and buttons - use BSP to control them. */
        error_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, buttons_handler);
        APP_ERROR_CHECK(error_code);
        /* By default the bsp_init attaches BSP_KEY_EVENTS_{0-4} to the PUSH events of the corresponding buttons. */
    
        bsp_board_leds_off();
    }
    int main(void)
    {
        zb_ret_t       zb_err_code;
        zb_ieee_addr_t ieee_addr;
        NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_LFCLKSTART    = 1;
        /* Initialize timers, loging system and GPIOs. */
        timers_init();
        log_init();
        leds_buttons_init();
    
        /* Set Zigbee stack logging level and traffic dump subsystem. */
        ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
        ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
        ZB_SET_TRAF_DUMP_OFF();
    
        /* Initialize Zigbee stack. */
        ZB_INIT("light_switch");
    
        /* Set device address to the value read from FICR registers. */
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        zb_set_network_ed_role(IEEE_CHANNEL_MASK);
        zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    
        zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN);
        zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
        // sleepy_device_setup();
    
        /* Initialize application context structure. */
        UNUSED_RETURN_VALUE(ZB_MEMSET(&m_device_ctx, 0, sizeof(light_switch_ctx_t)));
        
        /* Set default bulb short_addr. */
        m_device_ctx.bulb_params.short_addr = 0xFFFF;
    
        /* Register dimmer switch device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&dimmer_switch_ctx);
    
        /** Start Zigbee Stack. */
        zb_err_code = zboss_start_no_autostart();
        ZB_ERROR_CHECK(zb_err_code);
    
        // bsp_board_led_on(BSP_BOARD_LED_3);
    
        while(1)
        {
            zboss_main_loop_iteration();
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        }
    }

    It's supposed that at least led would invert on button press, but nothing happens at all. 

Reply
  • Hi! Thanks. That helped to fix the issue with small parts of code above. But, unfortunately, I still don't know what should I do with Zigbee example. Here are some parts of init code from my modified light_switch. But the same situation is with other examples.

    #include "zboss_api.h"
    #include "zb_mem_config_custom.h"
    #include "zb_error_handler.h"
    #include "zigbee_helpers.h"
    
    #include "app_timer.h"
    #include "bsp.h"
    #include "boards.h"
    #include "nordic_common.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    static void buttons_handler(bsp_event_t evt)
    {
        zb_ret_t zb_err_code;
        zb_uint32_t button;
        bsp_board_led_invert(BSP_BOARD_LED_1);
        if (m_device_ctx.bulb_params.short_addr == 0xFFFF)
        {
            /* No bulb found yet. */
            bsp_board_led_off(BULB_FOUND_LED);
            return;
        }
    
        switch(evt)
        {
            case BSP_EVENT_KEY_0:
                zb_err_code = zb_buf_get_out_delayed_ext(light_switch_send_on_off, ZB_FALSE, 0);
                bsp_board_led_invert(BSP_BOARD_LED_2);
                button = BSP_BUTTON_0;
                break;
    
            default:
                NRF_LOG_INFO("Unhandled BSP Event received: %d", evt);
                return;
        }
    
    }
    
    /**@brief Function for initializing LEDs and buttons.
     */
    static zb_void_t leds_buttons_init(void)
    {
        ret_code_t error_code;
    
        /* Initialize LEDs and buttons - use BSP to control them. */
        error_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, buttons_handler);
        APP_ERROR_CHECK(error_code);
        /* By default the bsp_init attaches BSP_KEY_EVENTS_{0-4} to the PUSH events of the corresponding buttons. */
    
        bsp_board_leds_off();
    }
    int main(void)
    {
        zb_ret_t       zb_err_code;
        zb_ieee_addr_t ieee_addr;
        NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_LFCLKSTART    = 1;
        /* Initialize timers, loging system and GPIOs. */
        timers_init();
        log_init();
        leds_buttons_init();
    
        /* Set Zigbee stack logging level and traffic dump subsystem. */
        ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
        ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
        ZB_SET_TRAF_DUMP_OFF();
    
        /* Initialize Zigbee stack. */
        ZB_INIT("light_switch");
    
        /* Set device address to the value read from FICR registers. */
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        zb_set_network_ed_role(IEEE_CHANNEL_MASK);
        zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    
        zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN);
        zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
        // sleepy_device_setup();
    
        /* Initialize application context structure. */
        UNUSED_RETURN_VALUE(ZB_MEMSET(&m_device_ctx, 0, sizeof(light_switch_ctx_t)));
        
        /* Set default bulb short_addr. */
        m_device_ctx.bulb_params.short_addr = 0xFFFF;
    
        /* Register dimmer switch device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&dimmer_switch_ctx);
    
        /** Start Zigbee Stack. */
        zb_err_code = zboss_start_no_autostart();
        ZB_ERROR_CHECK(zb_err_code);
    
        // bsp_board_led_on(BSP_BOARD_LED_3);
    
        while(1)
        {
            zboss_main_loop_iteration();
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        }
    }

    It's supposed that at least led would invert on button press, but nothing happens at all. 

Children
  • I modified the Zigbee light_switch example with your buttons_handler code, and LED2 (BSP_BOARD_LED_1) is toggling on every button press in my test. LED3 (BSP_BOARD_LED_2) does not toggle, as the application enters and returns from the button_handler in this section:

    if (m_device_ctx.bulb_params.short_addr == 0xFFFF)
    {
        /* No bulb found yet. */
        bsp_board_led_off(BULB_FOUND_LED);
        return;
    }

    If I remove this or comment out the return, LED3 also toggles.

Related