1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2024-11-12 00:40:47 +01:00

Card identification and display

This commit is contained in:
whowechina 2024-06-16 15:13:17 +08:00
parent 45d2413dc2
commit c785454607
7 changed files with 3353 additions and 24 deletions

View File

@ -19,7 +19,27 @@ typedef enum {
NFC_CARD_VICINITY, NFC_CARD_VICINITY,
} nfc_card_type; } nfc_card_type;
const char *nfc_card_name(nfc_card_type card_type); const char *nfc_card_type_str(nfc_card_type card_type);
typedef enum {
CARD_NONE,
CARD_AIC,
CARD_AIC_SEGA,
CARD_AIC_KONAMI,
CARD_AIC_BANA,
CARD_AIC_NESICA,
CARD_AIC_VIRTUAL,
CARD_MIFARE,
CARD_AIME,
CARD_BANA,
CARD_NESICA,
CARD_VICINITY,
CARD_EAMUSE,
} nfc_card_name;
const char *nfc_card_name_str(nfc_card_name card_name);
nfc_card_name nfc_last_card_name();
void nfc_identify_last_card();
typedef void (*nfc_wait_loop_t)(); typedef void (*nfc_wait_loop_t)();
typedef struct { typedef struct {
@ -61,7 +81,7 @@ nfc_card_t nfc_detect_card();
nfc_card_t nfc_detect_card_ex(bool mifare, bool felica, bool vicinity); nfc_card_t nfc_detect_card_ex(bool mifare, bool felica, bool vicinity);
void display_card(const nfc_card_t *card); void display_card(const nfc_card_t *card);
\
const char *nfc_module_name(); const char *nfc_module_name();
const char *nfc_module_version(); const char *nfc_module_version();

View File

@ -106,7 +106,7 @@ static void handle_nfc()
nfc_card_t card = nfc_detect_card(); nfc_card_t card = nfc_detect_card();
nfc_rf_field(false); nfc_rf_field(false);
printf("Card: %s", nfc_card_name(card.card_type)); printf("Card: %s", nfc_card_name_str(card.card_type));
for (int i = 0; i < card.len; i++) { for (int i = 0; i < card.len; i++) {
printf(" %02x", card.uid[i]); printf(" %02x", card.uid[i]);
} }

View File

@ -29,6 +29,7 @@
#include "ltsaeada.h" #include "ltsaeada.h"
#include "light.h" #include "light.h"
#include "star_ani.h" #include "star_ani.h"
#include "light_ani.h"
#include "glow_ani.h" #include "glow_ani.h"
#include "images.h" #include "images.h"
@ -49,6 +50,22 @@ void gui_level(uint8_t level)
st7789_dimmer(255 - level); st7789_dimmer(255 - level);
} }
static struct {
nfc_card_name card;
uint64_t time;
} card_splash;
static inline bool card_splash_active()
{
return time_us_64() - card_splash.time < 3000000;
}
void report_card(nfc_card_name card)
{
card_splash.card = card;
card_splash.time = time_us_64();
}
static int tapped_key = -1; static int tapped_key = -1;
static void draw_home_keypad() static void draw_home_keypad()
@ -96,9 +113,25 @@ static void draw_home_bana()
center_image(&bana_logo); center_image(&bana_logo);
} }
static void draw_home_card()
{
if (card_splash.card == CARD_AIC_SEGA) {
center_image(&aic_sega);
} else if (card_splash.card == CARD_AIC_BANA) {
center_image(&aic_bana);
} else if (card_splash.card == CARD_AIC_KONAMI){
center_image(&aic_konami);
} else if (card_splash.card == CARD_AIC_NESICA) {
center_image(&aic_nesica);
}
}
static void draw_home() static void draw_home()
{ {
if (aime_is_active()) { if (card_splash_active()) {
draw_home_card();
}
else if (aime_is_active()) {
draw_home_aime(); draw_home_aime();
} else if (bana_is_active()) { } else if (bana_is_active()) {
draw_home_bana(); draw_home_bana();
@ -197,7 +230,7 @@ static void draw_credits()
SET_COLOR(\x80\xff\x80) "AIC Pico (AIC Touch)\n" SET_COLOR(\x80\xff\x80) "AIC Pico (AIC Touch)\n"
SET_COLOR(\x80\x80\xff) "https://github.com/whowechina\n\n\n" SET_COLOR(\x80\x80\xff) "https://github.com/whowechina\n\n\n"
SET_COLOR(\x80\xff\x80) "THANKS TO\n\n" SET_COLOR(\x80\xff\x80) "THANKS TO\n\n"
SET_COLOR(\x80\x80\x80) "CrazyRedMachine\n" SET_COLOR(\xb0\xb0\xb0) "CrazyRedMachine\n"
"Sucareto Bottersnike\n" "Sucareto Bottersnike\n"
"Gyt4 chujohiroto\n\n" "Gyt4 chujohiroto\n\n"
"KiCAD OnShape Fritzing\n" "KiCAD OnShape Fritzing\n"
@ -208,30 +241,35 @@ static void draw_credits()
st7789_text(120, 30, credits, &lv_lts14, st7789_rgb565(0xc0c060), ALIGN_CENTER); st7789_text(120, 30, credits, &lv_lts14, st7789_rgb565(0xc0c060), ALIGN_CENTER);
} }
uint16_t ani_colors[] = {
0x00 << 1, 0x01 << 1, 0x02 << 1, 0x03 << 1, 0x04 << 1, 0x05 << 1, 0x06 << 1, 0x07 << 1,
0x08 << 1, 0x09 << 1, 0x0a << 1, 0x0b << 1, 0x0c << 1, 0x0d << 1, 0x0e << 1, 0x0f << 1
};
static void rotate_colors() static void gen_pallete(uint16_t pallete[16], uint32_t color)
{ {
uint32_t color = rgb32_from_hsv(time_us_32() / 100000 + 128, 200, 250);
uint32_t r = (color >> 16) & 0xff; uint32_t r = (color >> 16) & 0xff;
uint32_t g = (color >> 8) & 0xff; uint32_t g = (color >> 8) & 0xff;
uint32_t b = color & 0xff; uint32_t b = color & 0xff;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
uint32_t mix = st7789_rgb32(r * i / 30, g * i / 30, b * i / 30); uint32_t mix = st7789_rgb32(r * i / 30, g * i / 30, b * i / 30);
ani_colors[i] = st7789_rgb565(mix); pallete[i] = st7789_rgb565(mix);
} }
} }
static void run_background() static void run_background()
{ {
static int phase = 0; static int phase = 0;
phase++; phase++;
rotate_colors();
gfx_anima_draw(&star_ani, 0, 0, phase, ani_colors); uint16_t pallete[16];
if (card_splash_active()) {
gen_pallete(pallete, 0x0000ff);
gfx_anima_draw(&light_ani, 0, 0, phase, pallete);
} else {
uint32_t color = rgb32_from_hsv(time_us_32() / 100000 + 128, 200, 250);
gen_pallete(pallete, color);
gfx_anima_draw(&star_ani, 0, 0, phase, pallete);
}
} }

View File

@ -11,9 +11,12 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "nfc.h"
void gui_init(); void gui_init();
void gui_level(uint8_t level); void gui_level(uint8_t level);
void gui_loop(); void gui_loop();
uint16_t gui_keypad_read(); uint16_t gui_keypad_read();
void report_card(nfc_card_name card);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -34,19 +34,63 @@ const char *nfc_module_name()
return nfc_module_names[nfc_module]; return nfc_module_names[nfc_module];
} }
static const char *nfc_card_names[] = { static const char *card_type_str[] = {
"None", "None",
"MIFARE", "MIFARE",
"FeliCa", "FeliCa",
"15693" "15693"
}; };
const char *nfc_card_name(nfc_card_type card_type) const char *nfc_card_type_str(nfc_card_type card_type)
{ {
if (card_type >= sizeof(nfc_card_names) / sizeof(nfc_card_names[0])) { if (card_type >= sizeof(card_type_str) / sizeof(card_type_str[0])) {
return "Unknown"; return "Unknown";
} }
return nfc_card_names[card_type]; return card_type_str[card_type];
}
static const char *card_name_str[] = {
"None",
"Amusement IC Generic",
"Amusement IC SEGA",
"Amusement IC KONAMI",
"Amusement IC Bandai Namco",
"Amusement IC NESiCA",
"Amusement IC Virtual",
"MIFARE Generic",
"AIME",
"Bandai Namco Passport",
"NESiCA",
"Vicinity Generic",
"E-Amusement Pass",
};
const char *nfc_card_name_str(nfc_card_name card_name)
{
if (card_name >= sizeof(card_name_str) / sizeof(card_name_str[0])) {
return "None";
}
return card_name_str[card_name];
}
#define CARD_INFO_TIMEOUT_US (1000 * 1000)
static nfc_card_name last_card_name = CARD_NONE;
static uint64_t last_card_name_time = 0;
static void update_card_name(nfc_card_name card_name)
{
last_card_name = card_name;
last_card_name_time = time_us_64();
}
nfc_card_name nfc_last_card_name()
{
if (time_us_64() - last_card_name_time > CARD_INFO_TIMEOUT_US) {
return CARD_NONE;
}
return last_card_name;
} }
#define func_null NULL #define func_null NULL
@ -228,6 +272,15 @@ void nfc_rf_field(bool on)
} }
} }
static nfc_card_t last_card;
static uint64_t last_card_time = 0;
static void update_last_card(const nfc_card_t *card)
{
last_card = *card;
last_card_time = time_us_64();
}
nfc_card_t nfc_detect_card() nfc_card_t nfc_detect_card()
{ {
nfc_card_t card = { 0 }; nfc_card_t card = { 0 };
@ -235,6 +288,7 @@ nfc_card_t nfc_detect_card()
if (nfc_detect_mifare(&card) || if (nfc_detect_mifare(&card) ||
nfc_detect_felica(&card) || nfc_detect_felica(&card) ||
nfc_detect_vicinity(&card)) { nfc_detect_vicinity(&card)) {
update_last_card(&card);
return card; return card;
} }
@ -249,6 +303,7 @@ nfc_card_t nfc_detect_card_ex(bool mifare, bool felica, bool vicinity)
if ((mifare && nfc_detect_mifare(&card)) if ((mifare && nfc_detect_mifare(&card))
|| (felica && nfc_detect_felica(&card)) || (felica && nfc_detect_felica(&card))
|| (vicinity && nfc_detect_vicinity(&card))) { || (vicinity && nfc_detect_vicinity(&card))) {
update_last_card(&card);
return card; return card;
} }
@ -256,10 +311,25 @@ nfc_card_t nfc_detect_card_ex(bool mifare, bool felica, bool vicinity)
return card; return card;
} }
void nfc_identify_last_card()
{
if (time_us_64() - last_card_time > CARD_INFO_TIMEOUT_US) {
return;
}
if (last_card.card_type == NFC_CARD_FELICA) {
nfc_felica_read(0x000b, 0x8082, last_card.uid);
} else if (last_card.card_type == NFC_CARD_MIFARE) {
update_card_name(CARD_MIFARE);
} else if (last_card.card_type == NFC_CARD_VICINITY) {
update_card_name(CARD_VICINITY);
}
}
void display_card(const nfc_card_t *card) void display_card(const nfc_card_t *card)
{ {
if (card->card_type != NFC_CARD_NONE) { if (card->card_type != NFC_CARD_NONE) {
printf("\n%s:", nfc_card_name(card->card_type)); printf("\n%s:", nfc_card_type_str(card->card_type));
for (int i = 0; i < card->len; i++) { for (int i = 0; i < card->len; i++) {
printf(" %02X", card->uid[i]); printf(" %02X", card->uid[i]);
} }
@ -282,12 +352,34 @@ bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16])
return api[nfc_module].mifare_read(block_id, block_data); return api[nfc_module].mifare_read(block_id, block_data);
} }
static void felica_report_name(const uint8_t dfc[2])
{
update_card_name(CARD_AIC);
if (dfc[1] == 0x78) {
update_card_name(CARD_AIC_SEGA);
} else if (dfc[1] == 0x68) {
update_card_name(CARD_AIC_KONAMI);
} else if ((dfc[1] == 0x2a) || (dfc[1] == 0x3a)) {
update_card_name(CARD_AIC_BANA);
} else if (dfc[1] == 0x79) {
update_card_name(CARD_AIC_NESICA);
}
}
bool nfc_felica_read(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]) bool nfc_felica_read(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16])
{ {
if (!api[nfc_module].felica_read) { if (!api[nfc_module].felica_read) {
return false; return false;
} }
return api[nfc_module].felica_read(svc_code, block_id, block_data);
bool read_ok = api[nfc_module].felica_read(svc_code, block_id, block_data);
if (read_ok && (svc_code = 0x000b) && (block_id == 0x8082)) {
felica_report_name(block_data + 8); // DFC
}
return read_ok;
} }
void nfc_select(int phase) void nfc_select(int phase)

View File

@ -106,15 +106,15 @@ static bool hid_is_active()
return (time_us_64() - last_hid_time) < 2000000; return (time_us_64() - last_hid_time) < 2000000;
} }
static bool cardio_is_available() static bool reader_is_active()
{ {
return !(hid_is_active() || aime_is_active() || bana_is_active()); return aime_is_active() || bana_is_active();
} }
static void light_mode_update() static void light_mode_update()
{ {
static bool was_cardio = true; static bool was_cardio = true;
bool cardio = cardio_is_available(); bool cardio = !reader_is_active() && !hid_is_active();
if (cardio && !was_cardio) { if (cardio && !was_cardio) {
light_rainbow(1, 1, aic_cfg->light.level_idle); light_rainbow(1, 1, aic_cfg->light.level_idle);
@ -197,6 +197,7 @@ static void cardio_run()
nfc_rf_field(true); nfc_rf_field(true);
nfc_card_t card = nfc_detect_card(); nfc_card_t card = nfc_detect_card();
nfc_identify_last_card();
nfc_rf_field(false); nfc_rf_field(false);
if (memcmp(&old_card, &card, sizeof(old_card)) == 0) { if (memcmp(&old_card, &card, sizeof(old_card)) == 0) {
@ -204,8 +205,9 @@ static void cardio_run()
} }
old_card = card; old_card = card;
report_card(nfc_last_card_name());
if (cardio_is_available()) { if (!reader_is_active() && !hid_is_active()) {
if (card.card_type != NFC_CARD_NONE) { if (card.card_type != NFC_CARD_NONE) {
light_rainbow(30, 0, aic_cfg->light.level_active); light_rainbow(30, 0, aic_cfg->light.level_active);
} else { } else {