1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2025-02-17 19:09:24 +01:00

Light follows aime or bana led commands

This commit is contained in:
whowechina 2024-04-21 16:03:32 +08:00
parent 6eb14a6ed1
commit 924b46ca53
6 changed files with 1074 additions and 947 deletions

View File

@ -1,22 +1,24 @@
/* /*
* Bandai Namco Protocol * Bandai Namco Protocol
* WHowe <github.com/whowechina> * WHowe <github.com/whowechina>
*/ */
#ifndef BANA_H #ifndef BANA_H
#define BANA_H #define BANA_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
/* return true if accepts a byte, false if rejects */ /* return true if accepts a byte, false if rejects */
typedef void (*bana_putc_func)(uint8_t byte); typedef void (*bana_putc_func)(uint8_t byte);
void bana_init(bana_putc_func putc_func); void bana_init(bana_putc_func putc_func);
bool bana_feed(int c); bool bana_feed(int c);
/* bana activity expires at this time */ /* bana activity expires at this time */
uint64_t bana_expire_time(); uint64_t bana_expire_time();
#endif uint32_t bana_led_color();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,79 +1,169 @@
/* /*
* Bandai Namco NFC Reader * Bandai Namco NFC Reader
* WHowe <github.com/whowechina> * WHowe <github.com/whowechina>
* *
* Use NFC Module to read BANA * Use NFC Module to read BANA
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include "bsp/board.h" #include "bsp/board.h"
#include "hardware/gpio.h" #include "hardware/gpio.h"
#include "hardware/i2c.h" #include "hardware/i2c.h"
#include "nfc.h" #include "nfc.h"
#include "bana.h" #include "bana.h"
#define BANA_EXPIRE_TIME 5000000ULL #define BANA_EXPIRE_TIME 5000000ULL
static void putc_trap(uint8_t byte) static void putc_trap(uint8_t byte)
{ {
} }
static bana_putc_func bana_putc = putc_trap; static bana_putc_func bana_putc = putc_trap;
void bana_init(bana_putc_func putc_func) static void bana_puts(const char *str, size_t len)
{ {
bana_putc = putc_func; for (size_t i = 0; i < len; i++) {
} bana_putc(str[i]);
}
/* }
static uint8_t mifare_keys[2][6]; // 'KeyA' and 'KeyB'
void bana_init(bana_putc_func putc_func)
static union __attribute__((packed)) { {
struct { bana_putc = putc_func;
}; }
uint8_t raw[256];
} response; typedef union __attribute__((packed)) {
struct {
static union __attribute__((packed)) { struct {
struct { uint8_t padding[3];
}; uint8_t len;
uint8_t raw[256]; uint8_t len_check;
} request; } hdr;
uint8_t dir;
struct { uint8_t cmd;
bool active; uint8_t data[0];
uint8_t len; };
uint8_t check_sum; uint8_t raw[48];
bool escaping; } message_t;
uint64_t time;
} req_ctx; static message_t request, response;
*/
struct {
typedef struct __attribute__((packed)) { uint8_t frame_len;
uint8_t count; uint32_t time;
uint8_t type; } req_ctx;
uint8_t id_len;
union { typedef struct __attribute__((packed)) {
struct { uint8_t count;
uint8_t idm[8]; uint8_t type;
uint8_t pmm[8]; uint8_t id_len;
}; union {
uint8_t uid[6]; struct {
}; uint8_t idm[8];
} card_info_t; uint8_t pmm[8];
};
static uint64_t expire_time; uint8_t uid[6];
};
bool bana_feed(int c) } card_info_t;
{
return true; static uint64_t expire_time;
}
static void send_response()
uint64_t bana_expire_time() {
{ uint8_t checksum = 0xff;
return expire_time; for (int i = 0; i < response.hdr.len; i++) {
} checksum += response.raw[5 + i];
}
memcpy(response.hdr.padding, "\x00\x00\xff", 3);
response.hdr.len_check = ~response.hdr.len + 1;
response.raw[5 + response.hdr.len] = ~checksum;
response.raw[6 + response.hdr.len] = 0;
int total_len = 7 + response.hdr.len;
bana_puts((const char *)response.raw, total_len);
printf("\nResp: %d %d\n", response.hdr.len, response.cmd);
for (int i = 0; i < total_len; i++) {
printf(">%02x", response.raw[i]);
}
}
static void send_simple_response(uint8_t code)
{
response.hdr.len = 2;
response.dir = 0xd5;
response.cmd = code;
send_response();
}
static void send_ack()
{
bana_puts("\x00\x00\xff\x00\xff\x00", 6);
}
static uint32_t led_color = 0;
static void handle_frame()
{
printf("\nBana: %d %02x", request.hdr.len, request.cmd);
if (request.hdr.len == 0) {
send_ack();
return;
}
if (request.hdr.len + 7 != req_ctx.frame_len) {
return;
}
if (request.hdr.len != 0) {
printf("Req: %d %02x", request.hdr.len, request.cmd);
send_simple_response(request.cmd + 1);
}
}
bool bana_feed(int c)
{
uint32_t now = time_us_32();
if ((req_ctx.frame_len == sizeof(request)) ||
(now - req_ctx.time > 100000)) {
req_ctx.frame_len = 0;
}
req_ctx.time = now;
request.raw[req_ctx.frame_len] = c;
req_ctx.frame_len++;
if ((req_ctx.frame_len == 1) && (request.raw[0] == 0x55)) {
req_ctx.frame_len = 0;
} if ((req_ctx.frame_len == 3) &&
(memcmp(request.hdr.padding, "\x00\x00\xff", 3) != 0)) {
request.raw[0] = request.raw[1];
request.raw[1] = request.raw[2];
req_ctx.frame_len--;
} if ((req_ctx.frame_len == 6) && (request.hdr.len == 0)) {
req_ctx.frame_len = 0;
} else if (req_ctx.frame_len == request.hdr.len + 7) {
handle_frame();
req_ctx.frame_len = 0;
expire_time = time_us_64() + BANA_EXPIRE_TIME;
}
return true;
}
uint64_t bana_expire_time()
{
return expire_time;
}
uint32_t bana_led_color()
{
return led_color;
}

View File

@ -237,10 +237,18 @@ void light_init()
} }
} }
static bool rainbow = true;
void light_set_rainbow(bool enable)
{
rainbow = enable;
}
void light_update() void light_update()
{ {
generate_color_wheel(); if (rainbow) {
rainbow_update(); generate_color_wheel();
rainbow_fade(); rainbow_update();
rainbow_fade();
}
drive_led(); drive_led();
} }

View File

@ -1,25 +1,27 @@
/* /*
* RGB LED (WS2812) Strip control * RGB LED (WS2812) Strip control
* WHowe <github.com/whowechina> * WHowe <github.com/whowechina>
*/ */
#ifndef RGB_H #ifndef RGB_H
#define RGB_H #define RGB_H
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "config.h" #include "config.h"
void light_init(); void light_init();
void light_update(); void light_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 light_set_color(unsigned index, uint32_t color); void light_set_color(unsigned index, uint32_t color);
void light_set_color_all(uint32_t color); void light_set_color_all(uint32_t color);
void light_stimulate();
void light_set_rainbow(bool enable);
#endif void light_stimulate();
#endif

View File

@ -1,308 +1,333 @@
/* /*
* Controller Main * Controller Main
* WHowe <github.com/whowechina> * WHowe <github.com/whowechina>
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "pico/stdio.h" #include "pico/stdio.h"
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "bsp/board.h" #include "bsp/board.h"
#include "pico/multicore.h" #include "pico/multicore.h"
#include "pico/bootrom.h" #include "pico/bootrom.h"
#include "hardware/gpio.h" #include "hardware/gpio.h"
#include "hardware/sync.h" #include "hardware/sync.h"
#include "hardware/structs/ioqspi.h" #include "hardware/structs/ioqspi.h"
#include "hardware/structs/sio.h" #include "hardware/structs/sio.h"
#include "board_defs.h" #include "board_defs.h"
#include "tusb.h" #include "tusb.h"
#include "usb_descriptors.h" #include "usb_descriptors.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 "light.h" #include "light.h"
#include "keypad.h" #include "keypad.h"
#include "nfc.h" #include "nfc.h"
#include "aime.h" #include "aime.h"
#include "bana.h"
static struct {
uint8_t current[9]; static struct {
uint8_t reported[9]; uint8_t current[9];
uint64_t report_time; uint8_t reported[9];
} hid_cardio; uint64_t report_time;
} hid_cardio;
void report_hid_cardio()
{ void report_hid_cardio()
if (!tud_hid_ready()) { {
return; if (!tud_hid_ready()) {
} return;
}
uint64_t now = time_us_64();
uint64_t now = time_us_64();
if (memcmp(hid_cardio.current, "\0\0\0\0\0\0\0\0\0", 9) != 0) {
light_stimulate(); if (memcmp(hid_cardio.current, "\0\0\0\0\0\0\0\0\0", 9) != 0) {
} light_stimulate();
}
if ((memcmp(hid_cardio.current, hid_cardio.reported, 9) != 0) &&
(now - hid_cardio.report_time > 1000000)) { if ((memcmp(hid_cardio.current, hid_cardio.reported, 9) != 0) &&
(now - hid_cardio.report_time > 1000000)) {
tud_hid_n_report(0x00, hid_cardio.current[0], hid_cardio.current + 1, 8);
memcpy(hid_cardio.reported, hid_cardio.current, 9); tud_hid_n_report(0x00, hid_cardio.current[0], hid_cardio.current + 1, 8);
hid_cardio.report_time = now; memcpy(hid_cardio.reported, hid_cardio.current, 9);
} hid_cardio.report_time = now;
} }
}
struct __attribute__((packed)) {
uint8_t modifier; struct __attribute__((packed)) {
uint8_t keymap[15]; uint8_t modifier;
} hid_nkro; uint8_t keymap[15];
} hid_nkro;
static const char keymap[12] = KEYPAD_NKRO_MAP;
static const char keymap[12] = KEYPAD_NKRO_MAP;
void report_hid_key()
{ void report_hid_key()
if (!tud_hid_ready()) { {
return; if (!tud_hid_ready()) {
} return;
}
uint16_t keys = keypad_read();
for (int i = 0; i < keypad_key_num(); i++) { uint16_t keys = keypad_read();
uint8_t code = keymap[i]; for (int i = 0; i < keypad_key_num(); i++) {
uint8_t byte = code / 8; uint8_t code = keymap[i];
uint8_t bit = code % 8; uint8_t byte = code / 8;
if (keys & (1 << i)) { uint8_t bit = code % 8;
hid_nkro.keymap[byte] |= (1 << bit); if (keys & (1 << i)) {
} else { hid_nkro.keymap[byte] |= (1 << bit);
hid_nkro.keymap[byte] &= ~(1 << bit); } else {
} hid_nkro.keymap[byte] &= ~(1 << bit);
} }
tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro)); }
} tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro));
}
void report_usb_hid()
{ void report_usb_hid()
report_hid_cardio(); {
report_hid_key(); report_hid_cardio();
} report_hid_key();
}
static mutex_t core1_io_lock;
static void core1_loop() static void light_effect()
{ {
while (1) { uint64_t now = time_us_64();
if (mutex_try_enter(&core1_io_lock, NULL)) { if (now < aime_expire_time()) {
light_update(); light_set_rainbow(false);
mutex_exit(&core1_io_lock); light_set_color_all(aime_led_color());
} } else if (now < bana_expire_time()) {
cli_fps_count(1); light_set_rainbow(false);
sleep_us(500); light_set_color_all(bana_led_color());
} } else {
} light_set_rainbow(true);
}
static void update_cardio(nfc_card_t *card) light_update();
{ }
switch (card->card_type) {
case NFC_CARD_MIFARE: static mutex_t core1_io_lock;
hid_cardio.current[0] = REPORT_ID_EAMU; static void core1_loop()
hid_cardio.current[1] = 0xe0; {
hid_cardio.current[2] = 0x04; while (1) {
if (card->len == 4) { if (mutex_try_enter(&core1_io_lock, NULL)) {
memcpy(hid_cardio.current + 3, card->uid, 4); light_effect();
memcpy(hid_cardio.current + 7, card->uid, 2); mutex_exit(&core1_io_lock);
} else if (card->len == 7) { }
memcpy(hid_cardio.current + 3, card->uid + 1, 6); cli_fps_count(1);
} sleep_us(500);
break; }
case NFC_CARD_FELICA: }
hid_cardio.current[0] = REPORT_ID_FELICA;
memcpy(hid_cardio.current + 1, card->uid, 8); static void update_cardio(nfc_card_t *card)
break; {
case NFC_CARD_VICINITY: switch (card->card_type) {
hid_cardio.current[0] = REPORT_ID_EAMU; case NFC_CARD_MIFARE:
memcpy(hid_cardio.current + 1, card->uid, 8); hid_cardio.current[0] = REPORT_ID_EAMU;
break; hid_cardio.current[1] = 0xe0;
default: hid_cardio.current[2] = 0x04;
memset(hid_cardio.current, 0, 9); if (card->len == 4) {
return; memcpy(hid_cardio.current + 3, card->uid, 4);
} memcpy(hid_cardio.current + 7, card->uid, 2);
} else if (card->len == 7) {
printf(" -> CardIO "); memcpy(hid_cardio.current + 3, card->uid + 1, 6);
for (int i = 1; i < 9; i++) { }
printf("%02X", hid_cardio.current[i]); break;
} case NFC_CARD_FELICA:
} hid_cardio.current[0] = REPORT_ID_FELICA;
memcpy(hid_cardio.current + 1, card->uid, 8);
void detect_card() break;
{ case NFC_CARD_VICINITY:
if (time_us_64() < aime_expire_time()) { hid_cardio.current[0] = REPORT_ID_EAMU;
return; memcpy(hid_cardio.current + 1, card->uid, 8);
} break;
default:
static nfc_card_t old_card = { 0 }; memset(hid_cardio.current, 0, 9);
return;
nfc_rf_field(true); }
nfc_card_t card = nfc_detect_card();
nfc_rf_field(false); printf(" -> CardIO ");
for (int i = 1; i < 9; i++) {
if (memcmp(&old_card, &card, sizeof(old_card)) == 0) { printf("%02X", hid_cardio.current[i]);
return; }
} }
old_card = card; void detect_card()
{
display_card(&card); if ((time_us_64() < aime_expire_time()) ||
update_cardio(&card); (time_us_64() < bana_expire_time())) {
} return;
}
const int aime_intf = 1;
static void cdc_aime_putc(uint8_t byte) static nfc_card_t old_card = { 0 };
{
tud_cdc_n_write(aime_intf, &byte, 1); nfc_rf_field(true);
tud_cdc_n_write_flush(aime_intf); nfc_card_t card = nfc_detect_card();
} nfc_rf_field(false);
static void aime_run() if (memcmp(&old_card, &card, sizeof(old_card)) == 0) {
{ return;
if (tud_cdc_n_available(aime_intf)) { }
uint8_t buf[32];
int count = tud_cdc_n_read(aime_intf, buf, sizeof(buf)); old_card = card;
for (int i = 0; i < count; i++) {
if ((aic_cfg->mode & 0xf0) == 0) { display_card(&card);
aime_feed(buf[i]); update_cardio(&card);
} else { }
//bana_feed(buf[i]);
} const int aime_intf = 1;
} static void cdc_aime_putc(uint8_t byte)
} {
} tud_cdc_n_write(aime_intf, &byte, 1);
tud_cdc_n_write_flush(aime_intf);
void wait_loop() }
{
keypad_update(); static void aime_run()
report_hid_key(); {
if (tud_cdc_n_available(aime_intf)) {
tud_task(); uint8_t buf[32];
cli_run(); int count = tud_cdc_n_read(aime_intf, buf, sizeof(buf));
if (count <= 0) {
cli_fps_count(0); return;
} }
static void core0_loop() printf("\n> ");
{ for (int i = 0; i < count; i++) {
while(1) { printf("|%02x", buf[i]);
tud_task(); if ((aic_cfg->mode & 0xf0) == 0) {
aime_feed(buf[i]);
cli_run(); } else {
aime_run(); bana_feed(buf[i]);
}
save_loop(); }
cli_fps_count(0);
light_set_color_all(aime_led_color());
keypad_update(); }
detect_card(); }
report_usb_hid(); void wait_loop()
{
sleep_ms(1); keypad_update();
} report_hid_key();
}
tud_task();
void init() cli_run();
{
tusb_init(); cli_fps_count(0);
stdio_init_all(); }
light_init();
keypad_init(); static void core0_loop()
{
config_init(); while(1) {
mutex_init(&core1_io_lock); tud_task();
save_init(0xca340a1c, &core1_io_lock);
cli_run();
nfc_init_i2c(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ); aime_run();
nfc_init_spi(SPI_PORT, SPI_MISO, SPI_SCK, SPI_MOSI, SPI_RST, SPI_NSS, SPI_BUSY);
nfc_init(); save_loop();
nfc_set_wait_loop(wait_loop); cli_fps_count(0);
aime_init(cdc_aime_putc); keypad_update();
aime_virtual_aic(aic_cfg->virtual_aic); detect_card();
if ((aic_cfg->mode & 0x0f) == 0) { report_usb_hid();
aime_set_mode(aic_cfg->mode);
} sleep_ms(1);
}
//bana_init(); }
cli_init("aic_pico>", "\n << AIC Pico >>\n" void init()
" https://github.com/whowechina\n\n"); {
tusb_init();
commands_init(); stdio_init_all();
} light_init();
keypad_init();
/* if certain key pressed when booting, enter update mode */
static void update_check() config_init();
{ mutex_init(&core1_io_lock);
const uint8_t pins[] = { 10, 11 }; // keypad 00 and * save_init(0xca340a1c, &core1_io_lock);
bool all_pressed = true;
for (int i = 0; i < sizeof(pins); i++) { nfc_init_i2c(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ);
uint8_t gpio = pins[i]; nfc_init_spi(SPI_PORT, SPI_MISO, SPI_SCK, SPI_MOSI, SPI_RST, SPI_NSS, SPI_BUSY);
gpio_init(gpio); nfc_init();
gpio_set_function(gpio, GPIO_FUNC_SIO); nfc_set_wait_loop(wait_loop);
gpio_set_dir(gpio, GPIO_IN);
gpio_pull_up(gpio); aime_init(cdc_aime_putc);
sleep_ms(1); aime_virtual_aic(aic_cfg->virtual_aic);
if (gpio_get(gpio)) {
all_pressed = false; if ((aic_cfg->mode & 0x0f) == 0) {
break; aime_set_mode(aic_cfg->mode);
} }
}
bana_init(cdc_aime_putc);
if (all_pressed) {
sleep_ms(100); cli_init("aic_pico>", "\n << AIC Pico >>\n"
reset_usb_boot(0, 2); " https://github.com/whowechina\n\n");
return;
} commands_init();
} }
static void sys_init() /* if certain key pressed when booting, enter update mode */
{ static void update_check()
sleep_ms(50); {
set_sys_clock_khz(150000, true); const uint8_t pins[] = { 10, 11 }; // keypad 00 and *
board_init(); bool all_pressed = true;
} for (int i = 0; i < sizeof(pins); i++) {
uint8_t gpio = pins[i];
int main(void) gpio_init(gpio);
{ gpio_set_function(gpio, GPIO_FUNC_SIO);
sys_init(); gpio_set_dir(gpio, GPIO_IN);
update_check(); gpio_pull_up(gpio);
init(); sleep_ms(1);
multicore_launch_core1(core1_loop); if (gpio_get(gpio)) {
core0_loop(); all_pressed = false;
return 0; break;
} }
}
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length. if (all_pressed) {
// Return zero will cause the stack to STALL request sleep_ms(100);
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, reset_usb_boot(0, 2);
hid_report_type_t report_type, uint8_t *buffer, return;
uint16_t reqlen) }
{ }
printf("Get from USB %d-%d\n", report_id, report_type);
return 0; static void sys_init()
} {
sleep_ms(50);
// Invoked when received SET_REPORT control request or set_sys_clock_khz(150000, true);
// received data on OUT endpoint ( Report ID = 0, Type = 0 ) board_init();
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, }
hid_report_type_t report_type, uint8_t const *buffer,
uint16_t bufsize) int main(void)
{ {
} sys_init();
update_check();
init();
multicore_launch_core1(core1_loop);
core0_loop();
return 0;
}
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id,
hid_report_type_t report_type, uint8_t *buffer,
uint16_t reqlen)
{
printf("Get from USB %d-%d\n", report_id, report_type);
return 0;
}
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id,
hid_report_type_t report_type, uint8_t const *buffer,
uint16_t bufsize)
{
}