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)
|
||||
pico_sdk_init()
|
||||
add_executable(${board}
|
||||
main.c touch.c rgb.c save.c config.c cli.c commands.c mpr121.c
|
||||
usb_descriptors.c)
|
||||
main.c touch.c button.c rgb.c save.c config.c cli.c commands.c io.c
|
||||
mpr121.c usb_descriptors.c)
|
||||
target_compile_definitions(${board} PUBLIC ${board_def})
|
||||
pico_enable_stdio_usb(${board} 1)
|
||||
pico_enable_stdio_uart(${board} 0)
|
||||
|
@ -12,8 +12,14 @@
|
||||
|
||||
#define RGB_PIN 13
|
||||
#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
|
||||
|
||||
#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 "touch.h"
|
||||
#include "button.h"
|
||||
#include "rgb.h"
|
||||
|
||||
#include "save.h"
|
||||
#include "config.h"
|
||||
#include "cli.h"
|
||||
#include "commands.h"
|
||||
|
||||
#include "rgb.h"
|
||||
#include "io.h"
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint16_t buttons; // 16 buttons; see JoystickButtons_t for bit mapping
|
||||
@ -48,10 +50,7 @@ void report_usb_hid()
|
||||
if (tud_hid_ready()) {
|
||||
hid_joy.HAT = 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)) {
|
||||
sent_hid_nkro = hid_nkro;
|
||||
tud_hid_n_report(0x02, 0, &sent_hid_nkro, sizeof(sent_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 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()
|
||||
{
|
||||
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 byte = code / 8;
|
||||
uint8_t bit = code % 8;
|
||||
if (touch_touched(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)) {
|
||||
if (buttons & (1 << i)) {
|
||||
hid_nkro.keymap[byte] |= (1 << bit);
|
||||
} else {
|
||||
hid_nkro.keymap[byte] &= ~(1 << bit);
|
||||
@ -109,68 +84,21 @@ static void run_lights()
|
||||
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++) {
|
||||
rgb_set_color(i, 0);
|
||||
}
|
||||
for (int i = 0; i < 34; i++) {
|
||||
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]);
|
||||
}
|
||||
uint32_t color = 0;
|
||||
if (buttons & (1 << i)) {
|
||||
color |= 0x00ff00;
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
tud_task();
|
||||
cdc_task();
|
||||
io_update();
|
||||
|
||||
cli_run();
|
||||
save_loop();
|
||||
cli_fps_count(0);
|
||||
|
||||
touch_update();
|
||||
button_update();
|
||||
|
||||
gen_joy_report();
|
||||
gen_nkro_report();
|
||||
report_usb_hid();
|
||||
}
|
||||
@ -219,6 +147,7 @@ void init()
|
||||
save_init(0xca34cafe, &core1_io_lock);
|
||||
|
||||
touch_init();
|
||||
button_init();
|
||||
rgb_init();
|
||||
|
||||
cli_init("mai_pico>", "\n << Mai Pico Controller >>\n"
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
static uint32_t rgb_buf[20];
|
||||
static const uint8_t button_led_map[] = RGB_BUTTON_MAP;
|
||||
|
||||
#define _MAP_LED(x) _MAKE_MAPPER(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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (index + num > ARRAY_SIZE(rgb_buf)) {
|
||||
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));
|
||||
}
|
||||
rgb_buf[8 + index] = apply_level(color);
|
||||
}
|
||||
|
||||
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_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_color(unsigned index, uint32_t color);
|
||||
void rgb_set_button_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 */
|
||||
void rgb_set_brg(unsigned index, const uint8_t *brg_array, size_t num);
|
||||
|
@ -22,10 +22,18 @@
|
||||
|
||||
#define MPR121_ADDR 0x5A
|
||||
|
||||
static uint16_t readout[36];
|
||||
static uint16_t touch[3];
|
||||
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()
|
||||
{
|
||||
i2c_init(I2C_PORT, I2C_FREQ);
|
||||
@ -40,30 +48,57 @@ void touch_init()
|
||||
touch_update_config();
|
||||
}
|
||||
|
||||
void touch_update()
|
||||
static uint64_t touch_reading;
|
||||
|
||||
static void remap_reading()
|
||||
{
|
||||
static uint16_t last_touched[3];
|
||||
|
||||
touch[0] = mpr121_touched(MPR121_ADDR);
|
||||
touch[1] = mpr121_touched(MPR121_ADDR + 1);
|
||||
touch[2] = mpr121_touched(MPR121_ADDR + 2);
|
||||
|
||||
uint64_t map = 0;
|
||||
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++) {
|
||||
if (just_touched & (1 << i)) {
|
||||
touch_counts[m * 12 + i]++;
|
||||
if (touch[m] & (1 << 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()
|
||||
{
|
||||
mpr121_raw(MPR121_ADDR, readout, 12);
|
||||
mpr121_raw(MPR121_ADDR + 1, readout + 12, 12);
|
||||
mpr121_raw(MPR121_ADDR + 2, readout + 24, 12);
|
||||
static uint16_t readout[36];
|
||||
uint16_t buf[36];
|
||||
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;
|
||||
}
|
||||
|
||||
@ -72,7 +107,12 @@ bool touch_touched(unsigned key)
|
||||
if (key >= 34) {
|
||||
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)
|
||||
|
@ -12,10 +12,11 @@
|
||||
void touch_init();
|
||||
void touch_update();
|
||||
bool touch_touched(unsigned key);
|
||||
uint64_t touch_touchmap();
|
||||
|
||||
const uint16_t *touch_raw();
|
||||
void touch_update_config();
|
||||
unsigned touch_count(unsigned key);
|
||||
void touch_reset_stat();
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user