1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2025-03-02 16:24:27 +01:00

Cardio mifare works, felica freezes.

This commit is contained in:
whowechina 2023-11-04 23:31:17 +08:00
parent 2d42b221da
commit 058071c519
6 changed files with 150 additions and 79 deletions

View File

@ -51,8 +51,8 @@ static void handle_nfc()
{ {
bool ret; bool ret;
ret = pn532_config_rf(); // ret = pn532_config_rf();
printf("RF: %d\n", ret); // printf("RF: %d\n", ret);
ret = pn532_config_sam(); ret = pn532_config_sam();
printf("Sam: %d\n", ret); printf("Sam: %d\n", ret);
@ -70,17 +70,6 @@ static void handle_nfc()
} }
printf("\n"); printf("\n");
len = sizeof(buf);
ret = pn532_poll_14443b(buf, &len);
printf("14443B: %d -", len);
if (ret) {
for (int i = 0; i < len; i++) {
printf(" %02x", buf[i]);
}
}
printf("\n");
printf("Felica: "); printf("Felica: ");
if (pn532_poll_felica(buf, buf + 8, buf + 16, false)) { if (pn532_poll_felica(buf, buf + 8, buf + 16, false)) {
for (int i = 0; i < 18; i++) { for (int i = 0; i < 18; i++) {

View File

@ -32,9 +32,49 @@
#include "pn532.h" #include "pn532.h"
#include "aime.h" #include "aime.h"
static struct {
uint8_t current[9];
uint8_t reported[9];
uint64_t report_time;
} cardio;
void report_usb_hid() void report_usb_hid()
{ {
if (tud_hid_ready()) { if (!tud_hid_ready()) {
return;
}
uint64_t now = time_us_64();
bool report = false;
if (memcmp(cardio.current, cardio.reported, 9) != 0) {
const uint8_t empty[9] = { 0 };
if ((memcmp(cardio.current, empty, 9) != 0) ||
(now - cardio.report_time > 5000000)) {
/* Immediate report for new card,
5 seconds delay for for card removal */
report = true;
}
} else if (now - cardio.report_time > 1000000) {
/* Same card, reports every 0.5 sec */
report = true;
}
if (report) {
tud_hid_n_report(0x00, cardio.current[0], cardio.current + 1, 8);
memcpy(cardio.reported, cardio.current, 9);
cardio.report_time = now;
const uint8_t empty[9] = { 0 };
if (memcmp(cardio.current, empty, 9) == 0) {
return;
}
printf("Card:");
for (int i = 0; i < 9; i++) {
printf(" %02x", cardio.current[i]);
}
printf("\n");
} }
} }
@ -55,6 +95,55 @@ static void core1_loop()
} }
} }
void detect_card()
{
static bool poll_mifare = false;
static bool detected_mifare = false;
if (poll_mifare) {
pn532_config_sam();
uint8_t id[8] = { 0 };
int len = sizeof(id);
detected_mifare = pn532_poll_mifare(id, &len);
if (detected_mifare) {
cardio.current[0] = REPORT_ID_EAMU;
cardio.current[1] = 0xe0;
cardio.current[2] = 0x04;
if (len == 4) {
memcpy(cardio.current + 3, id, 4);
memcpy(cardio.current + 7, id, 2);
} else if (len == 7) {
memcpy(cardio.current + 3, id + 1, 6);
} else {
detected_mifare = false;
}
}
poll_mifare = false;
} else {
pn532_config_sam();
uint8_t id[18] = { 0 };
//bool detected_felica = pn532_poll_felica(id, id + 8, id + 16, false);
bool detected_felica = false;
if (detected_felica) {
cardio.current[0] = REPORT_ID_FELICA;
memcpy(cardio.current + 1, id, 8);
} else if (!detected_mifare) {
memset(cardio.current, 0, 9);
}
poll_mifare = true;
}
}
void wait_loop()
{
tud_task();
cli_run();
aime_update();
cli_fps_count(0);
}
static void core0_loop() static void core0_loop()
{ {
while(1) { while(1) {
@ -66,6 +155,7 @@ static void core0_loop()
save_loop(); save_loop();
cli_fps_count(0); cli_fps_count(0);
detect_card();
report_usb_hid(); report_usb_hid();
sleep_ms(1); sleep_ms(1);
} }
@ -86,6 +176,7 @@ void init()
pn532_init(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ); pn532_init(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ);
pn532_set_wait_loop(wait_loop);
aime_init(1); aime_init(1);
cli_init("aic_pico>", "\n << AIC Pico >>\n" cli_init("aic_pico>", "\n << AIC Pico >>\n"

View File

@ -36,6 +36,13 @@ void pn532_init(i2c_inst_t *i2c, uint8_t scl, uint8_t sda, uint32_t freq)
i2c_port = i2c; i2c_port = i2c;
} }
static pn532_wait_loop_t wait_loop = NULL;
void pn532_set_wait_loop(pn532_wait_loop_t loop)
{
wait_loop = loop;
}
static int pn532_write(const uint8_t *data, uint8_t len) static int pn532_write(const uint8_t *data, uint8_t len)
{ {
return i2c_write_blocking_until(i2c_port, PN532_I2C_ADDRESS, data, len, false, return i2c_write_blocking_until(i2c_port, PN532_I2C_ADDRESS, data, len, false,
@ -52,11 +59,14 @@ static bool pn532_wait_ready()
{ {
uint8_t status = 0; uint8_t status = 0;
for (int retry = 0; retry < 20; retry++) { for (int retry = 0; retry < 30; retry++) {
if (pn532_read(&status, 1) == 1 && status == 0x01) { if (pn532_read(&status, 1) == 1 && status == 0x01) {
return true; return true;
} }
sleep_us(1000); if (wait_loop) {
wait_loop();
}
sleep_ms(1);
} }
return false; return false;
@ -275,7 +285,8 @@ bool pn532_config_sam()
uint8_t param[] = {0x01, 0x14, 0x01}; uint8_t param[] = {0x01, 0x14, 0x01};
pn532_write_command(0x14, param, sizeof(param)); pn532_write_command(0x14, param, sizeof(param));
return pn532_read_response(0x14, NULL, 0) == 0; uint8_t resp;
return pn532_read_response(0x14, &resp, 1) == 0;
} }
@ -284,7 +295,8 @@ bool pn532_set_rf_field(uint8_t auto_rf, uint8_t on_off)
uint8_t param[] = { 1, auto_rf | on_off }; uint8_t param[] = { 1, auto_rf | on_off };
pn532_write_command(0x32, param, 2); pn532_write_command(0x32, param, 2);
return pn532_read_response(0x32, NULL, 0) >= 0; uint8_t resp;
return pn532_read_response(0x32, &resp, 1) >= 0;
} }
static uint8_t readbuf[255]; static uint8_t readbuf[255];

View File

@ -9,6 +9,10 @@
#include "hardware/i2c.h" #include "hardware/i2c.h"
typedef void (*pn532_wait_loop_t)();
void pn532_set_wait_loop(pn532_wait_loop_t loop);
void pn532_init(i2c_inst_t *i2c_port, uint8_t scl, uint8_t sda, uint32_t freq); void pn532_init(i2c_inst_t *i2c_port, uint8_t scl, uint8_t sda, uint32_t freq);
int pn532_write_command(uint8_t cmd, const uint8_t *param, uint8_t len); int pn532_write_command(uint8_t cmd, const uint8_t *param, uint8_t len);

View File

@ -42,7 +42,7 @@
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Device Descriptors // Device Descriptors
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
tusb_desc_device_t desc_device_joy = { tusb_desc_device_t desc_device_dev = {
.bLength = sizeof(tusb_desc_device_t), .bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE, .bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200, .bcdUSB = 0x0200,
@ -51,11 +51,8 @@ tusb_desc_device_t desc_device_joy = {
.bDeviceProtocol = 0x00, .bDeviceProtocol = 0x00,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
// To match CrazyRedMachine dll .idVendor = 0xCaff,
// vid 0x0f0d, pid 0x0092, interface 1 .idProduct = USB_PID,
.idVendor = 0x0f0d,
.idProduct = 0x0092,
.bcdDevice = 0x0100, .bcdDevice = 0x0100,
.iManufacturer = 0x01, .iManufacturer = 0x01,
@ -67,15 +64,15 @@ tusb_desc_device_t desc_device_joy = {
// Invoked when received GET DEVICE DESCRIPTOR // Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
uint8_t const* tud_descriptor_device_cb(void) { uint8_t const* tud_descriptor_device_cb(void) {
return (uint8_t const*)&desc_device_joy; return (uint8_t const*)&desc_device_dev;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// HID Report Descriptor // HID Report Descriptor
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
uint8_t const desc_hid_report_joy[] = { uint8_t const desc_hid_report_cardio[] = {
AIC_PICO_REPORT_DESC_JOYSTICK, AIC_PICO_REPORT_DESC_CARDIO,
}; };
// Invoked when received GET HID REPORT DESCRIPTOR // Invoked when received GET HID REPORT DESCRIPTOR
@ -85,7 +82,7 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf)
{ {
switch (itf) { switch (itf) {
case 0: case 0:
return desc_hid_report_joy; return desc_hid_report_cardio;
default: default:
return NULL; return NULL;
} }
@ -94,14 +91,14 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf)
// Configuration Descriptor // Configuration Descriptor
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
enum { ITF_NUM_JOY, enum { ITF_NUM_CARDIO,
ITF_NUM_CLI, ITF_NUM_CLI_DATA, ITF_NUM_CLI, ITF_NUM_CLI_DATA,
ITF_NUM_AIME, ITF_NUM_AIME_DATA, ITF_NUM_AIME, ITF_NUM_AIME_DATA,
ITF_NUM_TOTAL }; ITF_NUM_TOTAL };
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN * 1 + TUD_CDC_DESC_LEN * 2) #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN * 1 + TUD_CDC_DESC_LEN * 2)
#define EPNUM_JOY 0x81 #define EPNUM_CARDIO 0x81
#define EPNUM_CLI_NOTIF 0x85 #define EPNUM_CLI_NOTIF 0x85
#define EPNUM_CLI_OUT 0x06 #define EPNUM_CLI_OUT 0x06
@ -111,7 +108,7 @@ enum { ITF_NUM_JOY,
#define EPNUM_AIME_OUT 0x08 #define EPNUM_AIME_OUT 0x08
#define EPNUM_AIME_IN 0x88 #define EPNUM_AIME_IN 0x88
uint8_t const desc_configuration_joy[] = { uint8_t const desc_configuration_dev[] = {
// Config number, interface count, string index, total length, attribute, // Config number, interface count, string index, total length, attribute,
// power in mA // power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN,
@ -119,8 +116,8 @@ uint8_t const desc_configuration_joy[] = {
// Interface number, string index, protocol, report descriptor len, EP In // Interface number, string index, protocol, report descriptor len, EP In
// address, size & polling interval // address, size & polling interval
TUD_HID_DESCRIPTOR(ITF_NUM_JOY, 4, HID_ITF_PROTOCOL_NONE, TUD_HID_DESCRIPTOR(ITF_NUM_CARDIO, 4, HID_ITF_PROTOCOL_NONE,
sizeof(desc_hid_report_joy), EPNUM_JOY, sizeof(desc_hid_report_cardio), EPNUM_CARDIO,
CFG_TUD_HID_EP_BUFSIZE, 1), CFG_TUD_HID_EP_BUFSIZE, 1),
TUD_CDC_DESCRIPTOR(ITF_NUM_CLI, 5, EPNUM_CLI_NOTIF, TUD_CDC_DESCRIPTOR(ITF_NUM_CLI, 5, EPNUM_CLI_NOTIF,
@ -134,7 +131,7 @@ uint8_t const desc_configuration_joy[] = {
// Application return pointer to descriptor // Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete // Descriptor contents must exist long enough for transfer to complete
uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { uint8_t const* tud_descriptor_configuration_cb(uint8_t index) {
return desc_configuration_joy; return desc_configuration_dev;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -146,10 +143,10 @@ static char serial_number_str[24] = "123456\0";
// array of pointer to string descriptors // array of pointer to string descriptors
const char *string_desc_arr[] = { const char *string_desc_arr[] = {
(const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
"WHowe" , // 1: Manufacturer "WHowe", // 1: Manufacturer
"AIC Pico", // 2: Product "AIC Pico", // 2: Product
serial_number_str, // 3: Serials, should use chip ID serial_number_str, // 3: Serials, should use chip ID
"AIC Pico Joystick", "AIC Pico CardIO",
"AIC Pico CLI Port", "AIC Pico CLI Port",
"AIC Pico AIME Port", "AIC Pico AIME Port",
}; };

View File

@ -5,49 +5,27 @@
#include "device/usbd.h" #include "device/usbd.h"
enum { enum {
REPORT_ID_JOYSTICK = 1, REPORT_ID_EAMU = 1,
REPORT_ID_FELICA = 2,
}; };
// because they are missing from tusb_hid.h #define AIC_PICO_REPORT_DESC_CARDIO \
#define HID_STRING_INDEX(x) HID_REPORT_ITEM(x, 7, RI_TYPE_LOCAL, 1) HID_USAGE_PAGE_N(0xffca, 2), \
#define HID_STRING_INDEX_N(x, n) HID_REPORT_ITEM(x, 7, RI_TYPE_LOCAL, n) HID_USAGE(0x01), \
#define HID_STRING_MINIMUM(x) HID_REPORT_ITEM(x, 8, RI_TYPE_LOCAL, 1) HID_COLLECTION(HID_COLLECTION_APPLICATION), \
#define HID_STRING_MINIMUM_N(x, n) HID_REPORT_ITEM(x, 8, RI_TYPE_LOCAL, n) HID_REPORT_ID(REPORT_ID_EAMU) \
#define HID_STRING_MAXIMUM(x) HID_REPORT_ITEM(x, 9, RI_TYPE_LOCAL, 1) HID_USAGE_PAGE_N(0xffca, 2), \
#define HID_STRING_MAXIMUM_N(x, n) HID_REPORT_ITEM(x, 9, RI_TYPE_LOCAL, n) HID_USAGE(0x41), \
HID_LOGICAL_MIN(1), HID_LOGICAL_MAX(0xff), \
// Joystick Report Descriptor Template - Based off Drewol/rp2040-gamecon HID_REPORT_SIZE(8), HID_REPORT_COUNT(8), \
// Button Map | X | Y HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
#define AIC_PICO_REPORT_DESC_JOYSTICK \ \
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \ HID_REPORT_ID(REPORT_ID_FELICA) \
HID_USAGE(HID_USAGE_DESKTOP_JOYSTICK), \ HID_USAGE_PAGE_N(0xffca, 2), \
HID_COLLECTION(HID_COLLECTION_APPLICATION), \ HID_USAGE(0x42), \
HID_REPORT_ID(REPORT_ID_JOYSTICK) \ HID_LOGICAL_MIN(1), HID_LOGICAL_MAX(0xff), \
HID_USAGE_PAGE(HID_USAGE_PAGE_BUTTON), \ HID_REPORT_SIZE(8), HID_REPORT_COUNT(8), \
HID_USAGE_MIN(1), HID_USAGE_MAX(16), \ HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(1), \
HID_REPORT_COUNT(16), HID_REPORT_SIZE(1), \
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
\
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
HID_USAGE(HID_USAGE_DESKTOP_HAT_SWITCH), \
HID_LOGICAL_MIN(1), HID_LOGICAL_MAX(8), \
HID_PHYSICAL_MIN(0), HID_PHYSICAL_MAX_N(315, 2), \
HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), \
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
\
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
HID_USAGE(HID_USAGE_DESKTOP_X), HID_USAGE(HID_USAGE_DESKTOP_Y), \
HID_USAGE(HID_USAGE_DESKTOP_Z), HID_USAGE(HID_USAGE_DESKTOP_RX), \
HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX(0xff), /* Analog */ \
HID_REPORT_SIZE(8), HID_REPORT_COUNT(4), \
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
\
HID_USAGE_PAGE_N(HID_USAGE_PAGE_VENDOR, 2), \
HID_USAGE(0), \
HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX(0xff), \
HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), \
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
HID_COLLECTION_END HID_COLLECTION_END
#endif /* USB_DESCRIPTORS_H_ */ #endif