update star code references

This commit is contained in:
2025-07-12 18:16:15 -05:00
parent 1267d1356d
commit e27fb6f015
19 changed files with 299 additions and 356 deletions
+1
View File
@@ -8,6 +8,7 @@ set(SOURCES
"char_lcd.cpp"
"game_timer.cpp"
"i2c_lcd_pcf8574.c"
"i2c.cpp"
"leds.cpp"
"power.cpp"
"sd.cpp"
-2
View File
@@ -1,7 +1,5 @@
#include "all.h"
static const char *TAG = "driver_all";
void init_drivers() {
init_i2c();
// init char_lcd so we can use it to report other initialization errors.
+8 -37
View File
@@ -5,11 +5,6 @@
static const char *TAG = "bottom_half";
volatile bool doing_starcode = false;
static uint16_t starcode_waiting_on_release;
static char current_starcode[STARCODE_MAX_LEN + 1];
static size_t current_starcode_idx;
static uint16_t keypad_state;
static uint8_t button_state;
static uint8_t switch_state;
@@ -78,12 +73,14 @@ static uint8_t receive_delta(void) {
esp_err_t result = i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, &reg, 1, buf, 1, (100 / portTICK_PERIOD_MS));
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
if (result != ESP_OK) {
return;
return 0;
}
return buf[0];
}
static void receive_keypad(void) {
// TODO: use mutex
// TODO: change the bottom half polling scheme from a state-based protocol to an event based protocol
uint8_t reg = 2;
esp_err_t result = i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, &reg, 1, buf, 2, (100 / portTICK_PERIOD_MS));
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
@@ -105,34 +102,7 @@ static void receive_keypad(void) {
event_occured("KP_RELEASE", buf);
}
if (handling_new_starcodes && (just_pressed | (1 << KeypadKey::star))) {
current_starcode_idx = 0;
current_starcode[current_starcode_idx] = '\0';
doing_starcode = true;
}
if (doing_starcode) {
// If we get a press while handling a starcode, we also want to capture the release of that key.
starcode_waiting_on_release |= just_pressed;
KeypadKey key;
while (_take_key(&key, &just_pressed)) {
if (key == KeypadKey::star) {
current_starcode_idx = 0;
current_starcode[current_starcode_idx] = '\0';
} else if (key == KeypadKey::pound) {
doing_starcode = false;
trigger_star_code(current_starcode);
} else if (current_starcode_idx < STARCODE_MAX_LEN) {
current_starcode[current_starcode_idx++] = char_of_keypad_key(key);
current_starcode[current_starcode_idx] = '\0';
}
}
}
// capture any releases from starcodes
uint16_t new_just_released = just_released & (~starcode_waiting_on_release);
starcode_waiting_on_release = starcode_waiting_on_release & (~just_released);
just_released = new_just_released;
star_code_handle_keypad(&just_pressed, &just_released);
keypad_pressed |= just_pressed;
keypad_released |= just_released;
@@ -261,7 +231,8 @@ void clear_all_pressed_released(void) {
touch_released = 0;
}
static bool _take_key(KeypadKey* kp, uint16_t* keypad_bitfield) {
// TODO: this is public, but it won't need to be after the event-based protocol refactor
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) {
@@ -277,10 +248,10 @@ static bool _take_key(KeypadKey* kp, uint16_t* keypad_bitfield) {
}
bool get_keypad_pressed(KeypadKey* kp) {
return _take_key(kp, &keypad_pressed);
return take_key(kp, &keypad_pressed);
}
bool get_keypad_released(KeypadKey* kp) {
return _take_key(kp, &keypad_released);
return take_key(kp, &keypad_released);
}
char char_of_keypad_key(KeypadKey kp) {
+8 -3
View File
@@ -12,9 +12,6 @@
#define DELTA_BIT_BUTTON_SWITCH 1
#define DELTA_BIT_TOUCH 2
/// @brief `true` if a starcode is currently being handled.
extern volatile bool doing_starcode;
/// @brief An enum for the possible keypad buttons.
typedef enum {
k1 = 0,
@@ -129,6 +126,14 @@ bool get_touch_pressed();
/// @return true if the touch sensor was just released
bool get_touch_released();
/// @brief A helper function for internal use.
///
/// Takes one key from the bitfield and sets the `kp` variable accordingly if the bitfield is not 0.
/// @param kp Out. The keypad key to set.
/// @param keypad_bitfield A pointer to the keypad bitfield to take a key from
/// @return true if a key was taken from the bitfield
bool take_key(KeypadKey* kp, uint16_t* keypad_bitfield);
// TODO: add touch sensor for switch
#endif /* BOTTOM_HALF_HPP */
+1 -6
View File
@@ -77,14 +77,9 @@ static bool replay_handler(const char* event, char* arg) {
lcd_create_char(location, charmap);
return true;
}
if (strcmp(event, "LCD_WRITE") == 0) {
uint8_t value = atoi(arg);
lcd_write(value);
return true;
}
if (strcmp(event, "LCD_PRINT") == 0) {
// TODO: handle \r and \n
lcd_print(arg);
lcd_print(&lcd, arg);
return true;
}
+1 -1
View File
@@ -44,7 +44,7 @@ void lcd_right_to_left();
void lcd_set_autoscroll(bool autoscroll);
// Set backlight brightness
void lcd_set_backlight(uint8_t brightness);
void lcd_set_backlight(bool backlight);
// Create a custom character
void lcd_create_char(uint8_t location, uint8_t charmap[]);
+4 -2
View File
@@ -1,11 +1,13 @@
#include "i2c.h"
#include "esp_log.h"
#include "esp_err.h"
#include "driver/i2c_master.h"
#include "driver/i2c.h"
static const char *TAG = "i2c";
static void init_i2c() {
SemaphoreHandle_t i2c0_mutex;
void init_i2c() {
ESP_LOGI(TAG, "Initializing i2c...");
i2c_config_t conf = {
+2 -2
View File
@@ -1,11 +1,11 @@
#ifndef I2C_H
#define I2C_H
#include "FreeRTOS.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
/// The mutex for accessing `I2C_NUM_0`.
SemaphoreHandle_t i2c0_mutex;
extern SemaphoreHandle_t i2c0_mutex;
/// @brief Initializes `I2C_NUM_0`.
///
+1 -1
View File
@@ -51,5 +51,5 @@ void init_power_board() {
}
uint16_t get_bat_voltage() {
lipo.voltage();
return lipo.voltage();
}
+51 -69
View File
@@ -1,5 +1,4 @@
#include "star_code.h"
#include <vector>
#include <algorithm>
#include <string.h>
@@ -10,85 +9,61 @@
static const char* TAG = "star_code";
volatile bool handling_new_starcodes = false;
static bool system_initialized = false;
static volatile bool system_initialized = false;
static volatile SemaphoreHandle_t star_codes_sem;
static std::vector<StarCodeEntry> star_codes;
static TaskHandle_t task_handle;
static volatile bool doing_starcode = false;
static uint16_t starcode_waiting_on_release;
static char current[STARCODE_MAX_LEN + 1];
static size_t current_idx;
static void star_code_task(void* param) {
KeypadKey key;
int current_idx = 0;
char current[STRING_MAX_LEN+1] = {0};
while (1) {
while (get_keypad_pressed(&key)) {
if (key == KeypadKey::star) {
current[0] = '*';
for (int i = 1; i < STRING_MAX_LEN; i++) {
current[i] = 0;
}
current_idx = 1;
} else if (key == KeypadKey::pound) {
// submit
if (current[0] == '\0') {
continue;
}
bool hit = false;
for (int i = 0; i < star_codes_len; i++) {
StarCodeHandler sch = star_codes[i];
if (strcmp(current, sch.code) == 0) {
hit = true;
lcd_print(1, 2, sch.display_text);
vTaskDelay(pdMS_TO_TICKS(2000));
if (sch.callback != nullptr) {
(sch.callback)();
}
if (sch.should_exit) {
return;
}
break;
}
}
if (!hit) {
lcd_print(1, 2, "Invalid Star Code");
vTaskDelay(pdMS_TO_TICKS(2000));
}
// clear
for (int i = 0; i < STRING_MAX_LEN; i++) {
current[i] = 0;
}
current_idx = 0;
} else {
// out of room. skip
if (current_idx >= STRING_MAX_LEN) break;
// no code started.
if (current[0] != '*') continue;
char c = char_of_keypad_key(key);
current[current_idx++] = c;
}
// ESP_LOGI(STEP0_TAG, "Pressed: %c", c);
lcd_clear();
lcd_print(1, 1, current);
}
vTaskDelay(pdMS_TO_TICKS(10));
void star_code_handle_keypad(uint16_t* just_pressed, uint16_t* just_released) {
if (handling_new_starcodes && (*just_pressed | (1 << KeypadKey::star))) {
current_idx = 0;
current[current_idx] = '\0';
doing_starcode = true;
}
if (doing_starcode) {
// If we get a press while handling a starcode, we also want to capture the release of that key.
starcode_waiting_on_release |= *just_pressed;
KeypadKey key;
while (take_key(&key, just_pressed)) {
if (key == KeypadKey::star) {
current_idx = 0;
current[current_idx] = '\0';
} else if (key == KeypadKey::pound) {
doing_starcode = false;
if (current_idx != 0) {
trigger_star_code(current);
}
} else {
// shift the digits left if neccesary
if (current_idx >= STARCODE_MAX_LEN) {
for (int i = 1; i < current_idx; i++) {
current[i-1] = current[i];
}
current_idx--;
}
// append the character
current[current_idx++] = char_of_keypad_key(key);
current[current_idx] = '\0';
}
}
}
// capture any releases from starcodes
uint16_t new_just_released = (*just_released) & (~starcode_waiting_on_release);
starcode_waiting_on_release = starcode_waiting_on_release & (~*just_released);
*just_released = new_just_released;
}
void init_star_code_system() {
star_codes_sem = xSemaphoreCreateBinary();
xSemaphoreGive(star_codes_sem);
xTaskCreate(star_code_task, "star_code", 2048, nullptr, 1, &task_handle);
handling_new_starcodes = true;
system_initialized = true;
}
@@ -191,15 +166,22 @@ bool trigger_star_code(const char* code) {
return false;
}
// TODO: do display text
// TODO: do delay ticks
if (it->triggered_sem != nullptr)
xSemaphoreGive(it->triggered_sem);
if (it->callback != nullptr)
(it->callback)();
return true;
}
void pause_star_code_system() {
doing_starcode = false;
handling_new_starcodes = false;
}
void resume_star_code_system() {
handling_new_starcodes = system_initialized;
}
}
+5 -3
View File
@@ -8,8 +8,6 @@
/// The max length of a starcode (not counting the star)
#define STARCODE_MAX_LEN 8
extern volatile bool handling_new_starcodes;
/// @brief A handler for a specific star code
struct StarCodeEntry {
/// @brief The star code without the star
@@ -35,6 +33,9 @@ struct StarCodeEntry {
/// @brief Initializes the star code system.
void init_star_code_system();
/// @brief Handles any keypad presses and releases before they bubble up to the rest of the BLK_BOX.
void star_code_handle_keypad(uint16_t* just_pressed, uint16_t* just_released);
/// @brief Adds a star code to be handled.
/// @param code the star code to add
/// @return true iff the star code was added
@@ -72,7 +73,8 @@ void clear_star_codes();
bool trigger_star_code(const char* code);
/// @brief Tempararilly starts/stops the star code system from handling new star codes.
/// @brief Starts/stops the star code system from handling new star codes.
/// If one is being handled currently, it is canceled.
void set_star_code_sys_enabled(bool enable);
/// @brief Gets weather or not the star code system is handling new star codes.