blk_box_tc/main/drivers/wires.cpp

170 lines
4.8 KiB
C++

#include "wires.h"
extern uint32_t current_step;
/// The mutex for accessing `I2C_NUM_1` (wires I2C bus).
SemaphoreHandle_t wires_i2c_mutex;
uint32_t total_strikes;
uint32_t step_strikes[N_STEPS] = {0};
uint32_t step_finish_times[N_STEPS] = {0};
static const char *TAG = "wires";
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 = PIN_WIRES_SDA,
.scl_io_num = PIN_WIRES_SCL,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 100000,
},
};
gpio_reset_pin(PIN_WIRES_SDA);
gpio_reset_pin(PIN_WIRES_SCL);
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));
// Create mutex for wires I2C bus
wires_i2c_mutex = xSemaphoreCreateMutex();
assert(wires_i2c_mutex != NULL);
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(const char* reason) {
ESP_LOGW("strike!", "%s", reason);
lcd_print(3, 0, reason);
time_penalty(STRIKE_TIME_PENALTY);
if (current_step > 0 && current_step <= N_STEPS) {
total_strikes += 1;
step_strikes[current_step - 1] += 1;
}
uint8_t reg = 6;
xSemaphoreTake(wires_i2c_mutex, portMAX_DELAY);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_to_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, (100 / portTICK_PERIOD_MS)));
xSemaphoreGive(wires_i2c_mutex);
}
void set_leds(uint8_t led_states) {
buf[0] = 5; // register 5
buf[1] = led_states;
xSemaphoreTake(wires_i2c_mutex, portMAX_DELAY);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_to_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, buf, 2, (100 / portTICK_PERIOD_MS)));
xSemaphoreGive(wires_i2c_mutex);
}
static uint8_t receive_delta(void) {
uint8_t reg = 1;
buf[0] = 0;
xSemaphoreTake(wires_i2c_mutex, portMAX_DELAY);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, buf, 1, (100 / portTICK_PERIOD_MS)));
xSemaphoreGive(wires_i2c_mutex);
return buf[0];
}
static void receive_wires(void) {
uint8_t reg = 2;
buf[0] = 0;
xSemaphoreTake(wires_i2c_mutex, portMAX_DELAY);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, buf, 1, (100 / portTICK_PERIOD_MS)));
xSemaphoreGive(wires_i2c_mutex);
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;
xSemaphoreTake(wires_i2c_mutex, portMAX_DELAY);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, &reg, 1, buf, 1, (100 / portTICK_PERIOD_MS)));
xSemaphoreGive(wires_i2c_mutex);
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);
}