mirror of
https://github.com/whowechina/chu_pico.git
synced 2024-11-28 12:40:48 +01:00
Command line functional but not completed
This commit is contained in:
parent
1b95be1144
commit
979fbd48e6
@ -4,7 +4,7 @@ set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
|
|||||||
function(make_firmware board board_def)
|
function(make_firmware board board_def)
|
||||||
pico_sdk_init()
|
pico_sdk_init()
|
||||||
add_executable(${board}
|
add_executable(${board}
|
||||||
main.c slider.c air.c rgb.c save.c lzfx.c usb_descriptors.c)
|
main.c slider.c air.c rgb.c save.c config.c cmd.c lzfx.c usb_descriptors.c)
|
||||||
target_compile_definitions(${board} PUBLIC ${board_def})
|
target_compile_definitions(${board} PUBLIC ${board_def})
|
||||||
pico_enable_stdio_usb(${board} 1)
|
pico_enable_stdio_usb(${board} 1)
|
||||||
pico_enable_stdio_uart(${board} 0)
|
pico_enable_stdio_uart(${board} 0)
|
||||||
|
183
firmware/src/cmd.c
Normal file
183
firmware/src/cmd.c
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "pico/stdio.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define MAX_COMMANDS 10
|
||||||
|
#define MAX_COMMAND_LENGTH 20
|
||||||
|
#define MAX_PARAMETERS 5
|
||||||
|
#define MAX_PARAMETER_LENGTH 20
|
||||||
|
|
||||||
|
const char *chu_prompt = "chu_pico>";
|
||||||
|
|
||||||
|
typedef void (*cmd_handler_t)(int argc, char *argv[]);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[MAX_COMMAND_LENGTH];
|
||||||
|
cmd_handler_t handler;
|
||||||
|
} command_t;
|
||||||
|
|
||||||
|
command_t commands[MAX_COMMANDS];
|
||||||
|
int num_commands = 0;
|
||||||
|
|
||||||
|
void register_command(char *name, cmd_handler_t handler)
|
||||||
|
{
|
||||||
|
if (num_commands < MAX_COMMANDS) {
|
||||||
|
strcpy(commands[num_commands].name, name);
|
||||||
|
commands[num_commands].handler = handler;
|
||||||
|
num_commands++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_help(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
printf("Available commands:\n");
|
||||||
|
for (int i = 0; i < num_commands; i++) {
|
||||||
|
printf("%s\n", commands[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_list(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
printf("[Colors]\n");
|
||||||
|
printf(" Key upper: %6x, lower: %6x, both: %6x, off: %6x\n",
|
||||||
|
chu_cfg->colors.key_on_upper, chu_cfg->colors.key_on_lower,
|
||||||
|
chu_cfg->colors.key_on_both, chu_cfg->colors.key_off);
|
||||||
|
printf(" Gap: %6x\n", chu_cfg->colors.gap);
|
||||||
|
printf("[Style]\n");
|
||||||
|
printf(" Key: %d, Gap: %d, ToF: %d, Level: %d\n",
|
||||||
|
chu_cfg->style.key, chu_cfg->style.gap,
|
||||||
|
chu_cfg->style.tof, chu_cfg->style.level);
|
||||||
|
printf("[ToF]\n");
|
||||||
|
printf(" Offset: %d, Pitch: %d\n", chu_cfg->tof.offset, chu_cfg->tof.pitch);
|
||||||
|
printf("[Sense]\n");
|
||||||
|
printf(" Global: %d, debounce: %d\n", chu_cfg->sense.global, chu_cfg->sense.debounce);
|
||||||
|
printf(" | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |\n");
|
||||||
|
printf(" -----------------------------------------------------------------\n");
|
||||||
|
printf(" A |");
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
printf("%3d|", chu_cfg->sense.keys[i * 2]);
|
||||||
|
}
|
||||||
|
printf("\n B |");
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
printf("%3d|", chu_cfg->sense.keys[i * 2 + 1]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("[HID]\n");
|
||||||
|
printf(" Joy: %s, NKRO: %s.\n",
|
||||||
|
chu_cfg->hid.joy ? "on" : "off",
|
||||||
|
chu_cfg->hid.nkro ? "on" : "off" );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fps[2];
|
||||||
|
|
||||||
|
void fps_count(int core)
|
||||||
|
{
|
||||||
|
static uint32_t last[2] = {0};
|
||||||
|
static int counter[2] = {0};
|
||||||
|
|
||||||
|
counter[core]++;
|
||||||
|
|
||||||
|
uint32_t now = time_us_32();
|
||||||
|
if (now - last[core] < 1000000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last[core] = now;
|
||||||
|
fps[core] = counter[core];
|
||||||
|
counter[core] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_fps(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
printf("FPS: core 0: %d, core 1: %d\n", fps[0], fps[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_hid(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const char *usage = "Usage: hid <joy|nkro>\n";
|
||||||
|
if (argc != 1) {
|
||||||
|
printf(usage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[0], "joy") == 0) {
|
||||||
|
chu_cfg->hid.joy = 1;
|
||||||
|
chu_cfg->hid.nkro = 0;
|
||||||
|
} else if (strcmp(argv[0], "nkro") == 0) {
|
||||||
|
chu_cfg->hid.joy = 0;
|
||||||
|
chu_cfg->hid.nkro = 1;
|
||||||
|
} else if (strcmp(argv[0], "both") == 0) {
|
||||||
|
chu_cfg->hid.joy = 1;
|
||||||
|
chu_cfg->hid.nkro = 1;
|
||||||
|
} else {
|
||||||
|
printf(usage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_init()
|
||||||
|
{
|
||||||
|
fcntl(0, F_SETFL, O_NONBLOCK);
|
||||||
|
register_command("?", handle_help);
|
||||||
|
register_command("list", handle_list);
|
||||||
|
register_command("fps", handle_fps);
|
||||||
|
register_command("hid", handle_hid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char cmd_buf[256];
|
||||||
|
static int cmd_len = 0;
|
||||||
|
|
||||||
|
static void process_cmd()
|
||||||
|
{
|
||||||
|
char *command;
|
||||||
|
char *argv[MAX_PARAMETERS];
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
command = strtok(cmd_buf, " \n");
|
||||||
|
argc = 0;
|
||||||
|
while ((argc < MAX_PARAMETERS) &&
|
||||||
|
(argv[argc] = strtok(NULL, " \n")) != NULL) {
|
||||||
|
argc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < num_commands; i++) {
|
||||||
|
if (strcmp(commands[i].name, command) == 0) {
|
||||||
|
commands[i].handler(argc, argv);
|
||||||
|
printf("\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_run()
|
||||||
|
{
|
||||||
|
int c = getchar_timeout_us(0);
|
||||||
|
if (c == EOF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c != '\n') && (c != '\r')) {
|
||||||
|
if (cmd_len < sizeof(cmd_buf) - 2) {
|
||||||
|
cmd_buf[cmd_len] = c;
|
||||||
|
printf("%c", c);
|
||||||
|
cmd_len++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buf[cmd_len] = '\0';
|
||||||
|
cmd_len = 0;
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
process_cmd();
|
||||||
|
|
||||||
|
printf(chu_prompt);
|
||||||
|
}
|
13
firmware/src/cmd.h
Normal file
13
firmware/src/cmd.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Chu Controller Command Line
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CMD_H
|
||||||
|
#define CMD_H
|
||||||
|
|
||||||
|
void cmd_init();
|
||||||
|
void cmd_run();
|
||||||
|
void fps_count(int core);
|
||||||
|
|
||||||
|
#endif
|
@ -1,69 +1,59 @@
|
|||||||
/*
|
/*
|
||||||
* Controller Config Data
|
* Controller Config and Runtime Data
|
||||||
* WHowe <github.com/whowechina>
|
* WHowe <github.com/whowechina>
|
||||||
*
|
*
|
||||||
* Config is a global data structure that stores all the configuration
|
* Config is a global data structure that stores all the configuration
|
||||||
|
* Runtime is something to share between files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
|
|
||||||
iidx_cfg_t *iidx_cfg;
|
chu_cfg_t *chu_cfg;
|
||||||
|
|
||||||
static iidx_cfg_t default_cfg = {
|
static chu_cfg_t default_cfg = {
|
||||||
.key_off = { {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}},
|
.colors = {
|
||||||
.key_on = { {40,40,40}, {40,40,40}, {40,40,40}, {40,40,40}, {40,40,40}, {40,40,40},
|
.key_on_upper = 0x00FF00,
|
||||||
{40,40,40}, {40,40,40}, {40,40,40}, {40,40,40}, {40,40,40},
|
.key_on_lower = 0xff0000,
|
||||||
|
.key_on_both = 0xff0000,
|
||||||
|
.key_off = 0x000000,
|
||||||
|
.gap = 0x000000,
|
||||||
},
|
},
|
||||||
.tt_led = {
|
.style = {
|
||||||
.start = 0,
|
.key = 0,
|
||||||
.num = 24,
|
.gap = 0,
|
||||||
.effect = 0,
|
.tof = 0,
|
||||||
.param = 0,
|
.level = 7,
|
||||||
.mode = 0,
|
|
||||||
},
|
},
|
||||||
.tt_sensor = {
|
.tof = {
|
||||||
.mode = 2,
|
.offset = 64,
|
||||||
.deadzone = 1,
|
.pitch = 16,
|
||||||
.ppr = 1,
|
|
||||||
},
|
},
|
||||||
.effects = {
|
.sense = {
|
||||||
.e1 = 255,
|
.debounce = 4,
|
||||||
.e2 = 128,
|
},
|
||||||
.e3 = 128,
|
.hid = {
|
||||||
.e4 = 128,
|
.joy = 0x0f,
|
||||||
|
.nkro = 0,
|
||||||
},
|
},
|
||||||
.level = 128,
|
|
||||||
.konami = false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
chu_runtime_t *chu_runtime;
|
||||||
|
|
||||||
static void config_loaded()
|
static void config_loaded()
|
||||||
{
|
{
|
||||||
if (iidx_cfg->tt_led.num == 0) {
|
if (chu_cfg->style.level > 10) {
|
||||||
iidx_cfg->tt_led.num = 24;
|
chu_cfg->style.level = default_cfg.style.level;
|
||||||
config_changed();
|
config_changed();
|
||||||
}
|
}
|
||||||
if ((iidx_cfg->tt_led.start > 8) ||
|
if ((chu_cfg->tof.offset < 400) || (chu_cfg->tof.offset > 2000) ||
|
||||||
(iidx_cfg->tt_led.start + iidx_cfg->tt_led.num > 128)) {
|
(chu_cfg->tof.pitch < 50) || (chu_cfg->tof.pitch > 500)) {
|
||||||
iidx_cfg->tt_led.start = 0;
|
chu_cfg->tof = default_cfg.tof;
|
||||||
iidx_cfg->tt_led.num = 24;
|
|
||||||
config_changed();
|
config_changed();
|
||||||
}
|
}
|
||||||
if (iidx_cfg->tt_sensor.deadzone > 2) {
|
|
||||||
iidx_cfg->tt_sensor.deadzone = 0;
|
if (chu_cfg->sense.debounce > 32) {
|
||||||
config_changed();
|
chu_cfg->sense.debounce = default_cfg.sense.debounce;
|
||||||
}
|
|
||||||
if (iidx_cfg->tt_led.mode > 2) {
|
|
||||||
iidx_cfg->tt_led.mode = 0;
|
|
||||||
config_changed();
|
|
||||||
}
|
|
||||||
if (iidx_cfg->tt_sensor.mode > 3) {
|
|
||||||
iidx_cfg->tt_sensor.mode = 2;
|
|
||||||
config_changed();
|
|
||||||
}
|
|
||||||
if (iidx_cfg->tt_sensor.ppr > 3) {
|
|
||||||
iidx_cfg->tt_sensor.ppr = 1;
|
|
||||||
config_changed();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,11 +64,11 @@ void config_changed()
|
|||||||
|
|
||||||
void config_factory_reset()
|
void config_factory_reset()
|
||||||
{
|
{
|
||||||
*iidx_cfg = default_cfg;
|
*chu_cfg = default_cfg;
|
||||||
save_request(true);
|
save_request(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void config_init()
|
void config_init()
|
||||||
{
|
{
|
||||||
iidx_cfg = (iidx_cfg_t *)save_alloc(sizeof(iidx_cfg), &default_cfg, config_loaded);
|
chu_cfg = (chu_cfg_t *)save_alloc(sizeof(*chu_cfg), &default_cfg, config_loaded);
|
||||||
}
|
}
|
||||||
|
@ -9,38 +9,41 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct __attribute ((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
uint8_t h; // hue;
|
struct {
|
||||||
uint8_t s; // saturation;
|
uint32_t key_on_upper;
|
||||||
uint8_t v; // value;
|
uint32_t key_on_lower;
|
||||||
} hsv_t;
|
uint32_t key_on_both;
|
||||||
|
uint32_t key_off;
|
||||||
|
uint32_t gap;
|
||||||
|
} colors;
|
||||||
|
struct {
|
||||||
|
uint8_t key;
|
||||||
|
uint8_t gap;
|
||||||
|
uint8_t tof;
|
||||||
|
uint8_t level;
|
||||||
|
} style;
|
||||||
|
struct {
|
||||||
|
uint8_t offset;
|
||||||
|
uint8_t pitch;
|
||||||
|
} tof;
|
||||||
|
struct {
|
||||||
|
int8_t global;
|
||||||
|
uint8_t debounce;
|
||||||
|
int8_t keys[32];
|
||||||
|
} sense;
|
||||||
|
struct {
|
||||||
|
uint8_t joy : 4;
|
||||||
|
uint8_t nkro : 4;
|
||||||
|
} hid;
|
||||||
|
} chu_cfg_t;
|
||||||
|
|
||||||
typedef struct __attribute ((packed)) {
|
typedef struct {
|
||||||
hsv_t key_off[11];
|
uint16_t fps[2];
|
||||||
hsv_t key_on[11];
|
} chu_runtime_t;
|
||||||
struct {
|
|
||||||
uint8_t start;
|
|
||||||
uint8_t num;
|
|
||||||
uint8_t effect;
|
|
||||||
uint8_t param;
|
|
||||||
uint8_t mode; /* 0: on, 1: reversed, 2: off */
|
|
||||||
} tt_led;
|
|
||||||
struct {
|
|
||||||
uint8_t mode; /* 0: analog, 1: analog reversed, 2: i2c, 3: i2c reversed */
|
|
||||||
uint8_t deadzone; /* only for analog */
|
|
||||||
uint8_t ppr; /* 0: 256, 1: 128, 2: 96, 3: 64, other: 256 */
|
|
||||||
} tt_sensor;
|
|
||||||
struct {
|
|
||||||
uint8_t e1;
|
|
||||||
uint8_t e2;
|
|
||||||
uint8_t e3;
|
|
||||||
uint8_t e4;
|
|
||||||
} effects;
|
|
||||||
uint8_t level; /* led brightness limit */
|
|
||||||
bool konami; /* konami spoof */
|
|
||||||
} iidx_cfg_t;
|
|
||||||
|
|
||||||
extern iidx_cfg_t *iidx_cfg;
|
extern chu_cfg_t *chu_cfg;
|
||||||
|
extern chu_runtime_t *chu_runtime;
|
||||||
|
|
||||||
void config_init();
|
void config_init();
|
||||||
void config_changed(); // Notify the config has changed
|
void config_changed(); // Notify the config has changed
|
||||||
|
@ -22,16 +22,16 @@
|
|||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
|
|
||||||
#include "board_defs.h"
|
#include "board_defs.h"
|
||||||
|
|
||||||
|
#include "save.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "cmd.h"
|
||||||
|
|
||||||
#include "slider.h"
|
#include "slider.h"
|
||||||
#include "air.h"
|
#include "air.h"
|
||||||
#include "rgb.h"
|
#include "rgb.h"
|
||||||
#include "lzfx.h"
|
#include "lzfx.h"
|
||||||
|
|
||||||
/* Measure the time of a function call */
|
|
||||||
#define RUN_TIME(func) \
|
|
||||||
{ uint64_t _t = time_us_64(); func; \
|
|
||||||
printf(#func ":%lld\n", time_us_64() - _t); }
|
|
||||||
|
|
||||||
struct __attribute__((packed)) {
|
struct __attribute__((packed)) {
|
||||||
uint16_t buttons; // 16 buttons; see JoystickButtons_t for bit mapping
|
uint16_t buttons; // 16 buttons; see JoystickButtons_t for bit mapping
|
||||||
uint8_t HAT; // HAT switch; one nibble w/ unused nibble
|
uint8_t HAT; // HAT switch; one nibble w/ unused nibble
|
||||||
@ -49,10 +49,13 @@ void report_usb_hid()
|
|||||||
if (tud_hid_ready()) {
|
if (tud_hid_ready()) {
|
||||||
hid_joy.HAT = 0;
|
hid_joy.HAT = 0;
|
||||||
hid_joy.VendorSpec = 0;
|
hid_joy.VendorSpec = 0;
|
||||||
tud_hid_n_report(0x00, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy));
|
if (chu_cfg->hid.joy) {
|
||||||
if (memcmp(&hid_nkro, &sent_hid_nkro, sizeof(hid_nkro)) != 0) {
|
tud_hid_n_report(0x00, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy));
|
||||||
|
}
|
||||||
|
if (chu_cfg->hid.nkro &&
|
||||||
|
(memcmp(&hid_nkro, &sent_hid_nkro, sizeof(hid_nkro)) != 0)) {
|
||||||
sent_hid_nkro = hid_nkro;
|
sent_hid_nkro = hid_nkro;
|
||||||
//tud_hid_n_report(0x02, 0, &sent_hid_nkro, sizeof(sent_hid_nkro));
|
tud_hid_n_report(0x02, 0, &sent_hid_nkro, sizeof(sent_hid_nkro));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,41 +69,6 @@ static void pause_core1(bool pause)
|
|||||||
sleep_ms(5); /* wait for any IO ops to finish */
|
sleep_ms(5); /* wait for any IO ops to finish */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fps[2] = {0};
|
|
||||||
|
|
||||||
static int get_fps(int core)
|
|
||||||
{
|
|
||||||
return fps[core];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fps_count(int core)
|
|
||||||
{
|
|
||||||
static uint32_t last[2] = {0};
|
|
||||||
static int counter[2] = {0};
|
|
||||||
|
|
||||||
counter[core]++;
|
|
||||||
|
|
||||||
uint32_t now = time_us_32();
|
|
||||||
if (now - last[core] < 1000000) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
last[core] = now;
|
|
||||||
fps[core] = counter[core];
|
|
||||||
counter[core] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_fps()
|
|
||||||
{
|
|
||||||
static uint32_t last = 0;
|
|
||||||
uint32_t now = time_us_32();
|
|
||||||
if (now - last < 5000000) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
last = now;
|
|
||||||
printf("FPS: %d %d\n", get_fps(0), get_fps(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_joy_report()
|
static void gen_joy_report()
|
||||||
{
|
{
|
||||||
hid_joy.axis = 0;
|
hid_joy.axis = 0;
|
||||||
@ -182,7 +150,6 @@ static void core1_loop()
|
|||||||
|
|
||||||
slider_update_baseline();
|
slider_update_baseline();
|
||||||
fps_count(1);
|
fps_count(1);
|
||||||
print_fps();
|
|
||||||
sleep_ms(1);
|
sleep_ms(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,6 +157,8 @@ static void core1_loop()
|
|||||||
static void core0_loop()
|
static void core0_loop()
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
|
cmd_run();
|
||||||
|
save_loop();
|
||||||
fps_count(0);
|
fps_count(0);
|
||||||
|
|
||||||
slider_update();
|
slider_update();
|
||||||
@ -209,9 +178,15 @@ void init()
|
|||||||
board_init();
|
board_init();
|
||||||
tusb_init();
|
tusb_init();
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
|
||||||
|
config_init();
|
||||||
|
save_init(0xca34cafe, pause_core1);
|
||||||
|
|
||||||
slider_init();
|
slider_init();
|
||||||
air_init();
|
air_init();
|
||||||
rgb_init();
|
rgb_init();
|
||||||
|
|
||||||
|
cmd_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Controller Save Save and Load
|
* Controller Config Save and Load
|
||||||
* WHowe <github.com/whowechina>
|
* WHowe <github.com/whowechina>
|
||||||
*
|
*
|
||||||
* Save is stored in last sector of flash
|
* Config is stored in last sector of flash
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
@ -27,7 +27,8 @@ static struct {
|
|||||||
} modules[8] = {0};
|
} modules[8] = {0};
|
||||||
static int module_num = 0;
|
static int module_num = 0;
|
||||||
|
|
||||||
#define SAVE_PAGE_MAGIC 0x13424321
|
static uint32_t my_magic = 0xcafecafe;
|
||||||
|
|
||||||
#define SAVE_SECTOR_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE)
|
#define SAVE_SECTOR_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE)
|
||||||
|
|
||||||
typedef struct __attribute ((packed)) {
|
typedef struct __attribute ((packed)) {
|
||||||
@ -66,7 +67,7 @@ static void load_default()
|
|||||||
{
|
{
|
||||||
printf("Load Default\n");
|
printf("Load Default\n");
|
||||||
new_data = default_data;
|
new_data = default_data;
|
||||||
new_data.magic = SAVE_PAGE_MAGIC;
|
new_data.magic = my_magic;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const page_t *get_page(int id)
|
static const page_t *get_page(int id)
|
||||||
@ -78,7 +79,7 @@ static const page_t *get_page(int id)
|
|||||||
static void save_load()
|
static void save_load()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < FLASH_SECTOR_SIZE / FLASH_PAGE_SIZE; i++) {
|
for (int i = 0; i < FLASH_SECTOR_SIZE / FLASH_PAGE_SIZE; i++) {
|
||||||
if (get_page(i)->magic != SAVE_PAGE_MAGIC) {
|
if (get_page(i)->magic != my_magic) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
data_page = i;
|
data_page = i;
|
||||||
@ -102,8 +103,9 @@ static void save_loaded()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_init(io_locker_func locker)
|
void save_init(uint32_t magic, io_locker_func locker)
|
||||||
{
|
{
|
||||||
|
my_magic = magic;
|
||||||
io_lock = locker;
|
io_lock = locker;
|
||||||
save_load();
|
save_load();
|
||||||
save_loop();
|
save_loop();
|
||||||
@ -142,7 +144,7 @@ void save_request(bool immediately)
|
|||||||
if (!requesting_save) {
|
if (!requesting_save) {
|
||||||
printf("Save marked.\n");
|
printf("Save marked.\n");
|
||||||
requesting_save = true;
|
requesting_save = true;
|
||||||
new_data.magic = SAVE_PAGE_MAGIC;
|
new_data.magic = my_magic;
|
||||||
requesting_time = time_us_64();
|
requesting_time = time_us_64();
|
||||||
}
|
}
|
||||||
if (immediately) {
|
if (immediately) {
|
||||||
|
@ -7,11 +7,12 @@
|
|||||||
#define SAVE_H
|
#define SAVE_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* It's safer to lock other I/O ops during saving, so we need a locker */
|
/* It's safer to lock other I/O ops during saving, so we need a locker */
|
||||||
typedef void (*io_locker_func)(bool pause);
|
typedef void (*io_locker_func)(bool pause);
|
||||||
void save_init(io_locker_func locker);
|
void save_init(uint32_t magic, io_locker_func locker);
|
||||||
|
|
||||||
void save_loop();
|
void save_loop();
|
||||||
|
|
||||||
|
@ -15,9 +15,10 @@
|
|||||||
#include "hardware/gpio.h"
|
#include "hardware/gpio.h"
|
||||||
|
|
||||||
#include "board_defs.h"
|
#include "board_defs.h"
|
||||||
|
|
||||||
#include "mpr121.h"
|
#include "mpr121.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#define TOUCH_THRESHOLD 17
|
#define TOUCH_THRESHOLD 17
|
||||||
#define RELEASE_THRESHOLD 8
|
#define RELEASE_THRESHOLD 8
|
||||||
|
|
||||||
@ -145,19 +146,23 @@ bool slider_touched(unsigned key)
|
|||||||
}
|
}
|
||||||
int delta = baseline[key] - readout[key];
|
int delta = baseline[key] - readout[key];
|
||||||
|
|
||||||
|
int bias = chu_cfg->sense.global + chu_cfg->sense.keys[key];
|
||||||
|
int touch_thre = TOUCH_THRESHOLD + bias;
|
||||||
|
int release_thre = RELEASE_THRESHOLD + bias / 2;
|
||||||
|
|
||||||
if (touched[key]) {
|
if (touched[key]) {
|
||||||
if (delta > TOUCH_THRESHOLD) {
|
if (delta > touch_thre) {
|
||||||
debounce[key] = 0;
|
debounce[key] = 0;
|
||||||
}
|
}
|
||||||
if (debounce[key] > 4) {
|
if (debounce[key] > chu_cfg->sense.debounce) {
|
||||||
if (delta < RELEASE_THRESHOLD) {
|
if (delta < release_thre) {
|
||||||
touched[key] = false;
|
touched[key] = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debounce[key]++;
|
debounce[key]++;
|
||||||
}
|
}
|
||||||
} else if (!touched[key]) {
|
} else if (!touched[key]) {
|
||||||
if (delta > TOUCH_THRESHOLD) {
|
if (delta > touch_thre) {
|
||||||
touched[key] = true;
|
touched[key] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user