mirror of
https://github.com/whowechina/aic_pico.git
synced 2024-11-24 05:50:11 +01:00
Light follows aime or bana led commands
This commit is contained in:
parent
6eb14a6ed1
commit
924b46ca53
@ -1,22 +1,24 @@
|
||||
/*
|
||||
* Bandai Namco Protocol
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#ifndef BANA_H
|
||||
#define BANA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* return true if accepts a byte, false if rejects */
|
||||
typedef void (*bana_putc_func)(uint8_t byte);
|
||||
|
||||
void bana_init(bana_putc_func putc_func);
|
||||
|
||||
bool bana_feed(int c);
|
||||
|
||||
/* bana activity expires at this time */
|
||||
uint64_t bana_expire_time();
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Bandai Namco Protocol
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#ifndef BANA_H
|
||||
#define BANA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* return true if accepts a byte, false if rejects */
|
||||
typedef void (*bana_putc_func)(uint8_t byte);
|
||||
|
||||
void bana_init(bana_putc_func putc_func);
|
||||
|
||||
bool bana_feed(int c);
|
||||
|
||||
/* bana activity expires at this time */
|
||||
uint64_t bana_expire_time();
|
||||
|
||||
uint32_t bana_led_color();
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,79 +1,169 @@
|
||||
/*
|
||||
* Bandai Namco NFC Reader
|
||||
* WHowe <github.com/whowechina>
|
||||
*
|
||||
* Use NFC Module to read BANA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bsp/board.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/i2c.h"
|
||||
|
||||
#include "nfc.h"
|
||||
#include "bana.h"
|
||||
|
||||
#define BANA_EXPIRE_TIME 5000000ULL
|
||||
|
||||
static void putc_trap(uint8_t byte)
|
||||
{
|
||||
}
|
||||
|
||||
static bana_putc_func bana_putc = putc_trap;
|
||||
|
||||
void bana_init(bana_putc_func putc_func)
|
||||
{
|
||||
bana_putc = putc_func;
|
||||
}
|
||||
|
||||
/*
|
||||
static uint8_t mifare_keys[2][6]; // 'KeyA' and 'KeyB'
|
||||
|
||||
static union __attribute__((packed)) {
|
||||
struct {
|
||||
};
|
||||
uint8_t raw[256];
|
||||
} response;
|
||||
|
||||
static union __attribute__((packed)) {
|
||||
struct {
|
||||
};
|
||||
uint8_t raw[256];
|
||||
} request;
|
||||
|
||||
struct {
|
||||
bool active;
|
||||
uint8_t len;
|
||||
uint8_t check_sum;
|
||||
bool escaping;
|
||||
uint64_t time;
|
||||
} req_ctx;
|
||||
*/
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t count;
|
||||
uint8_t type;
|
||||
uint8_t id_len;
|
||||
union {
|
||||
struct {
|
||||
uint8_t idm[8];
|
||||
uint8_t pmm[8];
|
||||
};
|
||||
uint8_t uid[6];
|
||||
};
|
||||
} card_info_t;
|
||||
|
||||
static uint64_t expire_time;
|
||||
|
||||
bool bana_feed(int c)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t bana_expire_time()
|
||||
{
|
||||
return expire_time;
|
||||
}
|
||||
/*
|
||||
* Bandai Namco NFC Reader
|
||||
* WHowe <github.com/whowechina>
|
||||
*
|
||||
* Use NFC Module to read BANA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bsp/board.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/i2c.h"
|
||||
|
||||
#include "nfc.h"
|
||||
#include "bana.h"
|
||||
|
||||
#define BANA_EXPIRE_TIME 5000000ULL
|
||||
|
||||
static void putc_trap(uint8_t byte)
|
||||
{
|
||||
}
|
||||
|
||||
static bana_putc_func bana_putc = putc_trap;
|
||||
|
||||
static void bana_puts(const char *str, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
bana_putc(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void bana_init(bana_putc_func putc_func)
|
||||
{
|
||||
bana_putc = putc_func;
|
||||
}
|
||||
|
||||
typedef union __attribute__((packed)) {
|
||||
struct {
|
||||
struct {
|
||||
uint8_t padding[3];
|
||||
uint8_t len;
|
||||
uint8_t len_check;
|
||||
} hdr;
|
||||
uint8_t dir;
|
||||
uint8_t cmd;
|
||||
uint8_t data[0];
|
||||
};
|
||||
uint8_t raw[48];
|
||||
} message_t;
|
||||
|
||||
static message_t request, response;
|
||||
|
||||
struct {
|
||||
uint8_t frame_len;
|
||||
uint32_t time;
|
||||
} req_ctx;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t count;
|
||||
uint8_t type;
|
||||
uint8_t id_len;
|
||||
union {
|
||||
struct {
|
||||
uint8_t idm[8];
|
||||
uint8_t pmm[8];
|
||||
};
|
||||
uint8_t uid[6];
|
||||
};
|
||||
} card_info_t;
|
||||
|
||||
static uint64_t expire_time;
|
||||
|
||||
static void send_response()
|
||||
{
|
||||
uint8_t checksum = 0xff;
|
||||
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;
|
||||
}
|
||||
|
@ -237,10 +237,18 @@ void light_init()
|
||||
}
|
||||
}
|
||||
|
||||
static bool rainbow = true;
|
||||
void light_set_rainbow(bool enable)
|
||||
{
|
||||
rainbow = enable;
|
||||
}
|
||||
|
||||
void light_update()
|
||||
{
|
||||
generate_color_wheel();
|
||||
rainbow_update();
|
||||
rainbow_fade();
|
||||
if (rainbow) {
|
||||
generate_color_wheel();
|
||||
rainbow_update();
|
||||
rainbow_fade();
|
||||
}
|
||||
drive_led();
|
||||
}
|
||||
|
@ -1,25 +1,27 @@
|
||||
/*
|
||||
* RGB LED (WS2812) Strip control
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#ifndef RGB_H
|
||||
#define RGB_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void light_init();
|
||||
void light_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 light_set_color(unsigned index, uint32_t color);
|
||||
void light_set_color_all(uint32_t color);
|
||||
void light_stimulate();
|
||||
|
||||
#endif
|
||||
/*
|
||||
* RGB LED (WS2812) Strip control
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#ifndef RGB_H
|
||||
#define RGB_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void light_init();
|
||||
void light_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 light_set_color(unsigned index, uint32_t color);
|
||||
void light_set_color_all(uint32_t color);
|
||||
|
||||
void light_set_rainbow(bool enable);
|
||||
void light_stimulate();
|
||||
|
||||
#endif
|
||||
|
@ -1,308 +1,333 @@
|
||||
/*
|
||||
* Controller Main
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pico/stdio.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include "bsp/board.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "pico/bootrom.h"
|
||||
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/sync.h"
|
||||
#include "hardware/structs/ioqspi.h"
|
||||
#include "hardware/structs/sio.h"
|
||||
|
||||
#include "board_defs.h"
|
||||
|
||||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
#include "save.h"
|
||||
#include "config.h"
|
||||
#include "cli.h"
|
||||
#include "commands.h"
|
||||
#include "light.h"
|
||||
#include "keypad.h"
|
||||
|
||||
#include "nfc.h"
|
||||
|
||||
#include "aime.h"
|
||||
|
||||
static struct {
|
||||
uint8_t current[9];
|
||||
uint8_t reported[9];
|
||||
uint64_t report_time;
|
||||
} hid_cardio;
|
||||
|
||||
void report_hid_cardio()
|
||||
{
|
||||
if (!tud_hid_ready()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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, 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);
|
||||
hid_cardio.report_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t modifier;
|
||||
uint8_t keymap[15];
|
||||
} hid_nkro;
|
||||
|
||||
static const char keymap[12] = KEYPAD_NKRO_MAP;
|
||||
|
||||
void report_hid_key()
|
||||
{
|
||||
if (!tud_hid_ready()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t keys = keypad_read();
|
||||
for (int i = 0; i < keypad_key_num(); i++) {
|
||||
uint8_t code = keymap[i];
|
||||
uint8_t byte = code / 8;
|
||||
uint8_t bit = code % 8;
|
||||
if (keys & (1 << i)) {
|
||||
hid_nkro.keymap[byte] |= (1 << bit);
|
||||
} else {
|
||||
hid_nkro.keymap[byte] &= ~(1 << bit);
|
||||
}
|
||||
}
|
||||
tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro));
|
||||
}
|
||||
|
||||
void report_usb_hid()
|
||||
{
|
||||
report_hid_cardio();
|
||||
report_hid_key();
|
||||
}
|
||||
|
||||
static mutex_t core1_io_lock;
|
||||
static void core1_loop()
|
||||
{
|
||||
while (1) {
|
||||
if (mutex_try_enter(&core1_io_lock, NULL)) {
|
||||
light_update();
|
||||
mutex_exit(&core1_io_lock);
|
||||
}
|
||||
cli_fps_count(1);
|
||||
sleep_us(500);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_cardio(nfc_card_t *card)
|
||||
{
|
||||
switch (card->card_type) {
|
||||
case NFC_CARD_MIFARE:
|
||||
hid_cardio.current[0] = REPORT_ID_EAMU;
|
||||
hid_cardio.current[1] = 0xe0;
|
||||
hid_cardio.current[2] = 0x04;
|
||||
if (card->len == 4) {
|
||||
memcpy(hid_cardio.current + 3, card->uid, 4);
|
||||
memcpy(hid_cardio.current + 7, card->uid, 2);
|
||||
} else if (card->len == 7) {
|
||||
memcpy(hid_cardio.current + 3, card->uid + 1, 6);
|
||||
}
|
||||
break;
|
||||
case NFC_CARD_FELICA:
|
||||
hid_cardio.current[0] = REPORT_ID_FELICA;
|
||||
memcpy(hid_cardio.current + 1, card->uid, 8);
|
||||
break;
|
||||
case NFC_CARD_VICINITY:
|
||||
hid_cardio.current[0] = REPORT_ID_EAMU;
|
||||
memcpy(hid_cardio.current + 1, card->uid, 8);
|
||||
break;
|
||||
default:
|
||||
memset(hid_cardio.current, 0, 9);
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" -> CardIO ");
|
||||
for (int i = 1; i < 9; i++) {
|
||||
printf("%02X", hid_cardio.current[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void detect_card()
|
||||
{
|
||||
if (time_us_64() < aime_expire_time()) {
|
||||
return;
|
||||
}
|
||||
|
||||
static nfc_card_t old_card = { 0 };
|
||||
|
||||
nfc_rf_field(true);
|
||||
nfc_card_t card = nfc_detect_card();
|
||||
nfc_rf_field(false);
|
||||
|
||||
if (memcmp(&old_card, &card, sizeof(old_card)) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
old_card = card;
|
||||
|
||||
display_card(&card);
|
||||
update_cardio(&card);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void aime_run()
|
||||
{
|
||||
if (tud_cdc_n_available(aime_intf)) {
|
||||
uint8_t buf[32];
|
||||
int count = tud_cdc_n_read(aime_intf, buf, sizeof(buf));
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((aic_cfg->mode & 0xf0) == 0) {
|
||||
aime_feed(buf[i]);
|
||||
} else {
|
||||
//bana_feed(buf[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wait_loop()
|
||||
{
|
||||
keypad_update();
|
||||
report_hid_key();
|
||||
|
||||
tud_task();
|
||||
cli_run();
|
||||
|
||||
cli_fps_count(0);
|
||||
}
|
||||
|
||||
static void core0_loop()
|
||||
{
|
||||
while(1) {
|
||||
tud_task();
|
||||
|
||||
cli_run();
|
||||
aime_run();
|
||||
|
||||
save_loop();
|
||||
cli_fps_count(0);
|
||||
|
||||
keypad_update();
|
||||
detect_card();
|
||||
|
||||
report_usb_hid();
|
||||
|
||||
sleep_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
tusb_init();
|
||||
stdio_init_all();
|
||||
light_init();
|
||||
keypad_init();
|
||||
|
||||
config_init();
|
||||
mutex_init(&core1_io_lock);
|
||||
save_init(0xca340a1c, &core1_io_lock);
|
||||
|
||||
nfc_init_i2c(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ);
|
||||
nfc_init_spi(SPI_PORT, SPI_MISO, SPI_SCK, SPI_MOSI, SPI_RST, SPI_NSS, SPI_BUSY);
|
||||
nfc_init();
|
||||
nfc_set_wait_loop(wait_loop);
|
||||
|
||||
aime_init(cdc_aime_putc);
|
||||
aime_virtual_aic(aic_cfg->virtual_aic);
|
||||
|
||||
if ((aic_cfg->mode & 0x0f) == 0) {
|
||||
aime_set_mode(aic_cfg->mode);
|
||||
}
|
||||
|
||||
//bana_init();
|
||||
|
||||
cli_init("aic_pico>", "\n << AIC Pico >>\n"
|
||||
" https://github.com/whowechina\n\n");
|
||||
|
||||
commands_init();
|
||||
}
|
||||
|
||||
/* if certain key pressed when booting, enter update mode */
|
||||
static void update_check()
|
||||
{
|
||||
const uint8_t pins[] = { 10, 11 }; // keypad 00 and *
|
||||
bool all_pressed = true;
|
||||
for (int i = 0; i < sizeof(pins); i++) {
|
||||
uint8_t gpio = pins[i];
|
||||
gpio_init(gpio);
|
||||
gpio_set_function(gpio, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(gpio, GPIO_IN);
|
||||
gpio_pull_up(gpio);
|
||||
sleep_ms(1);
|
||||
if (gpio_get(gpio)) {
|
||||
all_pressed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (all_pressed) {
|
||||
sleep_ms(100);
|
||||
reset_usb_boot(0, 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void sys_init()
|
||||
{
|
||||
sleep_ms(50);
|
||||
set_sys_clock_khz(150000, true);
|
||||
board_init();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
/*
|
||||
* Controller Main
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pico/stdio.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include "bsp/board.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "pico/bootrom.h"
|
||||
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/sync.h"
|
||||
#include "hardware/structs/ioqspi.h"
|
||||
#include "hardware/structs/sio.h"
|
||||
|
||||
#include "board_defs.h"
|
||||
|
||||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
#include "save.h"
|
||||
#include "config.h"
|
||||
#include "cli.h"
|
||||
#include "commands.h"
|
||||
#include "light.h"
|
||||
#include "keypad.h"
|
||||
|
||||
#include "nfc.h"
|
||||
|
||||
#include "aime.h"
|
||||
#include "bana.h"
|
||||
|
||||
static struct {
|
||||
uint8_t current[9];
|
||||
uint8_t reported[9];
|
||||
uint64_t report_time;
|
||||
} hid_cardio;
|
||||
|
||||
void report_hid_cardio()
|
||||
{
|
||||
if (!tud_hid_ready()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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, 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);
|
||||
hid_cardio.report_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t modifier;
|
||||
uint8_t keymap[15];
|
||||
} hid_nkro;
|
||||
|
||||
static const char keymap[12] = KEYPAD_NKRO_MAP;
|
||||
|
||||
void report_hid_key()
|
||||
{
|
||||
if (!tud_hid_ready()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t keys = keypad_read();
|
||||
for (int i = 0; i < keypad_key_num(); i++) {
|
||||
uint8_t code = keymap[i];
|
||||
uint8_t byte = code / 8;
|
||||
uint8_t bit = code % 8;
|
||||
if (keys & (1 << i)) {
|
||||
hid_nkro.keymap[byte] |= (1 << bit);
|
||||
} else {
|
||||
hid_nkro.keymap[byte] &= ~(1 << bit);
|
||||
}
|
||||
}
|
||||
tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro));
|
||||
}
|
||||
|
||||
void report_usb_hid()
|
||||
{
|
||||
report_hid_cardio();
|
||||
report_hid_key();
|
||||
}
|
||||
|
||||
static void light_effect()
|
||||
{
|
||||
uint64_t now = time_us_64();
|
||||
if (now < aime_expire_time()) {
|
||||
light_set_rainbow(false);
|
||||
light_set_color_all(aime_led_color());
|
||||
} else if (now < bana_expire_time()) {
|
||||
light_set_rainbow(false);
|
||||
light_set_color_all(bana_led_color());
|
||||
} else {
|
||||
light_set_rainbow(true);
|
||||
}
|
||||
light_update();
|
||||
}
|
||||
|
||||
static mutex_t core1_io_lock;
|
||||
static void core1_loop()
|
||||
{
|
||||
while (1) {
|
||||
if (mutex_try_enter(&core1_io_lock, NULL)) {
|
||||
light_effect();
|
||||
mutex_exit(&core1_io_lock);
|
||||
}
|
||||
cli_fps_count(1);
|
||||
sleep_us(500);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_cardio(nfc_card_t *card)
|
||||
{
|
||||
switch (card->card_type) {
|
||||
case NFC_CARD_MIFARE:
|
||||
hid_cardio.current[0] = REPORT_ID_EAMU;
|
||||
hid_cardio.current[1] = 0xe0;
|
||||
hid_cardio.current[2] = 0x04;
|
||||
if (card->len == 4) {
|
||||
memcpy(hid_cardio.current + 3, card->uid, 4);
|
||||
memcpy(hid_cardio.current + 7, card->uid, 2);
|
||||
} else if (card->len == 7) {
|
||||
memcpy(hid_cardio.current + 3, card->uid + 1, 6);
|
||||
}
|
||||
break;
|
||||
case NFC_CARD_FELICA:
|
||||
hid_cardio.current[0] = REPORT_ID_FELICA;
|
||||
memcpy(hid_cardio.current + 1, card->uid, 8);
|
||||
break;
|
||||
case NFC_CARD_VICINITY:
|
||||
hid_cardio.current[0] = REPORT_ID_EAMU;
|
||||
memcpy(hid_cardio.current + 1, card->uid, 8);
|
||||
break;
|
||||
default:
|
||||
memset(hid_cardio.current, 0, 9);
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" -> CardIO ");
|
||||
for (int i = 1; i < 9; i++) {
|
||||
printf("%02X", hid_cardio.current[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void detect_card()
|
||||
{
|
||||
if ((time_us_64() < aime_expire_time()) ||
|
||||
(time_us_64() < bana_expire_time())) {
|
||||
return;
|
||||
}
|
||||
|
||||
static nfc_card_t old_card = { 0 };
|
||||
|
||||
nfc_rf_field(true);
|
||||
nfc_card_t card = nfc_detect_card();
|
||||
nfc_rf_field(false);
|
||||
|
||||
if (memcmp(&old_card, &card, sizeof(old_card)) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
old_card = card;
|
||||
|
||||
display_card(&card);
|
||||
update_cardio(&card);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void aime_run()
|
||||
{
|
||||
if (tud_cdc_n_available(aime_intf)) {
|
||||
uint8_t buf[32];
|
||||
int count = tud_cdc_n_read(aime_intf, buf, sizeof(buf));
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\n> ");
|
||||
for (int i = 0; i < count; i++) {
|
||||
printf("|%02x", buf[i]);
|
||||
if ((aic_cfg->mode & 0xf0) == 0) {
|
||||
aime_feed(buf[i]);
|
||||
} else {
|
||||
bana_feed(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
light_set_color_all(aime_led_color());
|
||||
}
|
||||
}
|
||||
|
||||
void wait_loop()
|
||||
{
|
||||
keypad_update();
|
||||
report_hid_key();
|
||||
|
||||
tud_task();
|
||||
cli_run();
|
||||
|
||||
cli_fps_count(0);
|
||||
}
|
||||
|
||||
static void core0_loop()
|
||||
{
|
||||
while(1) {
|
||||
tud_task();
|
||||
|
||||
cli_run();
|
||||
aime_run();
|
||||
|
||||
save_loop();
|
||||
cli_fps_count(0);
|
||||
|
||||
keypad_update();
|
||||
detect_card();
|
||||
|
||||
report_usb_hid();
|
||||
|
||||
sleep_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
tusb_init();
|
||||
stdio_init_all();
|
||||
light_init();
|
||||
keypad_init();
|
||||
|
||||
config_init();
|
||||
mutex_init(&core1_io_lock);
|
||||
save_init(0xca340a1c, &core1_io_lock);
|
||||
|
||||
nfc_init_i2c(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ);
|
||||
nfc_init_spi(SPI_PORT, SPI_MISO, SPI_SCK, SPI_MOSI, SPI_RST, SPI_NSS, SPI_BUSY);
|
||||
nfc_init();
|
||||
nfc_set_wait_loop(wait_loop);
|
||||
|
||||
aime_init(cdc_aime_putc);
|
||||
aime_virtual_aic(aic_cfg->virtual_aic);
|
||||
|
||||
if ((aic_cfg->mode & 0x0f) == 0) {
|
||||
aime_set_mode(aic_cfg->mode);
|
||||
}
|
||||
|
||||
bana_init(cdc_aime_putc);
|
||||
|
||||
cli_init("aic_pico>", "\n << AIC Pico >>\n"
|
||||
" https://github.com/whowechina\n\n");
|
||||
|
||||
commands_init();
|
||||
}
|
||||
|
||||
/* if certain key pressed when booting, enter update mode */
|
||||
static void update_check()
|
||||
{
|
||||
const uint8_t pins[] = { 10, 11 }; // keypad 00 and *
|
||||
bool all_pressed = true;
|
||||
for (int i = 0; i < sizeof(pins); i++) {
|
||||
uint8_t gpio = pins[i];
|
||||
gpio_init(gpio);
|
||||
gpio_set_function(gpio, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(gpio, GPIO_IN);
|
||||
gpio_pull_up(gpio);
|
||||
sleep_ms(1);
|
||||
if (gpio_get(gpio)) {
|
||||
all_pressed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (all_pressed) {
|
||||
sleep_ms(100);
|
||||
reset_usb_boot(0, 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void sys_init()
|
||||
{
|
||||
sleep_ms(50);
|
||||
set_sys_clock_khz(150000, true);
|
||||
board_init();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user