add in code for button debouncing

main
rkcf 2023-01-28 13:40:44 -06:00
parent 9e0ece753d
commit 9bcbd9f4b1
1 changed files with 41 additions and 8 deletions

View File

@ -34,8 +34,12 @@ static QueueHandle_t control_event_queue = NULL;
#define LEDC_GATE_OUT (6) #define LEDC_GATE_OUT (6)
/* Timers */ /* Timers */
gptimer_handle_t tap_tempo_timer = NULL; static gptimer_handle_t tap_tempo_timer = NULL;
gptimer_handle_t gate_timer = NULL; static gptimer_handle_t gate_timer = NULL;
static const uint16_t DEBOUNCE_TIMEOUT = 20; // polling period length when debouncing in ms
static uint64_t debounce_time = 0; // system time of last intterupt
static uint8_t btn_state = 1; // state of gpio last recorded
static const uint32_t DEFAULT_BPM = 120; static const uint32_t DEFAULT_BPM = 120;
@ -71,20 +75,49 @@ static void mutate_seq(uint8_t *sequence) {
} }
} }
/* Handle tap tempo button presses */
static void tap_tempo_handler(){
// check the count to see if we have already started the timer
uint64_t count;
ESP_ERROR_CHECK(gptimer_get_raw_count(tap_tempo_timer, &count));
if (count == 0) { // the timer hasn't started yet
ESP_ERROR_CHECK(gptimer_start(tap_tempo_timer));
ESP_LOGI(TAG, "Starting tap tempo monitoring");
} else { // stop the timer and calc bpm
ESP_ERROR_CHECK(gptimer_stop(tap_tempo_timer));
ESP_LOGI(TAG, "Stopping tap tempo monitoring at %" PRIu64 "µs", count);
}
}
static void IRAM_ATTR gpio_isr_handler(void* arg) { static void IRAM_ATTR gpio_isr_handler(void* arg) {
debounce_time = xTaskGetTickCount(); // set time of interrupt
uint32_t gpio_num = (uint32_t)arg; uint32_t gpio_num = (uint32_t)arg;
btn_state = gpio_get_level(gpio_num); // set state
xQueueSendFromISR(control_event_queue, &gpio_num, NULL); xQueueSendFromISR(control_event_queue, &gpio_num, NULL);
} }
static void control_event_handler(void* arg) { static void control_event_handler(void* arg) {
uint32_t gpio_num; uint32_t gpio_num;
uint8_t last_btn_state;
uint64_t last_debounce_time;
while (1) { while (1) {
// save these so we can make comparisons
last_btn_state = btn_state;
last_debounce_time = debounce_time;
uint8_t current_state = gpio_get_level(gpio_num);
if (xQueueReceive(control_event_queue, &gpio_num, portMAX_DELAY)) { if (xQueueReceive(control_event_queue, &gpio_num, portMAX_DELAY)) {
// Check if interrupt triggered stays the same for long enough
if ((current_state == last_btn_state) &&
(xTaskGetTickCount() - last_debounce_time > DEBOUNCE_TIMEOUT)) {
ESP_LOGI(TAG, "Handling control from GPIO %" PRIu32, gpio_num); ESP_LOGI(TAG, "Handling control from GPIO %" PRIu32, gpio_num);
switch (gpio_num) { switch (gpio_num) {
case GPIO_MUTATE_BTN: case GPIO_MUTATE_BTN:
mutate_seq(sequence); mutate_seq(sequence);
break; break;
case GPIO_TAP_TEMPO_BTN:
tap_tempo_handler();
break;
}
} }
} }
} }