update star code references

This commit is contained in:
Mitchell Marino 2025-07-12 18:16:15 -05:00
parent 1267d1356d
commit e27fb6f015
19 changed files with 299 additions and 356 deletions

View File

@ -8,6 +8,7 @@ set(SOURCES
"char_lcd.cpp" "char_lcd.cpp"
"game_timer.cpp" "game_timer.cpp"
"i2c_lcd_pcf8574.c" "i2c_lcd_pcf8574.c"
"i2c.cpp"
"leds.cpp" "leds.cpp"
"power.cpp" "power.cpp"
"sd.cpp" "sd.cpp"

View File

@ -1,7 +1,5 @@
#include "all.h" #include "all.h"
static const char *TAG = "driver_all";
void init_drivers() { void init_drivers() {
init_i2c(); init_i2c();
// init char_lcd so we can use it to report other initialization errors. // init char_lcd so we can use it to report other initialization errors.

View File

@ -5,11 +5,6 @@
static const char *TAG = "bottom_half"; 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 uint16_t keypad_state;
static uint8_t button_state; static uint8_t button_state;
static uint8_t switch_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_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); ESP_ERROR_CHECK_WITHOUT_ABORT(result);
if (result != ESP_OK) { if (result != ESP_OK) {
return; return 0;
} }
return buf[0]; return buf[0];
} }
static void receive_keypad(void) { 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; 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_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); ESP_ERROR_CHECK_WITHOUT_ABORT(result);
@ -105,34 +102,7 @@ static void receive_keypad(void) {
event_occured("KP_RELEASE", buf); event_occured("KP_RELEASE", buf);
} }
if (handling_new_starcodes && (just_pressed | (1 << KeypadKey::star))) { star_code_handle_keypad(&just_pressed, &just_released);
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;
keypad_pressed |= just_pressed; keypad_pressed |= just_pressed;
keypad_released |= just_released; keypad_released |= just_released;
@ -261,7 +231,8 @@ void clear_all_pressed_released(void) {
touch_released = 0; 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++) { for (int i = 0; i < 16; i++) {
int bit_selector = (1 << i); int bit_selector = (1 << i);
if ((*keypad_bitfield) & bit_selector) { 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) { bool get_keypad_pressed(KeypadKey* kp) {
return _take_key(kp, &keypad_pressed); return take_key(kp, &keypad_pressed);
} }
bool get_keypad_released(KeypadKey* kp) { 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) { char char_of_keypad_key(KeypadKey kp) {

View File

@ -12,9 +12,6 @@
#define DELTA_BIT_BUTTON_SWITCH 1 #define DELTA_BIT_BUTTON_SWITCH 1
#define DELTA_BIT_TOUCH 2 #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. /// @brief An enum for the possible keypad buttons.
typedef enum { typedef enum {
k1 = 0, k1 = 0,
@ -129,6 +126,14 @@ bool get_touch_pressed();
/// @return true if the touch sensor was just released /// @return true if the touch sensor was just released
bool get_touch_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 // TODO: add touch sensor for switch
#endif /* BOTTOM_HALF_HPP */ #endif /* BOTTOM_HALF_HPP */

View File

@ -77,14 +77,9 @@ static bool replay_handler(const char* event, char* arg) {
lcd_create_char(location, charmap); lcd_create_char(location, charmap);
return true; return true;
} }
if (strcmp(event, "LCD_WRITE") == 0) {
uint8_t value = atoi(arg);
lcd_write(value);
return true;
}
if (strcmp(event, "LCD_PRINT") == 0) { if (strcmp(event, "LCD_PRINT") == 0) {
// TODO: handle \r and \n // TODO: handle \r and \n
lcd_print(arg); lcd_print(&lcd, arg);
return true; return true;
} }

View File

@ -44,7 +44,7 @@ void lcd_right_to_left();
void lcd_set_autoscroll(bool autoscroll); void lcd_set_autoscroll(bool autoscroll);
// Set backlight brightness // Set backlight brightness
void lcd_set_backlight(uint8_t brightness); void lcd_set_backlight(bool backlight);
// Create a custom character // Create a custom character
void lcd_create_char(uint8_t location, uint8_t charmap[]); void lcd_create_char(uint8_t location, uint8_t charmap[]);

View File

@ -1,11 +1,13 @@
#include "i2c.h" #include "i2c.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_err.h" #include "esp_err.h"
#include "driver/i2c_master.h" #include "driver/i2c.h"
static const char *TAG = "i2c"; static const char *TAG = "i2c";
static void init_i2c() { SemaphoreHandle_t i2c0_mutex;
void init_i2c() {
ESP_LOGI(TAG, "Initializing i2c..."); ESP_LOGI(TAG, "Initializing i2c...");
i2c_config_t conf = { i2c_config_t conf = {

View File

@ -1,11 +1,11 @@
#ifndef I2C_H #ifndef I2C_H
#define I2C_H #define I2C_H
#include "FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
/// The mutex for accessing `I2C_NUM_0`. /// The mutex for accessing `I2C_NUM_0`.
SemaphoreHandle_t i2c0_mutex; extern SemaphoreHandle_t i2c0_mutex;
/// @brief Initializes `I2C_NUM_0`. /// @brief Initializes `I2C_NUM_0`.
/// ///

View File

@ -51,5 +51,5 @@ void init_power_board() {
} }
uint16_t get_bat_voltage() { uint16_t get_bat_voltage() {
lipo.voltage(); return lipo.voltage();
} }

View File

@ -1,5 +1,4 @@
#include "star_code.h" #include "star_code.h"
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <string.h> #include <string.h>
@ -10,85 +9,61 @@
static const char* TAG = "star_code"; static const char* TAG = "star_code";
volatile bool handling_new_starcodes = false; 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 volatile SemaphoreHandle_t star_codes_sem;
static std::vector<StarCodeEntry> star_codes; 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) { void star_code_handle_keypad(uint16_t* just_pressed, uint16_t* just_released) {
KeypadKey key; if (handling_new_starcodes && (*just_pressed | (1 << KeypadKey::star))) {
current_idx = 0;
int current_idx = 0; current[current_idx] = '\0';
char current[STRING_MAX_LEN+1] = {0}; doing_starcode = true;
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));
} }
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() { void init_star_code_system() {
star_codes_sem = xSemaphoreCreateBinary(); star_codes_sem = xSemaphoreCreateBinary();
xSemaphoreGive(star_codes_sem); xSemaphoreGive(star_codes_sem);
xTaskCreate(star_code_task, "star_code", 2048, nullptr, 1, &task_handle);
handling_new_starcodes = true; handling_new_starcodes = true;
system_initialized = true; system_initialized = true;
} }
@ -191,15 +166,22 @@ bool trigger_star_code(const char* code) {
return false; return false;
} }
// TODO: do display text
// TODO: do delay ticks
if (it->triggered_sem != nullptr)
xSemaphoreGive(it->triggered_sem);
if (it->callback != nullptr) if (it->callback != nullptr)
(it->callback)(); (it->callback)();
return true; return true;
} }
void pause_star_code_system() { void pause_star_code_system() {
doing_starcode = false;
handling_new_starcodes = false; handling_new_starcodes = false;
} }
void resume_star_code_system() { void resume_star_code_system() {
handling_new_starcodes = system_initialized; handling_new_starcodes = system_initialized;
} }

View File

@ -8,8 +8,6 @@
/// The max length of a starcode (not counting the star) /// The max length of a starcode (not counting the star)
#define STARCODE_MAX_LEN 8 #define STARCODE_MAX_LEN 8
extern volatile bool handling_new_starcodes;
/// @brief A handler for a specific star code /// @brief A handler for a specific star code
struct StarCodeEntry { struct StarCodeEntry {
/// @brief The star code without the star /// @brief The star code without the star
@ -35,6 +33,9 @@ struct StarCodeEntry {
/// @brief Initializes the star code system. /// @brief Initializes the star code system.
void init_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. /// @brief Adds a star code to be handled.
/// @param code the star code to add /// @param code the star code to add
/// @return true iff the star code was added /// @return true iff the star code was added
@ -72,7 +73,8 @@ void clear_star_codes();
bool trigger_star_code(const char* code); 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); void set_star_code_sys_enabled(bool enable);
/// @brief Gets weather or not the star code system is handling new star codes. /// @brief Gets weather or not the star code system is handling new star codes.

View File

@ -20,73 +20,8 @@ void clean_bomb(void) {
lcd_clear(); lcd_clear();
lcd_set_cursor_vis(false); lcd_set_cursor_vis(false);
lcd_cursor_home(); lcd_cursor_home();
}
static const int STRING_MAX_LEN = 8; // TODO: add stuff for starcode system
void do_star_codes(StarCodeHandler* star_codes, int star_codes_len) {
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));
}
} }
static lv_obj_t* old_scr; static lv_obj_t* old_scr;

View File

@ -6,15 +6,13 @@ static const char* TAG = "step0";
extern uint32_t initial_game_time; extern uint32_t initial_game_time;
extern uint32_t skip_to_step; extern uint32_t skip_to_step;
static SemaphoreHandle_t continue_sem;
static void set_game_time(); static void set_game_time();
static void skip_to_step1() { skip_to_step = 1; xSemaphoreGive(continue_sem, portMAX_DELAY); } static void skip_to_step1() { skip_to_step = 1; }
static void skip_to_step2() { skip_to_step = 2; xSemaphoreGive(continue_sem, portMAX_DELAY); } static void skip_to_step2() { skip_to_step = 2; }
static void skip_to_step3() { skip_to_step = 3; xSemaphoreGive(continue_sem, portMAX_DELAY); } static void skip_to_step3() { skip_to_step = 3; }
static void skip_to_step4() { skip_to_step = 4; xSemaphoreGive(continue_sem, portMAX_DELAY); } static void skip_to_step4() { skip_to_step = 4; }
static void skip_to_step5() { skip_to_step = 5; xSemaphoreGive(continue_sem, portMAX_DELAY); } static void skip_to_step5() { skip_to_step = 5; }
static void skip_to_step6() { skip_to_step = 6; xSemaphoreGive(continue_sem, portMAX_DELAY); } static void skip_to_step6() { skip_to_step = 6; }
static void try_step1() { clean_bomb(); step1(); } static void try_step1() { clean_bomb(); step1(); }
static void try_step2() { clean_bomb(); step2(); } static void try_step2() { clean_bomb(); step2(); }
static void try_step3() { clean_bomb(); step3(); } static void try_step3() { clean_bomb(); step3(); }
@ -47,135 +45,157 @@ static void replay_last() {
start_playback(); start_playback();
} }
static const StarCodeEntry star_codes[] = {
{
.code = "9819",
.display_text = "Defusal Initiated",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = nullptr,
},
{
.code = "59862",
.display_text = "Set Up Wires",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = setup_wires,
},
{
.code = "59862",
.display_text = "Set Game Time",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = set_game_time,
},
{
.code = "59863",
.display_text = "Debug Switches",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = debug_switches,
},
{
.code = "59864",
.display_text = "Battery Stats",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = battery_stats,
},
{
.code = "59871",
.display_text = "Try Step 1",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step1,
},
{
.code = "59872",
.display_text = "Try Step 2",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step2,
},
{
.code = "59873",
.display_text = "Try Step 3",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step3,
},
{
.code = "59874",
.display_text = "Try Step 4",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step4,
},
{
.code = "59875",
.display_text = "Try Step 5",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step5,
},
{
.code = "59876",
.display_text = "Try Step 6",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step6,
},
{
.code = "59881",
.display_text = "Skip To Step 1",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step1,
},
{
.code = "59882",
.display_text = "Skip To Step 2",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step2,
},
{
.code = "59883",
.display_text = "Skip To Step 3",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step3,
},
{
.code = "59884",
.display_text = "Skip To Step 4",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step4,
},
{
.code = "59885",
.display_text = "Skip To Step 5",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step5,
},
{
.code = "59886",
.display_text = "Skip To Step 6",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step6,
},
{
.code = "1111",
.display_text = "Issue Strike",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = issue_strike,
},
{
.code = "1112",
.display_text = "????",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = flashbang,
},
{
.code = "1113",
.display_text = "replay_last",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = replay_last,
},
};
const static size_t len = sizeof(star_codes)/sizeof(star_codes[0]);
void step0() { void step0() {
uint8_t _byte; StarCodeEntry star_codes[] = {
continue_sem = xSemaphoreCreateBinary(); {
.code = "9819",
.display_text = "Defusal Initiated",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = nullptr,
.triggered_sem = nullptr,
},
{
.code = "59862",
.display_text = "Set Up Wires",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = setup_wires,
.triggered_sem = nullptr,
},
{
.code = "59862",
.display_text = "Set Game Time",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = set_game_time,
.triggered_sem = nullptr,
},
{
.code = "59863",
.display_text = "Debug Switches",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = debug_switches,
.triggered_sem = nullptr,
},
{
.code = "59864",
.display_text = "Battery Stats",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = battery_stats,
.triggered_sem = nullptr,
},
{
.code = "59871",
.display_text = "Try Step 1",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step1,
.triggered_sem = nullptr,
},
{
.code = "59872",
.display_text = "Try Step 2",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step2,
.triggered_sem = nullptr,
},
{
.code = "59873",
.display_text = "Try Step 3",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step3,
.triggered_sem = nullptr,
},
{
.code = "59874",
.display_text = "Try Step 4",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step4,
.triggered_sem = nullptr,
},
{
.code = "59875",
.display_text = "Try Step 5",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step5,
.triggered_sem = nullptr,
},
{
.code = "59876",
.display_text = "Try Step 6",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = try_step6,
.triggered_sem = nullptr,
},
{
.code = "59881",
.display_text = "Skip To Step 1",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step1,
.triggered_sem = nullptr,
},
{
.code = "59882",
.display_text = "Skip To Step 2",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step2,
.triggered_sem = nullptr,
},
{
.code = "59883",
.display_text = "Skip To Step 3",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step3,
.triggered_sem = nullptr,
},
{
.code = "59884",
.display_text = "Skip To Step 4",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step4,
.triggered_sem = nullptr,
},
{
.code = "59885",
.display_text = "Skip To Step 5",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step5,
.triggered_sem = nullptr,
},
{
.code = "59886",
.display_text = "Skip To Step 6",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = skip_to_step6,
.triggered_sem = nullptr,
},
{
.code = "1111",
.display_text = "Issue Strike",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = issue_strike,
.triggered_sem = nullptr,
},
{
.code = "1112",
.display_text = "????",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = flashbang,
.triggered_sem = nullptr,
},
{
.code = "1113",
.display_text = "replay_last",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = replay_last,
.triggered_sem = nullptr,
},
};
size_t len = sizeof(star_codes)/sizeof(star_codes[0]);
SemaphoreHandle_t continue_sem = xSemaphoreCreateBinary();
if (continue_sem == nullptr) { if (continue_sem == nullptr) {
ESP_FAIL("could not create semaphore"); ESP_LOGE(TAG, "could not create semaphore");
return;
} }
led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE); led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE);
@ -184,6 +204,7 @@ void step0() {
add_star_codes(star_codes, len); add_star_codes(star_codes, len);
xSemaphoreTake(continue_sem, portMAX_DELAY); xSemaphoreTake(continue_sem, portMAX_DELAY);
rm_star_codes(star_codes, len); rm_star_codes(star_codes, len);
vSemaphoreDelete(continue_sem);
} }
static const int CURSOR_POS_MAP[5] = {1, 3, 4, 6, 7}; static const int CURSOR_POS_MAP[5] = {1, 3, 4, 6, 7};

View File

@ -3,6 +3,7 @@
#include "../drivers/all.h" #include "../drivers/all.h"
#include "setup_wires.h"
#include "step1.h" #include "step1.h"
#include "step2.h" #include "step2.h"
#include "step3.h" #include "step3.h"

View File

@ -206,18 +206,17 @@ static bool play_part(uint32_t time) {
set_module_time(time); set_module_time(time);
lcd_clear(); lcd_clear();
lcd_set_cursor_pos(1, 1);
switch (part) { switch (part) {
case 0: case 0:
lcd_print("COLOR"); lcd_print(1, 1, "COLOR");
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_PINK); led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_PINK);
break; break;
case 1: case 1:
lcd_print("NUMBER"); lcd_print(1, 1, "NUMBER");
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_BLUE); led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_BLUE);
break; break;
case 2: case 2:
lcd_print("SWITCH"); lcd_print(1, 1, "SWITCH");
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_YELLOW); led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_YELLOW);
break; break;
} }

View File

@ -73,16 +73,24 @@ static bool three_second();
static bool six_second(); static bool six_second();
void step3(void) { void step3(void) {
StarCodeHandler star_codes[] = { SemaphoreHandle_t continue_sem = xSemaphoreCreateBinary();
{ if (continue_sem == nullptr) {
.code = "*1642", ESP_LOGE(TAG, "could not create semaphore");
.display_text = "Starting...", return;
.should_exit = true, }
.callback = nullptr,
}, StarCodeEntry start_code = {
.code = "1642",
.display_text = "Starting...",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = nullptr,
.triggered_sem = continue_sem,
}; };
int len = sizeof(star_codes)/sizeof(StarCodeHandler);
do_star_codes(star_codes, len); add_star_code(start_code);
xSemaphoreTake(continue_sem, portMAX_DELAY);
rm_star_code(start_code.code);
vSemaphoreDelete(continue_sem);
while (times < TIMES_TO_COMPLETE) { while (times < TIMES_TO_COMPLETE) {
tone = tone_dist(gen); tone = tone_dist(gen);

View File

@ -380,16 +380,29 @@ static void fail() {
} }
void step4() { void step4() {
StarCodeHandler star_code = { // TODO: extract to helper function
.code = "*3850", SemaphoreHandle_t continue_sem = xSemaphoreCreateBinary();
if (continue_sem == nullptr) {
ESP_LOGE(TAG, "could not create semaphore");
}
StarCodeEntry start_code = {
.code = "3850",
.display_text = "Starting...", .display_text = "Starting...",
.should_exit = true, .delay_ticks = pdMS_TO_TICKS(2000),
.callback = nullptr, .callback = nullptr,
.triggered_sem = continue_sem,
}; };
do_star_codes(&star_code, 1);
add_star_code(start_code);
xSemaphoreTake(continue_sem, portMAX_DELAY);
rm_star_code(start_code.code);
vSemaphoreDelete(continue_sem);
init_screen(); init_screen();
while (!play_game(4*60*1000, 2)) fail(); while (!play_game(4*60*1000, 2)) fail();
// TODO: create constants for common assets, and put them in a folder.
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0); play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
complete(); complete();
while (!play_game(4*60*1000, 4)) fail(); while (!play_game(4*60*1000, 4)) fail();

View File

@ -4,6 +4,7 @@
#include <random> #include <random>
#include "../drivers/all.h" #include "../drivers/all.h"
#include "../helper.h" #include "../helper.h"
#include "esp_log.h"
#define TETRIS_USE_FLASH_IMG #define TETRIS_USE_FLASH_IMG
#define TETRIS_USE_FLASH_BG_IMG #define TETRIS_USE_FLASH_BG_IMG

View File

@ -179,13 +179,23 @@ bool submit_6(bool* buttons_cycling, bool button_turned_on, int led_off) {
} }
void step5(void) { void step5(void) {
StarCodeEntry star_code = { SemaphoreHandle_t continue_sem = xSemaphoreCreateBinary();
.code = "*2648", if (continue_sem == nullptr) {
ESP_LOGE(TAG, "could not create semaphore");
}
StarCodeEntry start_code = {
.code = "2648",
.display_text = "Starting...", .display_text = "Starting...",
.delay_ticks = pdMS_TO_TICKS(2000), .delay_ticks = pdMS_TO_TICKS(2000),
.callback = nullptr, // TODO .callback = nullptr,
.triggered_sem = continue_sem,
}; };
add_star_code(star_code);
add_star_code(start_code);
xSemaphoreTake(continue_sem, portMAX_DELAY);
rm_star_code(start_code.code);
vSemaphoreDelete(continue_sem);
std::vector<int> all_leds; std::vector<int> all_leds;
@ -219,14 +229,13 @@ void step5(void) {
clean_bomb(); clean_bomb();
int solved_puzzles = 0; int solved_puzzles = 0;
while (solved_puzzles < TIMES_TO_SOLVE) { while (solved_puzzles < TIMES_TO_SOLVE) {
lcd_set_cursor_pos(1, 1);
bool solved_correctly = false; bool solved_correctly = false;
int puzzle = puzzle_dist(gen); int puzzle = puzzle_dist(gen);
switch (puzzle) { switch (puzzle) {
case 0: { case 0: {
lcd_print("Clear"); lcd_print(1, 1, "Clear");
set_module_time(TIME_CLEAR); set_module_time(TIME_CLEAR);
start_module_timer(); start_module_timer();
@ -261,7 +270,7 @@ void step5(void) {
break; break;
} }
case 1: { case 1: {
lcd_print("Blank"); lcd_print(1, 1, "Blank");
set_module_time(TIME_BLANK); set_module_time(TIME_BLANK);
start_module_timer(); start_module_timer();
@ -375,7 +384,7 @@ void step5(void) {
break; break;
} }
case 3: { case 3: {
lcd_print("Nothing"); lcd_print(1, 1, "Nothing");
set_module_time(TIME_NOTHING); set_module_time(TIME_NOTHING);
start_module_timer(); start_module_timer();
@ -434,7 +443,7 @@ void step5(void) {
break; break;
} }
case 4: { case 4: {
lcd_print("Blink"); lcd_print(1, 1, "Blink");
set_module_time(TIME_BLINK); set_module_time(TIME_BLINK);
start_module_timer(); start_module_timer();
@ -498,7 +507,7 @@ void step5(void) {
break; break;
} }
case 5: { case 5: {
lcd_print("Ummm"); lcd_print(1, 1, "Ummm");
set_module_time(TIME_UMMM); set_module_time(TIME_UMMM);
start_module_timer(); start_module_timer();
@ -554,7 +563,7 @@ void step5(void) {
break; break;
} }
case 6: { case 6: {
lcd_print("Plank"); lcd_print(1, 1, "Plank");
set_module_time(TIME_PLANK); set_module_time(TIME_PLANK);
start_module_timer(); start_module_timer();
@ -647,7 +656,7 @@ void step5(void) {
break; break;
} }
case 7: { case 7: {
lcd_print("What"); lcd_print(1, 1, "What");
set_module_time(TIME_WHAT); set_module_time(TIME_WHAT);
start_module_timer(); start_module_timer();
@ -795,7 +804,7 @@ void step5(void) {
break; break;
} }
case 8: { case 8: {
lcd_print("Plink"); lcd_print(1, 1, "Plink");
set_module_time(TIME_PLINK); set_module_time(TIME_PLINK);
start_module_timer(); start_module_timer();