Improve button press filtering by software
authorNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 30 Jan 2024 02:38:19 +0000 (03:38 +0100)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 30 Jan 2024 02:38:19 +0000 (03:38 +0100)
v10/interface.c

index f1db754..d7806bc 100644 (file)
@@ -149,25 +149,36 @@ void display_arrows(uint8_t line1, uint8_t line2, uint8_t col)
 
 /***************************************************************************** */
 volatile uint8_t button_pressed = 0;
+volatile uint32_t last_button_seen_tick = 0; /* Button pressed filtering */
 void button_callback(uint32_t gpio)
 {
+       uint32_t cur_tick = systick_get_tick_count();
+       /* Simple button press filtering : multiple buttons pressed within 5ms are ignored
+        * The 5ms delay is increased by each new button pressed within the interval, but this
+        *  is OK and allows for easy handling of tick value wrapping.
+        */
+       if (cur_tick <= (last_button_seen_tick + 5)) {
+                       last_button_seen_tick = cur_tick;
+                       return;
+       }
        switch (gpio) {
                case GPIO_BUTTON_OK:
-                       button_pressed |= BUTTON_OK;
+                       button_pressed = BUTTON_OK;
                        break;
                case GPIO_BUTTON_UP:
-                       button_pressed |= BUTTON_UP;
+                       button_pressed = BUTTON_UP;
                        break;
                case GPIO_BUTTON_DOWN:
-                       button_pressed |= BUTTON_DOWN;
+                       button_pressed = BUTTON_DOWN;
                        break;
                case GPIO_BUTTON_LEFT:
-                       button_pressed |= BUTTON_LEFT;
+                       button_pressed = BUTTON_LEFT;
                        break;
                case GPIO_BUTTON_RIGHT:
-                       button_pressed |= BUTTON_RIGHT;
+                       button_pressed = BUTTON_RIGHT;
                        break;
        }
+       last_button_seen_tick = cur_tick;
 }
 
 #define SCIALYS_WS2812_NB_LEDS 2
@@ -187,6 +198,14 @@ int interface_config(uint32_t uart)
        set_gpio_callback(button_callback, &button_right, EDGE_FALLING);
        set_gpio_callback(button_callback, &button_down, EDGE_FALLING);
        set_gpio_callback(button_callback, &button_ok, EDGE_FALLING);
+       /* Add filtering */
+       /* Configure input clock filter */
+       config_gpio_filtering_clk_divider(0, 250);
+       config_gpio_add_filtering(&button_up, LPC_FILTER_THREE_CLK, 0);
+       config_gpio_add_filtering(&button_left, LPC_FILTER_THREE_CLK, 0);
+       config_gpio_add_filtering(&button_right, LPC_FILTER_THREE_CLK, 0);
+       config_gpio_add_filtering(&button_down, LPC_FILTER_THREE_CLK, 0);
+       config_gpio_add_filtering(&button_ok, LPC_FILTER_THREE_CLK, 0);
 
        /* WS2812B Leds on display board */
        ws2812_config(&ws2812_leds, &ws2812_data_out_pin);