12 Commits
Author SHA1 Message Date
mitchell a9e44145f0 more LCD Header work 2025-07-17 17:02:31 -05:00
mitchell 15e8630a88 update resources 2025-07-13 14:44:14 -05:00
mitchell 4e75aeb69c work on header 2025-07-13 14:37:03 -05:00
mitchell 4a47558ef6 some header work 2025-07-12 18:53:52 -05:00
mitchell e27fb6f015 update star code references 2025-07-12 18:16:15 -05:00
mitchell 1267d1356d impl i2c mutex and some work on global star code handler 2025-07-12 16:39:28 -05:00
mitchell 9cc1a93e73 some bottom_half side star code work 2025-07-06 22:52:39 -05:00
mitchell 72ff92b444 update steps 3 & 5 2025-06-05 16:48:03 -05:00
mitchell e1ce43d57c start impl on generic starcode handler 2025-06-05 16:24:07 -05:00
mitchell ee30fce074 set partition table for OTA 2025-04-24 14:46:26 -05:00
mitchell 219f1f1507 small wlvgl work 2025-04-05 00:20:38 -05:00
mitchell 10648045a3 start wlvgl 2025-04-04 23:52:48 -05:00
70 changed files with 1008 additions and 4268 deletions
+4
View File
@@ -6,16 +6,20 @@ set(SOURCES
"esp_lcd_ili9488/esp_lcd_ili9488.c" "esp_lcd_ili9488/esp_lcd_ili9488.c"
"bottom_half.cpp" "bottom_half.cpp"
"char_lcd.cpp" "char_lcd.cpp"
"game_info.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"
"speaker.cpp" "speaker.cpp"
"sseg.cpp" "sseg.cpp"
"star_code.cpp"
"state_tracking.cpp" "state_tracking.cpp"
"tft.cpp" "tft.cpp"
"wires.cpp" "wires.cpp"
"wlvgl.cpp"
) )
target_sources(${COMPONENT_LIB} PRIVATE ${SOURCES}) target_sources(${COMPONENT_LIB} PRIVATE ${SOURCES})
@@ -32,6 +32,7 @@ Arduino Uno (any 'duino should do)
******************************************************************************/ ******************************************************************************/
#include "SparkFunBQ27441.h" #include "SparkFunBQ27441.h"
#include "../i2c.h"
/***************************************************************************** /*****************************************************************************
************************** Initialization Functions ************************* ************************** Initialization Functions *************************
@@ -710,7 +711,9 @@ bool BQ27441::writeExtendedData(uint8_t classID, uint8_t offset, uint8_t * data,
int16_t BQ27441::i2cReadBytes(uint8_t subAddress, uint8_t * dest, uint8_t count) int16_t BQ27441::i2cReadBytes(uint8_t subAddress, uint8_t * dest, uint8_t count)
{ {
int16_t timeout = BQ72441_I2C_TIMEOUT; int16_t timeout = BQ72441_I2C_TIMEOUT;
xSemaphoreTake(i2c0_mutex, portMAX_DELAY);
i2c_master_write_read_device(BQ72441_I2C_NUM, _deviceAddress, &subAddress, 1, dest, count, timeout); i2c_master_write_read_device(BQ72441_I2C_NUM, _deviceAddress, &subAddress, 1, dest, count, timeout);
xSemaphoreGive(i2c0_mutex);
return timeout; return timeout;
} }
+3 -35
View File
@@ -1,12 +1,10 @@
#include "all.h" #include "all.h"
static const char *TAG = "driver_all";
static void init_i2c();
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.
init_lcd(); init_lcd();
init_star_code_system();
// init the bottom half so that we can get user input. // init the bottom half so that we can get user input.
init_bottom_half(); init_bottom_half();
init_sd(); init_sd();
@@ -16,36 +14,6 @@ void init_drivers() {
init_tft(); init_tft();
init_leds(); init_leds();
init_power_board(); init_power_board();
set_lcd_header_enabled(true);
} }
/// @brief Initializes I2C_NUM_0.
///
/// This is hooked up the to:
/// - The bottom half
/// - The char lcd
/// - The power board
/// - The MPU6050
/// - The PERH port
/// - The Capacitive Touch Panel
static void init_i2c() {
ESP_LOGI(TAG, "Initializing i2c...");
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_DISABLE,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
// .sda_pullup_en = GPIO_PULLUP_ENABLE,
// .scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 100*1000,
},
.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL
};
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0));
ESP_LOGI(TAG, "i2c initialized!");
}
+10 -5
View File
@@ -1,14 +1,19 @@
#ifndef ALL_H #ifndef ALL_H
#define ALL_H #define ALL_H
#include "char_lcd.h"
#include "bottom_half.h" #include "bottom_half.h"
#include "char_lcd.h"
#include "game_timer.h"
#include "i2c.h"
#include "leds.h"
#include "power.h"
#include "sd.h" #include "sd.h"
#include "speaker.h" #include "speaker.h"
#include "game_timer.h" #include "sseg.h"
#include "drivers/tft.h" #include "star_code.h"
#include "drivers/leds.h" #include "state_tracking.h"
#include "drivers/power.h" #include "tft.h"
#include "wires.h"
void init_drivers(); void init_drivers();
+27 -12
View File
@@ -1,6 +1,7 @@
#include "bottom_half.h" #include "bottom_half.h"
#include <esp_log.h> #include <esp_log.h>
#include "state_tracking.h" #include "state_tracking.h"
#include "star_code.h"
static const char *TAG = "bottom_half"; static const char *TAG = "bottom_half";
@@ -69,20 +70,25 @@ void init_bottom_half() {
static uint8_t receive_delta(void) { static uint8_t receive_delta(void) {
uint8_t reg = 1; uint8_t reg = 1;
buf[0] = 0; 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(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 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;
buf[0] = 0; esp_err_t result = i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, &reg, 1, buf, 2, (100 / portTICK_PERIOD_MS));
buf[1] = 0; ESP_ERROR_CHECK_WITHOUT_ABORT(result);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, &reg, 1, buf, 2, (100 / portTICK_PERIOD_MS))); if (result != ESP_OK) {
return;
}
uint16_t new_keypad_state = buf[0] | (buf[1] << 8); uint16_t new_keypad_state = buf[0] | (buf[1] << 8);
uint16_t just_pressed = new_keypad_state & ~keypad_state; uint16_t just_pressed = new_keypad_state & ~keypad_state;
keypad_pressed |= just_pressed;
if (is_state_tracking() && just_pressed) { if (is_state_tracking() && just_pressed) {
char buf[6]; char buf[6];
sprintf(buf, "%d", just_pressed); sprintf(buf, "%d", just_pressed);
@@ -90,19 +96,27 @@ static void receive_keypad(void) {
} }
uint16_t just_released = ~new_keypad_state & keypad_state; uint16_t just_released = ~new_keypad_state & keypad_state;
keypad_released |= just_released;
if (is_state_tracking() && just_released) { if (is_state_tracking() && just_released) {
char buf[6]; char buf[6];
sprintf(buf, "%d", just_released); sprintf(buf, "%d", just_released);
event_occured("KP_RELEASE", buf); event_occured("KP_RELEASE", buf);
} }
star_code_handle_keypad(&just_pressed, &just_released);
keypad_pressed |= just_pressed;
keypad_released |= just_released;
keypad_state = new_keypad_state; keypad_state = new_keypad_state;
} }
static void receive_button_switch(void) { static void receive_button_switch(void) {
uint8_t reg = 3; uint8_t reg = 3;
ESP_ERROR_CHECK_WITHOUT_ABORT(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);
if (result != ESP_OK) {
return;
}
uint8_t new_button_state = buf[1] & 0xF; uint8_t new_button_state = buf[1] & 0xF;
uint8_t new_switch_state = (~buf[0]) & 0xF; uint8_t new_switch_state = (~buf[0]) & 0xF;
uint8_t new_switch_touch_state = (buf[1] >> 4) & 0xF; uint8_t new_switch_touch_state = (buf[1] >> 4) & 0xF;
@@ -217,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) {
@@ -233,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) {
+8
View File
@@ -126,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 */
+79 -34
View File
@@ -4,13 +4,26 @@
#include <esp_log.h> #include <esp_log.h>
#include "state_tracking.h" #include "state_tracking.h"
#include <cstring> #include <cstring>
#include "power.h"
i2c_lcd_pcf8574_handle_t lcd; i2c_lcd_pcf8574_handle_t lcd;
static volatile bool header_enabled = false;
static const char *TAG = "char_lcd"; static const char *TAG = "char_lcd";
static const char* EMPTY_ROW = " ";
static char buf[65]; static char buf[65];
static void monitor_battery_task(void* _arg) {
(void) _arg;
while (true) {
vTaskDelay(pdMS_TO_TICKS(1'000));
lcd_print_header_bat();
}
}
static bool replay_handler(const char* event, char* arg) { static bool replay_handler(const char* event, char* arg) {
if (strcmp(event, "LCD_CLEAR") == 0) { if (strcmp(event, "LCD_CLEAR") == 0) {
lcd_clear(); lcd_clear();
@@ -57,8 +70,7 @@ static bool replay_handler(const char* event, char* arg) {
return true; return true;
} }
if (strcmp(event, "LCD_BACKLIGHT") == 0) { if (strcmp(event, "LCD_BACKLIGHT") == 0) {
uint32_t brightness = atoi(arg); lcd_set_backlight(strcmp(arg, "true") == 0);
lcd_set_backlight(brightness);
return true; return true;
} }
if (strcmp(event, "LCD_CREATE_CHAR") == 0) { if (strcmp(event, "LCD_CREATE_CHAR") == 0) {
@@ -74,14 +86,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;
} }
@@ -98,25 +105,31 @@ void init_lcd() {
register_replay_fn(replay_handler); register_replay_fn(replay_handler);
xTaskCreate(monitor_battery_task, "bat_monitor", 1024*2, nullptr, 0, nullptr);
ESP_LOGI(TAG, "LCD initialized!"); ESP_LOGI(TAG, "LCD initialized!");
} }
void lcd_clear() { void lcd_clear() {
lcd_clear(&lcd); if (!header_enabled) {
lcd_clear(&lcd);
if (is_state_tracking()) { if (is_state_tracking()) {
event_occured("LCD_CLEAR", NULL); event_occured("LCD_CLEAR", NULL);
}
} else {
lcd_print(0, 1, EMPTY_ROW);
lcd_print(0, 2, EMPTY_ROW);
lcd_print(0, 3, EMPTY_ROW);
} }
} }
// TODO: rm
void lcd_cursor_home() { void lcd_cursor_home() {
lcd_home(&lcd); lcd_set_cursor_pos(0, 0);
if (is_state_tracking()) {
event_occured("LCD_CURSOR", "0,0");
}
} }
// TODO: with print requiring you to set a pos every time, this function is not helpful
void lcd_set_cursor_pos(uint8_t col, uint8_t row) { void lcd_set_cursor_pos(uint8_t col, uint8_t row) {
lcd_set_cursor(&lcd, col, row); lcd_set_cursor(&lcd, col, row);
@@ -204,16 +217,16 @@ void lcd_set_autoscroll(bool autoscroll) {
} }
} }
void lcd_set_backlight(uint8_t brightness) { void lcd_set_backlight(bool backlight) {
lcd_set_backlight(&lcd, brightness); lcd_set_backlight(&lcd, backlight);
if (is_state_tracking()) { if (is_state_tracking()) {
sprintf(buf, "%d", brightness); sprintf(buf, "%d", backlight);
event_occured("LCD_BACKLIGHT", buf); event_occured("LCD_BACKLIGHT", backlight ? "true" : "false");
} }
} }
void lcd_create_char(uint8_t location, uint8_t* charmap) { void lcd_create_char(uint8_t location, const uint8_t charmap[]) {
lcd_create_char(&lcd, location, charmap); lcd_create_char(&lcd, location, charmap);
if (is_state_tracking()) { if (is_state_tracking()) {
@@ -225,16 +238,9 @@ void lcd_create_char(uint8_t location, uint8_t* charmap) {
} }
} }
void lcd_write(uint8_t value) { // TODO: switch to row, col
lcd_write(&lcd, value); void lcd_print(uint8_t col, uint8_t row, const char* str) {
lcd_set_cursor_pos(col, row);
if (is_state_tracking()) {
sprintf(buf, "%d", value);
event_occured("LCD_WRITE", buf);
}
}
void lcd_print(const char* str) {
lcd_print(&lcd, str); lcd_print(&lcd, str);
if (is_state_tracking()) { if (is_state_tracking()) {
@@ -243,7 +249,46 @@ void lcd_print(const char* str) {
} }
} }
void lcd_print(uint8_t col, uint8_t row, const char* str) { void set_lcd_header_enabled(bool enable) {
lcd_set_cursor_pos(col, row); bool old_header_enabled = header_enabled;
lcd_print(str); header_enabled = enable;
// update header in response to enabling/disabling the header
if (enable && !old_header_enabled) {
lcd_print_header();
} else if (!enable && old_header_enabled) {
lcd_print(0, 0, EMPTY_ROW);
}
} }
bool lcd_header_enabled() {
return header_enabled;
}
void lcd_print_header() {
lcd_print_header_star_code();
lcd_print_header_step();
lcd_print_header_bat();
}
void lcd_do_splash() {
const uint8_t custom_char[6][8] = {
{ 0x01, 0x01, 0x02, 0x02, 0x07, 0x07, 0x0F, 0x0D },
{ 0x10, 0x10, 0x18, 0x18, 0x1C, 0x0C, 0x0E, 0x06 },
{ 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x07, 0x07 },
{ 0x19, 0x1B, 0x13, 0x17, 0x07, 0x0F, 0x0F, 0x1F },
{ 0x13, 0x1B, 0x1F, 0x1F, 0x00, 0x1F, 0x1F, 0x1F },
{ 0x00, 0x00, 0x10, 0x10, 0x00, 0x18, 0x1C, 0x1C },
};
// TODO: make the lcd_lib somehow support the custom character 0 which would otherwise be a null terminator
lcd_create_char(1, custom_char[0]);
lcd_create_char(2, custom_char[1]);
lcd_create_char(3, custom_char[2]);
lcd_create_char(4, custom_char[3]);
lcd_create_char(5, custom_char[4]);
lcd_create_char(6, custom_char[5]);
lcd_print(6, 1, "\x01\x02Marino");
lcd_print(5, 2, "\x03\x04\x05\x06""DEV");
}
+29 -9
View File
@@ -44,18 +44,38 @@ 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, const uint8_t charmap[]);
// Write a character to the LCD /// @brief Print a string to the LCD at a given pos.
void lcd_write(uint8_t value); /// @param col the column to print the string at.
/// @param row the row the print the string at.
// Print a string to the LCD /// @param str the string to print.
void lcd_print(const char* str);
// Print a string to the LCD at a given pos
void lcd_print(uint8_t col, uint8_t row, const char* str); void lcd_print(uint8_t col, uint8_t row, const char* str);
/// @brief Enables or disables the header on the LCD.
/// @param enable `true` to enable the header, `false` to disable.
void set_lcd_header_enabled(bool enable);
/// @brief Returns weather or not the lcd_header is enabled.
/// @return `true` if the header is enabled, `false` otherwise.
bool lcd_header_enabled();
/// @brief Prints the header in the LCD.
void lcd_print_header();
/// @brief Prints the star code section of the LCD header.
void lcd_print_header_star_code();
/// @brief Prints the step section of the LCD header.
void lcd_print_header_step();
/// @brief Prints the battery section of the LCD header.
void lcd_print_header_bat();
/// @brief Prints the splash screen for the BLK_BOX.
void lcd_do_splash();
#endif /* CHAR_LCD_H */ #endif /* CHAR_LCD_H */
+23
View File
@@ -0,0 +1,23 @@
#include "game_info.h"
#include <stdio.h>
#include "char_lcd.h"
// static char game_state[GAME_STATE_MAX_LEN+1] = " ";
static char game_state[GAME_STATE_MAX_LEN+1] = "MENU ";
void set_game_state(char* new_state) {
snprintf(game_state, sizeof(game_state), "%-5s", new_state);
}
void reset_game_state() {
for (int i = 0; i < GAME_STATE_MAX_LEN; i++) {
game_state[i] = '\0';
}
game_state[GAME_STATE_MAX_LEN] = '\0';
}
void lcd_print_header_step() {
if (!lcd_header_enabled()) return;
lcd_print(10, 0, game_state);
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef GAME_INFO_H
#define GAME_INFO_H
#define GAME_STATE_MAX_LEN 5
/// @brief Sets the game state, used for the header.
///
/// Must be <= 5 characters
void set_game_state(char* new_state);
/// @brief Resets the game state to be blank.
void reset_game_state();
/// @brief Prints the game state section of the header to the char_lcd. (row 0, columns 10-14)
void lcd_print_header_step();
#endif /* GAME_INFO_H */
+34
View File
@@ -0,0 +1,34 @@
#include "i2c.h"
#include "esp_log.h"
#include "esp_err.h"
#include "driver/i2c.h"
static const char *TAG = "i2c";
SemaphoreHandle_t i2c0_mutex;
void init_i2c() {
ESP_LOGI(TAG, "Initializing i2c...");
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_DISABLE,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
// .sda_pullup_en = GPIO_PULLUP_ENABLE,
// .scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 100*1000,
},
.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL
};
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0));
i2c0_mutex = xSemaphoreCreateMutex();
assert(i2c0_mutex != NULL);
ESP_LOGI(TAG, "i2c initialized!");
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef I2C_H
#define I2C_H
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
/// The mutex for accessing `I2C_NUM_0`.
extern SemaphoreHandle_t i2c0_mutex;
/// @brief Initializes `I2C_NUM_0`.
///
/// This is hooked up the to:
/// - The bottom half
/// - The char lcd
/// - The power board
/// - The MPU6050
/// - The PERH port
/// - The Capacitive Touch Panel
void init_i2c();
#endif /* I2C_H */
+10 -3
View File
@@ -12,6 +12,7 @@
#include "esp_check.h" #include "esp_check.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "i2c.h"
#define TAG "I2C_LCD_PCF8574" #define TAG "I2C_LCD_PCF8574"
@@ -58,6 +59,7 @@ void lcd_begin(i2c_lcd_pcf8574_handle_t* lcd, uint8_t cols, uint8_t rows) {
lcd->entrymode = 0x02; lcd->entrymode = 0x02;
// The following are the reset sequence: Please see "Initialization instruction in the PCF8574 datasheet." // The following are the reset sequence: Please see "Initialization instruction in the PCF8574 datasheet."
xSemaphoreTake(i2c0_mutex, portMAX_DELAY);
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd); i2c_master_start(cmd);
// We left-shift the device addres and add the read/write command // We left-shift the device addres and add the read/write command
@@ -95,6 +97,7 @@ void lcd_begin(i2c_lcd_pcf8574_handle_t* lcd, uint8_t cols, uint8_t rows) {
i2c_master_stop(cmd); i2c_master_stop(cmd);
i2c_master_cmd_begin(lcd->i2c_port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); i2c_master_cmd_begin(lcd->i2c_port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
xSemaphoreGive(i2c0_mutex);
// Instruction: function set = 0x20 // Instruction: function set = 0x20
lcd_send(lcd, 0x20 | (rows > 1 ? 0x08 : 0x00), false); lcd_send(lcd, 0x20 | (rows > 1 ? 0x08 : 0x00), false);
@@ -110,7 +113,7 @@ void lcd_clear(i2c_lcd_pcf8574_handle_t* lcd) {
// Instruction: Clear display = 0x01 // Instruction: Clear display = 0x01
lcd_send(lcd, 0x01, false); lcd_send(lcd, 0x01, false);
// Clearing the display takes a while: takes approx. 1.5ms // Clearing the display takes a while: takes approx. 1.5ms
esp_rom_delay_us(1600); esp_rom_delay_us(2000);
} // lcd_clear() } // lcd_clear()
// Set the display to home // Set the display to home
@@ -118,7 +121,7 @@ void lcd_home(i2c_lcd_pcf8574_handle_t* lcd) {
// Instruction: Return home = 0x02 // Instruction: Return home = 0x02
lcd_send(lcd, 0x02, false); lcd_send(lcd, 0x02, false);
// Same as clearing the display: takes approx. 1.5ms // Same as clearing the display: takes approx. 1.5ms
esp_rom_delay_us(1600); esp_rom_delay_us(2000);
} // lcd_home() } // lcd_home()
// Set the cursor to a new position. // Set the cursor to a new position.
@@ -238,7 +241,7 @@ void lcd_set_backlight(i2c_lcd_pcf8574_handle_t* lcd, uint8_t brightness) {
} // lcd_set_backlight() } // lcd_set_backlight()
// Custom character creation: allows us to create up to 8 custom characters in the CGRAM locations // Custom character creation: allows us to create up to 8 custom characters in the CGRAM locations
void lcd_create_char(i2c_lcd_pcf8574_handle_t* lcd, uint8_t location, uint8_t charmap[]) { void lcd_create_char(i2c_lcd_pcf8574_handle_t* lcd, uint8_t location, const uint8_t charmap[]) {
location &= 0x7; // Only 8 locations are available location &= 0x7; // Only 8 locations are available
// Set the CGRAM address // Set the CGRAM address
lcd_send(lcd, 0x40 | (location << 3), false); lcd_send(lcd, 0x40 | (location << 3), false);
@@ -295,6 +298,7 @@ void lcd_print_number(i2c_lcd_pcf8574_handle_t* lcd, uint8_t col, uint8_t row, u
static void lcd_send(i2c_lcd_pcf8574_handle_t* lcd, uint8_t value, bool is_data) { static void lcd_send(i2c_lcd_pcf8574_handle_t* lcd, uint8_t value, bool is_data) {
xSemaphoreTake(i2c0_mutex, portMAX_DELAY);
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd); i2c_master_start(cmd);
i2c_master_write_byte(cmd, (lcd->i2c_addr << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, (lcd->i2c_addr << 1) | I2C_MASTER_WRITE, true);
@@ -303,6 +307,7 @@ static void lcd_send(i2c_lcd_pcf8574_handle_t* lcd, uint8_t value, bool is_data)
i2c_master_stop(cmd); i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(lcd->i2c_port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); esp_err_t ret = i2c_master_cmd_begin(lcd->i2c_port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
xSemaphoreGive(i2c0_mutex);
if (ret != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to send data to LCD: %s", esp_err_to_name(ret)); ESP_LOGE(TAG, "Failed to send data to LCD: %s", esp_err_to_name(ret));
@@ -341,6 +346,7 @@ static void lcd_write_i2c(i2c_lcd_pcf8574_handle_t* lcd, uint8_t data, bool is_d
data |= lcd->backlight_mask; data |= lcd->backlight_mask;
} }
xSemaphoreTake(i2c0_mutex, portMAX_DELAY);
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd); i2c_master_start(cmd);
i2c_master_write_byte(cmd, (lcd->i2c_addr << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, (lcd->i2c_addr << 1) | I2C_MASTER_WRITE, true);
@@ -348,6 +354,7 @@ static void lcd_write_i2c(i2c_lcd_pcf8574_handle_t* lcd, uint8_t data, bool is_d
i2c_master_stop(cmd); i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(lcd->i2c_port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); esp_err_t ret = i2c_master_cmd_begin(lcd->i2c_port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
xSemaphoreGive(i2c0_mutex);
if (ret != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to write to LCD: %s", esp_err_to_name(ret)); ESP_LOGE(TAG, "Failed to write to LCD: %s", esp_err_to_name(ret));
+1 -1
View File
@@ -94,7 +94,7 @@ void lcd_no_autoscroll(i2c_lcd_pcf8574_handle_t* lcd);
void lcd_set_backlight(i2c_lcd_pcf8574_handle_t* lcd, uint8_t brightness); void lcd_set_backlight(i2c_lcd_pcf8574_handle_t* lcd, uint8_t brightness);
// Create a custom character // Create a custom character
void lcd_create_char(i2c_lcd_pcf8574_handle_t* lcd, uint8_t location, uint8_t charmap[]); void lcd_create_char(i2c_lcd_pcf8574_handle_t* lcd, uint8_t location, const uint8_t charmap[]);
// Write a character to the LCD // Write a character to the LCD
void lcd_write(i2c_lcd_pcf8574_handle_t* lcd, uint8_t value); void lcd_write(i2c_lcd_pcf8574_handle_t* lcd, uint8_t value);
+1 -1
View File
@@ -8,11 +8,11 @@ static const char* TAG = "leds";
static led_strip_handle_t leds; static led_strip_handle_t leds;
// TODO: rename these to playback_handler
static bool replay_handler(const char* event, char* arg) { static bool replay_handler(const char* event, char* arg) {
if (strcmp(event, "LED_SET") == 0) { if (strcmp(event, "LED_SET") == 0) {
uint32_t led = atoi(strtok(arg, ",")); uint32_t led = atoi(strtok(arg, ","));
uint32_t color = atoi(strtok(NULL, ",")); uint32_t color = atoi(strtok(NULL, ","));
ESP_LOGI("leds", "color: %ld", color);
led_set(led, color); led_set(led, color);
return true; return true;
} }
+1
View File
@@ -26,6 +26,7 @@ enum LEDColor: uint32_t {
LED_COLOR_WHITE_STRONG = 0xFF'FF'FF, LED_COLOR_WHITE_STRONG = 0xFF'FF'FF,
}; };
// TODO: sepperate the indicator leds from the shape display.
enum IndicatorLED { enum IndicatorLED {
LED_SHAPE1 = 0u, LED_SHAPE1 = 0u,
LED_SHAPE2 = 1u, LED_SHAPE2 = 1u,
+20
View File
@@ -50,4 +50,24 @@ void init_power_board() {
ESP_LOGI(TAG, "Power board initialized!"); ESP_LOGI(TAG, "Power board initialized!");
} }
uint16_t get_bat_voltage() {
return lipo.voltage();
}
void lcd_print_header_bat() {
if (!lcd_header_enabled()) return;
uint8_t soc = lipo.soc();
char buf[5];
if (soc < 5) {
sprintf(buf, "LOW ");
} else {
snprintf(buf, sizeof(buf), "%3d%%", soc);
}
if (lipo.current() > 0) {
buf[3] = '+';
}
lcd_print(16, 0, buf);
}
+6 -1
View File
@@ -3,13 +3,18 @@
#include "SparkFunBQ27441/SparkFunBQ27441.h" #include "SparkFunBQ27441/SparkFunBQ27441.h"
extern volatile uint32_t battery_charge;
void bat_monitor_task(void* arg); void bat_monitor_task(void* arg);
/// Initializes the battery gas guage for getting battery stats. /// Initializes the battery gas guage for getting battery stats.
void init_power_board(); void init_power_board();
/// @brief Gets the battery voltage /// @brief Gets the battery voltage.
/// @return battery voltage in mV. /// @return battery voltage in mV.
uint16_t get_bat_voltage(); uint16_t get_bat_voltage();
/// @brief Prints the battery section of the header to the char_lcd. (row 0, columns 16-19)
void lcd_print_header_bat();
#endif /* POWER_H */ #endif /* POWER_H */
+252
View File
@@ -0,0 +1,252 @@
#include "star_code.h"
#include <vector>
#include <algorithm>
#include <string.h>
#include <stdint.h>
#include <esp_log.h>
#include "drivers/bottom_half.h"
#include "char_lcd.h"
#include "esp_timer.h"
static const char* TAG = "star_code";
volatile bool handling_new_starcodes = false;
static volatile bool system_initialized = false;
// TODO: use the semaphore, convert to RWLock?
static volatile SemaphoreHandle_t star_codes_sem;
static std::vector<StarCodeEntry> star_codes;
static const char EMPTY_STAR_CODE_HEADER[] = " ";
esp_timer_handle_t starcode_delay_timer;
static volatile bool processing_starcode;
static volatile StarCodeEntry* current_starcode = nullptr;
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 starcode_trigger_cb(void* arg) {
(void) arg;
processing_starcode = false;
if (current_starcode != nullptr) {
if (current_starcode->triggered_sem != nullptr)
xSemaphoreGive(current_starcode->triggered_sem);
if (current_starcode->callback != nullptr)
(current_starcode->callback)();
current_starcode = nullptr;
}
// TODO: rename star code everywhere to starcode
lcd_print_header_star_code();
}
void star_code_handle_keypad(uint16_t* just_pressed, uint16_t* just_released) {
if ((!processing_starcode) && 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';
}
lcd_print_header_star_code();
}
}
// 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);
const esp_timer_create_args_t timer_args = {
.callback = &starcode_trigger_cb,
.arg = nullptr,
.dispatch_method = ESP_TIMER_TASK,
.name = "starcode_trigger",
.skip_unhandled_events = false,
};
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &starcode_delay_timer));
handling_new_starcodes = true;
system_initialized = true;
}
/// Checks if a triggered code matches an expected code.
/// @return true iff the codes match, where '*'s in the expected code can match any character in the triggered code
static bool check_code_match(const char* triggered, const char* expected) {
size_t triggered_len = strlen(triggered);
size_t match_len = strlen(triggered);
if (triggered_len != match_len)
return false;
for (int i = 0; i < triggered_len; i++) {
if (!(expected[i] == '*' || expected[i] == triggered[i])) {
return false;
}
}
return true;
}
bool add_star_code(StarCodeEntry code) {
if (code.code == nullptr || strlen(code.code) > STARCODE_MAX_LEN) {
return false;
}
if (code.display_text != nullptr && strlen(code.display_text) > STARCODE_MAX_LEN + 1) {
return false;
}
// check for a existing entry
auto it = std::find_if(star_codes.begin(), star_codes.end(), [&](const StarCodeEntry& other) {
return check_code_match(code.code, other.code);
});
if (it != star_codes.end()) {
// existing star code found!
ESP_LOGW(TAG, "Failed to add star code %s", code.code);
return false;
}
star_codes.push_back(code);
return true;
}
bool add_star_codes(const StarCodeEntry* codes, size_t len) {
bool success = true;
for (int i = 0; i < len; i++) {
if (!add_star_code(codes[i])) {
success = false;
}
}
return success;
}
bool rm_star_code(const char* code){
auto it = std::find_if(star_codes.begin(), star_codes.end(), [&](const StarCodeEntry& star_code) {
return strcmp(code, star_code.code) == 0;
});
if (it == star_codes.end()) {
ESP_LOGW(TAG, "Failed to remove star code %s", code);
return false;
}
star_codes.erase(it);
return true;
}
bool rm_star_codes(const StarCodeEntry* codes, size_t len) {
bool success = true;
for (int i = 0; i < len; i++) {
if (!rm_star_code(codes[i].code)) {
success = false;
}
}
return success;
}
bool rm_star_codes_str(const char** codes, size_t len) {
bool success = true;
for (int i = 0; i < len; i++) {
if (!rm_star_code(codes[i])) {
success = false;
}
}
return success;
}
void clear_star_codes() {
star_codes.clear();
}
bool trigger_star_code(const char* code) {
ESP_LOGI(TAG, "Star codes to checK:");
for (const auto& entry : star_codes) {
ESP_LOGI(TAG, "%s", entry.code);
}
auto it = std::find_if(star_codes.begin(), star_codes.end(), [&](const StarCodeEntry& other) {
return check_code_match(code, other.code);
});
uint64_t delay_us = 2'000'000;
processing_starcode = true;
if (it != star_codes.end()) {
current_starcode = &*it;
delay_us = current_starcode->delay_us;
}
ESP_ERROR_CHECK(esp_timer_start_once(starcode_delay_timer, delay_us));
return current_starcode != nullptr;
}
void pause_star_code_system() {
doing_starcode = false;
handling_new_starcodes = false;
}
void resume_star_code_system() {
handling_new_starcodes = system_initialized;
}
void lcd_print_header_star_code() {
if (!lcd_header_enabled()) return;
// TODO: consider upping the display text size to be able to overwrite the game_state area.
if (processing_starcode) {
if (current_starcode == nullptr) {
lcd_print(0, 0, "Invalid ");
} else if (current_starcode->display_text != nullptr) {
char buf[STARCODE_MAX_LEN + 2];
snprintf(buf, sizeof(buf), "%s", current_starcode->display_text);
lcd_print(0, 0, buf);
} else {
lcd_print(0, 0, EMPTY_STAR_CODE_HEADER);
}
} else if (doing_starcode) {
char buf[STARCODE_MAX_LEN + 2];
snprintf(buf, sizeof(buf), "*%-8s", current);
lcd_print(0, 0, buf);
} else {
lcd_print(0, 0, EMPTY_STAR_CODE_HEADER);
}
}
+87
View File
@@ -0,0 +1,87 @@
#ifndef STAR_CODE_H
#define STAR_CODE_H
#include <stddef.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
/// The max length of a starcode (not counting the star)
#define STARCODE_MAX_LEN 8
/// @brief A handler for a specific star code
struct StarCodeEntry {
/// @brief The star code without the star
///
/// This must be <= 8 characters.
///
/// You may include a * in the code to match on any character
const char* code;
/// @brief The text to display when the star code is entered (or null).
///
/// This must be <= 9 characters.
const char* display_text;
/// @brief The number of microseconds to delay when the star code is entered before calling the handler.
uint64_t delay_us;
/// @brief The function to call when the star code is entered.
/// Can be null.
void (*callback)(void);
/// @brief The binary semaphore that will be given when this star code is triggered.
/// Can be null.
SemaphoreHandle_t triggered_sem;
};
/// @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
bool add_star_code(StarCodeEntry code);
/// @brief Adds a list of star codes to be handled.
/// @param codes the list of star codes to add
/// @param len the length of the list
/// @return true iff all the star codes were added
bool add_star_codes(const StarCodeEntry* codes, size_t len);
/// @brief removes a star code to stop handling it.
/// @param code the star code to remove
/// @return true iff the star code was removed
bool rm_star_code(const char* code);
/// @brief removes all given star codes to stop handling them.
/// @param codes the list of star codes to remove
/// @param len the length of the list
/// @return true iff all star codes were removed
bool rm_star_codes(const StarCodeEntry* codes, size_t len);
/// @brief removes all given star codes to stop handling them.
/// @param codes the list of star codes to remove
/// @param len the length of the list
/// @return true iff all star codes were removed
bool rm_star_codes_str(const char** codes, size_t len);
/// @brief clears all star codes.
void clear_star_codes();
/// @brief Triggers the given star code.
/// @param code the star code to trigger (without the *)
/// @return true iff a star code was triggered
bool trigger_star_code(const char* code);
/// @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.
/// @return `true` if the star code system is handling star codes.
bool star_code_sys_enabled();
/// @brief Prints the star code section of the header to the char_lcd. (row 0, columns 0-9)
void lcd_print_header_star_code();
#endif /* STAR_CODE_H */
+3 -1
View File
@@ -1,6 +1,7 @@
#include "state_tracking.h" #include "state_tracking.h"
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
#include "wlvgl.h"
static const char* PLAYBACK_TAG = "playback"; static const char* PLAYBACK_TAG = "playback";
@@ -24,7 +25,6 @@ TaskHandle_t playback_task_handle;
static volatile state_t state = STATE_IDLE; static volatile state_t state = STATE_IDLE;
/// @brief Periodically flushes and syncs (if neccesary) the output stream. /// @brief Periodically flushes and syncs (if neccesary) the output stream.
/// @param arg unused. /// @param arg unused.
static void flush_file_task(void* arg) { static void flush_file_task(void* arg) {
@@ -171,6 +171,7 @@ bool start_recording() {
state = STATE_RECORDING; state = STATE_RECORDING;
recording_start_time = xTaskGetTickCount(); recording_start_time = xTaskGetTickCount();
xTaskCreate(flush_file_task, "flush_recording", 2048, NULL, 2, &flush_file_task_handle); xTaskCreate(flush_file_task, "flush_recording", 2048, NULL, 2, &flush_file_task_handle);
reset_wlv_tables(); // TODO: generify this
return true; return true;
} }
@@ -198,6 +199,7 @@ bool start_playback() {
state = STATE_PLAYBACK; state = STATE_PLAYBACK;
playback_start_time = xTaskGetTickCount(); playback_start_time = xTaskGetTickCount();
xTaskCreate(playback_task, "playback", 4096, NULL, 2, &playback_task_handle); xTaskCreate(playback_task, "playback", 4096, NULL, 2, &playback_task_handle);
reset_wlv_tables(); // TODO: generify this
return true; return true;
} }
+1 -1
View File
@@ -26,7 +26,7 @@ static bool notify_lvgl_flush_ready(
esp_lcd_panel_io_event_data_t *edata, esp_lcd_panel_io_event_data_t *edata,
void *user_ctx void *user_ctx
) { ) {
lv_disp_drv_t *disp_driver = (lv_disp_drv_t *)user_ctx; lv_disp_drv_t* disp_driver = (lv_disp_drv_t *)user_ctx;
lv_disp_flush_ready(disp_driver); lv_disp_flush_ready(disp_driver);
return false; return false;
} }
+1 -1
View File
@@ -32,7 +32,7 @@ void init_wires(void) {
.scl_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = { .master = {
.clk_speed = 100000, .clk_speed = 100000,
} },
}; };
gpio_reset_pin(GPIO_NUM_41); gpio_reset_pin(GPIO_NUM_41);
+152
View File
@@ -0,0 +1,152 @@
#include "wlvgl.h"
#include <vector>
/// A table that maps an incrementing integer to a style reference
static std::vector<lv_style_t*> style_table;
/// A table that maps an incrementing integer to a style reference
static std::vector<lv_obj_t*> obj_table;
static int index_of_style(lv_style_t* style) {
for (size_t i = 0; i < style_table.size(); i++) {
if (style_table[i] == style) {
return i;
}
}
return -1;
}
static int index_of_obj(lv_obj_t* obj) {
for (size_t i = 0; i < obj_table.size(); i++) {
if (obj_table[i] == obj) {
return i;
}
}
return -1;
}
void reset_wlv_tables() {
style_table.clear();
obj_table.clear();
}
lv_obj_t * wlv_obj_create(lv_obj_t* parent) {
// initialize the obj
lv_obj_t* value = lv_obj_create(parent);
if (is_state_tracking()) {
// add the style to the table
obj_table.push_back(value);
size_t obj_index = obj_table.size();
char buf[8];
sprintf(buf, "%d", obj_index);
event_occured("lv_obj_create", buf);
}
return value;
}
void wlv_style_init(lv_style_t* style) {
// initialize the style
lv_style_init(style);
if (is_state_tracking()) {
// add the style to the table
style_table.push_back(style);
size_t style_index = style_table.size();
char buf[8];
sprintf(buf, "%d", style_index);
event_occured("lv_style_init", buf);
}
}
void wlv_obj_set_style_bg_color(lv_obj_t* obj, lv_color_t value, lv_style_selector_t selector) {
lv_obj_set_style_bg_color(obj, value, selector);
if (is_state_tracking()) {
int obj_index = index_of_obj(obj);
char buf[64];
sprintf(buf, "%d,%d,%ld", obj_index, value.full, selector);
event_occured("lv_obj_set_style_bg_color", buf);
}
}
void wlv_style_set_text_color() {
}
void wlv_style_set_text_align() {
}
void wlv_obj_align() {
}
void wlv_obj_set_size() {
}
void wlv_obj_add_style() {
}
void wlv_obj_set_style_text_align() {
}
void wlv_label_set_text() {
}
void wlv_scr_load() {
}
void wlv_scr_act() {
}
void wlv_style_set_bg_color() {
}
void wlv_style_set_bg_opa() {
}
void wlv_obj_set_width() {
}
void wlv_style_set_text_font() {
}
void wlv_label_create() {
}
void wlv_obj_del() {
}
void wlv_obj_center() {
}
void wlv_obj_remove_style() {
}
void wlv_obj_add_flag() {
}
void wlv_obj_clear_flag() {
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef WLVGL_H
#define WLVGL_H
#include "lvgl.h"
#include "state_tracking.h"
void reset_wlv_tables();
lv_obj_t* wlv_obj_create(lv_obj_t* parent);
void wlv_style_init(lv_style_t* style);
void wlv_obj_set_style_bg_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
void wlv_style_set_text_color();
void wlv_style_set_text_align();
void wlv_obj_align();
void wlv_obj_set_size();
void wlv_obj_add_style();
void wlv_obj_set_style_text_align();
void wlv_label_set_text();
void wlv_scr_load();
void wlv_scr_act();
void wlv_style_set_bg_color();
void wlv_style_set_bg_opa();
void wlv_obj_set_width();
void wlv_style_set_text_font();
void wlv_label_create();
void wlv_obj_del();
void wlv_obj_center();
void wlv_obj_remove_style();
void wlv_obj_add_flag();
void wlv_obj_clear_flag();
#endif /* WLVGL_H */
+2 -69
View File
@@ -17,76 +17,10 @@ void clean_bomb(void) {
set_module_sseg_raw(clear); set_module_sseg_raw(clear);
// clear char lcd // clear char lcd
lcd_clear();
lcd_set_cursor_vis(false); lcd_set_cursor_vis(false);
lcd_cursor_home(); lcd_clear();
}
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;
@@ -120,7 +54,6 @@ void display_game_results(void) {
lv_style_init(&game_results_style); lv_style_init(&game_results_style);
lv_style_set_text_color(&game_results_style, lv_color_white()); lv_style_set_text_color(&game_results_style, lv_color_white());
// lv_style_set_bg_color(&game_results_style, lv_color_black());
lv_style_set_text_align(&game_results_style, LV_TEXT_ALIGN_LEFT); lv_style_set_text_align(&game_results_style, LV_TEXT_ALIGN_LEFT);
overall_results_label = lv_label_create(scr); overall_results_label = lv_label_create(scr);
-9
View File
@@ -10,20 +10,11 @@
#include "drivers/speaker.h" #include "drivers/speaker.h"
#include "drivers/tft.h" #include "drivers/tft.h"
struct StarCodeHandler {
const char* code;
const char* display_text;
bool should_exit;
void (*callback)(void);
};
// TODO: add something for RNG. // TODO: add something for RNG.
// TODO: add something for colors, to make everything consistant.
/// Clears most persistant bomb state /// Clears most persistant bomb state
void clean_bomb(void); void clean_bomb(void);
void poster_child_task(void* arg); void poster_child_task(void* arg);
void do_star_codes(StarCodeHandler* star_codes, int star_codes_len);
void display_game_results(); void display_game_results();
#endif /* HELPER_H */ #endif /* HELPER_H */
+1
View File
@@ -37,6 +37,7 @@ extern "C" void app_main(void) {
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
clean_bomb(); clean_bomb();
lcd_do_splash();
step0(); step0();
// set_recording_source(stdout, false); // set_recording_source(stdout, false);
+74 -45
View File
@@ -45,137 +45,166 @@ static void replay_last() {
start_playback(); start_playback();
} }
/// Wait for "*9819"
void step0() { void step0() {
led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE); led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE);
leds_flush(); leds_flush();
StarCodeHandler star_codes[] = { SemaphoreHandle_t continue_sem = xSemaphoreCreateBinary();
if (continue_sem == nullptr) {
ESP_LOGE(TAG, "could not create semaphore");
return;
}
StarCodeEntry star_codes[] = {
{ {
.code = "*9819", .code = "9819",
.display_text = "Defusal Initiated", .display_text = "Defusal Initiated",
.should_exit = true, .delay_us = 2'000'000,
.callback = nullptr, .callback = nullptr,
.triggered_sem = continue_sem,
}, },
{ {
.code = "*59861", .code = "59862",
.display_text = "Set Up Wires", .display_text = "Set Up Wires",
.should_exit = false, .delay_us = 10'000'000,
.callback = setup_wires, .callback = setup_wires,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59862", .code = "59862",
.display_text = "Set Game Time", .display_text = "Set Game Time",
.should_exit = false, .delay_us = 2'000'000,
.callback = set_game_time, .callback = set_game_time,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59863", .code = "59863",
.display_text = "Debug Switches", .display_text = "Debug Switches",
.should_exit = false, .delay_us = 2'000'000,
.callback = debug_switches, .callback = debug_switches,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59864", .code = "59864",
.display_text = "Battery Stats", .display_text = "Battery Stats",
.should_exit = false, .delay_us = 2'000'000,
.callback = battery_stats, .callback = battery_stats,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59871", .code = "59871",
.display_text = "Try Step 1", .display_text = "Try Step 1",
.should_exit = false, .delay_us = 2'000'000,
.callback = try_step1, .callback = try_step1,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59872", .code = "59872",
.display_text = "Try Step 2", .display_text = "Try Step 2",
.should_exit = false, .delay_us = 2'000'000,
.callback = try_step2, .callback = try_step2,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59873", .code = "59873",
.display_text = "Try Step 3", .display_text = "Try Step 3",
.should_exit = false, .delay_us = 2'000'000,
.callback = try_step3, .callback = try_step3,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59874", .code = "59874",
.display_text = "Try Step 4", .display_text = "Try Step 4",
.should_exit = false, .delay_us = 2'000'000,
.callback = try_step4, .callback = try_step4,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59875", .code = "59875",
.display_text = "Try Step 5", .display_text = "Try Step 5",
.should_exit = false, .delay_us = 2'000'000,
.callback = try_step5, .callback = try_step5,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59876", .code = "59876",
.display_text = "Try Step 6", .display_text = "Try Step 6",
.should_exit = false, .delay_us = 2'000'000,
.callback = try_step6, .callback = try_step6,
.triggered_sem = nullptr,
}, },
{ {
.code = "*59881", .code = "59881",
.display_text = "Skip To Step 1", .display_text = "Skip To Step 1",
.should_exit = true, .delay_us = 2'000'000,
.callback = skip_to_step1, .callback = skip_to_step1,
.triggered_sem = continue_sem,
}, },
{ {
.code = "*59882", .code = "59882",
.display_text = "Skip To Step 2", .display_text = "Skip To Step 2",
.should_exit = true, .delay_us = 2'000'000,
.callback = skip_to_step2, .callback = skip_to_step2,
.triggered_sem = continue_sem,
}, },
{ {
.code = "*59883", .code = "59883",
.display_text = "Skip To Step 3", .display_text = "Skip To Step 3",
.should_exit = true, .delay_us = 2'000'000,
.callback = skip_to_step3, .callback = skip_to_step3,
.triggered_sem = continue_sem,
}, },
{ {
.code = "*59884", .code = "59884",
.display_text = "Skip To Step 4", .display_text = "Skip To Step 4",
.should_exit = true, .delay_us = 2'000'000,
.callback = skip_to_step4, .callback = skip_to_step4,
.triggered_sem = continue_sem,
}, },
{ {
.code = "*59885", .code = "59885",
.display_text = "Skip To Step 5", .display_text = "Skip To Step 5",
.should_exit = true, .delay_us = 2'000'000,
.callback = skip_to_step5, .callback = skip_to_step5,
.triggered_sem = continue_sem,
}, },
{ {
.code = "*59886", .code = "59886",
.display_text = "Skip To Step 6", .display_text = "Skip To Step 6",
.should_exit = true, .delay_us = 2'000'000,
.callback = skip_to_step6, .callback = skip_to_step6,
.triggered_sem = continue_sem,
}, },
{ {
.code = "*1111", .code = "1111",
.display_text = "Issue Strike", .display_text = "Issue Strike",
.should_exit = false, .delay_us = 2'000'000,
.callback = issue_strike, .callback = issue_strike,
.triggered_sem = nullptr,
}, },
{ {
.code = "*1112", .code = "1112",
.display_text = "????", .display_text = "????",
.should_exit = false, .delay_us = 2'000'000,
.callback = flashbang, .callback = flashbang,
.triggered_sem = nullptr,
}, },
{ {
.code = "*1113", .code = "1113",
.display_text = "replay_last", .display_text = "replay_last",
.should_exit = false, .delay_us = 2'000'000,
.callback = replay_last, .callback = replay_last,
.triggered_sem = continue_sem,
}, },
}; };
int len = sizeof(star_codes)/sizeof(StarCodeHandler); size_t len = sizeof(star_codes)/sizeof(star_codes[0]);
do_star_codes(star_codes, len);
}
add_star_codes(star_codes, len);
xSemaphoreTake(continue_sem, portMAX_DELAY);
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};
static char str_buf[18] = {0}; static char str_buf[18] = {0};
+2 -6
View File
@@ -1,13 +1,9 @@
#ifndef STEP_0_H #ifndef STEP_0_H
#define STEP_0_H #define STEP_0_H
#include "../drivers/bottom_half.h" #include "../drivers/all.h"
#include "../drivers/char_lcd.h"
#include "../drivers/wires.h"
#include "../drivers/power.h"
#include "setup_wires.h"
#include "../helper.h"
#include "setup_wires.h"
#include "step1.h" #include "step1.h"
#include "step2.h" #include "step2.h"
#include "step3.h" #include "step3.h"
+3 -4
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;
} }
+2 -7
View File
@@ -2,13 +2,8 @@
#define STEP_1_H #define STEP_1_H
#include <random> #include <random>
#include "../drivers/bottom_half.h" #include "../drivers/all.h"
#include "../drivers/tft.h" #include "../helper.h"
#include "../drivers/leds.h"
#include "../drivers/wires.h"
#include "../drivers/speaker.h"
#include "../drivers/game_timer.h"
#include "../drivers/char_lcd.h"
void step1(void); void step1(void);
+1 -5
View File
@@ -1,11 +1,7 @@
#ifndef STEP_2_H #ifndef STEP_2_H
#define STEP_2_H #define STEP_2_H
#include "../drivers/bottom_half.h" #include "../drivers/all.h"
#include "../drivers/wires.h"
#include "../drivers/game_timer.h"
#include "../drivers/leds.h"
#include "../drivers/speaker.h"
#include "../helper.h" #include "../helper.h"
#include <iostream> #include <iostream>
#include <random> #include <random>
+38 -21
View File
@@ -21,6 +21,8 @@ static const char* TONE_FILES[] = {
MOUNT_POINT "/high-6.wav", MOUNT_POINT "/high-6.wav",
}; };
static const size_t LCD_STRING_SOMETHING = 0;
static const size_t LCD_STRING_NOTHING = 1;
static const char* LCD_STRINGS[] = { static const char* LCD_STRINGS[] = {
"something", "something",
"nothing", "nothing",
@@ -49,13 +51,20 @@ static std::uniform_int_distribution<> lcd_rand_char_dist(0, sizeof(lcd_random_c
static std::uniform_int_distribution<> has_coconut_dist(0, 2); static std::uniform_int_distribution<> has_coconut_dist(0, 2);
static std::uniform_int_distribution<> coconut_position_dist(0, 13); static std::uniform_int_distribution<> coconut_position_dist(0, 13);
const static uint32_t NEOPIXEL_COLOR_IDX_RED = 0;
const static uint32_t NEOPIXEL_COLOR_IDX_YELLOW = 1;
const static uint32_t NEOPIXEL_COLOR_IDX_GREEN = 2;
const static uint32_t NEOPIXEL_COLOR_IDX_BLUE = 3;
const static uint32_t NEOPIXEL_COLOR_IDX_PINK = 4;
const static uint32_t NEOPIXEL_COLOR_IDX_WHITE = 5;
const static uint32_t NEOPIXEL_COLOR_IDX_OFF = 6;
static uint32_t NEOPIXEL_COLORS[7] = { static uint32_t NEOPIXEL_COLORS[7] = {
LEDColor::LED_COLOR_RED, LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_ORANGE,
LEDColor::LED_COLOR_YELLOW, LEDColor::LED_COLOR_YELLOW,
LEDColor::LED_COLOR_GREEN, LEDColor::LED_COLOR_GREEN,
LEDColor::LED_COLOR_BLUE, LEDColor::LED_COLOR_BLUE,
LEDColor::LED_COLOR_PINK, LEDColor::LED_COLOR_PINK,
LEDColor::LED_COLOR_WHITE,
LEDColor::LED_COLOR_OFF, LEDColor::LED_COLOR_OFF,
}; };
@@ -64,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_us = 2'000'000,
.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);
@@ -82,7 +99,7 @@ void step3(void) {
play_clip_wav(MOUNT_POINT "/ready.wav", true, false, 3, 0); play_clip_wav(MOUNT_POINT "/ready.wav", true, false, 3, 0);
// The high pitched tones need to be scaled down by 3 more // The high pitched tones need to be scaled down by 3 more
play_clip_wav(TONE_FILES[tone], false, false, 2 + (tone/3) * 3, 0); play_clip_wav(TONE_FILES[tone], false, false, 1 + (tone/3) * 4, 0);
bool correct = false; bool correct = false;
switch (tone % 3) { switch (tone % 3) {
@@ -221,16 +238,16 @@ static bool one_second() {
int red_led_count = 0; int red_led_count = 0;
int blue_led_count = 0; int blue_led_count = 0;
for (int i = 0; i < LED_COUNT; i++) { for (int i = 0; i < LED_COUNT; i++) {
if (indicator_led_idxs[i] == 0) { if (indicator_led_idxs[i] == NEOPIXEL_COLOR_IDX_RED) {
red_led_count++; red_led_count++;
} else if (indicator_led_idxs[i] == 4) { } else if (indicator_led_idxs[i] == NEOPIXEL_COLOR_IDX_BLUE) {
blue_led_count++; blue_led_count++;
} }
} }
uint8_t correct_switches = four_bit_flag( uint8_t correct_switches = four_bit_flag(
speaker_color == 0 || speaker_color == 1 || speaker_color == 2, speaker_color == NEOPIXEL_COLOR_IDX_RED || speaker_color == NEOPIXEL_COLOR_IDX_YELLOW || speaker_color == NEOPIXEL_COLOR_IDX_PINK,
lcd_string_idx == 0 || lcd_string_idx == 1, lcd_string_idx == LCD_STRING_SOMETHING || lcd_string_idx == LCD_STRING_NOTHING,
was_high, was_high,
!was_high !was_high
); );
@@ -280,9 +297,9 @@ static bool three_second() {
int red_led_count = 0; int red_led_count = 0;
int blue_led_count = 0; int blue_led_count = 0;
for (int i = 0; i < LED_COUNT; i++) { for (int i = 0; i < LED_COUNT; i++) {
if (indicator_led_idxs[i] == 0) { if (indicator_led_idxs[i] == NEOPIXEL_COLOR_IDX_RED) {
red_led_count++; red_led_count++;
} else if (indicator_led_idxs[i] == 4) { } else if (indicator_led_idxs[i] == NEOPIXEL_COLOR_IDX_BLUE) {
blue_led_count++; blue_led_count++;
} }
} }
@@ -345,7 +362,7 @@ static bool six_second() {
bool was_high = (tone / 3) == 1; bool was_high = (tone / 3) == 1;
bool second_switch_correct_state = (indicator_led_idxs[IndicatorLED::LED_S2] == 0) || (indicator_led_idxs[IndicatorLED::LED_S2] == 6); bool second_switch_correct_state = (indicator_led_idxs[IndicatorLED::LED_S2] == NEOPIXEL_COLOR_IDX_RED) || (indicator_led_idxs[IndicatorLED::LED_S2] == NEOPIXEL_COLOR_IDX_OFF);
second_switch_correct_state = second_switch_correct_state || was_high; second_switch_correct_state = second_switch_correct_state || was_high;
rng_leds(); rng_leds();
@@ -354,16 +371,16 @@ static bool six_second() {
int green_led_count = 0; int green_led_count = 0;
int blue_led_count = 0; int blue_led_count = 0;
for (int i = 0; i < LED_COUNT; i++) { for (int i = 0; i < LED_COUNT; i++) {
if (indicator_led_idxs[i] == 4) { if (indicator_led_idxs[i] == NEOPIXEL_COLOR_IDX_BLUE) {
blue_led_count++; blue_led_count++;
} else if (indicator_led_idxs[i] == 3) { } else if (indicator_led_idxs[i] == NEOPIXEL_COLOR_IDX_GREEN) {
green_led_count++; green_led_count++;
} }
} }
int pink_led_on_bottom_count = 0; int pink_led_on_bottom_count = 0;
for (int i = IndicatorLED::LED_RFID; i < LED_COUNT; i++) { for (int i = IndicatorLED::LED_RFID; i < LED_COUNT; i++) {
if (indicator_led_idxs[i] == 5) { if (indicator_led_idxs[i] == NEOPIXEL_COLOR_IDX_PINK) {
pink_led_on_bottom_count++; pink_led_on_bottom_count++;
} }
} }
+1 -6
View File
@@ -2,12 +2,7 @@
#define STEP_3_H #define STEP_3_H
#include <random> #include <random>
#include "../drivers/bottom_half.h" #include "../drivers/all.h"
#include "../drivers/wires.h"
#include "../drivers/speaker.h"
#include "../drivers/leds.h"
#include "../drivers/char_lcd.h"
#include "../drivers/game_timer.h"
#include "../helper.h" #include "../helper.h"
void step3(void); void step3(void);
+17 -4
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_us = 2'000'000,
.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();
+2 -6
View File
@@ -2,13 +2,9 @@
#define STEP_4_H #define STEP_4_H
#include <random> #include <random>
#include "../drivers/tft.h" #include "../drivers/all.h"
#include "../drivers/speaker.h"
#include "../drivers/bottom_half.h"
#include "../drivers/game_timer.h"
#include "../drivers/wires.h"
#include "../drivers/char_lcd.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
+26 -21
View File
@@ -179,16 +179,23 @@ bool submit_6(bool* buttons_cycling, bool button_turned_on, int led_off) {
} }
void step5(void) { void step5(void) {
StarCodeHandler star_codes[] = { SemaphoreHandle_t continue_sem = xSemaphoreCreateBinary();
{ if (continue_sem == nullptr) {
.code = "*2648", ESP_LOGE(TAG, "could not create semaphore");
.display_text = "Starting...", }
.should_exit = true,
.callback = nullptr, StarCodeEntry start_code = {
}, .code = "2648",
.display_text = "Starting...",
.delay_us = 2'000'000,
.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);
std::vector<int> all_leds; std::vector<int> all_leds;
@@ -222,15 +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);
// int puzzle = 2;
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();
@@ -265,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();
@@ -379,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();
@@ -438,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();
@@ -502,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();
@@ -558,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();
@@ -651,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();
@@ -799,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();
@@ -900,13 +905,13 @@ void step5(void) {
stop_module_timer(); stop_module_timer();
if (solved_correctly) { if (solved_correctly) {
solved_puzzles++; solved_puzzles++;
play_clip_wav(MOUNT_POINT "/correct.wav", true, false, 3, 0); play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
vTaskDelay(pdMS_TO_TICKS(500)); vTaskDelay(pdMS_TO_TICKS(500));
solved_correctly = false; solved_correctly = false;
} else { } else {
vTaskDelay(pdMS_TO_TICKS(3000)); vTaskDelay(pdMS_TO_TICKS(3000));
} }
clear_all_pressed_released(); play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
clean_bomb(); clean_bomb();
} }
} }
+1 -5
View File
@@ -1,11 +1,7 @@
#ifndef STEP_5_H #ifndef STEP_5_H
#define STEP_5_H #define STEP_5_H
#include "../drivers/bottom_half.h" #include "../drivers/all.h"
#include "../drivers/game_timer.h"
#include "../drivers/char_lcd.h"
#include "../drivers/leds.h"
#include "../drivers/wires.h"
#include "../helper.h" #include "../helper.h"
#include <random> #include <random>
#include <iostream> #include <iostream>
+2 -4
View File
@@ -2,10 +2,8 @@
#define STEP_6_H #define STEP_6_H
#include "wires_puzzle.h" #include "wires_puzzle.h"
#include "drivers/wires.h" #include "../drivers/all.h"
#include "drivers/bottom_half.h" #include "../helper.h"
#include "drivers/sd.h"
#include "drivers/speaker.h"
void step6(void); void step6(void);
+8
View File
@@ -0,0 +1,8 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,0x6000,,
phy_init,data,phy,0xf000,0x1000,,
ota,data,ota,0x10000,0x2000,,
factory,app,factory,0x20000,2M,,
ota0,app,ota_0,0x220000,2M,,
ota1,app,ota_1,0x420000,2M,,
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs,data,nvs,0x9000,0x6000,,
4 phy_init,data,phy,0xf000,0x1000,,
5 ota,data,ota,0x10000,0x2000,,
6 factory,app,factory,0x20000,2M,,
7 ota0,app,ota_0,0x220000,2M,,
8 ota1,app,ota_1,0x420000,2M,,
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-550
View File
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
-3366
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -527,11 +527,11 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
# Partition Table # Partition Table
# #
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP is not set
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set
# CONFIG_PARTITION_TABLE_TWO_OTA is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set
# CONFIG_PARTITION_TABLE_CUSTOM is not set CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp_large.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_MD5=y CONFIG_PARTITION_TABLE_MD5=y
# end of Partition Table # end of Partition Table