blk_box_tc/main/drivers/bottom_half.cpp
2024-08-02 17:53:22 -05:00

179 lines
5.0 KiB
C++

#include "bottom_half.h"
static const char *TAG = "bottom_half";
static uint16_t keypad_state;
static uint16_t button_state;
static uint8_t touch_state;
static uint16_t keypad_pressed;
static uint16_t button_pressed;
static uint8_t touch_pressed;
static uint16_t keypad_released;
static uint16_t button_released;
static uint8_t touch_released;
/// read buffer
static uint8_t read_buf[8];
static bool _take_key(KeypadKey* kp, uint16_t* keypad_bitfield) {
for (int i = 0; i < 16; i++) {
int bit_selector = (1 << i);
if ((*keypad_bitfield) & bit_selector) {
*kp = (KeypadKey) i;
// clear bit
*keypad_bitfield &= ~bit_selector;
return true;
}
}
return false;
}
bool get_pressed_keypad(KeypadKey* kp) {
return _take_key(kp, &keypad_pressed);
}
bool get_released_keypad(KeypadKey* kp) {
return _take_key(kp, &keypad_released);
}
char char_of_keypad_key(KeypadKey kp) {
switch (kp) {
case KeypadKey::k1:
return '1';
case KeypadKey::k2:
return '2';
case KeypadKey::k3:
return '3';
case KeypadKey::k4:
return '4';
case KeypadKey::k5:
return '5';
case KeypadKey::k6:
return '6';
case KeypadKey::k7:
return '7';
case KeypadKey::k8:
return '8';
case KeypadKey::k9:
return '9';
case KeypadKey::k0:
return '0';
case KeypadKey::ka:
return 'A';
case KeypadKey::kb:
return 'B';
case KeypadKey::kc:
return 'C';
case KeypadKey::kd:
return 'D';
case KeypadKey::star:
return '*';
case KeypadKey::pound:
return '#';
default:
return ' ';
}
}
static void poll_bottom_task(void *arg);
// static void IRAM_ATTR gpio_isr_handler(void* arg)
// {
// // TODO: do somthing
// ESP_LOGI("BOTTOM_HALF", "Hit");
// }
void init_bottom_half() {
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_5,
.scl_io_num = GPIO_NUM_6,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 100000,
}
};
ESP_ERROR_CHECK(i2c_param_config(BOTTOM_I2C_NUM, &conf));
ESP_ERROR_CHECK(i2c_driver_install(BOTTOM_I2C_NUM, conf.mode, 0, 0, 0));
gpio_config_t delta_pin_conf = {};
// delta_pin_conf.intr_type = GPIO_INTR_LOW_LEVEL;
delta_pin_conf.mode = GPIO_MODE_INPUT;
// GPIO 0
delta_pin_conf.pin_bit_mask = (1ULL<<BOTTOM_PIN_INTERUPT);
delta_pin_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&delta_pin_conf);
//install gpio isr service
// gpio_install_isr_service(0);
//hook isr handler for specific gpio pin
// gpio_isr_handler_add(BOTTOM_INTERUPT_PIN, gpio_isr_handler, NULL);
xTaskCreate(poll_bottom_task, "poll_bottom", 4096, NULL, 10, NULL);
}
static uint8_t receive_delta(void) {
uint8_t reg = 1;
read_buf[0] = 0;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, &reg, 1, read_buf, 1, (100 / portTICK_PERIOD_MS)));
return read_buf[0];
}
static void receive_keypad(void) {
uint8_t reg = 2;
read_buf[0] = 0;
read_buf[1] = 0;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, &reg, 1, read_buf, 2, (100 / portTICK_PERIOD_MS)));
uint16_t new_keypad_state = read_buf[0] | (read_buf[1] << 8);
uint16_t just_pressed = new_keypad_state & ~keypad_state;
keypad_pressed |= just_pressed;
uint16_t just_released = ~new_keypad_state & keypad_state;
keypad_released |= just_released;
keypad_state = new_keypad_state;
}
static void receive_button(void) {
uint8_t reg = 3;
read_buf[0] = 0;
read_buf[1] = 0;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, &reg, 1, read_buf, 2, (100 / portTICK_PERIOD_MS)));
uint16_t new_button_state = read_buf[0] | (read_buf[1] << 8);
uint16_t just_pressed = new_button_state & ~button_state;
button_pressed |= just_pressed;
uint16_t just_released = ~new_button_state & button_state;
button_released |= just_released;
button_state = new_button_state;
}
static void poll_bottom_task(void *arg) {
while (1) {
bool new_data = gpio_get_level(BOTTOM_PIN_INTERUPT) == 0;
if (new_data) {
uint8_t delta = receive_delta();
// ESP_LOGI(_TAG, "delta: %d", delta);
if (delta == 0) ESP_LOGW(TAG, "delta pin was low, but delta register returned 0");
if (delta & (1 << DELTA_BIT_KP)) {
receive_keypad();
// ESP_LOGI(_TAG, "keypad: %d", keypad_state);
}
if (delta & (1 << DELTA_BIT_BUTTON)) {
receive_button();
// ESP_LOGI(_TAG, "button: %d", button_state);
}
}
vTaskDelay(pdMS_TO_TICKS(10));
}
vTaskDelete(NULL);
}