1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2025-02-16 10:42:36 +01:00

Fix amiibo not working on PN5180 and refactoring of cardio

This commit is contained in:
whowechina 2024-01-14 15:42:50 +08:00
parent 3c36a36c05
commit 32d9b819a6
8 changed files with 209 additions and 115 deletions

Binary file not shown.

View File

@ -5,7 +5,7 @@ function(make_firmware board board_def)
pico_sdk_init()
add_executable(${board}
main.c save.c config.c commands.c light.c keypad.c
aime.c cli.c pn532.c pn5180.c
aime.c cli.c nfc.c pn532.c pn5180.c
usb_descriptors.c)
target_compile_definitions(${board} PUBLIC ${board_def})
pico_enable_stdio_usb(${board} 1)

View File

@ -30,8 +30,7 @@
#include "light.h"
#include "keypad.h"
#include "pn532.h"
#include "pn5180.h"
#include "nfc.h"
#include "aime.h"
@ -59,14 +58,6 @@ void report_hid_cardio()
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;
if (memcmp(hid_cardio.current, "\0\0\0\0\0\0\0\0\0", 9) != 0) {
printf("Card:");
for (int i = 0; i < 9; i++) {
printf(" %02x", hid_cardio.current[i]);
}
printf("\n");
}
}
}
@ -116,64 +107,47 @@ static void core1_loop()
}
}
static enum {
NFC_UNKNOWN,
NFC_PN532,
NFC_PN5180
} nfc_module = NFC_PN5180;
void detect_card()
{
if (nfc_module == NFC_PN532) {
pn532_config_sam();
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;
}
uint8_t id[20] = { 0 };
int len = sizeof(id);
bool mifare = false;
if (nfc_module == NFC_PN532) {
mifare = pn532_poll_mifare(id, &len);
} else if (nfc_module == NFC_PN5180) {
mifare = pn5180_poll_mifare(id, &len);
}
if (mifare) {
hid_cardio.current[0] = REPORT_ID_EAMU;
hid_cardio.current[1] = 0xe0;
hid_cardio.current[2] = 0x04;
if (len == 4) {
memcpy(hid_cardio.current + 3, id, 4);
memcpy(hid_cardio.current + 7, id, 2);
} else if (len == 7) {
memcpy(hid_cardio.current + 3, id + 1, 6);
if (card.card_type != NFC_CARD_NULL) {
const char *card_type_str[3] = { "MIFARE", "FeliCa", "15693" };
printf("\n%s:", card_type_str[card.card_type - 1]);
for (int i = 0; i < card.len; i++) {
printf(" %02x", hid_cardio.current[i]);
}
return;
}
bool felica = false;
if (nfc_module == NFC_PN532) {
felica = pn532_poll_felica(id, id + 8, id + 16, false);
} else if (nfc_module == NFC_PN5180) {
felica = pn5180_poll_felica(id, id + 8, id + 16, false);
}
if (felica) {
hid_cardio.current[0] = REPORT_ID_FELICA;
memcpy(hid_cardio.current + 1, id, 8);
return;
}
bool vicinity = false;
if (nfc_module == NFC_PN5180) {
vicinity = pn5180_poll_vicinity(id);
}
if (vicinity) {
hid_cardio.current[0] = REPORT_ID_EAMU;
memcpy(hid_cardio.current + 1, id, 8);
return;
}
memset(hid_cardio.current, 0, 9);
old_card = card;
}
const int aime_intf = 1;
@ -236,14 +210,7 @@ void init()
mutex_init(&core1_io_lock);
save_init(0xca340a1c, &core1_io_lock);
if (pn532_init(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ)) {
nfc_module = NFC_PN532;
pn532_set_wait_loop(wait_loop);
} else if (pn5180_init(spi0, 16, 18, 19, 27, 17, 26)) {
nfc_module = NFC_PN5180;
pn5180_set_wait_loop(wait_loop);
}
nfc_init(wait_loop);
aime_init(cdc_aime_putc);

128
firmware/src/nfc.c Normal file
View File

@ -0,0 +1,128 @@
/*
* NFC Reader Interface to real modules
* WHowe <github.com/whowechina>
*
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "board_defs.h"
#include "nfc.h"
#include "pn532.h"
#include "pn5180.h"
static enum {
NFC_MODULE_PN532 = 0,
NFC_MODULE_PN5180,
NFC_MODULE_UNKNOWN,
} nfc_module = NFC_MODULE_UNKNOWN;
static bool null_poll_mifare(uint8_t uid[7], int *len)
{
return false;
}
static bool null_poll_felica(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache)
{
return false;
}
static bool null_poll_vicinity(uint8_t uid[8])
{
return false;
}
struct {
bool (*poll_mifare)(uint8_t uid[7], int *len);
bool (*poll_felica)(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache);
bool (*poll_vicinity)(uint8_t uid[8]);
} api[3] = {
{ pn532_poll_mifare, pn532_poll_felica, null_poll_vicinity,},
{ pn5180_poll_mifare, pn5180_poll_felica, pn5180_poll_vicinity,},
{ null_poll_mifare, null_poll_felica, null_poll_vicinity,},
};
void nfc_init(nfc_wait_loop_t loop)
{
if (pn532_init(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ)) {
nfc_module = NFC_MODULE_PN532;
pn532_set_wait_loop(loop);
} else if (pn5180_init(spi0, 16, 18, 19, 27, 17, 26)) {
nfc_module = NFC_MODULE_PN5180;
pn5180_set_wait_loop(loop);
}
}
static void nfc_config_sam()
{
if (nfc_module == NFC_MODULE_PN532) {
pn532_config_sam();
}
}
static bool nfc_detect_mifare(nfc_card_t *card)
{
uint8_t id[20] = { 0 };
int len = sizeof(id);
if (!api[nfc_module].poll_mifare(id, &len)) {
return false;
}
card->card_type = NFC_CARD_MIFARE;
card->len = len;
memcpy(card->uid, id, len);
return true;
}
static bool nfc_detect_felica(nfc_card_t *card)
{
uint8_t id[20] = { 0 };
if (!api[nfc_module].poll_felica(id, id + 8, id + 16, false)) {
return false;
}
card->card_type = NFC_CARD_FELICA;
card->len = 8;
memcpy(card->uid, id, 8);
memcpy(card->pmm, id + 8, 8);
memcpy(card->syscode, id + 16, 2);
return true;
}
static bool nfc_detect_vicinity(nfc_card_t *card)
{
uint8_t id[8] = { 0 };
if (!api[nfc_module].poll_vicinity(id)) {
return false;
}
card->card_type = NFC_CARD_VICINITY;
card->len = 8;
memcpy(card->uid, id, 8);
return true;
}
nfc_card_t nfc_detect_card()
{
nfc_card_t card = { 0 };
nfc_config_sam();
if (!nfc_detect_mifare(&card) &&
!nfc_detect_felica(&card) &&
!nfc_detect_vicinity(&card)) {
card.card_type = NFC_CARD_NULL;
}
return card;
}

31
firmware/src/nfc.h Normal file
View File

@ -0,0 +1,31 @@
/*
* NFC Reader Interface
* WHowe <github.com/whowechina>
*
*/
#ifndef NFC_H
#define NFC_H
#include "hardware/i2c.h"
typedef enum {
NFC_CARD_NULL = 0,
NFC_CARD_MIFARE,
NFC_CARD_FELICA,
NFC_CARD_VICINITY,
} nfc_card_type;
typedef void (*nfc_wait_loop_t)();
typedef struct {
nfc_card_type card_type;
uint16_t len;
uint8_t uid[8];
uint8_t pmm[8];
uint8_t syscode[2];
} nfc_card_t;
void nfc_init(nfc_wait_loop_t loop);
nfc_card_t nfc_detect_card();
#endif

View File

@ -281,12 +281,14 @@ bool pn5180_poll_mifare(uint8_t uid[7], int *len)
memmove(uid, buf, 4);
*len = 4;
result = true;
} else if (sak == 0x88) {
} else if (buf[0] == 0x88) {
memmove(uid, buf + 1, 3);
anti_collision(0x95, buf + 5, &sak);
memmove(uid + 3, buf, 4);
*len = 7;
result = true;
anti_collision(0x95, buf, &sak);
if (sak != 0xff) {
memmove(uid + 3, buf, 4);
*len = 7;
result = true;
}
}
pn5180_rf_off();

View File

@ -306,7 +306,7 @@ bool pn532_set_rf_field(uint8_t auto_rf, uint8_t on_off)
static uint8_t readbuf[255];
bool pn532_poll_mifare(uint8_t *uid, int *len)
bool pn532_poll_mifare(uint8_t uid[7], int *len)
{
uint8_t param[] = {0x01, 0x00};
int ret = pn532_write_command(0x4a, param, sizeof(param));
@ -319,46 +319,13 @@ bool pn532_poll_mifare(uint8_t *uid, int *len)
return false;
}
if (result != readbuf[5] + 6) {
int idlen = readbuf[5];
if ((idlen > 8) || (result != idlen + 6)) {
return false;
}
if (*len < readbuf[5]) {
return false;
}
memcpy(uid, readbuf + 6, readbuf[5]);
*len = readbuf[5];
return true;
}
bool pn532_poll_14443b(uint8_t *uid, int *len)
{
uint8_t param[] = {0x01, 0x03, 0x00};
int ret = pn532_write_command(0x4a, param, sizeof(param));
if (ret < 0) {
return false;
}
int result = pn532_read_response(0x4a, readbuf, sizeof(readbuf));
if (result < 1 || readbuf[0] != 1) {
printf("result: %d\n", result);
return false;
}
if (result != readbuf[5] + 6) {
printf("result: %d %d\n", result, readbuf[5]);
return false;
}
if (*len < readbuf[5]) {
printf("result: %d %d\n", result, readbuf[5]);
return false;
}
memcpy(uid, readbuf + 6, readbuf[5]);
*len = readbuf[5];
memcpy(uid, readbuf + 6, idlen);
*len = idlen;
return true;
}

View File

@ -25,8 +25,7 @@ bool pn532_config_rf();
bool pn532_set_rf_field(uint8_t auto_rf, uint8_t on_off);
bool pn532_poll_mifare(uint8_t *uid, int *len);
bool pn532_poll_14443b(uint8_t *uid, int *len);
bool pn532_poll_mifare(uint8_t uid[7], int *len);
bool pn532_poll_felica(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache);
bool pn532_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key);