mirror of
https://github.com/whowechina/aic_pico.git
synced 2026-10-08 22:49:58 +03:00
282 lines
6.1 KiB
C
282 lines
6.1 KiB
C
/*
|
|
* 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);
|
|
}
|
|
}
|
|
|
|
void detect_card()
|
|
{
|
|
static nfc_card_t old_card = { 0 };
|
|
|
|
nfc_card_t card = nfc_detect_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);
|
|
}
|
|
if (memcmp(&old_card, &card, sizeof(card)) == 0) {
|
|
return;
|
|
}
|
|
|
|
if (card.card_type != NFC_CARD_NONE) {
|
|
printf("\n%s:", nfc_card_name(card.card_type));
|
|
for (int i = 0; i < card.len; i++) {
|
|
printf(" %02x", hid_cardio.current[i + 1]);
|
|
}
|
|
}
|
|
|
|
old_card = 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++) {
|
|
aime_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(wait_loop);
|
|
|
|
aime_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)
|
|
{
|
|
}
|