blk_box_tc/main/drivers/wires.cpp
2024-08-11 23:18:41 -05:00

144 lines
3.9 KiB
C++

#include "wires.h"
static const char *TAG = "wires";
static const uint32_t STRIKE_TIME_PENALTY = 30'000;
static bool button_state;
static bool button_pressed;
static bool button_released;
static uint8_t wires_state;
static uint8_t wires_cut;
static uint8_t buf[8];
static void poll_wires_task(void *arg);
static void receive_wires(void);
static void receive_button(void);
void init_wires(void) {
i2c_config_t wires_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_41,
.scl_io_num = GPIO_NUM_42,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 100000,
}
};
gpio_reset_pin(GPIO_NUM_41);
gpio_reset_pin(GPIO_NUM_42);
ESP_ERROR_CHECK(i2c_param_config(WIRES_I2C_NUM, &wires_conf));
ESP_ERROR_CHECK(i2c_driver_install(WIRES_I2C_NUM, wires_conf.mode, 0, 0, 0));
gpio_config_t int_pin_conf = {};
// delta_pin_conf.intr_type = GPIO_INTR_LOW_LEVEL;
int_pin_conf.mode = GPIO_MODE_INPUT;
int_pin_conf.pin_bit_mask = (1ULL<<WIRES_PIN_DELTA);
int_pin_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&int_pin_conf);
receive_button();
receive_wires();
xTaskCreate(poll_wires_task, "poll_wires", 4096, NULL, 10, NULL);
}
uint8_t get_wires(void) {
return wires_state;
}
uint8_t get_cut_wires(void) {
uint8_t return_ = wires_cut;
wires_cut = 0;
return return_;
}
bool get_help_button(void) {
return button_state;
}
bool get_help_button_pressed(void) {
bool return_ = button_pressed;
button_pressed = false;
return return_;
}
bool get_help_button_released(void) {
bool return_ = button_released;
button_released = false;
return return_;
}
void clear_wires_pressed_released_cut(void) {
wires_cut = 0;
button_pressed = false;
button_released = false;
}
void strike(char* reason) {
ESP_LOGW("strike!", "%s", reason);
lcd_set_cursor(&lcd, 0, 3);
lcd_print(&lcd, reason);
set_game_time(get_game_time() - STRIKE_TIME_PENALTY);
uint8_t reg = 6;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_to_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, (100 / portTICK_PERIOD_MS)));
}
void set_leds(uint8_t led_states) {
buf[0] = 5; // register 5
buf[1] = led_states;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_to_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, buf, 2, (100 / portTICK_PERIOD_MS)));
}
static uint8_t receive_delta(void) {
uint8_t reg = 1;
buf[0] = 0;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, buf, 1, (100 / portTICK_PERIOD_MS)));
return buf[0];
}
static void receive_wires(void) {
uint8_t reg = 2;
buf[0] = 0;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, buf, 1, (100 / portTICK_PERIOD_MS)));
uint8_t new_wires = buf[0];
uint8_t just_cut = ~new_wires & wires_state;
wires_cut |= just_cut;
wires_state = new_wires;
}
static void receive_button(void) {
uint8_t reg = 3;
buf[0] = 0;
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, buf, 1, (100 / portTICK_PERIOD_MS)));
bool new_button = buf[0] != 0;
bool just_pressed = new_button & !button_state;
button_pressed |= just_pressed;
bool just_released = !new_button & button_state;
button_released |= just_released;
button_state = new_button;
}
static void poll_wires_task(void *arg) {
while (1) {
bool new_data = gpio_get_level(WIRES_PIN_DELTA) == 0;
if (new_data) {
uint8_t delta = receive_delta();
if (delta == 0) ESP_LOGW(TAG, "delta pin was low, but delta register returned 0");
if (delta & (1 << DELTA_BIT_WIRES)) receive_wires();
if (delta & (1 << DELTA_BIT_BUTTON)) receive_button();
}
vTaskDelay(pdMS_TO_TICKS(10));
}
vTaskDelete(NULL);
}