From 1ab2bec642c94078ef592e73cc8632b9c42ca3d1 Mon Sep 17 00:00:00 2001 From: whowechina Date: Sat, 16 Mar 2024 10:25:27 +0800 Subject: [PATCH] Refactoring nfc interface --- firmware/include/nfc.h | 15 ++-- firmware/src/board_defs.h | 8 ++ firmware/src/lib/nfc.c | 156 +++++++++++++++++++------------------- firmware/src/lib/pn5180.c | 39 +++++----- firmware/src/lib/pn5180.h | 2 +- firmware/src/lib/pn532.c | 8 +- firmware/src/lib/pn532.h | 2 +- firmware/src/main.c | 4 +- 8 files changed, 124 insertions(+), 110 deletions(-) diff --git a/firmware/include/nfc.h b/firmware/include/nfc.h index b00393e..8d68d4a 100644 --- a/firmware/include/nfc.h +++ b/firmware/include/nfc.h @@ -10,6 +10,7 @@ #include #include #include "hardware/i2c.h" +#include "hardware/spi.h" typedef enum { NFC_CARD_NONE = 0, @@ -32,7 +33,14 @@ typedef struct { uint8_t syscode[2]; } nfc_card_t; -void nfc_init(i2c_inst_t *i2c, uint8_t scl, uint8_t sda, uint32_t freq); +/* should set i2c and spi port before init */ +void nfc_set_i2c(i2c_inst_t *port, uint8_t sda, uint8_t scl, uint32_t freq); +void nfc_set_spi(spi_inst_t *port, uint8_t miso, uint8_t sck, uint8_t mosi, + uint8_t rst, uint8_t nss, uint8_t busy); + +void nfc_init(); + +/* should be called only after init */ void nfc_set_wait_loop(nfc_wait_loop_t loop); void nfc_rf_field(bool on); @@ -40,14 +48,9 @@ void nfc_rf_field(bool on); nfc_card_t nfc_detect_card(); void display_card(const nfc_card_t *card); -nfc_card_t nfc_poll_felica(); - const char *nfc_module_name(); bool nfc_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key); bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16]); -bool nfc_felica_read_wo_encrypt(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]); -bool nfc_felica_write_wo_encrypt(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16]); - #endif diff --git a/firmware/src/board_defs.h b/firmware/src/board_defs.h index 9308850..6c77a04 100644 --- a/firmware/src/board_defs.h +++ b/firmware/src/board_defs.h @@ -10,6 +10,14 @@ #define I2C_SDA 20 #define I2C_FREQ 433*1000 +#define SPI_PORT spi0 +#define SPI_MISO 16 +#define SPI_SCK 18 +#define SPI_MOSI 19 +#define SPI_RST 27 +#define SPI_NSS 17 +#define SPI_BUSY 26 + #define RGB_PIN 12 #define RGB_ORDER GRB // or RGB #define LED_DEF { 25, 22, 13, 15 } diff --git a/firmware/src/lib/nfc.c b/firmware/src/lib/nfc.c index aa1e1ec..5fd2a83 100644 --- a/firmware/src/lib/nfc.c +++ b/firmware/src/lib/nfc.c @@ -47,59 +47,85 @@ const char *nfc_card_name(nfc_card_type card_type) return nfc_card_names[card_type]; } -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; -} - -static void null_rf_field(bool on) -{ -} - -static void null_set_wait_loop(nfc_wait_loop_t loop) -{ - -} - +#define func_null NULL 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]); void (*rf_field)(bool on); + bool (*mifare_auth)(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key); + bool (*mifare_read)(uint8_t block_id, uint8_t block_data[16]); void (*set_wait_loop)(nfc_wait_loop_t loop); } api[3] = { - { pn532_poll_mifare, pn532_poll_felica, null_poll_vicinity, pn532_rf_field, pn532_set_wait_loop}, - { pn5180_poll_mifare, pn5180_poll_felica, pn5180_poll_vicinity, null_rf_field, pn5180_set_wait_loop}, - { null_poll_mifare, null_poll_felica, null_poll_vicinity, null_rf_field, null_set_wait_loop}, + { + pn532_poll_mifare, pn532_poll_felica, func_null, + pn532_rf_field, + pn532_mifare_auth, pn532_mifare_read, + pn532_set_wait_loop + }, + { + pn5180_poll_mifare, pn5180_poll_felica, pn5180_poll_vicinity, + func_null, + func_null, func_null, + pn5180_set_wait_loop + }, + { 0 }, }; -void nfc_init(i2c_inst_t *i2c, uint8_t scl, uint8_t sda, uint32_t freq) -{ - i2c_init(i2c, freq); - gpio_set_function(scl, GPIO_FUNC_I2C); - gpio_set_function(sda, GPIO_FUNC_I2C); - gpio_pull_up(scl); - gpio_pull_up(sda); +static struct { + i2c_inst_t *port; + uint32_t freq; + uint8_t scl; + uint8_t sda; +} i2c = {0}; - if (pn532_init(i2c)) { +void nfc_set_i2c(i2c_inst_t *port, uint8_t scl, uint8_t sda, uint32_t freq) +{ + i2c.port = port; + i2c.freq = freq; + i2c.scl = scl; + i2c.sda = sda; +} + +static struct { + spi_inst_t *port; + uint8_t miso; + uint8_t sck; + uint8_t mosi; + uint8_t rst; + uint8_t nss; + uint8_t busy; +} spi = {0}; + +void nfc_set_spi(spi_inst_t *port, uint8_t miso, uint8_t sck, uint8_t mosi, + uint8_t rst, uint8_t nss, uint8_t busy) +{ + spi.port = port; + spi.miso = miso; + spi.sck = sck; + spi.mosi = mosi; + spi.rst = rst; + spi.nss = nss; + spi.busy = busy; +} + +void nfc_init() +{ + if (i2c.port && + pn532_init(i2c.port, i2c.scl, i2c.sda, i2c.freq)) { nfc_module = NFC_MODULE_PN532; - } else if (pn5180_init(spi0, 16, 18, 19, 27, 17, 26)) { + } else if (spi.port && + pn5180_init(spi.port, spi.miso, spi.sck, spi.mosi, + spi.rst, spi.nss, spi.busy)) { nfc_module = NFC_MODULE_PN5180; } } void nfc_set_wait_loop(nfc_wait_loop_t loop) { + if (!api[nfc_module].set_wait_loop) { + return; + } api[nfc_module].set_wait_loop(loop); } @@ -108,7 +134,8 @@ 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)) { + if (!api[nfc_module].poll_mifare || + !api[nfc_module].poll_mifare(id, &len)) { return false; } @@ -123,7 +150,8 @@ 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)) { + if (!api[nfc_module].poll_felica || + !api[nfc_module].poll_felica(id, id + 8, id + 16, false)) { return false; } @@ -140,7 +168,8 @@ static bool nfc_detect_vicinity(nfc_card_t *card) { uint8_t id[8] = { 0 }; - if (!api[nfc_module].poll_vicinity(id)) { + if (!api[nfc_module].poll_vicinity || + !api[nfc_module].poll_vicinity(id)) { return false; } @@ -153,7 +182,9 @@ static bool nfc_detect_vicinity(nfc_card_t *card) void nfc_rf_field(bool on) { - api[nfc_module].rf_field(on); + if (api[nfc_module].rf_field) { + api[nfc_module].rf_field(on); + } } nfc_card_t nfc_detect_card() @@ -169,15 +200,6 @@ nfc_card_t nfc_detect_card() return card; } -nfc_card_t nfc_poll_felica() -{ - nfc_card_t card = { 0 }; - if (!nfc_detect_felica(&card)) { - card.card_type = NFC_CARD_NONE; - } - return card; -} - void display_card(const nfc_card_t *card) { if (card->card_type != NFC_CARD_NONE) { @@ -190,40 +212,16 @@ void display_card(const nfc_card_t *card) bool nfc_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key) { - if (nfc_module == NFC_MODULE_PN532) { - return pn532_mifare_auth(uid, block_id, key_id, key); - } else if (nfc_module == NFC_MODULE_PN5180) { - return false;//pn5180_mifare_auth(uid, block_id, key_id, key); + if (!api[nfc_module].mifare_auth) { + return false; } - return false; + return api[nfc_module].mifare_auth(uid, block_id, key_id, key); } bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16]) { - if (nfc_module == NFC_MODULE_PN532) { - return pn532_mifare_read(block_id, block_data); - } else if (nfc_module == NFC_MODULE_PN5180) { - return false; // pn5180_mifare_read(block_id, block_data); + if (!api[nfc_module].mifare_read) { + return false; } - return false; -} - -bool nfc_felica_read_wo_encrypt(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]) -{ - if (nfc_module == NFC_MODULE_PN532) { - return pn532_felica_read_wo_encrypt(svc_code, block_id, block_data); - } else if (nfc_module == NFC_MODULE_PN5180) { - return false; //pn5180_felica_read_wo_encrypt(svc_code, block_id, block_data); - } - return false; -} - -bool nfc_felica_write_wo_encrypt(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16]) -{ - if (nfc_module == NFC_MODULE_PN532) { - return pn532_felica_write_wo_encrypt(svc_code, block_id, block_data); - } else if (nfc_module == NFC_MODULE_PN5180) { - return false; //pn5180_felica_write_wo_encrypt(svc_code, block_id, block_data); - } - return false; + return api[nfc_module].mifare_read(block_id, block_data); } diff --git a/firmware/src/lib/pn5180.c b/firmware/src/lib/pn5180.c index 0173e7a..a3b2905 100644 --- a/firmware/src/lib/pn5180.c +++ b/firmware/src/lib/pn5180.c @@ -30,23 +30,20 @@ #define CMD_RF_ON 0x16 #define CMD_RF_OFF 0x17 -static struct { - spi_inst_t *port; - uint8_t rst; - uint8_t nss; - uint8_t busy; -} spi; +static spi_inst_t *spi_port; +static uint8_t gpio_rst; +static uint8_t gpio_nss; +static uint8_t gpio_busy; -bool pn5180_init(spi_inst_t *port, uint8_t rx, uint8_t sck, uint8_t tx, +bool pn5180_init(spi_inst_t *port, uint8_t miso, uint8_t sck, uint8_t mosi, uint8_t rst, uint8_t nss, uint8_t busy) { spi_init(port, 2000 * 1000); spi_set_format(port, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); - gpio_set_function(rx, GPIO_FUNC_SPI); + gpio_set_function(miso, GPIO_FUNC_SPI); gpio_set_function(sck, GPIO_FUNC_SPI); - gpio_set_function(tx, GPIO_FUNC_SPI); - //gpio_set_function(nss, GPIO_FUNC_SPI); + gpio_set_function(mosi, GPIO_FUNC_SPI); gpio_init(nss); gpio_set_dir(nss, GPIO_OUT); @@ -58,10 +55,10 @@ bool pn5180_init(spi_inst_t *port, uint8_t rx, uint8_t sck, uint8_t tx, gpio_pull_up(rst); gpio_put(rst, 1); - spi.port = port; - spi.rst = rst; - spi.nss = nss; - spi.busy = busy; + spi_port = port; + gpio_rst = rst; + gpio_nss = nss; + gpio_busy = busy; uint8_t buf[2]; pn5180_read_eeprom(0x12, buf, sizeof(buf)); @@ -73,7 +70,7 @@ static pn5180_wait_loop_t wait_loop = NULL; static inline void wait_not_busy() { int count = 0; - while (gpio_get(spi.busy)) { + while (gpio_get(gpio_busy)) { sleep_us(10); count += 10; if ((count > 1000) && wait_loop) { @@ -96,13 +93,13 @@ static void sleep_ms_with_loop(uint32_t ms) static inline void begin_transmission() { wait_not_busy(); - gpio_put(spi.nss, 0); + gpio_put(gpio_nss, 0); sleep_ms_with_loop(2); } static inline void end_transmission() { - gpio_put(spi.nss, 1); + gpio_put(gpio_nss, 1); sleep_ms_with_loop(3); } @@ -114,7 +111,7 @@ void pn5180_set_wait_loop(pn5180_wait_loop_t loop) static bool read_write(const uint8_t *data, uint8_t len, uint8_t *buf, uint8_t buf_len) { begin_transmission(); - spi_write_blocking(spi.port, data, len); + spi_write_blocking(spi_port, data, len); end_transmission(); if (!buf || (buf_len == 0)) { @@ -122,7 +119,7 @@ static bool read_write(const uint8_t *data, uint8_t len, uint8_t *buf, uint8_t b } begin_transmission(); - spi_read_blocking(spi.port, 0, buf, buf_len); + spi_read_blocking(spi_port, 0, buf, buf_len); end_transmission(); return true; @@ -199,9 +196,9 @@ void pn5180_rf_off() void pn5180_reset() { - gpio_put(spi.rst, 0); + gpio_put(gpio_rst, 0); sleep_us(20); - gpio_put(spi.rst, 1); + gpio_put(gpio_rst, 1); sleep_ms(1); while ((pn5180_get_irq() & (1 << 2)) == 0) { if (wait_loop) { diff --git a/firmware/src/lib/pn5180.h b/firmware/src/lib/pn5180.h index 69971ea..97ae70f 100644 --- a/firmware/src/lib/pn5180.h +++ b/firmware/src/lib/pn5180.h @@ -23,7 +23,7 @@ typedef void (*pn5180_wait_loop_t)(); void pn5180_set_wait_loop(pn5180_wait_loop_t loop); -bool pn5180_init(spi_inst_t *port, uint8_t rx, uint8_t sck, uint8_t tx, +bool pn5180_init(spi_inst_t *port, uint8_t miso, uint8_t sck, uint8_t mosi, uint8_t rst, uint8_t nss, uint8_t busy); void pn5180_write_reg(uint8_t reg, uint32_t v32); diff --git a/firmware/src/lib/pn532.c b/firmware/src/lib/pn532.c index e623728..ed6c26f 100644 --- a/firmware/src/lib/pn532.c +++ b/firmware/src/lib/pn532.c @@ -26,8 +26,14 @@ static i2c_inst_t *i2c_port = i2c0; -bool pn532_init(i2c_inst_t *i2c) +bool pn532_init(i2c_inst_t *i2c, uint8_t scl, uint8_t sda, uint32_t freq) { + i2c_init(i2c, freq); + gpio_set_function(scl, GPIO_FUNC_I2C); + gpio_set_function(sda, GPIO_FUNC_I2C); + gpio_pull_up(scl); + gpio_pull_up(sda); + i2c_port = i2c; uint32_t ver = pn532_firmware_ver(); diff --git a/firmware/src/lib/pn532.h b/firmware/src/lib/pn532.h index 8ce1e7f..853a7aa 100644 --- a/firmware/src/lib/pn532.h +++ b/firmware/src/lib/pn532.h @@ -14,7 +14,7 @@ typedef void (*pn532_wait_loop_t)(); void pn532_set_wait_loop(pn532_wait_loop_t loop); -bool pn532_init(i2c_inst_t *i2c_port); +bool 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_read_response(uint8_t cmd, uint8_t *resp, uint8_t len); diff --git a/firmware/src/main.c b/firmware/src/main.c index 61b03d2..08ead73 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -223,7 +223,9 @@ void init() mutex_init(&core1_io_lock); save_init(0xca340a1c, &core1_io_lock); - nfc_init(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ); + nfc_set_i2c(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ); + nfc_set_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);