1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2024-09-23 18:48:24 +02: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_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 struct {
@ -61,7 +81,7 @@ nfc_card_t nfc_detect_card();
nfc_card_t nfc_detect_card_ex(bool mifare, bool felica, bool vicinity);
void display_card(const nfc_card_t *card);
\
const char *nfc_module_name();
const char *nfc_module_version();

View File

@ -106,7 +106,7 @@ static void handle_nfc()
nfc_card_t card = nfc_detect_card();
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++) {
printf(" %02x", card.uid[i]);
}

View File

@ -29,6 +29,7 @@
#include "ltsaeada.h"
#include "light.h"
#include "star_ani.h"
#include "light_ani.h"
#include "glow_ani.h"
#include "images.h"
@ -49,6 +50,22 @@ void gui_level(uint8_t 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 void draw_home_keypad()
@ -96,9 +113,25 @@ static void draw_home_bana()
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()
{
if (aime_is_active()) {
if (card_splash_active()) {
draw_home_card();
}
else if (aime_is_active()) {
draw_home_aime();
} else if (bana_is_active()) {
draw_home_bana();
@ -197,7 +230,7 @@ static void draw_credits()
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\xff\x80) "THANKS TO\n\n"
SET_COLOR(\x80\x80\x80) "CrazyRedMachine\n"
SET_COLOR(\xb0\xb0\xb0) "CrazyRedMachine\n"
"Sucareto Bottersnike\n"
"Gyt4 chujohiroto\n\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);
}
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 g = (color >> 8) & 0xff;
uint32_t b = color & 0xff;
for (int i = 0; i < 16; i++) {
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 int phase = 0;
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 <stdbool.h>
#include "nfc.h"
void gui_init();
void gui_level(uint8_t level);
void gui_loop();
uint16_t gui_keypad_read();
void report_card(nfc_card_name card);
#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];
}
static const char *nfc_card_names[] = {
static const char *card_type_str[] = {
"None",
"MIFARE",
"FeliCa",
"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 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
@ -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 card = { 0 };
@ -235,6 +288,7 @@ nfc_card_t nfc_detect_card()
if (nfc_detect_mifare(&card) ||
nfc_detect_felica(&card) ||
nfc_detect_vicinity(&card)) {
update_last_card(&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))
|| (felica && nfc_detect_felica(&card))
|| (vicinity && nfc_detect_vicinity(&card))) {
update_last_card(&card);
return card;
}
@ -256,10 +311,25 @@ nfc_card_t nfc_detect_card_ex(bool mifare, bool felica, bool vicinity)
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)
{
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++) {
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);
}
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])
{
if (!api[nfc_module].felica_read) {
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)

View File

@ -106,15 +106,15 @@ static bool hid_is_active()
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 bool was_cardio = true;
bool cardio = cardio_is_available();
bool cardio = !reader_is_active() && !hid_is_active();
if (cardio && !was_cardio) {
light_rainbow(1, 1, aic_cfg->light.level_idle);
@ -197,6 +197,7 @@ static void cardio_run()
nfc_rf_field(true);
nfc_card_t card = nfc_detect_card();
nfc_identify_last_card();
nfc_rf_field(false);
if (memcmp(&old_card, &card, sizeof(old_card)) == 0) {
@ -204,8 +205,9 @@ static void cardio_run()
}
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) {
light_rainbow(30, 0, aic_cfg->light.level_active);
} else {