mirror of
https://github.com/whowechina/mai_pico.git
synced 2024-11-30 22:17:17 +01:00
Just playable now
This commit is contained in:
parent
fec2f5e6f7
commit
aef8ce1931
@ -4,8 +4,8 @@ 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 touch.c rgb.c save.c config.c cli.c commands.c mpr121.c
|
main.c touch.c button.c rgb.c save.c config.c cli.c commands.c io.c
|
||||||
usb_descriptors.c)
|
mpr121.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)
|
||||||
|
@ -12,8 +12,14 @@
|
|||||||
|
|
||||||
#define RGB_PIN 13
|
#define RGB_PIN 13
|
||||||
#define RGB_ORDER GRB // or RGB
|
#define RGB_ORDER GRB // or RGB
|
||||||
|
#define RGB_BUTTON_MAP { 5, 4, 3, 2, 1, 0, 7, 6 }
|
||||||
|
|
||||||
#define NKRO_KEYMAP "1aqz2swx3dec4frv5gtb6hyn7jum8ki90olp,."
|
#define BUTTON_DEF { 1, 0, 4, 5, 8, 9, 3, 2 }
|
||||||
|
#define BUTTON_NKRO_MAP "WEDCXZAQ"
|
||||||
|
|
||||||
|
#define TOUCH_MAP { E3, A2, B2, D2, E2, A1, B1, D1, E1, C2, A8, B8, \
|
||||||
|
D8, E8, A7, B7, D7, E7, A6, B6, D6, E6, A5, B5, \
|
||||||
|
D5, E5, C1, A4, B4, D4, E4, A3, B3, D3 }
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
76
firmware/src/button.c
Normal file
76
firmware/src/button.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Mai Controller Buttons
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "button.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "hardware/timer.h"
|
||||||
|
#include "hardware/pwm.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "board_defs.h"
|
||||||
|
|
||||||
|
static const uint8_t button_gpio[] = BUTTON_DEF;
|
||||||
|
|
||||||
|
#define BUTTON_NUM (sizeof(button_gpio))
|
||||||
|
|
||||||
|
static bool sw_val[BUTTON_NUM]; /* true if pressed */
|
||||||
|
static uint64_t sw_freeze_time[BUTTON_NUM];
|
||||||
|
|
||||||
|
void button_init()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < BUTTON_NUM; i++)
|
||||||
|
{
|
||||||
|
sw_val[i] = false;
|
||||||
|
sw_freeze_time[i] = 0;
|
||||||
|
int8_t gpio = button_gpio[i];
|
||||||
|
gpio_init(gpio);
|
||||||
|
gpio_set_function(gpio, GPIO_FUNC_SIO);
|
||||||
|
gpio_set_dir(gpio, GPIO_IN);
|
||||||
|
gpio_pull_up(gpio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t button_num()
|
||||||
|
{
|
||||||
|
return BUTTON_NUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t button_reading;
|
||||||
|
|
||||||
|
/* If a switch flips, it freezes for a while */
|
||||||
|
#define DEBOUNCE_FREEZE_TIME_US 1000
|
||||||
|
void button_update()
|
||||||
|
{
|
||||||
|
uint64_t now = time_us_64();
|
||||||
|
uint16_t buttons = 0;
|
||||||
|
|
||||||
|
for (int i = BUTTON_NUM - 1; i >= 0; i--) {
|
||||||
|
bool sw_pressed = !gpio_get(button_gpio[i]);
|
||||||
|
|
||||||
|
if (now >= sw_freeze_time[i]) {
|
||||||
|
if (sw_pressed != sw_val[i]) {
|
||||||
|
sw_val[i] = sw_pressed;
|
||||||
|
sw_freeze_time[i] = now + DEBOUNCE_FREEZE_TIME_US;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons <<= 1;
|
||||||
|
if (sw_val[i]) {
|
||||||
|
buttons |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button_reading = buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t button_read()
|
||||||
|
{
|
||||||
|
return button_reading;
|
||||||
|
}
|
18
firmware/src/button.h
Normal file
18
firmware/src/button.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Mai Controller Buttons
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BUTTONS_H
|
||||||
|
#define BUTTONS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "hardware/flash.h"
|
||||||
|
|
||||||
|
void button_init();
|
||||||
|
uint8_t button_num();
|
||||||
|
void button_update();
|
||||||
|
uint16_t button_read();
|
||||||
|
|
||||||
|
#endif
|
260
firmware/src/io.c
Normal file
260
firmware/src/io.c
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "io.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "usb_descriptors.h"
|
||||||
|
|
||||||
|
#include "touch.h"
|
||||||
|
#include "rgb.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
bool stat;
|
||||||
|
uint64_t last_io_time;
|
||||||
|
int touch_interface;
|
||||||
|
} ctx = { false, 0, 0 };
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
uint8_t raw[28];
|
||||||
|
struct {
|
||||||
|
uint8_t body;
|
||||||
|
uint8_t ext;
|
||||||
|
uint8_t side;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint8_t index;
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint8_t start;
|
||||||
|
uint8_t len;
|
||||||
|
uint8_t skip;
|
||||||
|
uint8_t mr;
|
||||||
|
uint8_t mg;
|
||||||
|
uint8_t mb;
|
||||||
|
uint8_t speed;
|
||||||
|
};
|
||||||
|
uint8_t rgb[11][3];
|
||||||
|
} led_data_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int interface;
|
||||||
|
bool connected;
|
||||||
|
bool in_cmd;
|
||||||
|
bool is_touch;
|
||||||
|
bool escape;
|
||||||
|
union {
|
||||||
|
uint8_t buf[48];
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
uint8_t dst;
|
||||||
|
uint8_t src;
|
||||||
|
uint8_t len;
|
||||||
|
uint8_t cmd;
|
||||||
|
} hdr;
|
||||||
|
led_data_t data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
uint8_t len;
|
||||||
|
uint8_t checksum;
|
||||||
|
} cdc_t;
|
||||||
|
|
||||||
|
static cdc_t cdc[2] = {
|
||||||
|
{ .interface = 1 },
|
||||||
|
{ .interface = 2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void touch_cmd(cdc_t *cdc)
|
||||||
|
{
|
||||||
|
cdc->in_cmd = false;
|
||||||
|
if (cdc->len != 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cdc->len = 0;
|
||||||
|
ctx.last_io_time = time_us_64();
|
||||||
|
|
||||||
|
ctx.touch_interface = cdc->interface;
|
||||||
|
|
||||||
|
printf("Touch CMD: %*s -> ", 4, cdc->buf);
|
||||||
|
switch (cdc->buf[2]) {
|
||||||
|
case 'E':
|
||||||
|
printf("RSET\n");
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
printf("HALT\n");
|
||||||
|
ctx.stat = false;
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
printf("STAT\n");
|
||||||
|
ctx.stat = true;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
printf("Ratio\n");
|
||||||
|
tud_cdc_n_write_char(cdc->interface, '(');
|
||||||
|
tud_cdc_n_write_char(cdc->interface, cdc->buf[0]); //L,R
|
||||||
|
tud_cdc_n_write_char(cdc->interface, cdc->buf[1]); //sensor
|
||||||
|
tud_cdc_n_write_char(cdc->interface, 'r');
|
||||||
|
tud_cdc_n_write_char(cdc->interface, cdc->buf[3]); // Ratio
|
||||||
|
tud_cdc_n_write_char(cdc->interface, ')');
|
||||||
|
tud_cdc_n_write_flush(cdc->interface);
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
printf("Sense\n");
|
||||||
|
tud_cdc_n_write_char(cdc->interface, '(');
|
||||||
|
tud_cdc_n_write_char(cdc->interface, cdc->buf[0]); //L,R
|
||||||
|
tud_cdc_n_write_char(cdc->interface, cdc->buf[1]); //sensor
|
||||||
|
tud_cdc_n_write_char(cdc->interface, 'k');
|
||||||
|
tud_cdc_n_write_char(cdc->interface, cdc->buf[3]); // Ratio
|
||||||
|
tud_cdc_n_write_char(cdc->interface, ')');
|
||||||
|
tud_cdc_n_write_flush(cdc->interface);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void led_cmd(cdc_t *cdc)
|
||||||
|
{
|
||||||
|
cdc->in_cmd = false;
|
||||||
|
cdc->len = 0;
|
||||||
|
ctx.last_io_time = time_us_64();
|
||||||
|
|
||||||
|
switch (cdc->hdr.cmd) {
|
||||||
|
case 0x31:
|
||||||
|
printf("8b\n");
|
||||||
|
uint32_t color = rgb32(cdc->data.r, cdc->data.g, cdc->data.b, false);
|
||||||
|
rgb_set_button_color(cdc->data.index, color);
|
||||||
|
break;
|
||||||
|
case 0x32:
|
||||||
|
printf("8bM\n");
|
||||||
|
for (int i = 0; i < cdc->data.len; i++) {
|
||||||
|
rgb_set_button_color(i + cdc->data.start, rgb32(cdc->data.mr, cdc->data.mg, cdc->data.mb, false));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x33:
|
||||||
|
printf("8bMF\n");
|
||||||
|
for (int i = 0; i < cdc->data.len; i++) {
|
||||||
|
rgb_set_button_color(i + cdc->data.start, rgb32(cdc->data.mr, cdc->data.mg, cdc->data.mb, false));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x39:
|
||||||
|
printf("Fet\n");
|
||||||
|
rgb_set_cab_color(0, rgb32(cdc->data.body, cdc->data.body, cdc->data.body, false));
|
||||||
|
rgb_set_cab_color(1, rgb32(cdc->data.ext, cdc->data.ext, cdc->data.ext, false));
|
||||||
|
rgb_set_cab_color(2, rgb32(cdc->data.side, cdc->data.side, cdc->data.side, false));
|
||||||
|
break;
|
||||||
|
case 0x3C:
|
||||||
|
printf("Upd\n");
|
||||||
|
break;
|
||||||
|
case 0x82:
|
||||||
|
printf("Dir\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("LEDUnk\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void assemble_cmd(cdc_t *cdc, uint8_t c)
|
||||||
|
{
|
||||||
|
if (c == 0xE0) {
|
||||||
|
cdc->len = 0;
|
||||||
|
cdc->in_cmd = true;
|
||||||
|
cdc->is_touch = false;
|
||||||
|
cdc->escape = false;
|
||||||
|
cdc->checksum = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!cdc->in_cmd || cdc->is_touch) && (c == '{')) {
|
||||||
|
cdc->len = 0;
|
||||||
|
cdc->in_cmd = true;
|
||||||
|
cdc->is_touch = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdc->is_touch) {
|
||||||
|
// Touch cmd
|
||||||
|
if (c == '}') {
|
||||||
|
touch_cmd(cdc);
|
||||||
|
} else if (cdc->len < sizeof(cdc->buf)) {
|
||||||
|
cdc->buf[cdc->len] = c;
|
||||||
|
cdc->len++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LED cmd
|
||||||
|
if (c == 0xD0) {
|
||||||
|
cdc->escape = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdc->escape) {
|
||||||
|
cdc->escape = false;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cdc->len == cdc->hdr.len + 3) && (cdc->checksum == c)) {
|
||||||
|
led_cmd(cdc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdc->len < sizeof(cdc->buf)) {
|
||||||
|
cdc->buf[cdc->len] = c;
|
||||||
|
cdc->len++;
|
||||||
|
cdc->checksum += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_itf(cdc_t *cdc)
|
||||||
|
{
|
||||||
|
cdc->connected = tud_cdc_n_connected(cdc->interface);
|
||||||
|
|
||||||
|
if (tud_cdc_n_available(cdc->interface)) {
|
||||||
|
uint8_t buf[48];
|
||||||
|
uint32_t count = tud_cdc_n_read(cdc->interface, buf, sizeof(buf));
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
assemble_cmd(cdc, buf[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_touch()
|
||||||
|
{
|
||||||
|
if ((ctx.touch_interface == 0) | (!ctx.stat)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t last_sent_time = 0;
|
||||||
|
uint32_t now = time_us_32();
|
||||||
|
if (now - last_sent_time < 5000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_sent_time = now;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t report[9] = "(\0\0\0\0\0\0\0)";
|
||||||
|
uint64_t touch = touch_touchmap();
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
report[i + 1] = touch & 0x1f;
|
||||||
|
touch >>= 5;
|
||||||
|
}
|
||||||
|
tud_cdc_n_write(ctx.touch_interface, report, sizeof(report));
|
||||||
|
tud_cdc_n_write_flush(ctx.touch_interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_update()
|
||||||
|
{
|
||||||
|
update_itf(cdc);
|
||||||
|
update_itf(cdc + 1);
|
||||||
|
send_touch();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t io_last_io_time()
|
||||||
|
{
|
||||||
|
return ctx.last_io_time;
|
||||||
|
}
|
12
firmware/src/io.h
Normal file
12
firmware/src/io.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Game I/O
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IO_H_
|
||||||
|
#define IO_H_
|
||||||
|
|
||||||
|
void io_update();
|
||||||
|
uint64_t io_last_io_time();
|
||||||
|
|
||||||
|
#endif
|
@ -24,12 +24,14 @@
|
|||||||
#include "board_defs.h"
|
#include "board_defs.h"
|
||||||
|
|
||||||
#include "touch.h"
|
#include "touch.h"
|
||||||
|
#include "button.h"
|
||||||
|
#include "rgb.h"
|
||||||
|
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
#include "io.h"
|
||||||
#include "rgb.h"
|
|
||||||
|
|
||||||
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
|
||||||
@ -48,9 +50,6 @@ 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;
|
||||||
if (mai_cfg->hid.joy) {
|
|
||||||
tud_hid_n_report(0x00, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy));
|
|
||||||
}
|
|
||||||
if (mai_cfg->hid.nkro &&
|
if (mai_cfg->hid.nkro &&
|
||||||
(memcmp(&hid_nkro, &sent_hid_nkro, sizeof(hid_nkro)) != 0)) {
|
(memcmp(&hid_nkro, &sent_hid_nkro, sizeof(hid_nkro)) != 0)) {
|
||||||
sent_hid_nkro = hid_nkro;
|
sent_hid_nkro = hid_nkro;
|
||||||
@ -59,40 +58,16 @@ void report_usb_hid()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_joy_report()
|
|
||||||
{
|
|
||||||
hid_joy.axis = 0;
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
if (touch_touched(i * 2)) {
|
|
||||||
hid_joy.axis |= 1 << (30 - i * 2);
|
|
||||||
}
|
|
||||||
if (touch_touched(i * 2 + 1)) {
|
|
||||||
hid_joy.axis |= 1 << (31 - i * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
hid_joy.axis ^= 0x80808080; // some magic number from CrazyRedMachine
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t keycode_table[128][2] = { HID_ASCII_TO_KEYCODE };
|
const uint8_t keycode_table[128][2] = { HID_ASCII_TO_KEYCODE };
|
||||||
const char keymap[38 + 1] = NKRO_KEYMAP; // 32 keys, 6 air keys, 1 terminator
|
const char keymap[8] = BUTTON_NKRO_MAP; // 8 buttons
|
||||||
static void gen_nkro_report()
|
static void gen_nkro_report()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 32; i++) {
|
uint16_t buttons = button_read();
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
uint8_t code = keycode_table[keymap[i]][1];
|
uint8_t code = keycode_table[keymap[i]][1];
|
||||||
uint8_t byte = code / 8;
|
uint8_t byte = code / 8;
|
||||||
uint8_t bit = code % 8;
|
uint8_t bit = code % 8;
|
||||||
if (touch_touched(i)) {
|
if (buttons & (1 << i)) {
|
||||||
hid_nkro.keymap[byte] |= (1 << bit);
|
|
||||||
} else {
|
|
||||||
hid_nkro.keymap[byte] &= ~(1 << bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
uint8_t code = keycode_table[keymap[32 + i]][1];
|
|
||||||
uint8_t byte = code / 8;
|
|
||||||
uint8_t bit = code % 8;
|
|
||||||
if (hid_joy.buttons & (1 << i)) {
|
|
||||||
hid_nkro.keymap[byte] |= (1 << bit);
|
hid_nkro.keymap[byte] |= (1 << bit);
|
||||||
} else {
|
} else {
|
||||||
hid_nkro.keymap[byte] &= ~(1 << bit);
|
hid_nkro.keymap[byte] &= ~(1 << bit);
|
||||||
@ -109,68 +84,21 @@ static void run_lights()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t colors[5] = { 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xffffff };
|
if (now - io_last_io_time() < 5000000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t buttons = button_read();
|
||||||
|
uint16_t touch = touch_touchmap();
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
rgb_set_color(i, 0);
|
uint32_t color = 0;
|
||||||
}
|
if (buttons & (1 << i)) {
|
||||||
for (int i = 0; i < 34; i++) {
|
color |= 0x00ff00;
|
||||||
if (touch_touched(i)) {
|
|
||||||
if (i < 32) {
|
|
||||||
rgb_set_color((i + 16) / 4 % 8, colors[i % 4]);
|
|
||||||
} else {
|
|
||||||
rgb_set_color(i - 32, colors[4]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for (int i = 0; i < 15; i++) {
|
|
||||||
// uint32_t color = rgb32_from_hsv(i * 255 / 8, 255, 16);
|
|
||||||
// rgb_set_color(i, color);
|
|
||||||
// }
|
|
||||||
|
|
||||||
for (int i = 0; i < 34; i++) {
|
|
||||||
// bool r = touch_touched(i * 2);
|
|
||||||
// bool g = touch_touched(i * 2 + 1);
|
|
||||||
// rgb_set_color(30 - i * 2, rgb32(r ? 80 : 0, g ? 80 : 0, 0, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count)
|
|
||||||
{
|
|
||||||
//tud_cdc_n_write_char(itf, buf[i]);
|
|
||||||
//tud_cdc_n_write_flush(itf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cdc_task(void)
|
|
||||||
{
|
|
||||||
uint8_t itf;
|
|
||||||
|
|
||||||
for (itf = 1; itf < CFG_TUD_CDC; itf++)
|
|
||||||
{
|
|
||||||
// connected() check for DTR bit
|
|
||||||
// Most but not all terminal client set this when making connection
|
|
||||||
// if ( tud_cdc_n_connected(itf) )
|
|
||||||
if ( tud_cdc_n_available(itf) )
|
|
||||||
{
|
|
||||||
uint8_t buf[64];
|
|
||||||
|
|
||||||
uint32_t count = tud_cdc_n_read(itf, buf, sizeof(buf));
|
|
||||||
|
|
||||||
if (itf == 1) {
|
|
||||||
printf("1 TXT:", itf);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
printf("%c", buf[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
} else if (itf == 2) {
|
|
||||||
printf("2 HEX:", itf);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
printf(" %02x", buf[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
if (touch & (1 << i)) {
|
||||||
|
color |= 0xff0000;
|
||||||
}
|
}
|
||||||
|
rgb_set_button_color(i, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,15 +120,15 @@ static void core0_loop()
|
|||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
tud_task();
|
tud_task();
|
||||||
cdc_task();
|
io_update();
|
||||||
|
|
||||||
cli_run();
|
cli_run();
|
||||||
save_loop();
|
save_loop();
|
||||||
cli_fps_count(0);
|
cli_fps_count(0);
|
||||||
|
|
||||||
touch_update();
|
touch_update();
|
||||||
|
button_update();
|
||||||
|
|
||||||
gen_joy_report();
|
|
||||||
gen_nkro_report();
|
gen_nkro_report();
|
||||||
report_usb_hid();
|
report_usb_hid();
|
||||||
}
|
}
|
||||||
@ -219,6 +147,7 @@ void init()
|
|||||||
save_init(0xca34cafe, &core1_io_lock);
|
save_init(0xca34cafe, &core1_io_lock);
|
||||||
|
|
||||||
touch_init();
|
touch_init();
|
||||||
|
button_init();
|
||||||
rgb_init();
|
rgb_init();
|
||||||
|
|
||||||
cli_init("mai_pico>", "\n << Mai Pico Controller >>\n"
|
cli_init("mai_pico>", "\n << Mai Pico Controller >>\n"
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
|
||||||
static uint32_t rgb_buf[20];
|
static uint32_t rgb_buf[20];
|
||||||
|
static const uint8_t button_led_map[] = RGB_BUTTON_MAP;
|
||||||
|
|
||||||
#define _MAP_LED(x) _MAKE_MAPPER(x)
|
#define _MAP_LED(x) _MAKE_MAPPER(x)
|
||||||
#define _MAKE_MAPPER(x) MAP_LED_##x
|
#define _MAKE_MAPPER(x) MAP_LED_##x
|
||||||
@ -121,28 +122,20 @@ static inline uint32_t apply_level(uint32_t color)
|
|||||||
return r << 16 | g << 8 | b;
|
return r << 16 | g << 8 | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rgb_set_color(unsigned index, uint32_t color)
|
void rgb_set_button_color(unsigned index, uint32_t color)
|
||||||
{
|
{
|
||||||
if (index >= ARRAY_SIZE(rgb_buf)) {
|
if (index >= 8) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rgb_buf[index] = apply_level(color);
|
rgb_buf[button_led_map[index]] = apply_level(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rgb_set_brg(unsigned index, const uint8_t *brg_array, size_t num)
|
void rgb_set_cab_color(unsigned index, uint32_t color)
|
||||||
{
|
{
|
||||||
if (index >= ARRAY_SIZE(rgb_buf)) {
|
if (index >= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (index + num > ARRAY_SIZE(rgb_buf)) {
|
rgb_buf[8 + index] = apply_level(color);
|
||||||
num = ARRAY_SIZE(rgb_buf) - index;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < num; i++) {
|
|
||||||
uint8_t b = brg_array[i * 3 + 0];
|
|
||||||
uint8_t r = brg_array[i * 3 + 1];
|
|
||||||
uint8_t g = brg_array[i * 3 + 2];
|
|
||||||
rgb_buf[index + i] = apply_level(rgb32(r, g, b, false));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rgb_init()
|
void rgb_init()
|
||||||
|
@ -18,8 +18,8 @@ void rgb_update();
|
|||||||
uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix);
|
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);
|
||||||
|
|
||||||
void rgb_set_colors(const uint32_t *colors, unsigned index, size_t num);
|
void rgb_set_button_color(unsigned index, uint32_t color);
|
||||||
void rgb_set_color(unsigned index, uint32_t color);
|
void rgb_set_cab_color(unsigned index, uint32_t color);
|
||||||
|
|
||||||
/* num of the rgb leds, num*3 bytes in the array */
|
/* num of the rgb leds, num*3 bytes in the array */
|
||||||
void rgb_set_brg(unsigned index, const uint8_t *brg_array, size_t num);
|
void rgb_set_brg(unsigned index, const uint8_t *brg_array, size_t num);
|
||||||
|
@ -22,10 +22,18 @@
|
|||||||
|
|
||||||
#define MPR121_ADDR 0x5A
|
#define MPR121_ADDR 0x5A
|
||||||
|
|
||||||
static uint16_t readout[36];
|
|
||||||
static uint16_t touch[3];
|
static uint16_t touch[3];
|
||||||
static unsigned touch_counts[36];
|
static unsigned touch_counts[36];
|
||||||
|
|
||||||
|
enum touch_pads {
|
||||||
|
A1 = 0, A2, A3, A4, A5, A6, A7, A8,
|
||||||
|
B1, B2, B3, B4, B5, B6, B7, B8,
|
||||||
|
C1, C2, D1, D2, D3, D4, D5, D6, D7, D8,
|
||||||
|
E1, E2, E3, E4, E5, E6, E7, E8,
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned touch_map[] = TOUCH_MAP;
|
||||||
|
|
||||||
void touch_init()
|
void touch_init()
|
||||||
{
|
{
|
||||||
i2c_init(I2C_PORT, I2C_FREQ);
|
i2c_init(I2C_PORT, I2C_FREQ);
|
||||||
@ -40,30 +48,57 @@ void touch_init()
|
|||||||
touch_update_config();
|
touch_update_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void touch_update()
|
static uint64_t touch_reading;
|
||||||
|
|
||||||
|
static void remap_reading()
|
||||||
{
|
{
|
||||||
static uint16_t last_touched[3];
|
uint64_t map = 0;
|
||||||
|
|
||||||
touch[0] = mpr121_touched(MPR121_ADDR);
|
|
||||||
touch[1] = mpr121_touched(MPR121_ADDR + 1);
|
|
||||||
touch[2] = mpr121_touched(MPR121_ADDR + 2);
|
|
||||||
|
|
||||||
for (int m = 0; m < 3; m++) {
|
for (int m = 0; m < 3; m++) {
|
||||||
uint16_t just_touched = touch[m] & ~last_touched[m];
|
|
||||||
last_touched[m] = touch[m];
|
|
||||||
for (int i = 0; i < 12; i++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
if (just_touched & (1 << i)) {
|
if (touch[m] & (1 << i)) {
|
||||||
touch_counts[m * 12 + i]++;
|
map |= 1ULL << touch_map[m * 12 + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
touch_reading = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void touch_stat()
|
||||||
|
{
|
||||||
|
static uint64_t last_reading;
|
||||||
|
|
||||||
|
uint64_t just_touched = touch_reading & ~last_reading;
|
||||||
|
last_reading = touch_reading;
|
||||||
|
|
||||||
|
for (int i = 0; i < 34; i++) {
|
||||||
|
if (just_touched & (1ULL << i)) {
|
||||||
|
touch_counts[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void touch_update()
|
||||||
|
{
|
||||||
|
touch[0] = mpr121_touched(MPR121_ADDR) & 0x0fff;
|
||||||
|
touch[1] = mpr121_touched(MPR121_ADDR + 1) & 0x0fff;
|
||||||
|
touch[2] = mpr121_touched(MPR121_ADDR + 2) & 0x0fff;
|
||||||
|
|
||||||
|
remap_reading();
|
||||||
|
|
||||||
|
touch_stat();
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint16_t *touch_raw()
|
const uint16_t *touch_raw()
|
||||||
{
|
{
|
||||||
mpr121_raw(MPR121_ADDR, readout, 12);
|
static uint16_t readout[36];
|
||||||
mpr121_raw(MPR121_ADDR + 1, readout + 12, 12);
|
uint16_t buf[36];
|
||||||
mpr121_raw(MPR121_ADDR + 2, readout + 24, 12);
|
mpr121_raw(MPR121_ADDR, buf, 12);
|
||||||
|
mpr121_raw(MPR121_ADDR + 1, buf + 12, 12);
|
||||||
|
mpr121_raw(MPR121_ADDR + 2, buf + 24, 10);
|
||||||
|
|
||||||
|
for (int i = 0; i < 34; i++) {
|
||||||
|
readout[touch_map[i]] = buf[i];
|
||||||
|
}
|
||||||
return readout;
|
return readout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +107,12 @@ bool touch_touched(unsigned key)
|
|||||||
if (key >= 34) {
|
if (key >= 34) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return touch[key / 12] & (1 << (key % 12));
|
return touch_reading & (1ULL << key);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t touch_touchmap()
|
||||||
|
{
|
||||||
|
return touch_reading;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned touch_count(unsigned key)
|
unsigned touch_count(unsigned key)
|
||||||
|
@ -12,10 +12,11 @@
|
|||||||
void touch_init();
|
void touch_init();
|
||||||
void touch_update();
|
void touch_update();
|
||||||
bool touch_touched(unsigned key);
|
bool touch_touched(unsigned key);
|
||||||
|
uint64_t touch_touchmap();
|
||||||
|
|
||||||
const uint16_t *touch_raw();
|
const uint16_t *touch_raw();
|
||||||
void touch_update_config();
|
void touch_update_config();
|
||||||
unsigned touch_count(unsigned key);
|
unsigned touch_count(unsigned key);
|
||||||
void touch_reset_stat();
|
void touch_reset_stat();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user