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

HID Mouse click and hold confusion

I have modified the included HID mouse example to allow for left/right/middle mouse clicks. However, it is not clear to me how to set an event handler for both when a button goes HIGH as well as LOW using the button handler module.

static void buttons_init(void) { static app_button_cfg_t buttons[] =
{ {LEFT_CLICK_PIN_NO, false, NRF_GPIO_PIN_NOPULL, button_event_handler}, {RIGHT_CLICK_PIN_NO, false, NRF_GPIO_PIN_NOPULL, button_event_handler} };

APP_BUTTON_INIT(buttons, sizeof(buttons) / sizeof(buttons[0]), BUTTON_DETECTION_DELAY, true);

button_event_handler will only be called when the left click pin goes LOW. No handler is called when the pin goes HIGH.

I do not see a way to use the app_button.c library to set both a HIGH and LOW handler for the same pin, only one or the other.

I have attempted:

static void buttons_init(void) { static app_button_cfg_t buttons[] =
{ {LEFT_CLICK_PIN_NO, false, NRF_GPIO_PIN_NOPULL, button_event_handler}, {LEFT_CLICK_PIN_NO, true, NRF_GPIO_PIN_NOPULL, button_event_handler2}, {RIGHT_CLICK_PIN_NO, false, NRF_GPIO_PIN_NOPULL, button_event_handler} };

But seem to get repeated mouse click sends using this method.

Am I missing something here?

  • Hi,

    The GPIO sense is set to either high or low level. You will not be able to get interrupt on both rising and falling edge. What we have done in our reference design (nrfready desktop 2) is that we poll the buttons (each 15ms) using app_timer and store the previous result to see if there is any change.

    static void button_handler(void* p_context)
    {
        static uint8_t prev_buttons     = 0;
        static uint8_t prev_adv_buttons = 0;
        uint8_t        buttons          = 0;
        uint8_t        adv_buttons      = 0;
        uint32_t       all_lines;
        
        // Read button state
        all_lines = drv_mouse_btn_read();    
       
        // Check which buttons are held and flip interrupt sense polarity of those who are
        if (all_lines & IO_BTN_LEFT_MSK)
        {
            buttons |= (1 << 0);
        }
        
        if (all_lines & IO_BTN_RIGHT_MSK)
        {
            buttons |= (1 << 1);
        }
        
        if (all_lines & IO_BTN_MIDDLE_MSK)
        {
            buttons |= (1 << 2);
        }  
        
        if (all_lines & IO_BTN_SIDE_LEFT_MSK)
        {
            buttons |= (1 << 3);
        }
        
        if (all_lines & IO_BTN_SIDE_RIGHT_MSK)
        {
            buttons |= (1 << 4);
        }
        
        if ((all_lines & IO_BTN_RESET_MSK) == IO_BTN_RESET_MSK)
        {    
            // Pairing button combo has been pressed. Sending empty event to indicate this
            s_event_handler(0, 0);
        }
        
        if (buttons != prev_buttons)
        {
            mouse_data_t data;
    
            data.type                 = packet_type_mouse_buttons;
            data.packet.mouse_buttons = buttons;
            
            s_event_handler(&data, sizeof(data));
            
            prev_buttons = buttons;
        }
        
        if (adv_buttons != prev_adv_buttons)
        {
            mouse_data_t data;
    
            data.type                     = packet_type_mouse_adv_buttons;
            data.packet.mouse_adv_buttons = adv_buttons;
    
            s_event_handler(&data, sizeof(data));
            
            prev_adv_buttons = adv_buttons;
        }
        
        if ((adv_buttons == 0) && (buttons == 0))
        {
            app_timer_stop(s_timer_id);
            s_timer_running = false;
            drv_mouse_btn_sense_enable(true);
        }
    }
    
Related