some bottom_half side star code work
This commit is contained in:
parent
72ff92b444
commit
9cc1a93e73
@ -7,6 +7,7 @@ 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();
|
||||||
@ -18,7 +19,7 @@ void init_drivers() {
|
|||||||
init_power_board();
|
init_power_board();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Initializes I2C_NUM_0.
|
/// @brief Initializes `I2C_NUM_0`.
|
||||||
///
|
///
|
||||||
/// This is hooked up the to:
|
/// This is hooked up the to:
|
||||||
/// - The bottom half
|
/// - The bottom half
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
#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";
|
||||||
|
|
||||||
|
volatile bool doing_starcode = false;
|
||||||
|
static uint16_t starcode_waiting_on_release;
|
||||||
|
static char current_starcode[STARCODE_MAX_LEN + 1];
|
||||||
|
static size_t current_starcode_idx;
|
||||||
|
|
||||||
static uint16_t keypad_state;
|
static uint16_t keypad_state;
|
||||||
static uint8_t button_state;
|
static uint8_t button_state;
|
||||||
static uint8_t switch_state;
|
static uint8_t switch_state;
|
||||||
@ -69,20 +75,23 @@ 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, ®, 1, buf, 1, (100 / portTICK_PERIOD_MS));
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, ®, 1, buf, 1, (100 / portTICK_PERIOD_MS)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
|
||||||
|
if (result != ESP_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return buf[0];
|
return buf[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_keypad(void) {
|
static void receive_keypad(void) {
|
||||||
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, ®, 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, ®, 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 +99,54 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (handling_new_starcodes && (just_pressed | (1 << KeypadKey::star))) {
|
||||||
|
current_starcode_idx = 0;
|
||||||
|
current_starcode[current_starcode_idx] = '\0';
|
||||||
|
doing_starcode = true;
|
||||||
|
}
|
||||||
|
if (doing_starcode) {
|
||||||
|
// If we get a press while handling a starcode, we also want to capture the release of that key.
|
||||||
|
starcode_waiting_on_release |= just_pressed;
|
||||||
|
|
||||||
|
KeypadKey key;
|
||||||
|
while (_take_key(&key, &just_pressed)) {
|
||||||
|
if (key == KeypadKey::star) {
|
||||||
|
current_starcode_idx = 0;
|
||||||
|
current_starcode[current_starcode_idx] = '\0';
|
||||||
|
} else if (key == KeypadKey::pound) {
|
||||||
|
doing_starcode = false;
|
||||||
|
trigger_star_code(current_starcode);
|
||||||
|
} else if (current_starcode_idx < STARCODE_MAX_LEN) {
|
||||||
|
current_starcode[current_starcode_idx++] = char_of_keypad_key(key);
|
||||||
|
current_starcode[current_starcode_idx] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// capture any releases from starcodes
|
||||||
|
uint16_t new_just_released = just_released & (~starcode_waiting_on_release);
|
||||||
|
starcode_waiting_on_release = starcode_waiting_on_release & (~just_released);
|
||||||
|
just_released = new_just_released;
|
||||||
|
|
||||||
|
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, ®, 1, buf, 2, (100 / portTICK_PERIOD_MS)));
|
esp_err_t result = i2c_master_write_read_device(BOTTOM_I2C_NUM, BOTTOM_I2C_ADDR, ®, 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;
|
||||||
|
|||||||
@ -12,6 +12,9 @@
|
|||||||
#define DELTA_BIT_BUTTON_SWITCH 1
|
#define DELTA_BIT_BUTTON_SWITCH 1
|
||||||
#define DELTA_BIT_TOUCH 2
|
#define DELTA_BIT_TOUCH 2
|
||||||
|
|
||||||
|
/// @brief `true` if a starcode is currently being handled.
|
||||||
|
extern volatile bool doing_starcode;
|
||||||
|
|
||||||
/// @brief An enum for the possible keypad buttons.
|
/// @brief An enum for the possible keypad buttons.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
k1 = 0,
|
k1 = 0,
|
||||||
|
|||||||
@ -5,11 +5,94 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
|
#include "drivers/bottom_half.h"
|
||||||
|
|
||||||
static const char* TAG = "star_code";
|
static const char* TAG = "star_code";
|
||||||
|
|
||||||
|
volatile bool handling_new_starcodes = false;
|
||||||
|
static bool system_initialized = false;
|
||||||
|
|
||||||
|
static volatile SemaphoreHandle_t star_codes_sem;
|
||||||
static std::vector<StarCodeEntry> star_codes;
|
static std::vector<StarCodeEntry> star_codes;
|
||||||
|
|
||||||
|
static TaskHandle_t task_handle;
|
||||||
|
|
||||||
|
static void star_code_task(void* param) {
|
||||||
|
KeypadKey key;
|
||||||
|
|
||||||
|
int current_idx = 0;
|
||||||
|
char current[STRING_MAX_LEN+1] = {0};
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
while (get_keypad_pressed(&key)) {
|
||||||
|
if (key == KeypadKey::star) {
|
||||||
|
current[0] = '*';
|
||||||
|
for (int i = 1; i < STRING_MAX_LEN; i++) {
|
||||||
|
current[i] = 0;
|
||||||
|
}
|
||||||
|
current_idx = 1;
|
||||||
|
} else if (key == KeypadKey::pound) {
|
||||||
|
// submit
|
||||||
|
if (current[0] == '\0') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hit = false;
|
||||||
|
for (int i = 0; i < star_codes_len; i++) {
|
||||||
|
StarCodeHandler sch = star_codes[i];
|
||||||
|
if (strcmp(current, sch.code) == 0) {
|
||||||
|
hit = true;
|
||||||
|
lcd_print(1, 2, sch.display_text);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
if (sch.callback != nullptr) {
|
||||||
|
(sch.callback)();
|
||||||
|
}
|
||||||
|
if (sch.should_exit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hit) {
|
||||||
|
lcd_print(1, 2, "Invalid Star Code");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear
|
||||||
|
for (int i = 0; i < STRING_MAX_LEN; i++) {
|
||||||
|
current[i] = 0;
|
||||||
|
}
|
||||||
|
current_idx = 0;
|
||||||
|
} else {
|
||||||
|
// out of room. skip
|
||||||
|
if (current_idx >= STRING_MAX_LEN) break;
|
||||||
|
// no code started.
|
||||||
|
if (current[0] != '*') continue;
|
||||||
|
|
||||||
|
char c = char_of_keypad_key(key);
|
||||||
|
current[current_idx++] = c;
|
||||||
|
}
|
||||||
|
// ESP_LOGI(STEP0_TAG, "Pressed: %c", c);
|
||||||
|
|
||||||
|
lcd_clear();
|
||||||
|
lcd_print(1, 1, current);
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_star_code_system() {
|
||||||
|
star_codes_sem = xSemaphoreCreateBinary();
|
||||||
|
xSemaphoreGive(star_codes_sem);
|
||||||
|
|
||||||
|
xTaskCreate(star_code_task, "star_code", 2048, nullptr, 1, &task_handle);
|
||||||
|
|
||||||
|
handling_new_starcodes = true;
|
||||||
|
system_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if a triggered code matches an expected code.
|
/// 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
|
/// @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) {
|
static bool check_code_match(const char* triggered, const char* expected) {
|
||||||
@ -29,10 +112,10 @@ static bool check_code_match(const char* triggered, const char* expected) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool add_star_code(StarCodeEntry code) {
|
bool add_star_code(StarCodeEntry code) {
|
||||||
if (code.code == nullptr || strlen(code.code) > 8) {
|
if (code.code == nullptr || strlen(code.code) > STARCODE_MAX_LEN) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (code.display_text != nullptr && strlen(code.display_text) > 9) {
|
if (code.display_text != nullptr && strlen(code.display_text) > STARCODE_MAX_LEN + 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +191,15 @@ bool trigger_star_code(const char* code) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (it->callback != nullptr)
|
||||||
(it->callback)();
|
(it->callback)();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pause_star_code_system() {
|
||||||
|
handling_new_starcodes = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume_star_code_system() {
|
||||||
|
handling_new_starcodes = system_initialized;
|
||||||
|
}
|
||||||
@ -1,7 +1,14 @@
|
|||||||
#ifndef STAR_CODE_H
|
#ifndef STAR_CODE_H
|
||||||
#define STAR_CODE_H
|
#define STAR_CODE_H
|
||||||
|
|
||||||
#include <stdint.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
|
||||||
|
|
||||||
|
extern volatile bool handling_new_starcodes;
|
||||||
|
|
||||||
/// @brief A handler for a specific star code
|
/// @brief A handler for a specific star code
|
||||||
struct StarCodeEntry {
|
struct StarCodeEntry {
|
||||||
@ -11,16 +18,23 @@ struct StarCodeEntry {
|
|||||||
///
|
///
|
||||||
/// 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 <= 9 characters.
|
||||||
const char* display_text;
|
const char* display_text;
|
||||||
/// @brief The number of ticks to delay when the star code is entered before calling the handler.
|
/// @brief The number of ticks to delay when the star code is entered before calling the handler.
|
||||||
uint32_t delay_ticks;
|
uint32_t delay_ticks;
|
||||||
/// @brief The function to call when the star code is entered.
|
/// @brief The function to call when the star code is entered.
|
||||||
|
/// Can be null.
|
||||||
void (*callback)(void);
|
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 Adds a star code to be handled.
|
/// @brief Adds a star code to be handled.
|
||||||
/// @param code the star code to add
|
/// @param code the star code to add
|
||||||
/// @return true iff the star code was added
|
/// @return true iff the star code was added
|
||||||
@ -57,4 +71,11 @@ void clear_star_codes();
|
|||||||
/// @return true iff a star code was triggered
|
/// @return true iff a star code was triggered
|
||||||
bool trigger_star_code(const char* code);
|
bool trigger_star_code(const char* code);
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Tempararilly stops the starcode system from handling new starcodes.
|
||||||
|
void pause_star_code_system();
|
||||||
|
|
||||||
|
/// @brief Resumes the starcode system to start handling new starcodes again.
|
||||||
|
void resume_star_code_system();
|
||||||
|
|
||||||
#endif /* STAR_CODE_H */
|
#endif /* STAR_CODE_H */
|
||||||
@ -55,7 +55,7 @@ static const StarCodeEntry star_codes[] = {
|
|||||||
.callback = nullptr,
|
.callback = nullptr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = "*9861",
|
.code = "59862",
|
||||||
.display_text = "Set Up Wires",
|
.display_text = "Set Up Wires",
|
||||||
.delay_ticks = pdMS_TO_TICKS(2000),
|
.delay_ticks = pdMS_TO_TICKS(2000),
|
||||||
.callback = setup_wires,
|
.callback = setup_wires,
|
||||||
|
|||||||
@ -182,8 +182,8 @@ void step5(void) {
|
|||||||
StarCodeEntry star_code = {
|
StarCodeEntry star_code = {
|
||||||
.code = "*2648",
|
.code = "*2648",
|
||||||
.display_text = "Starting...",
|
.display_text = "Starting...",
|
||||||
.should_exit = true,
|
.delay_ticks = pdMS_TO_TICKS(2000),
|
||||||
.callback = nullptr,
|
.callback = nullptr, // TODO
|
||||||
};
|
};
|
||||||
add_star_code(star_code);
|
add_star_code(star_code);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user