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

Auto mode (protocol) detection

This commit is contained in:
whowechina 2024-05-07 12:05:45 +08:00
parent 6b020e3e3f
commit 84310663cb
10 changed files with 159 additions and 37 deletions

Binary file not shown.

View File

@ -15,7 +15,7 @@ typedef void (*aime_putc_func)(uint8_t byte);
void aime_init(aime_putc_func putc_func);
void aime_virtual_aic(bool enable);
void aime_set_mode(int mode);
void aime_sub_mode(int sub_mode);
const char *aime_get_mode_string();
bool aime_feed(int c);

22
firmware/include/mode.h Normal file
View File

@ -0,0 +1,22 @@
/*
* COM Port Protocol Definition and Detection
* WHowe <github.com/whowechina>
*/
#ifndef MODE_H
#define MODE_H
#include <stdint.h>
typedef enum {
MODE_AUTO = 0,
MODE_AIME0 = 0x10,
MODE_AIME1 = 0x11,
MODE_BANA = 0x20,
MODE_NONE = 0xff,
} reader_mode_t;
reader_mode_t mode_detect(const uint8_t *data, uint32_t len, uint32_t baudrate);
const char *mode_name(reader_mode_t mode);
#endif

View File

@ -28,5 +28,5 @@ function(make_firmware board board_def)
COMMAND cp ${board}.uf2 ${CMAKE_CURRENT_LIST_DIR}/..)
endfunction()
add_library(aic lib/aime.c lib/bana.c lib/pn532.c lib/pn5180.c lib/nfc.c)
add_library(aic lib/aime.c lib/bana.c lib/pn532.c lib/pn5180.c lib/nfc.c lib/mode.c)
make_firmware(aic_pico BOARD_AIC_PICO)

View File

@ -44,11 +44,12 @@ static void handle_display()
printf("[AIME]\n");
printf(" Virtual AIC: %s\n", aic_cfg->virtual_aic ? "ON" : "OFF");
printf(" Mode: %s\n", aic_cfg->mode == 0 ? "aime0" :
aic_cfg->mode == 1 ? "aime1" :
aic_cfg->mode == 0x10 ? "bana" : "not set");
if ((aic_cfg->mode & 0xf0) == 0) {
printf(" Pattern: %s\n", aime_get_mode_string());
printf(" Mode: %s\n", mode_name(aic_cfg->mode));
if (aic_cfg->mode == MODE_AUTO) {
printf(" Detected: %s\n", mode_name(aic_runtime.mode));
}
if ((aic_runtime.mode == MODE_AIME0) || (aic_runtime.mode == MODE_AIME1)) {
printf(" AIME Pattern: %s\n", aime_get_mode_string());
}
}
@ -101,7 +102,8 @@ static void handle_virtual(int argc, char *argv[])
static void handle_mode(int argc, char *argv[])
{
const char *usage = "Usage: mode <aime0:aime1:bana>\n"
const char *usage = "Usage: mode <auto|aime0|aime1|bana>\n"
" auto: Auto detect\n"
" aime0: Sega Aime 0\n"
" aime1: Sega Aime 1\n"
" bana: Bandai Namco\n";
@ -110,27 +112,27 @@ static void handle_mode(int argc, char *argv[])
return;
}
const char *commands[] = { "aime0", "aime1", "bana" };
int match = cli_match_prefix(commands, 3, argv[0]);
const char *commands[] = { "auto", "aime0", "aime1", "bana" };
int match = cli_match_prefix(commands, 4, argv[0]);
switch (match) {
case 0:
aic_cfg->mode = 0x00;
aic_cfg->mode = MODE_AUTO;
break;
case 1:
aic_cfg->mode = 0x01;
aic_cfg->mode = MODE_AIME0;
break;
case 2:
aic_cfg->mode = 0x10;
aic_cfg->mode = MODE_AIME1;
break;
case 3:
aic_cfg->mode = MODE_BANA;
break;
default:
printf("%s", usage);
return;
}
if ((aic_cfg->mode & 0xf0) == 0) {
aime_set_mode(aic_cfg->mode);
}
aic_runtime.mode = aic_cfg->mode == MODE_AUTO ? MODE_NONE : aic_cfg->mode;
config_changed();
}

View File

@ -8,13 +8,14 @@
#include "config.h"
#include "save.h"
#include "mode.h"
aic_cfg_t *aic_cfg;
static aic_cfg_t default_cfg = {
.light = { .min = 24, .max = 128, .rgb = true, .led = true },
.virtual_aic = true,
.mode = 0,
.mode = MODE_AUTO,
};
aic_runtime_t aic_runtime;
@ -25,6 +26,12 @@ static void config_loaded()
aic_cfg->light = default_cfg.light;
config_changed();
}
if ((aic_cfg->mode != MODE_AIME0) &&
(aic_cfg->mode != MODE_AIME1) &&
(aic_cfg->mode != MODE_BANA)) {
aic_cfg->mode = MODE_AUTO;
config_changed();
}
}
void config_changed()

View File

@ -9,6 +9,8 @@
#include <stdint.h>
#include <stdbool.h>
#include <mode.h>
typedef struct __attribute__((packed)) {
struct {
uint8_t min;
@ -23,6 +25,7 @@ typedef struct __attribute__((packed)) {
typedef volatile struct {
bool debug;
reader_mode_t mode;
} aic_runtime_t;
extern aic_cfg_t *aic_cfg;

View File

@ -84,9 +84,9 @@ static void putc_trap(uint8_t byte)
static aime_putc_func aime_putc = putc_trap;
void aime_set_mode(int mode)
void aime_sub_mode(int sub_mode)
{
ver_mode = (mode == 0) ? 0 : 1;
ver_mode = (sub_mode == 0) ? 0 : 1;
}
const char *aime_get_mode_string()

57
firmware/src/lib/mode.c Normal file
View File

@ -0,0 +1,57 @@
/*
* COM Port Protocol Definition and Detection
* WHowe <github.com/whowechina>
*
*/
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "mode.h"
static uint64_t last_detect_time;
reader_mode_t mode_detect(const uint8_t *data, uint32_t len, uint32_t baudrate)
{
last_detect_time = time_us_64();
if ((len > 2) && (data[0] == 0xe0) && (data[1] < 0x10)) {
return baudrate == 115200 ? MODE_AIME0 : MODE_AIME1;
}
if ((len == 1) && (data[0] == 0x55)) {
return MODE_BANA;
}
if ((len >= 3) && (memcmp(data, "\x00\x00\xff", 3) == 0)) {
return MODE_BANA;
}
if ((len >= 4) && (memcmp(data, "\x55\x00\x00\xff", 4) == 0)) {
return MODE_BANA;
}
last_detect_time = 0;
return MODE_NONE;
}
const char *mode_name(reader_mode_t mode)
{
switch (mode) {
case MODE_AUTO:
return "Auto";
case MODE_AIME0:
return "Aime0";
case MODE_AIME1:
return "Aime1";
case MODE_BANA:
return "Bana";
case MODE_NONE:
return "None";
default:
return "Unknown";
}
}

View File

@ -23,6 +23,11 @@
#include "tusb.h"
#include "usb_descriptors.h"
#include <nfc.h>
#include <mode.h>
#include <aime.h>
#include <bana.h>
#include "save.h"
#include "config.h"
#include "cli.h"
@ -30,11 +35,6 @@
#include "light.h"
#include "keypad.h"
#include "nfc.h"
#include "aime.h"
#include "bana.h"
#define DEBUG(...) if (aic_runtime.debug) printf(__VA_ARGS__)
static struct {
@ -209,22 +209,56 @@ static void aime_poll_data()
}
}
static void aime_detect_mode()
{
if (aic_cfg->mode == MODE_AUTO) {
static bool was_active = true; // so first time mode will be cleared
bool is_active = aime_is_active() || bana_is_active();
if (was_active && !is_active) {
aic_runtime.mode = MODE_NONE;
}
was_active = is_active;
} else {
aic_runtime.mode = aic_cfg->mode;
}
if (aic_runtime.mode == MODE_NONE) {
cdc_line_coding_t coding;
tud_cdc_n_get_line_coding(aime_intf, &coding);
aic_runtime.mode = mode_detect(aime.buf, aime.pos, coding.bit_rate);
if ((aime.pos > 10) && (aic_runtime.mode == MODE_NONE)) {
aime.pos = 0; // drop the buffer
}
}
}
static void aime_run()
{
aime_poll_data();
aime_detect_mode();
if (aime.pos > 0) {
uint8_t buf[64];
memcpy(buf, aime.buf, aime.pos);
int count = aime.pos;
aime.pos = 0;
switch (aic_runtime.mode) {
case MODE_AIME0:
case MODE_AIME1:
aime_sub_mode(aic_runtime.mode == MODE_AIME0 ? 0 : 1);
for (int i = 0; i < count; i++) {
if ((aic_cfg->mode & 0xf0) == 0) {
aime_feed(buf[i]);
} else {
}
aime.pos = 0;
break;
case MODE_BANA:
for (int i = 0; i < count; i++) {
bana_feed(buf[i]);
}
aime.pos = 0;
break;
default:
break;
}
}
}
@ -280,10 +314,6 @@ void init()
aime_init(cdc_aime_putc);
aime_virtual_aic(aic_cfg->virtual_aic);
if ((aic_cfg->mode & 0x0f) == 0) {
aime_set_mode(aic_cfg->mode);
}
bana_init(cdc_aime_putc);
cli_init("aic_pico>", "\n << AIC Pico >>\n"
@ -361,6 +391,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id,
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
{
DEBUG("\nCDC Line State: %d %d", dtr, rts);
aime_fast_expire();
bana_fast_expire();
}