From 465a17789d6a2a98e86e2263b72a3e2329e27f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 3 Jan 2020 19:28:57 +0100 Subject: [PATCH] remove gpio isr, polling debouncer works better --- main/knob.c | 356 ++++++++-------------------------------------------- 1 file changed, 55 insertions(+), 301 deletions(-) diff --git a/main/knob.c b/main/knob.c index d8efa29..18fe32e 100644 --- a/main/knob.c +++ b/main/knob.c @@ -8,347 +8,101 @@ const int pushPin = 5; const int wheelPin1 = 18; const int wheelPin2 = 23; -//const int sigPin1 = 12; -//const int sigPin2 = 14; - #define DEBOUNCE_WHEEL_MS 3 #define DEBOUNCE_BTN_MS 10 -static void handle_pushbtn(void *arg); -static void handle_wheel(void *arg); - - - static void debounce_service(void *arg); static TaskHandle_t hDebouncer; void knob_init() { printf("Knob init\n"); -// gpio_config_t cfgWheel = { -// .pin_bit_mask = (1 << wheelPin1) /*| (1 << wheelPin2)*/, -// .mode = GPIO_MODE_INPUT, -// .pull_up_en = 1, -// .intr_type = GPIO_INTR_NEGEDGE, // neg means active -// }; -// gpio_config(&cfgWheel); - gpio_config_t cfgPush = { - .pin_bit_mask = (1 << pushPin) | (1 << wheelPin1), + .pin_bit_mask = (1 << pushPin) | (1 << wheelPin1) | (1 << wheelPin2), .mode = GPIO_MODE_INPUT, - .pull_up_en = 1, - .intr_type = GPIO_INTR_ANYEDGE, // neg means active + .pull_up_en = 1 }; gpio_config(&cfgPush); - // wheel2 without itr - cfgPush.intr_type = GPIO_INTR_DISABLE; - cfgPush.pin_bit_mask = (1 << wheelPin2); - gpio_config(&cfgPush); - -// gpio_config_t output = { -// .pin_bit_mask = (1< pdMS_TO_TICKS(DEBOUNCE_WHEEL_MS)) { - // negedge - negedge_time = time; -// gpio_set_level(sigPin1, 0); - } - } else { - // posedge - if ((time - negedge_time) > pdMS_TO_TICKS(DEBOUNCE_WHEEL_MS)) { - posedge_time = time; - if (b) { - dir = -1; - } else { - dir = 1; - } -// gpio_set_level(sigPin1, 1); - } - } + while (1) { + vTaskDelay(pdMS_TO_TICKS(1)); -#if 0 - const uint32_t inputs = gpio_input_get(); - bool a = 0 == (inputs & (1 << wheelPin1)); // neg = active - bool b = 0 == (inputs & (1 << wheelPin2)); + uint32_t now = xTaskGetTickCount(); -#define ENCODER_POS1 1 -#define ENCODER_POS2 2 -#define ENCODER_POS3 3 -#define ENCODER_POS0 0 + const uint32_t inputs = gpio_input_get(); - uint8_t NewEnc = a | (b<<1); - if (NewEnc ^ OldEnc) { // Encoder value changed??? - switch(NewEnc) { - case ENCODER_POS1 : // 01 - if (OldEnc == ENCODER_POS0) // 00 - dir--; - else - dir++; - break; - case ENCODER_POS3 : // 11 - if (OldEnc == ENCODER_POS1) // 01 - dir--; - else - dir++; - break; - case ENCODER_POS2 : // 10 - if (OldEnc == ENCODER_POS3) // 11 - dir--; - else - dir++; - break; - case ENCODER_POS0 : // 00 - if (OldEnc == ENCODER_POS2) // 10 - dir--; - else - dir++; - break; + bool input[3] = { + (inputs & (1 << pushPin)) == 0, + (inputs & (1 << wheelPin1)) != 0, + (inputs & (1 << wheelPin2)) != 0, }; - OldEnc = NewEnc; - }; // end if encoder value changed. -#endif -#if 0 - // Omron version - int which = (int)arg; + enum change { + CHG_NONE = 2, + CHG_SET = 1, + CHG_CLEAR = 0, + }; - const uint32_t inputs = gpio_input_get(); + enum change changes[3] = {CHG_NONE, CHG_NONE, CHG_NONE}; - bool a = 0 == (inputs & (1 << wheelPin1)); // neg = active - bool b = 0 == (inputs & (1 << wheelPin2)); + for (int i=0; i<3;i++) { + if (input[i] == !state[i].state) { + // Change detected + if (state[i].start_time == 0) { + // start counting + state[i].start_time = now; + } - if (which == 0) { // itr from A - if (a) { - if (b) { - dir = -1; + if ((state[i].start_time != 0) && (now - state[i].start_time > state[i].debo_time)) { + state[i].state = !state[i].state; + changes[i] = state[i].state ? CHG_SET : CHG_CLEAR; + } } else { - dir = 1; + // returned back to original, reset counter + state[i].start_time = 0; } } - } - else { // itr from B - if (b) { - if (a) { - dir = 1; + + uint32_t signal = 0; + + // Wheel logic + if (changes[1] == CHG_SET) { + if (state[2].state) { + signal |= 0b01; } else { - dir = -1; + signal |= 0b10; } } - } -#endif - -#if 0 - // Naive version - int which = arg; - - const uint32_t inputs = gpio_input_get(); - - bool a = 0 == (inputs & (1 << wheelPin1)); // neg = active - bool b = 0 == (inputs & (1 << wheelPin2)); - if (which == 0) { // itr from A - if (b) { - dir = -1; - } /*else { - dir = 1; - }*/ - } - else { // itr from B - if (a) { - dir = 1; - } /*else { - dir = -1; - }*/ - } -#endif - -#if 0 - // More complex version - const uint32_t inputs = gpio_input_get(); - const uint8_t ab = - (((inputs >> wheelPin2) & 1) << 1) | - ((inputs >> wheelPin1) & 1); - - if (wheelState == S_ILLEGAL) { - if (ab != 0b11) { - return; + // knob + if (changes[0] != CHG_NONE) { + signal |= 0b100 << changes[0]; } - } - uint8_t next = switch_table[wheelState*4 + ab]; - - if (next & SW_FWD) dir = 1; - if (next & SW_BCK) dir = -1; - next &= ~(SW_FWD | SW_BCK); - - wheelState = next; -#endif - - if (dir != 0) { - BaseType_t higherWoken = 0; - xTaskNotifyFromISR(hGuiThread, dir == 1 ? 0b10 : 0b01, eSetBits, &higherWoken); - if (higherWoken) portYIELD_FROM_ISR(); - } -} - -static void __attribute__((noreturn)) debounce_service(void *arg) { - bool push_state = 0; - uint32_t push_change_time = 0; - - while (1) { -// uint32_t value = 0; -// xTaskNotifyWait(0, ULONG_MAX, &value, pdMS_TO_TICKS(1)); - vTaskDelay(pdMS_TO_TICKS(1)); - - uint32_t now = xTaskGetTickCount(); - - const uint32_t inputs = gpio_input_get(); - bool pushed = (inputs & (1 << pushPin)) == 0; - - if (pushed) { // event "PUSHED" - if (!push_state) { - if (push_change_time == 0) { - push_change_time = now; - } - } else { - push_change_time = 0; - } - } - else { // event "RELEASED" - if (push_state) { - if (push_change_time == 0) { - push_change_time = now; - } - } else { - push_change_time = 0; - } - } - - if ((push_change_time != 0) && (now - push_change_time > pdMS_TO_TICKS(DEBOUNCE_BTN_MS))) { - push_state = !push_state; + // send event to GUI + if (signal != 0) { BaseType_t higherWoken = 0; - xTaskNotifyFromISR(hGuiThread, 0b100<