Sound volume and complete io4

This commit is contained in:
whowechina 2024-09-16 21:47:28 +08:00
parent ec39e8f8fa
commit 1e00dc8b55
11 changed files with 124 additions and 3811 deletions

View File

@ -71,11 +71,9 @@ static bool readings[AIRKEY_NUM];
static void tof_read() static void tof_read()
{ {
printf("\n");
for (int i = 0; i < TOF_NUM; i++) { for (int i = 0; i < TOF_NUM; i++) {
vl53l0x_use(i); vl53l0x_use(i);
tof_dist[i] = readRangeContinuousMillimeters(i); tof_dist[i] = readRangeContinuousMillimeters(i);
printf(" %4d", tof_dist[i]);
} }
} }

View File

@ -13,6 +13,8 @@
#include "gimbal.h" #include "gimbal.h"
extern uint8_t RING_DATA[];
#include "nfc.h" #include "nfc.h"
#include "aime.h" #include "aime.h"
@ -72,7 +74,7 @@ static void disp_gimbal()
static void disp_sound() static void disp_sound()
{ {
printf("[Sound]\n"); printf("[Sound]\n");
printf(" Status: %s.\n", geki_cfg->sound.enabled ? "on" : "off"); printf(" Volume: %d\n", geki_cfg->sound.volume);
} }
static void disp_hid() static void disp_hid()
@ -353,25 +355,6 @@ static void handle_color(int argc, char *argv[])
disp_light(); disp_light();
} }
static void handle_sound(int argc, char *argv[])
{
const char *usage = "Usage: sound <on|off>\n";
if (argc != 1) {
printf(usage);
return;
}
int on_off = cli_match_prefix((const char *[]){"off", "on"}, 2, argv[0]);
if (on_off < 0) {
printf(usage);
return;
}
geki_cfg->sound.enabled = on_off;
config_changed();
disp_sound();
}
static void handle_save() static void handle_save()
{ {
save_request(true); save_request(true);
@ -452,6 +435,25 @@ static void handle_aime(int argc, char *argv[])
} }
} }
static void handle_volume(int argc, char *argv[])
{
const char *usage = "Usage: sound <0..255>\n";
if (argc != 1) {
printf(usage);
return;
}
int vol = cli_extract_non_neg_int(argv[0], 0);
if ((vol >= 0) && (vol <= 255)) {
geki_cfg->sound.volume = vol;
config_changed();
disp_sound();
} else {
printf(usage);
}
}
void commands_init() void commands_init()
{ {
cli_register("display", handle_display, "Display all config."); cli_register("display", handle_display, "Display all config.");
@ -459,7 +461,7 @@ void commands_init()
cli_register("color", handle_color, "Set LED color."); cli_register("color", handle_color, "Set LED color.");
cli_register("hid", handle_hid, "Set HID mode."); cli_register("hid", handle_hid, "Set HID mode.");
cli_register("gimbal", handle_gimbal, "Calibrate the gimbals."); cli_register("gimbal", handle_gimbal, "Calibrate the gimbals.");
cli_register("sound", handle_sound, "Enable/disable sound."); cli_register("volume", handle_volume, "Sound feedback volume settings.");
cli_register("save", handle_save, "Save config to flash."); cli_register("save", handle_save, "Save config to flash.");
cli_register("factory", handle_factory_reset, "Reset everything to default."); cli_register("factory", handle_factory_reset, "Reset everything to default.");
cli_register("nfc", handle_nfc, "NFC debug."); cli_register("nfc", handle_nfc, "NFC debug.");

View File

@ -44,7 +44,7 @@ static geki_cfg_t default_cfg = {
.reserved = { 0 }, .reserved = { 0 },
}, },
.sound = { .sound = {
.enabled = true, .volume = 127,
.reserved = { 0 }, .reserved = { 0 },
}, },
.hid = { .hid = {

View File

@ -33,7 +33,7 @@ typedef struct __attribute__((packed)) {
uint8_t reserved[15]; uint8_t reserved[15];
} light; } light;
struct { struct {
bool enabled; uint8_t volume;
uint8_t reserved[3]; uint8_t reserved[3];
} sound; } sound;
struct { struct {

View File

@ -41,22 +41,35 @@ static void gen_hid_buttons()
{ 0, 0 }, { 0, 5 }, { 0, 4 }, // Left ABC { 0, 0 }, { 0, 5 }, { 0, 4 }, // Left ABC
{ 0, 1 }, { 1, 0 }, { 0, 15 }, // Right ABC { 0, 1 }, { 1, 0 }, { 0, 15 }, // Right ABC
{ 1, 14 }, { 0, 13 }, // AUX 12 { 1, 14 }, { 0, 13 }, // AUX 12
}, wad_left = { 1, 15 }, wad_right = { 0, 14 }; },
wad_left = { 1, 15 },
wad_right = { 0, 14 },
key_test = { 0, 9 },
key_service = { 0, 6 };
uint16_t buttons = button_read(); uint16_t buttons = button_read();
hid_joy.buttons[0] = 0; hid_joy.buttons[0] = 0;
hid_joy.buttons[1] = 0; hid_joy.buttons[1] = 0;
if (airkey_get(3)) {
if (buttons & 0x40) {
hid_joy.buttons[key_test.group] |= (1 << key_test.bit);
}
if (buttons & 0x80) {
hid_joy.buttons[key_service.group] |= (1 << key_service.bit);
}
return;
}
for (int i = 0; i < button_num(); i++) { for (int i = 0; i < button_num(); i++) {
uint8_t group = button_to_io4_map[i].group; uint8_t group = button_to_io4_map[i].group;
uint8_t bit = button_to_io4_map[i].bit; uint8_t bit = button_to_io4_map[i].bit;
if (buttons & (1 << i)) { if (buttons & (1 << i)) {
if (!airkey_get(3)) { hid_joy.buttons[group] |= (1 << bit);
hid_joy.buttons[group] |= (1 << bit);
}
} }
} }
if (!airkey_get(0)) { if (!airkey_get(0)) {
hid_joy.buttons[wad_left.group] |= (1 << wad_left.bit); hid_joy.buttons[wad_left.group] |= (1 << wad_left.bit);
} }
@ -78,7 +91,7 @@ static void gen_hid_coins()
dec_count = 0; dec_count = 0;
} }
if (dec_count > 100) { if (dec_count > 60) {
dec_count = 0; dec_count = 0;
hid_joy.chutes[0] += 0x100; hid_joy.chutes[0] += 0x100;
} }
@ -136,19 +149,18 @@ typedef struct __attribute__((packed)) {
static void update_led(const uint8_t data[4]) static void update_led(const uint8_t data[4])
{ {
const uint8_t led_bit[18] = { 30, 31, 28, 26, 27, 29, 23, 25, 24, 20, 22, 21, 17, 19, 18, 14, 16, 15 }; const uint8_t led_bit[18] = { 30, 31, 28, 26, 27, 29, 23, 25, 24,
20, 22, 21, 17, 19, 18, 14, 16, 15 };
uint32_t leds = (data[0] << 24) | (data[1] << 16) | uint32_t leds = (data[0] << 24) | (data[1] << 16) |
(data[2] << 8) | data[3]; (data[2] << 8) | data[3];
uint8_t rgbs[18];
for (uint8_t i = 0; i < 18; i++) {
rgbs[i] = ((leds >> led_bit[i]) & 1) ? 0xff : 0x00;
}
for (uint8_t i = 0; i < 6; i++) { for (uint8_t i = 0; i < 6; i++) {
uint32_t color = rgb32(rgbs[i * 3 + 1], rgbs[i * 3 + 2], rgbs[i * 3], false); bool r = leds & (1 << led_bit[i * 3 + 1]);
light_set_main(i, color); bool g = leds & (1 << led_bit[i * 3 + 2]);
bool b = leds & (1 << led_bit[i * 3]);
uint32_t color = rgb32(r ? 0xff : 0, g ? 0xff : 0, b ? 0xff : 0, false);
light_set_main(i, color, true);
} }
} }

View File

@ -20,9 +20,9 @@
#include "board_defs.h" #include "board_defs.h"
#include "config.h" #include "config.h"
static uint32_t buf_rgb[37]; // left 3 + right 3 + button 4 * 7 + indicator 5 #define HID_TIMEOUT 300*1000*1000
static bool bind[37] = { 0 };
static uint32_t buf_rgb[37]; // left 3 + right 3 + button 4 * 7 + indicator 5
static inline uint32_t _rgb32(uint32_t c1, uint32_t c2, uint32_t c3, bool gamma_fix) static inline uint32_t _rgb32(uint32_t c1, uint32_t c2, uint32_t c3, bool gamma_fix)
{ {
@ -110,20 +110,6 @@ void light_init()
ws2812_program_init(pio0, 0, offset, RGB_PIN, 800000, false); ws2812_program_init(pio0, 0, offset, RGB_PIN, 800000, false);
} }
static void light_effect()
{
return;
static uint32_t loop = 0;
loop++;
for (int i = 0; i < count_of(buf_rgb); i++) {
uint32_t hue = (loop + i * 255 / count_of(buf_rgb)) % 255;
if (!bind[i]) {
buf_rgb[i] = rgb32_from_hsv(hue, 255, 255);
}
}
}
void light_update() void light_update()
{ {
static uint64_t last = 0; static uint64_t last = 0;
@ -134,7 +120,6 @@ void light_update()
last = now; last = now;
light_effect();
drive_led(); drive_led();
} }
@ -144,11 +129,20 @@ void light_set(uint8_t index, uint32_t color)
return; return;
} }
buf_rgb[index] = apply_level(color); buf_rgb[index] = apply_level(color);
bind[index] = true;
} }
void light_set_main(uint8_t index, uint32_t color) void light_set_main(uint8_t index, uint32_t color, bool hid)
{ {
static uint64_t hid_timeout = 0;
uint64_t now = time_us_64();
if (!hid && (now < hid_timeout)) {
return;
}
if (hid) {
hid_timeout = time_us_64() + HID_TIMEOUT;
}
if (index < 3) { if (index < 3) {
light_set(index * 4 + 4, color); light_set(index * 4 + 4, color);
light_set(index * 4 + 5, color); light_set(index * 4 + 5, color);
@ -171,11 +165,30 @@ void light_set_aux(uint8_t index, uint32_t color)
} }
} }
void light_unset(uint8_t index) void light_set_wad(uint8_t index, uint32_t color)
{ {
if (index >= count_of(buf_rgb)) { if (index == 0) {
return; light_set(1, color);
light_set(2, color);
light_set(3, color);
} else if (index == 1) {
light_set(33, color);
light_set(34, color);
light_set(35, color);
}
}
void light_set_pos(uint8_t pos, uint32_t color)
{
pos = pos * 5 / 256;
for (int i = 0; i < 5; i++) {
light_set(16 + i, (i == pos) ? color : 0);
}
}
void light_set_aime(uint32_t color)
{
for (int i = 0; i < 5; i++) {
light_set(16 + i, color);
} }
bind[index] = false;
} }

View File

@ -19,10 +19,12 @@ uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix);
uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v); uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v);
uint32_t load_color(const rgb_hsv_t *color); uint32_t load_color(const rgb_hsv_t *color);
void light_set_main(uint8_t index, uint32_t color); void light_set_main(uint8_t index, uint32_t color, bool hid);
void light_set_aux(uint8_t index, uint32_t color); void light_set_aux(uint8_t index, uint32_t color);
void light_set_wad(uint8_t index, uint32_t color);
void light_set_pos(uint8_t pos, uint32_t color);
void light_set_aime(uint32_t color);
void light_set(uint8_t index, uint32_t color); void light_set(uint8_t index, uint32_t color);
void light_unset(uint8_t index);
#endif #endif

View File

@ -41,59 +41,33 @@
static void run_lights() static void run_lights()
{ {
int gimbal = 255 - gimbal_read(); light_set_pos(255 - gimbal_read(), rgb32(0xff, 0, 0, false));
uint16_t button = button_read(); uint16_t button = button_read();
gimbal = gimbal * 5 / 256; light_set_aux(0, button & 0x40 ? 0xc0c0c0 : rgb32(0x60, 0, 0, false));
for (int i = 0; i < 5; i++) { light_set_aux(1, button & 0x80 ? 0xc0c0c0 : rgb32(0x50, 0x50, 0, false));
light_set(16 + i, (i == gimbal) ? 0x00ff00 : 0);
}
light_set_aux(0, button & 0x40 ? rgb32(0x80, 0, 0, false) : 0); uint32_t phase = time_us_32() >> 15;
light_set_aux(1, button & 0x80 ? 0x808080 : 0);
if (airkey_get(3)) { if (airkey_get(3)) {
uint32_t phase = (time_us_32() >> 16) % 3; uint32_t phase = (time_us_32() >> 15) % 3;
light_set(1, phase == 0 ? 0x808080 : 0); for (int i = 0; i < 3; i++) {
light_set(2, phase == 1 ? 0x808080 : 0); light_set(1 + i, phase % 3 == i ? 0x808080 : 0);
light_set(3, phase == 2 ? 0x808080 : 0); light_set(33 + i, phase % 3 == i ? 0x808080 : 0);
light_set(33, phase == 0 ? 0x808080 : 0);
light_set(34, phase == 1 ? 0x808080 : 0);
light_set(35, phase == 2 ? 0x808080 : 0);
} else {
if (airkey_get(0)) {
light_set(1, 0x804000);
light_set(2, 0x804000);
light_set(3, 0x804000);
} else {
light_set(1, 0);
light_set(2, 0);
light_set(3, 0);
} }
} else {
if (airkey_get(1)) { for (int i = 0; i < 2; i++) {
light_set(33, 0x004080); light_set_wad(i, airkey_get(i) ? rgb32(0x80, 0, 0xff, false) : 0);
light_set(34, 0x004080);
light_set(35, 0x004080);
} else {
light_set(33, 0);
light_set(34, 0);
light_set(35, 0);
} }
} }
return;
uint32_t colors[6] = {0x400000, 0x004000, 0x000040,
0x400000, 0x004000, 0x000040 };
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
uint32_t color = colors[i]; uint32_t color = rgb32_from_hsv(phase + i * 40, 0xff, 0x80);
if (button & (1 << i)) { light_set_main(i, button & (1 << i) ? 0xffffff : color, false);
color = 0x808080;
}
light_set_main(i, color);
} }
} }
static void run_sound() static void run_sound()
{ {
if (airkey_get(3)) { if (airkey_get(3)) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,6 @@
#include "hardware/pwm.h" #include "hardware/pwm.h"
#include "ring.h" #include "ring.h"
#include "music.h"
#include "config.h" #include "config.h"
#include "board_defs.h" #include "board_defs.h"
@ -22,8 +21,8 @@
static const uint8_t sound_gpio[2] = SOUND_DEF; static const uint8_t sound_gpio[2] = SOUND_DEF;
static int slice_num[2]; static int slice_num[2];
static int wav_pos[2]; static int wav_pos[2];
static const int wav_len[2] = { sizeof(MUSIC_DATA), sizeof(RING_DATA)}; static const int wad_sound_len = sizeof(RING_DATA);
static const uint8_t *wav_data[2] = { MUSIC_DATA, RING_DATA}; static const uint8_t *wad_sound = RING_DATA;
static bool active[2]; static bool active[2];
void pwm_interrupt_handler() void pwm_interrupt_handler()
@ -39,14 +38,21 @@ void pwm_interrupt_handler()
continue; continue;
} }
int len = wav_len[i]; int pos = wav_pos[i] >> 3;
const uint8_t *data = wav_data[i]; if (pos >= wad_sound_len) {
if (wav_pos[i] < (len << 3) - 1) { pos = 0;
pwm_set_gpio_level(gpio, data[wav_pos[i] >> 3]);
wav_pos[i]++;
} else {
wav_pos[i] = 0; wav_pos[i] = 0;
} }
static int amplitude = 0;
if (wav_pos[i] & 0x07) {
amplitude = wad_sound[pos] * geki_cfg->sound.volume / 200;
if (amplitude > 250) {
amplitude = 250;
}
}
pwm_set_gpio_level(gpio, amplitude);
wav_pos[i]++;
} }
} }
@ -65,7 +71,7 @@ void sound_init()
irq_set_enabled(PWM_IRQ_WRAP, true); irq_set_enabled(PWM_IRQ_WRAP, true);
pwm_config cfg = pwm_get_default_config(); pwm_config cfg = pwm_get_default_config();
pwm_config_set_clkdiv(&cfg, 8.0f); pwm_config_set_clkdiv(&cfg, 4.0f); // 8.0f: 11kHz, 4.0f: 22kHz, 2.0f: 44kHz
pwm_config_set_wrap(&cfg, 250); pwm_config_set_wrap(&cfg, 250);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
@ -83,7 +89,7 @@ void sound_toggle(bool on)
void sound_set(int id, bool on) void sound_set(int id, bool on)
{ {
if (!geki_cfg->sound.enabled) { if (!geki_cfg->sound.volume) {
active[id] = false; active[id] = false;
return; return;
} }