/* * btn.c: handler for user interface with real or capacitive buttons */ #include "ch32x035_conf.h" #include "btn.h" #include "driver/adc.h" BtnSub btn[BTN_COUNT]; uint16_t btn_pushed; uint16_t btn_held; void btn_push_cb(uint8_t idx) { if (!(btn_pushed & (1 << idx))) { btn_pushed |= (1 << idx); if (btn[idx].cb_push) btn[idx].cb_push(idx); } } void btn_hold_cb(uint8_t idx) { btn_held |= (1 << idx); if (btn[idx].cb_hold) btn[idx].cb_hold(idx); } void btn_release_cb(uint8_t idx) { btn_pushed &= ~(1 << idx); btn_held &= ~(1 << idx); if (btn[idx].cb_release) btn[idx].cb_release(idx); } void btn_process() { uint16_t i; uint32_t x; uint16_t btn_state[4] = {0}; // fill button bitfield for (i = 0; i < BTN_COUNT; i++) { if (i == 0) { // GPIOC pulldown button x = GPIOC->INDR & (1 << 10); // PC10 (or PC17) } else if (i < 3) { // GPIOB pullup buttons x = !(GPIOB->INDR & (1 << (i + 10))); // PB11, PB12 } else { // touch sensors x = adc_get_tkey(i - 3); } // is pushed? if (x) { if (btn[i].hold != 0xffff) btn[i].hold++; if (btn[i].hold == DEBOUNCE) { btn_state[1] |= (1 << i); } } // is held? if (btn[i].hold == HOLD_COUNTS) { btn_state[2] |= (1 << i); } // is repeated? if (btn[i].repeat && (btn[i].hold == (HOLD_COUNTS + btn[i].repeat))) { btn_state[2] |= (1 << i); btn[i].hold = HOLD_COUNTS; } // is released? if (!x) { if (btn[i].hold) { btn[i].hold = 0; btn_state[3] |= (1 << i); } } } // process callbacks for new events for (i = 0; i < BTN_COUNT; i++) { if (btn_state[1] & (1 << i)) { btn_push_cb(i); } if (btn_state[2] & (1 << i)) { btn_hold_cb(i); } if (btn_state[3] & (1 << i)) { btn_release_cb(i); } } }