Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d03a208272 | ||
|
|
202b926eb7 | ||
|
|
8bddceca66 | ||
|
|
cfc307ee72 |
@@ -4,18 +4,20 @@ set(SOURCES
|
|||||||
"TM1640/TM1640.cpp"
|
"TM1640/TM1640.cpp"
|
||||||
"SparkFunBQ27441/SparkFunBQ27441.cpp"
|
"SparkFunBQ27441/SparkFunBQ27441.cpp"
|
||||||
"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_info.cpp"
|
||||||
"game_timer.cpp"
|
"game_timer.cpp"
|
||||||
"i2c_lcd_pcf8574.c"
|
"i2c_lcd_pcf8574.c"
|
||||||
"i2c.cpp"
|
"i2c.cpp"
|
||||||
|
"inputs.cpp"
|
||||||
"leds.cpp"
|
"leds.cpp"
|
||||||
|
"perh.cpp"
|
||||||
"power.cpp"
|
"power.cpp"
|
||||||
"sd.cpp"
|
"sd.cpp"
|
||||||
"speaker.cpp"
|
"speaker.cpp"
|
||||||
"sseg.cpp"
|
"sseg.cpp"
|
||||||
"star_code.cpp"
|
"starcode.cpp"
|
||||||
"state_tracking.cpp"
|
"state_tracking.cpp"
|
||||||
"tft.cpp"
|
"tft.cpp"
|
||||||
"wires.cpp"
|
"wires.cpp"
|
||||||
|
|||||||
@@ -711,9 +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);
|
xSemaphoreTake(main_i2c_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);
|
xSemaphoreGive(main_i2c_mutex);
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
#include "speaker.h"
|
#include "speaker.h"
|
||||||
#include "sseg.h"
|
#include "sseg.h"
|
||||||
#include "star_code.h"
|
#include "starcode.h"
|
||||||
#include "state_tracking.h"
|
#include "state_tracking.h"
|
||||||
#include "tft.h"
|
#include "tft.h"
|
||||||
#include "wires.h"
|
#include "wires.h"
|
||||||
|
|||||||
@@ -1,7 +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"
|
#include "starcode.h"
|
||||||
|
|
||||||
static const char *TAG = "bottom_half";
|
static const char *TAG = "bottom_half";
|
||||||
|
|
||||||
@@ -46,8 +46,14 @@ static bool replay_handler(const char* event, char* arg) {
|
|||||||
void init_bottom_half() {
|
void init_bottom_half() {
|
||||||
ESP_LOGI(TAG, "Initializing bottom half...");
|
ESP_LOGI(TAG, "Initializing bottom half...");
|
||||||
|
|
||||||
ESP_ERROR_CHECK(gpio_set_direction(BOTTOM_PIN_INTERUPT, GPIO_MODE_INPUT));
|
gpio_config_t int_conf = {
|
||||||
ESP_ERROR_CHECK(gpio_set_pull_mode(BOTTOM_PIN_INTERUPT, GPIO_PULLUP_ONLY));
|
.pin_bit_mask = 1ULL << BOTTOM_PIN_INTERUPT,
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||||
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(gpio_config(&int_conf));
|
||||||
|
|
||||||
// TODO: do interupt stuff.
|
// TODO: do interupt stuff.
|
||||||
// ESP_ERROR_CHECK(gpio_intr_enable(BOTTOM_PIN_INTERUPT));
|
// ESP_ERROR_CHECK(gpio_intr_enable(BOTTOM_PIN_INTERUPT));
|
||||||
|
|||||||
+13
-13
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#define BOTTOM_I2C_NUM I2C_NUM_0
|
#define BOTTOM_I2C_NUM I2C_NUM_0
|
||||||
#define BOTTOM_I2C_ADDR 126
|
#define BOTTOM_I2C_ADDR 126
|
||||||
#define BOTTOM_PIN_INTERUPT GPIO_NUM_0
|
#define BOTTOM_PIN_INTERUPT GPIO_NUM_13
|
||||||
|
|
||||||
#define DELTA_BIT_KP 0
|
#define DELTA_BIT_KP 0
|
||||||
#define DELTA_BIT_BUTTON_SWITCH 1
|
#define DELTA_BIT_BUTTON_SWITCH 1
|
||||||
@@ -14,22 +14,22 @@
|
|||||||
|
|
||||||
/// @brief An enum for the possible keypad buttons.
|
/// @brief An enum for the possible keypad buttons.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
k1 = 0,
|
kd = 0,
|
||||||
k4 = 1,
|
pound = 1,
|
||||||
k7 = 2,
|
k0 = 2,
|
||||||
star = 3,
|
star = 3,
|
||||||
k2 = 4,
|
kc = 4,
|
||||||
k5 = 5,
|
k9 = 5,
|
||||||
k8 = 6,
|
k8 = 6,
|
||||||
k0 = 7,
|
k7 = 7,
|
||||||
k3 = 8,
|
kb = 8,
|
||||||
k6 = 9,
|
k6 = 9,
|
||||||
k9 = 10,
|
k5 = 10,
|
||||||
pound = 11,
|
k4 = 11,
|
||||||
ka = 12,
|
ka = 12,
|
||||||
kb = 13,
|
k3 = 13,
|
||||||
kc = 14,
|
k2 = 14,
|
||||||
kd = 15,
|
k1 = 15,
|
||||||
} KeypadKey;
|
} KeypadKey;
|
||||||
|
|
||||||
/// @brief An enum for the possible buttons.
|
/// @brief An enum for the possible buttons.
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "state_tracking.h"
|
#include "state_tracking.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
#include "starcode.h"
|
||||||
|
#include "game_info.h"
|
||||||
|
|
||||||
i2c_lcd_pcf8574_handle_t lcd;
|
i2c_lcd_pcf8574_handle_t lcd;
|
||||||
|
|
||||||
|
|||||||
@@ -66,15 +66,6 @@ bool lcd_header_enabled();
|
|||||||
/// @brief Prints the header in the LCD.
|
/// @brief Prints the header in the LCD.
|
||||||
void lcd_print_header();
|
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.
|
/// @brief Prints the splash screen for the BLK_BOX.
|
||||||
void lcd_do_splash();
|
void lcd_do_splash();
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
#include "game_info.h"
|
#include "game_info.h"
|
||||||
|
#include "starcode.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "char_lcd.h"
|
#include "char_lcd.h"
|
||||||
|
|
||||||
// static char game_state[GAME_STATE_MAX_LEN+1] = " ";
|
static char game_state[GAME_STATE_MAX_LEN+2] = " MENU ";
|
||||||
static char game_state[GAME_STATE_MAX_LEN+1] = "MENU ";
|
|
||||||
|
|
||||||
void set_game_state(char* new_state) {
|
void set_game_state(const char* new_state) {
|
||||||
snprintf(game_state, sizeof(game_state), "%-5s", new_state);
|
snprintf(game_state, sizeof(game_state), " %-5s", new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_game_state() {
|
void reset_game_state() {
|
||||||
for (int i = 0; i < GAME_STATE_MAX_LEN; i++) {
|
set_game_state("");
|
||||||
game_state[i] = '\0';
|
|
||||||
}
|
|
||||||
game_state[GAME_STATE_MAX_LEN] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_print_header_step() {
|
void lcd_print_header_step() {
|
||||||
if (!lcd_header_enabled()) return;
|
if (!lcd_header_enabled()) return;
|
||||||
|
if (lcd_starcode_displaying_result()) return;
|
||||||
|
|
||||||
lcd_print(10, 0, game_state);
|
lcd_print(10, 0, game_state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
/// @brief Sets the game state, used for the header.
|
/// @brief Sets the game state, used for the header.
|
||||||
///
|
///
|
||||||
/// Must be <= 5 characters
|
/// Must be <= 5 characters
|
||||||
void set_game_state(char* new_state);
|
void set_game_state(const char* new_state);
|
||||||
|
|
||||||
/// @brief Resets the game state to be blank.
|
/// @brief Resets the game state to be blank.
|
||||||
void reset_game_state();
|
void reset_game_state();
|
||||||
|
|
||||||
/// @brief Prints the game state section of the header to the char_lcd. (row 0, columns 10-14)
|
/// @brief Prints the game state section of the header to the char_lcd. (row 0, columns 11-15)
|
||||||
void lcd_print_header_step();
|
void lcd_print_header_step();
|
||||||
|
|
||||||
#endif /* GAME_INFO_H */
|
#endif /* GAME_INFO_H */
|
||||||
@@ -5,30 +5,31 @@
|
|||||||
|
|
||||||
static const char *TAG = "i2c";
|
static const char *TAG = "i2c";
|
||||||
|
|
||||||
SemaphoreHandle_t i2c0_mutex;
|
SemaphoreHandle_t main_i2c_mutex;
|
||||||
|
|
||||||
void init_i2c() {
|
void init_i2c() {
|
||||||
ESP_LOGI(TAG, "Initializing i2c...");
|
ESP_LOGI(TAG, "Initializing i2c...");
|
||||||
|
|
||||||
i2c_config_t conf = {
|
i2c_config_t conf = {
|
||||||
.mode = I2C_MODE_MASTER,
|
.mode = I2C_MODE_MASTER,
|
||||||
.sda_io_num = GPIO_NUM_5,
|
.sda_io_num = PIN_I2C_SDA,
|
||||||
.scl_io_num = GPIO_NUM_6,
|
.scl_io_num = PIN_I2C_SCL,
|
||||||
.sda_pullup_en = GPIO_PULLUP_DISABLE,
|
.sda_pullup_en = GPIO_PULLUP_DISABLE,
|
||||||
.scl_pullup_en = GPIO_PULLUP_DISABLE,
|
.scl_pullup_en = GPIO_PULLUP_DISABLE,
|
||||||
// .sda_pullup_en = GPIO_PULLUP_ENABLE,
|
// .sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
// .scl_pullup_en = GPIO_PULLUP_ENABLE,
|
// .scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
.master = {
|
.master = {
|
||||||
|
// TODO: 400k?
|
||||||
.clk_speed = 100*1000,
|
.clk_speed = 100*1000,
|
||||||
},
|
},
|
||||||
.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL
|
.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf));
|
ESP_ERROR_CHECK(i2c_param_config(MAIN_I2C_BUS_NUM, &conf));
|
||||||
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0));
|
ESP_ERROR_CHECK(i2c_driver_install(MAIN_I2C_BUS_NUM, conf.mode, 0, 0, 0));
|
||||||
|
|
||||||
i2c0_mutex = xSemaphoreCreateMutex();
|
main_i2c_mutex = xSemaphoreCreateMutex();
|
||||||
assert(i2c0_mutex != NULL);
|
assert(main_i2c_mutex != NULL);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "i2c initialized!");
|
ESP_LOGI(TAG, "i2c initialized!");
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -4,8 +4,13 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
#define MAIN_I2C_BUS_NUM I2C_NUM_0
|
||||||
|
|
||||||
|
#define PIN_I2C_SDA GPIO_NUM_7
|
||||||
|
#define PIN_I2C_SCL GPIO_NUM_15
|
||||||
|
|
||||||
/// The mutex for accessing `I2C_NUM_0`.
|
/// The mutex for accessing `I2C_NUM_0`.
|
||||||
extern SemaphoreHandle_t i2c0_mutex;
|
extern SemaphoreHandle_t main_i2c_mutex;
|
||||||
|
|
||||||
/// @brief Initializes `I2C_NUM_0`.
|
/// @brief Initializes `I2C_NUM_0`.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -59,7 +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);
|
xSemaphoreTake(main_i2c_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
|
||||||
@@ -97,7 +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);
|
xSemaphoreGive(main_i2c_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);
|
||||||
@@ -298,7 +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);
|
xSemaphoreTake(main_i2c_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);
|
||||||
@@ -307,7 +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);
|
xSemaphoreGive(main_i2c_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));
|
||||||
@@ -346,7 +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);
|
xSemaphoreTake(main_i2c_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);
|
||||||
@@ -354,7 +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);
|
xSemaphoreGive(main_i2c_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));
|
||||||
|
|||||||
@@ -0,0 +1,486 @@
|
|||||||
|
#include "blk_box_drivers/inputs.hpp"
|
||||||
|
|
||||||
|
#include "bottom_half.h"
|
||||||
|
#include "pins.h"
|
||||||
|
#include "driver/i2c.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
static const char *TAG = "INPUTS";
|
||||||
|
|
||||||
|
static TaskHandle_t expander_task_handle = NULL;
|
||||||
|
|
||||||
|
static i2c_master_dev_handle_t expander_i2c_dev_handle;
|
||||||
|
|
||||||
|
const static uint8_t REG_WHOAMI = 0x01;
|
||||||
|
const static uint8_t REG_SW_VERSION = 0x02;
|
||||||
|
const static uint8_t REG_EVENT_QUEUE_POP = 0x10;
|
||||||
|
const static uint8_t REG_EVENT_QUEUE_LEN = 0x11;
|
||||||
|
const static uint8_t REG_STATE_BUTTONS = 0x20;
|
||||||
|
const static uint8_t REG_STATE_SWITCHES = 0x21;
|
||||||
|
const static uint8_t REG_STATE_KEYPAD = 0x22;
|
||||||
|
const static uint8_t REG_STATE_TOUCH = 0x23;
|
||||||
|
const static uint8_t REG_STATE_RFID = 0x24;
|
||||||
|
const static uint8_t REG_STATE_HALL = 0x25;
|
||||||
|
const static uint8_t REG_STATE_CLOSE = 0x26;
|
||||||
|
const static uint8_t REG_RESET = 0x30;
|
||||||
|
const static uint8_t REG_HALL_SENSITIVITY = 0x31;
|
||||||
|
const static uint8_t REG_CLOSE_SENSITIVITY = 0x32;
|
||||||
|
const static uint8_t REG_SWITCH_TOUCH_EVENT = 0x33;
|
||||||
|
|
||||||
|
/// The global data for the expander peripheral.
|
||||||
|
class ExpanderPeripheral {
|
||||||
|
// TODO: change these to private
|
||||||
|
// or even make this class hidden
|
||||||
|
public:
|
||||||
|
SemaphoreHandle_t state_mutex;
|
||||||
|
InputsState state;
|
||||||
|
|
||||||
|
// channels
|
||||||
|
QueueHandle_t button_press_events;
|
||||||
|
QueueHandle_t button_release_events;
|
||||||
|
QueueHandle_t switch_flip_events;
|
||||||
|
QueueHandle_t switch_touch_events;
|
||||||
|
QueueHandle_t touch_events;
|
||||||
|
QueueHandle_t keypad_press_events;
|
||||||
|
QueueHandle_t keypad_release_events;
|
||||||
|
};
|
||||||
|
|
||||||
|
ExpanderPeripheral expander_peripheral_singleton;
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
static void get_events();
|
||||||
|
static void handle_event(uint8_t event);
|
||||||
|
static void handle_button_switch_event(uint8_t event);
|
||||||
|
static void handle_keypad_event(uint8_t event);
|
||||||
|
static void handle_touch_event(uint8_t event);
|
||||||
|
static void handle_rfid_event(uint8_t event);
|
||||||
|
static void handle_close_hal_event(uint8_t event);
|
||||||
|
static void expander_task(void *arg);
|
||||||
|
|
||||||
|
// ISR handler
|
||||||
|
static void IRAM_ATTR expander_isr_handler(void *arg) {
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
|
||||||
|
if (expander_task_handle != NULL) {
|
||||||
|
vTaskNotifyGiveFromISR(expander_task_handle, &xHigherPriorityTaskWoken);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||||
|
portYIELD_FROM_ISR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_expander() {
|
||||||
|
ESP_LOGI(TAG, "Initializing expander...");
|
||||||
|
|
||||||
|
i2c_device_config_t dev_config = {
|
||||||
|
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||||
|
.device_address = EXPANDER_I2C_ADDR,
|
||||||
|
.scl_speed_hz = EXPANDER_I2C_SPEED,
|
||||||
|
.scl_wait_us = 0, // default
|
||||||
|
.flags = {
|
||||||
|
.disable_ack_check = 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// setup interrupt on BOTTOM_PIN_INTERUPT
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.pin_bit_mask = (1ULL << BOTTOM_PIN_INTERUPT),
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||||
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
|
.intr_type = GPIO_INTR_NEGEDGE
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||||
|
|
||||||
|
// Install ISR service (only call once in your program)
|
||||||
|
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
||||||
|
|
||||||
|
// Attach the ISR to the expander pin
|
||||||
|
ESP_ERROR_CHECK(gpio_isr_handler_add(BOTTOM_PIN_INTERUPT, expander_isr_handler, NULL));
|
||||||
|
|
||||||
|
// verify the expander connection status by reading the WHOAMI register
|
||||||
|
uint8_t read_buf[2] = {0};
|
||||||
|
|
||||||
|
i2c_master_write_read_device(I2C_NUM_0, BOTTOM_I2C_ADDR, ®_WHOAMI, 1, read_buf, 1, 1000);
|
||||||
|
|
||||||
|
if (read_buf[0] != EXPANDER_WHOAMI_VALUE) {
|
||||||
|
ESP_LOGE(TAG, "WHOAMI mismatch, expected 0x%02X, got 0x%02X", EXPANDER_WHOAMI_VALUE, read_buf[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Expander WHOAMI check passed");
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(i2c_master_transmit_receive(expander_i2c_dev_handle, ®_SW_VERSION, 1, read_buf, 2, EXPANDER_TIMEOUT_MS));
|
||||||
|
|
||||||
|
// init the peripheral struct
|
||||||
|
expander_peripheral_singleton.state_mutex = xSemaphoreCreateMutex();
|
||||||
|
expander_peripheral_singleton.button_press_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(Button));
|
||||||
|
expander_peripheral_singleton.button_release_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(Button));
|
||||||
|
expander_peripheral_singleton.switch_flip_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(SwitchFlip));
|
||||||
|
expander_peripheral_singleton.switch_touch_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(SwitchTouch));
|
||||||
|
expander_peripheral_singleton.touch_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(TouchedReleased));
|
||||||
|
expander_peripheral_singleton.keypad_press_events= xQueueCreate(EXPANDER_KEYPAD_QUEUE_SIZE, sizeof(KeypadKey));
|
||||||
|
expander_peripheral_singleton.keypad_release_events= xQueueCreate(EXPANDER_KEYPAD_QUEUE_SIZE, sizeof(KeypadKey));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Expander initialized! SW version: v%d.%d", read_buf[0], read_buf[1]);
|
||||||
|
|
||||||
|
// Create the expander background worker task
|
||||||
|
BaseType_t task_created = xTaskCreate(
|
||||||
|
expander_task,
|
||||||
|
"expander_task",
|
||||||
|
4096,
|
||||||
|
NULL,
|
||||||
|
tskIDLE_PRIORITY + 1,
|
||||||
|
&expander_task_handle
|
||||||
|
);
|
||||||
|
|
||||||
|
if (task_created != pdPASS) {
|
||||||
|
ESP_LOGE(TAG, "Failed to create expander task");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void expander_task(void *arg) {
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
get_events();
|
||||||
|
|
||||||
|
// Wait for interrupt notification (signal is sent when INT falls)
|
||||||
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_events() {
|
||||||
|
uint8_t recv;
|
||||||
|
while (gpio_get_level(PIN_EXPANDER_INT) == 0) {
|
||||||
|
ESP_ERROR_CHECK(i2c_master_transmit_receive(expander_i2c_dev_handle, ®_EVENT_QUEUE_POP, 1, &recv, 1, EXPANDER_TIMEOUT_MS));
|
||||||
|
handle_event(recv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_event(uint8_t event) {
|
||||||
|
const uint8_t BUTTON_SWITCH = 0b000;
|
||||||
|
const uint8_t KEYPAD = 0b001;
|
||||||
|
const uint8_t TOUCH = 0b010;
|
||||||
|
const uint8_t RFID = 0b011;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Expander event: 0b%08b (0x%02X)", event, event);
|
||||||
|
|
||||||
|
if (event == 0) {
|
||||||
|
ESP_LOGE(TAG, "We read from event queue while it was empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t type_bits = event >> 5;
|
||||||
|
|
||||||
|
switch (type_bits) {
|
||||||
|
case BUTTON_SWITCH:
|
||||||
|
handle_button_switch_event(event);
|
||||||
|
break;
|
||||||
|
case KEYPAD:
|
||||||
|
handle_keypad_event(event);
|
||||||
|
break;
|
||||||
|
case TOUCH:
|
||||||
|
handle_touch_event(event);
|
||||||
|
break;
|
||||||
|
case RFID:
|
||||||
|
handle_rfid_event(event);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handle_close_hal_event(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_button_switch_event(uint8_t event) {
|
||||||
|
const uint8_t PRESSED_NOT_RELEASED_BIT = 0b10000;
|
||||||
|
const uint8_t SWITCH_NOT_BUTTON_BIT = 0b01000;
|
||||||
|
const uint8_t SWITCH_UP_NOT_DOWN_BIT = 0b00100;
|
||||||
|
const uint8_t NUMBER_MASK = 0b00011;
|
||||||
|
|
||||||
|
bool pressed = (event & PRESSED_NOT_RELEASED_BIT) != 0;
|
||||||
|
uint8_t number = event & NUMBER_MASK;
|
||||||
|
|
||||||
|
if ((event & SWITCH_NOT_BUTTON_BIT) != 0) {
|
||||||
|
// For now, we support two position switches by only looking at the switch up events
|
||||||
|
bool switch_up = (event & SWITCH_UP_NOT_DOWN_BIT) != 0;
|
||||||
|
if (!switch_up) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Switch sw = static_cast<Switch>(number);
|
||||||
|
SwitchFlip sw_flip = SwitchFlip(sw, pressed);
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.switch_flip_events, &sw_flip, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
if (pressed) {
|
||||||
|
// set
|
||||||
|
expander_peripheral_singleton.state.switch_state |= 1 << number;
|
||||||
|
} else {
|
||||||
|
// clear
|
||||||
|
expander_peripheral_singleton.state.switch_state &= ~(1 << number);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
} else {
|
||||||
|
// button
|
||||||
|
Button button = static_cast<Button>(number);
|
||||||
|
if (pressed) {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.button_press_events, &button, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.button_state |= 1 << number;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
} else {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.button_release_events, &button, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.button_state &= ~(1 << number);
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_keypad_event(uint8_t event) {
|
||||||
|
const uint8_t PRESSED_NOT_RELEASED_BIT = 0b10000;
|
||||||
|
const uint8_t KEY_MASK = 0b1111;
|
||||||
|
|
||||||
|
bool pressed = (event & PRESSED_NOT_RELEASED_BIT) != 0;
|
||||||
|
uint8_t number = event & KEY_MASK;
|
||||||
|
KeypadKey key = static_cast<KeypadKey>(number);
|
||||||
|
|
||||||
|
// starcode system gets first dibs
|
||||||
|
// TODO: do starcode inbetweener
|
||||||
|
// if starcode_handle_keypad(key, pressed).await {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (pressed) {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.keypad_press_events, &key, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.keypad_state |= 1 << number;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
} else {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.keypad_release_events, &key, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.keypad_state &= ~(1 << number);
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_touch_event(uint8_t event) {
|
||||||
|
const uint8_t TOUCHED_NOT_UNTOUCHED_BIT = 0b10000;
|
||||||
|
const uint8_t SENSOR_MASK = 0b0111;
|
||||||
|
const uint8_t FINGERPRINT_BIT = 0b0100;
|
||||||
|
|
||||||
|
bool touched = (event & TOUCHED_NOT_UNTOUCHED_BIT) != 0;
|
||||||
|
uint8_t sensor = event & SENSOR_MASK;
|
||||||
|
|
||||||
|
if ((sensor & FINGERPRINT_BIT) != 0) {
|
||||||
|
TouchedReleased touch_state = static_cast<TouchedReleased>(touched);
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.touch_events, &touch_state, 0);
|
||||||
|
} else {
|
||||||
|
Switch sw = static_cast<Switch>(sensor);
|
||||||
|
SwitchTouch sw_touch = SwitchTouch(sw, touched);
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.switch_touch_events, &sw_touch, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
if (touched) {
|
||||||
|
expander_peripheral_singleton.state.touch_state |= 1 << sensor;
|
||||||
|
} else {
|
||||||
|
expander_peripheral_singleton.state.touch_state &= ~(1 << sensor);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_rfid_event(uint8_t event) {
|
||||||
|
// TODO: impl
|
||||||
|
(void)event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_close_hal_event(uint8_t event) {
|
||||||
|
// TODO: impl
|
||||||
|
(void)event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// InputsController implementations
|
||||||
|
|
||||||
|
/// Clears all events waiting in the queues.
|
||||||
|
void InputsController::clear_all_events() {
|
||||||
|
xQueueReset(expander_peripheral_singleton.button_press_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.button_release_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.switch_flip_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.switch_touch_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.touch_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.keypad_press_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.keypad_release_events);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputsState InputsController::get_input_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
InputsState state_copy = expander_peripheral_singleton.state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return state_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a button press event waiting.
|
||||||
|
bool InputsController::has_button_press() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.button_press_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button press event (if any).
|
||||||
|
std::optional<Button> InputsController::get_button_press() {
|
||||||
|
Button b;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.button_press_events, &b, 0) == pdTRUE) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button press event, waiting if neccesary.
|
||||||
|
Button InputsController::wait_button_press() {
|
||||||
|
Button b;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.button_press_events, &b, portMAX_DELAY);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the buttons.
|
||||||
|
uint8_t InputsController::button_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint8_t value = expander_peripheral_singleton.state.button_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a button release event waiting.
|
||||||
|
bool InputsController::has_button_release() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.button_release_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button release event (if any).
|
||||||
|
std::optional<Button> InputsController::get_button_release() {
|
||||||
|
Button b;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.button_release_events, &b, 0) == pdTRUE) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button release event, waiting if neccesary.
|
||||||
|
Button InputsController::wait_button_release() {
|
||||||
|
Button b;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.button_release_events, &b, portMAX_DELAY);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a switch flip event waiting.
|
||||||
|
bool InputsController::has_switch_flip() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.switch_flip_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch flip event (if any).
|
||||||
|
std::optional<SwitchFlip> InputsController::get_switch_flip() {
|
||||||
|
SwitchFlip s;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.switch_flip_events, &s, 0) == pdTRUE) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch flip event, waiting if neccesary.
|
||||||
|
SwitchFlip InputsController::wait_switch_flip() {
|
||||||
|
SwitchFlip s;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.switch_flip_events, &s, portMAX_DELAY);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the switches.
|
||||||
|
uint8_t InputsController::switch_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint8_t value = expander_peripheral_singleton.state.switch_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a switch touch event waiting.
|
||||||
|
bool InputsController::has_switch_touch() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.switch_touch_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch touch event (if any).
|
||||||
|
std::optional<SwitchTouch> InputsController::get_switch_touch() {
|
||||||
|
SwitchTouch s;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.switch_touch_events, &s, 0) == pdTRUE) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch touch event, waiting if neccesary.
|
||||||
|
SwitchTouch InputsController::wait_switch_touch() {
|
||||||
|
SwitchTouch s;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.switch_touch_events, &s, portMAX_DELAY);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the touch sensors.
|
||||||
|
uint8_t InputsController::switch_touch_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint8_t value = expander_peripheral_singleton.state.touch_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a keypad press event waiting.
|
||||||
|
bool InputsController::has_keypad_press() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.keypad_press_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad press event (if any).
|
||||||
|
std::optional<KeypadKey> InputsController::get_keypad_press() {
|
||||||
|
KeypadKey k;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.keypad_press_events, &k, 0) == pdTRUE) {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad press event, waiting if neccesary.
|
||||||
|
KeypadKey InputsController::wait_keypad_press() {
|
||||||
|
KeypadKey k;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.keypad_press_events, &k, portMAX_DELAY);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a keypad release event waiting.
|
||||||
|
bool InputsController::has_keypad_release() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.keypad_release_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad release event (if any).
|
||||||
|
std::optional<KeypadKey> InputsController::get_keypad_release() {
|
||||||
|
KeypadKey k;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.keypad_release_events, &k, 0) == pdTRUE) {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad release event, waiting if neccesary.
|
||||||
|
KeypadKey InputsController::wait_keypad_release() {
|
||||||
|
KeypadKey k;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.keypad_release_events, &k, portMAX_DELAY);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the keypad.
|
||||||
|
uint16_t InputsController::keypad_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint16_t value = expander_peripheral_singleton.state.keypad_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define LED_COUNT 21
|
#define LED_COUNT 21
|
||||||
#define NEOPIXEL_PIN GPIO_NUM_7
|
#define NEOPIXEL_PIN GPIO_NUM_0
|
||||||
// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
|
// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
|
||||||
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000)
|
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#include "perh.h"
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef PERH_H
|
||||||
|
#define PERH_H
|
||||||
|
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
#define PIN_PERH0 GPIO_NUM_6
|
||||||
|
#define PIN_PERH1 GPIO_NUM_5
|
||||||
|
#define PIN_PERH2 GPIO_NUM_4
|
||||||
|
#define PIN_PERH3 GPIO_NUM_2
|
||||||
|
#define PIN_PERH4 GPIO_NUM_1
|
||||||
|
|
||||||
|
#endif /* PERH_H */
|
||||||
+13
-8
@@ -1,5 +1,6 @@
|
|||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "char_lcd.h"
|
#include "char_lcd.h"
|
||||||
|
#include "starcode.h"
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
|
|
||||||
static const char* TAG = "power";
|
static const char* TAG = "power";
|
||||||
@@ -56,17 +57,21 @@ uint16_t get_bat_voltage() {
|
|||||||
|
|
||||||
void lcd_print_header_bat() {
|
void lcd_print_header_bat() {
|
||||||
if (!lcd_header_enabled()) return;
|
if (!lcd_header_enabled()) return;
|
||||||
|
if (lcd_starcode_displaying_result()) return;
|
||||||
|
|
||||||
uint8_t soc = lipo.soc();
|
uint8_t soc = lipo.soc();
|
||||||
char buf[5];
|
uint8_t current = lipo.current();
|
||||||
if (soc < 5) {
|
char buf[6];
|
||||||
sprintf(buf, "LOW ");
|
if (soc < 5 && current <= 0) {
|
||||||
|
snprintf(buf, sizeof(buf), " LOW");
|
||||||
|
} else if (soc == 100) {
|
||||||
|
snprintf(buf, sizeof(buf), " 100");
|
||||||
} else {
|
} else {
|
||||||
snprintf(buf, sizeof(buf), "%3d%%", soc);
|
if (current > 0) {
|
||||||
}
|
snprintf(buf, sizeof(buf), " %2d+", soc);
|
||||||
|
} else {
|
||||||
if (lipo.current() > 0) {
|
snprintf(buf, sizeof(buf), " %2d%%", soc);
|
||||||
buf[3] = '+';
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_print(16, 0, buf);
|
lcd_print(16, 0, buf);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ void init_power_board();
|
|||||||
/// @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)
|
/// @brief Prints the battery section of the header to the char_lcd. (row 0, columns 17-19)
|
||||||
void lcd_print_header_bat();
|
void lcd_print_header_bat();
|
||||||
|
|
||||||
#endif /* POWER_H */
|
#endif /* POWER_H */
|
||||||
|
|||||||
+6
-6
@@ -12,12 +12,12 @@
|
|||||||
|
|
||||||
extern sdmmc_card_t *card;
|
extern sdmmc_card_t *card;
|
||||||
|
|
||||||
#define SD_PIN_CLK GPIO_NUM_48
|
#define SD_PIN_CLK GPIO_NUM_39
|
||||||
#define SD_PIN_CMD GPIO_NUM_45
|
#define SD_PIN_CMD GPIO_NUM_40
|
||||||
#define SD_PIN_D0 GPIO_NUM_47
|
#define SD_PIN_D0 GPIO_NUM_38
|
||||||
#define SD_PIN_D1 GPIO_NUM_21
|
#define SD_PIN_D1 GPIO_NUM_45
|
||||||
#define SD_PIN_D2 GPIO_NUM_39
|
#define SD_PIN_D2 GPIO_NUM_42
|
||||||
#define SD_PIN_D3 GPIO_NUM_38
|
#define SD_PIN_D3 GPIO_NUM_41
|
||||||
|
|
||||||
/// @brief Initializes the SD card
|
/// @brief Initializes the SD card
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
|
|
||||||
#define SPEAKER_PIN_BCLK GPIO_NUM_46
|
#define SPEAKER_PIN_BCLK GPIO_NUM_11
|
||||||
#define SPEAKER_PIN_WS GPIO_NUM_9
|
#define SPEAKER_PIN_WS GPIO_NUM_12
|
||||||
#define SPEAKER_PIN_DOUT GPIO_NUM_3
|
#define SPEAKER_PIN_DOUT GPIO_NUM_3
|
||||||
#define SAMPLE_RATE 44100
|
#define SAMPLE_RATE 44100
|
||||||
// The maximum number of clips that can be queued at one time.
|
// The maximum number of clips that can be queued at one time.
|
||||||
|
|||||||
+2
-2
@@ -4,8 +4,8 @@
|
|||||||
#include "TM1640/TM1640.h"
|
#include "TM1640/TM1640.h"
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
|
|
||||||
#define SSEG_PIN_DATA GPIO_NUM_10
|
#define SSEG_PIN_DATA GPIO_NUM_46
|
||||||
#define SSEG_PIN_CLK GPIO_NUM_11
|
#define SSEG_PIN_CLK GPIO_NUM_48
|
||||||
|
|
||||||
extern TM1640* sseg;
|
extern TM1640* sseg;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "star_code.h"
|
#include "starcode.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -17,11 +17,13 @@ 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 const char EMPTY_STAR_CODE_HEADER[] = " ";
|
static const char EMPTY_STAR_CODE_HEADER[] = " ";
|
||||||
|
|
||||||
esp_timer_handle_t starcode_delay_timer;
|
esp_timer_handle_t starcode_delay_timer;
|
||||||
static volatile bool processing_starcode;
|
/// @brief `true` if we are delaying for a starcode
|
||||||
|
static volatile bool delaying_for_starcode;
|
||||||
static volatile StarCodeEntry* current_starcode = nullptr;
|
static volatile StarCodeEntry* current_starcode = nullptr;
|
||||||
|
/// @brief `true` when we are handling user input for a starcode
|
||||||
static volatile bool doing_starcode = false;
|
static volatile bool doing_starcode = false;
|
||||||
static uint16_t starcode_waiting_on_release;
|
static uint16_t starcode_waiting_on_release;
|
||||||
static char current[STARCODE_MAX_LEN + 1];
|
static char current[STARCODE_MAX_LEN + 1];
|
||||||
@@ -30,7 +32,7 @@ static size_t current_idx;
|
|||||||
static void starcode_trigger_cb(void* arg) {
|
static void starcode_trigger_cb(void* arg) {
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
processing_starcode = false;
|
delaying_for_starcode = false;
|
||||||
|
|
||||||
if (current_starcode != nullptr) {
|
if (current_starcode != nullptr) {
|
||||||
if (current_starcode->triggered_sem != nullptr)
|
if (current_starcode->triggered_sem != nullptr)
|
||||||
@@ -42,12 +44,12 @@ static void starcode_trigger_cb(void* arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: rename star code everywhere to starcode
|
// TODO: rename star code everywhere to starcode
|
||||||
lcd_print_header_star_code();
|
lcd_print_header();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void star_code_handle_keypad(uint16_t* just_pressed, uint16_t* just_released) {
|
void star_code_handle_keypad(uint16_t* just_pressed, uint16_t* just_released) {
|
||||||
if ((!processing_starcode) && handling_new_starcodes && (*just_pressed & (1 << KeypadKey::star))) {
|
if ((!delaying_for_starcode) && handling_new_starcodes && (*just_pressed & (1 << KeypadKey::star))) {
|
||||||
current_idx = 0;
|
current_idx = 0;
|
||||||
current[current_idx] = '\0';
|
current[current_idx] = '\0';
|
||||||
doing_starcode = true;
|
doing_starcode = true;
|
||||||
@@ -125,10 +127,13 @@ static bool check_code_match(const char* triggered, const char* expected) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool add_star_code(StarCodeEntry code) {
|
bool add_star_code(StarCodeEntry code) {
|
||||||
|
ESP_LOGI(TAG, "Adding starcode: %s", code.code);
|
||||||
if (code.code == nullptr || strlen(code.code) > STARCODE_MAX_LEN) {
|
if (code.code == nullptr || strlen(code.code) > STARCODE_MAX_LEN) {
|
||||||
|
ESP_LOGW(TAG, "invalid code");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (code.display_text != nullptr && strlen(code.display_text) > STARCODE_MAX_LEN + 1) {
|
if (code.display_text != nullptr && strlen(code.display_text) > STARCODE_DISPLAY_TEXT_MAX_LEN) {
|
||||||
|
ESP_LOGW(TAG, "invalid display_text");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +144,7 @@ bool add_star_code(StarCodeEntry code) {
|
|||||||
|
|
||||||
if (it != star_codes.end()) {
|
if (it != star_codes.end()) {
|
||||||
// existing star code found!
|
// existing star code found!
|
||||||
ESP_LOGW(TAG, "Failed to add star code %s", code.code);
|
ESP_LOGW(TAG, "Duplicate starcode %s", code.code);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +162,9 @@ bool add_star_codes(const StarCodeEntry* codes, size_t len) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rm_star_code(const char* code){
|
bool rm_star_code(const char* code) {
|
||||||
|
ESP_LOGI(TAG, "Removing starcode: %s", code);
|
||||||
|
|
||||||
auto it = std::find_if(star_codes.begin(), star_codes.end(), [&](const StarCodeEntry& star_code) {
|
auto it = std::find_if(star_codes.begin(), star_codes.end(), [&](const StarCodeEntry& star_code) {
|
||||||
return strcmp(code, star_code.code) == 0;
|
return strcmp(code, star_code.code) == 0;
|
||||||
});
|
});
|
||||||
@@ -196,18 +203,12 @@ void clear_star_codes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool trigger_star_code(const char* code) {
|
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) {
|
auto it = std::find_if(star_codes.begin(), star_codes.end(), [&](const StarCodeEntry& other) {
|
||||||
return check_code_match(code, other.code);
|
return check_code_match(code, other.code);
|
||||||
});
|
});
|
||||||
|
|
||||||
uint64_t delay_us = 2'000'000;
|
uint64_t delay_us = 2'000'000;
|
||||||
processing_starcode = true;
|
delaying_for_starcode = true;
|
||||||
if (it != star_codes.end()) {
|
if (it != star_codes.end()) {
|
||||||
current_starcode = &*it;
|
current_starcode = &*it;
|
||||||
delay_us = current_starcode->delay_us;
|
delay_us = current_starcode->delay_us;
|
||||||
@@ -231,22 +232,25 @@ void lcd_print_header_star_code() {
|
|||||||
if (!lcd_header_enabled()) return;
|
if (!lcd_header_enabled()) return;
|
||||||
|
|
||||||
// TODO: consider upping the display text size to be able to overwrite the game_state area.
|
// TODO: consider upping the display text size to be able to overwrite the game_state area.
|
||||||
if (processing_starcode) {
|
if (delaying_for_starcode) {
|
||||||
if (current_starcode == nullptr) {
|
if (current_starcode == nullptr) {
|
||||||
lcd_print(0, 0, "Invalid ");
|
lcd_print(0, 0, "Invalid starcode ");
|
||||||
} else if (current_starcode->display_text != nullptr) {
|
} else if (current_starcode->display_text != nullptr) {
|
||||||
char buf[STARCODE_MAX_LEN + 2];
|
char buf[21];
|
||||||
snprintf(buf, sizeof(buf), "%s", current_starcode->display_text);
|
snprintf(buf, sizeof(buf), "%-20s", current_starcode->display_text);
|
||||||
lcd_print(0, 0, buf);
|
lcd_print(0, 0, buf);
|
||||||
} else {
|
} else {
|
||||||
lcd_print(0, 0, EMPTY_STAR_CODE_HEADER);
|
lcd_print(0, 0, EMPTY_STAR_CODE_HEADER);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (doing_starcode) {
|
} else if (doing_starcode) {
|
||||||
char buf[STARCODE_MAX_LEN + 2];
|
char buf[STARCODE_MAX_LEN + 2];
|
||||||
snprintf(buf, sizeof(buf), "*%-8s", current);
|
snprintf(buf, sizeof(buf), "*%-9s", current);
|
||||||
lcd_print(0, 0, buf);
|
lcd_print(0, 0, buf);
|
||||||
} else {
|
} else {
|
||||||
lcd_print(0, 0, EMPTY_STAR_CODE_HEADER);
|
lcd_print(0, 0, EMPTY_STAR_CODE_HEADER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lcd_starcode_displaying_result() {
|
||||||
|
return delaying_for_starcode;
|
||||||
|
}
|
||||||
@@ -6,19 +6,20 @@
|
|||||||
#include <freertos/semphr.h>
|
#include <freertos/semphr.h>
|
||||||
|
|
||||||
/// 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 9
|
||||||
|
#define STARCODE_DISPLAY_TEXT_MAX_LEN 20
|
||||||
|
|
||||||
/// @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
|
||||||
///
|
///
|
||||||
/// This must be <= 8 characters.
|
/// This must be <= 9 characters.
|
||||||
///
|
///
|
||||||
/// You may include a * in the code to match on any character
|
/// You may include a * in the code to match on any character
|
||||||
const char* code;
|
const char* code;
|
||||||
/// @brief The text to display when the star code is entered (or null).
|
/// @brief The text to display when the star code is entered (or null).
|
||||||
///
|
///
|
||||||
/// This must be <= 9 characters.
|
/// This must be <= 20 characters.
|
||||||
const char* display_text;
|
const char* display_text;
|
||||||
/// @brief The number of microseconds to delay when the star code is entered before calling the handler.
|
/// @brief The number of microseconds to delay when the star code is entered before calling the handler.
|
||||||
uint64_t delay_us;
|
uint64_t delay_us;
|
||||||
@@ -77,11 +78,13 @@ bool trigger_star_code(const char* code);
|
|||||||
/// If one is being handled currently, it is canceled.
|
/// 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.
|
/// @return `true` iff the star code system is handling star codes.
|
||||||
/// @return `true` if the star code system is handling star codes.
|
|
||||||
bool star_code_sys_enabled();
|
bool star_code_sys_enabled();
|
||||||
|
|
||||||
/// @brief Prints the star code section of the header to the char_lcd. (row 0, columns 0-9)
|
/// @brief Prints the star code section of the header to the char_lcd. (row 0, columns 0-9)
|
||||||
void lcd_print_header_star_code();
|
void lcd_print_header_star_code();
|
||||||
|
|
||||||
|
/// @return `true` iff the starcode system is using the full header.
|
||||||
|
bool lcd_starcode_displaying_result();
|
||||||
|
|
||||||
#endif /* STAR_CODE_H */
|
#endif /* STAR_CODE_H */
|
||||||
+4
-4
@@ -44,11 +44,11 @@
|
|||||||
#define SPI_MAX_TRANSFER_SIZE 32768
|
#define SPI_MAX_TRANSFER_SIZE 32768
|
||||||
|
|
||||||
#define TFT_PIN_MOSI GPIO_NUM_17
|
#define TFT_PIN_MOSI GPIO_NUM_17
|
||||||
#define TFT_PIN_MISO GPIO_NUM_18
|
#define TFT_PIN_MISO GPIO_NUM_16
|
||||||
#define TFT_PIN_CLK GPIO_NUM_16
|
#define TFT_PIN_CLK GPIO_NUM_18
|
||||||
#define TFT_PIN_CS GPIO_NUM_NC
|
#define TFT_PIN_CS GPIO_NUM_NC
|
||||||
#define TFT_PIN_DC GPIO_NUM_15
|
#define TFT_PIN_DC GPIO_NUM_8
|
||||||
#define TFT_PIN_RESET GPIO_NUM_8
|
#define TFT_PIN_RESET GPIO_NUM_9
|
||||||
|
|
||||||
#define TFT_INVERT_COLOR false
|
#define TFT_INVERT_COLOR false
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ static void receive_button(void);
|
|||||||
void init_wires(void) {
|
void init_wires(void) {
|
||||||
i2c_config_t wires_conf = {
|
i2c_config_t wires_conf = {
|
||||||
.mode = I2C_MODE_MASTER,
|
.mode = I2C_MODE_MASTER,
|
||||||
.sda_io_num = GPIO_NUM_41,
|
.sda_io_num = PIN_WIRES_SDA,
|
||||||
.scl_io_num = GPIO_NUM_42,
|
.scl_io_num = PIN_WIRES_SCL,
|
||||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
.master = {
|
.master = {
|
||||||
@@ -35,8 +35,8 @@ void init_wires(void) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
gpio_reset_pin(GPIO_NUM_41);
|
gpio_reset_pin(PIN_WIRES_SDA);
|
||||||
gpio_reset_pin(GPIO_NUM_42);
|
gpio_reset_pin(PIN_WIRES_SCL);
|
||||||
|
|
||||||
ESP_ERROR_CHECK(i2c_param_config(WIRES_I2C_NUM, &wires_conf));
|
ESP_ERROR_CHECK(i2c_param_config(WIRES_I2C_NUM, &wires_conf));
|
||||||
ESP_ERROR_CHECK(i2c_driver_install(WIRES_I2C_NUM, wires_conf.mode, 0, 0, 0));
|
ESP_ERROR_CHECK(i2c_driver_install(WIRES_I2C_NUM, wires_conf.mode, 0, 0, 0));
|
||||||
|
|||||||
@@ -8,8 +8,11 @@
|
|||||||
#include "drivers/char_lcd.h"
|
#include "drivers/char_lcd.h"
|
||||||
#include "drivers/game_timer.h"
|
#include "drivers/game_timer.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "perh.h"
|
||||||
|
|
||||||
#define WIRES_PIN_DELTA GPIO_NUM_2
|
#define WIRES_PIN_DELTA PIN_PERH3
|
||||||
|
#define PIN_WIRES_SDA PIN_PERH1
|
||||||
|
#define PIN_WIRES_SCL PIN_PERH2
|
||||||
#define WIRES_I2C_NUM I2C_NUM_1
|
#define WIRES_I2C_NUM I2C_NUM_1
|
||||||
#define WIRES_I2C_ADDR 125
|
#define WIRES_I2C_ADDR 125
|
||||||
|
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ void step0() {
|
|||||||
StarCodeEntry star_codes[] = {
|
StarCodeEntry star_codes[] = {
|
||||||
{
|
{
|
||||||
.code = "9819",
|
.code = "9819",
|
||||||
.display_text = "Defusal Initiated",
|
.display_text = "Diffusal Initiated",
|
||||||
.delay_us = 2'000'000,
|
.delay_us = 2'000'000,
|
||||||
.callback = nullptr,
|
.callback = nullptr,
|
||||||
.triggered_sem = continue_sem,
|
.triggered_sem = continue_sem,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = "59862",
|
.code = "59861",
|
||||||
.display_text = "Set Up Wires",
|
.display_text = "Setup Wires",
|
||||||
.delay_us = 10'000'000,
|
.delay_us = 10'000'000,
|
||||||
.callback = setup_wires,
|
.callback = setup_wires,
|
||||||
.triggered_sem = nullptr,
|
.triggered_sem = nullptr,
|
||||||
@@ -80,7 +80,7 @@ void step0() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = "59863",
|
.code = "59863",
|
||||||
.display_text = "Debug Switches",
|
.display_text = "Debug switches",
|
||||||
.delay_us = 2'000'000,
|
.delay_us = 2'000'000,
|
||||||
.callback = debug_switches,
|
.callback = debug_switches,
|
||||||
.triggered_sem = nullptr,
|
.triggered_sem = nullptr,
|
||||||
@@ -192,7 +192,7 @@ void step0() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = "1113",
|
.code = "1113",
|
||||||
.display_text = "replay_last",
|
.display_text = "replay",
|
||||||
.delay_us = 2'000'000,
|
.delay_us = 2'000'000,
|
||||||
.callback = replay_last,
|
.callback = replay_last,
|
||||||
.triggered_sem = continue_sem,
|
.triggered_sem = continue_sem,
|
||||||
|
|||||||
@@ -539,7 +539,7 @@ CONFIG_PARTITION_TABLE_MD5=y
|
|||||||
#
|
#
|
||||||
# BLK_BOX Config
|
# BLK_BOX Config
|
||||||
#
|
#
|
||||||
CONFIG_USE_NEW_DISPLAY=y
|
# CONFIG_USE_NEW_DISPLAY is not set
|
||||||
# end of BLK_BOX Config
|
# end of BLK_BOX Config
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1035,9 +1035,11 @@ CONFIG_SPIRAM=y
|
|||||||
#
|
#
|
||||||
# SPI RAM config
|
# SPI RAM config
|
||||||
#
|
#
|
||||||
# CONFIG_SPIRAM_MODE_QUAD is not set
|
CONFIG_SPIRAM_MODE_QUAD=y
|
||||||
CONFIG_SPIRAM_MODE_OCT=y
|
# CONFIG_SPIRAM_MODE_OCT is not set
|
||||||
CONFIG_SPIRAM_TYPE_AUTO=y
|
CONFIG_SPIRAM_TYPE_AUTO=y
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
|
||||||
# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
|
||||||
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
|
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
|
||||||
CONFIG_SPIRAM_CLK_IO=30
|
CONFIG_SPIRAM_CLK_IO=30
|
||||||
@@ -1045,10 +1047,10 @@ CONFIG_SPIRAM_CS_IO=26
|
|||||||
# CONFIG_SPIRAM_XIP_FROM_PSRAM is not set
|
# CONFIG_SPIRAM_XIP_FROM_PSRAM is not set
|
||||||
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
|
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
|
||||||
# CONFIG_SPIRAM_RODATA is not set
|
# CONFIG_SPIRAM_RODATA is not set
|
||||||
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
# CONFIG_SPIRAM_SPEED_80M is not set
|
# CONFIG_SPIRAM_SPEED_80M is not set
|
||||||
CONFIG_SPIRAM_SPEED_40M=y
|
CONFIG_SPIRAM_SPEED_40M=y
|
||||||
CONFIG_SPIRAM_SPEED=40
|
CONFIG_SPIRAM_SPEED=40
|
||||||
# CONFIG_SPIRAM_ECC_ENABLE is not set
|
|
||||||
CONFIG_SPIRAM_BOOT_INIT=y
|
CONFIG_SPIRAM_BOOT_INIT=y
|
||||||
# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
|
# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
|
||||||
# CONFIG_SPIRAM_USE_MEMMAP is not set
|
# CONFIG_SPIRAM_USE_MEMMAP is not set
|
||||||
|
|||||||
Reference in New Issue
Block a user