#include #include #include #include "knob.h" #include "gui.h" 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), .mode = GPIO_MODE_INPUT, .pull_up_en = 1, .intr_type = GPIO_INTR_ANYEDGE, // neg means active }; 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); } } #if 0 const uint32_t inputs = gpio_input_get(); bool a = 0 == (inputs & (1 << wheelPin1)); // neg = active bool b = 0 == (inputs & (1 << wheelPin2)); #define ENCODER_POS1 1 #define ENCODER_POS2 2 #define ENCODER_POS3 3 #define ENCODER_POS0 0 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; }; OldEnc = NewEnc; }; // end if encoder value changed. #endif #if 0 // Omron version int which = (int)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 (a) { if (b) { dir = -1; } else { dir = 1; } } } else { // itr from B if (b) { if (a) { dir = 1; } else { dir = -1; } } } #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; } } 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; BaseType_t higherWoken = 0; xTaskNotifyFromISR(hGuiThread, 0b100<