diff --git a/Production/Firmware/aic_pico.uf2 b/Production/Firmware/aic_pico.uf2 index 8b7ca67..6b3bdc1 100644 Binary files a/Production/Firmware/aic_pico.uf2 and b/Production/Firmware/aic_pico.uf2 differ diff --git a/firmware/src/CMakeLists.txt b/firmware/src/CMakeLists.txt index 89dc338..04d4ce4 100644 --- a/firmware/src/CMakeLists.txt +++ b/firmware/src/CMakeLists.txt @@ -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) diff --git a/firmware/src/main.c b/firmware/src/main.c index 3d55b56..bc0ef4b 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -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); diff --git a/firmware/src/nfc.c b/firmware/src/nfc.c new file mode 100644 index 0000000..67d5552 --- /dev/null +++ b/firmware/src/nfc.c @@ -0,0 +1,128 @@ +/* + * NFC Reader Interface to real modules + * WHowe + * + */ + +#include +#include +#include + +#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; +} \ No newline at end of file diff --git a/firmware/src/nfc.h b/firmware/src/nfc.h new file mode 100644 index 0000000..0d7342a --- /dev/null +++ b/firmware/src/nfc.h @@ -0,0 +1,31 @@ +/* + * NFC Reader Interface + * WHowe + * + */ + +#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 diff --git a/firmware/src/pn5180.c b/firmware/src/pn5180.c index a488a45..c5f25d7 100644 --- a/firmware/src/pn5180.c +++ b/firmware/src/pn5180.c @@ -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(); diff --git a/firmware/src/pn532.c b/firmware/src/pn532.c index 8bd7cdf..4d12f5d 100644 --- a/firmware/src/pn532.c +++ b/firmware/src/pn532.c @@ -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; } diff --git a/firmware/src/pn532.h b/firmware/src/pn532.h index 8d6c254..c40962a 100644 --- a/firmware/src/pn532.h +++ b/firmware/src/pn532.h @@ -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);