mirror of
https://github.com/whowechina/aic_pico.git
synced 2024-09-24 02:58:21 +02:00
Auto mode (protocol) detection
This commit is contained in:
parent
6b020e3e3f
commit
84310663cb
Binary file not shown.
@ -15,7 +15,7 @@ typedef void (*aime_putc_func)(uint8_t byte);
|
|||||||
void aime_init(aime_putc_func putc_func);
|
void aime_init(aime_putc_func putc_func);
|
||||||
|
|
||||||
void aime_virtual_aic(bool enable);
|
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();
|
const char *aime_get_mode_string();
|
||||||
|
|
||||||
bool aime_feed(int c);
|
bool aime_feed(int c);
|
||||||
|
22
firmware/include/mode.h
Normal file
22
firmware/include/mode.h
Normal 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
|
@ -28,5 +28,5 @@ function(make_firmware board board_def)
|
|||||||
COMMAND cp ${board}.uf2 ${CMAKE_CURRENT_LIST_DIR}/..)
|
COMMAND cp ${board}.uf2 ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||||
endfunction()
|
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)
|
make_firmware(aic_pico BOARD_AIC_PICO)
|
||||||
|
@ -44,11 +44,12 @@ static void handle_display()
|
|||||||
printf("[AIME]\n");
|
printf("[AIME]\n");
|
||||||
printf(" Virtual AIC: %s\n", aic_cfg->virtual_aic ? "ON" : "OFF");
|
printf(" Virtual AIC: %s\n", aic_cfg->virtual_aic ? "ON" : "OFF");
|
||||||
|
|
||||||
printf(" Mode: %s\n", aic_cfg->mode == 0 ? "aime0" :
|
printf(" Mode: %s\n", mode_name(aic_cfg->mode));
|
||||||
aic_cfg->mode == 1 ? "aime1" :
|
if (aic_cfg->mode == MODE_AUTO) {
|
||||||
aic_cfg->mode == 0x10 ? "bana" : "not set");
|
printf(" Detected: %s\n", mode_name(aic_runtime.mode));
|
||||||
if ((aic_cfg->mode & 0xf0) == 0) {
|
}
|
||||||
printf(" Pattern: %s\n", aime_get_mode_string());
|
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[])
|
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"
|
" aime0: Sega Aime 0\n"
|
||||||
" aime1: Sega Aime 1\n"
|
" aime1: Sega Aime 1\n"
|
||||||
" bana: Bandai Namco\n";
|
" bana: Bandai Namco\n";
|
||||||
@ -110,27 +112,27 @@ static void handle_mode(int argc, char *argv[])
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *commands[] = { "aime0", "aime1", "bana" };
|
const char *commands[] = { "auto", "aime0", "aime1", "bana" };
|
||||||
int match = cli_match_prefix(commands, 3, argv[0]);
|
int match = cli_match_prefix(commands, 4, argv[0]);
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case 0:
|
case 0:
|
||||||
aic_cfg->mode = 0x00;
|
aic_cfg->mode = MODE_AUTO;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
aic_cfg->mode = 0x01;
|
aic_cfg->mode = MODE_AIME0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
aic_cfg->mode = 0x10;
|
aic_cfg->mode = MODE_AIME1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
aic_cfg->mode = MODE_BANA;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("%s", usage);
|
printf("%s", usage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((aic_cfg->mode & 0xf0) == 0) {
|
aic_runtime.mode = aic_cfg->mode == MODE_AUTO ? MODE_NONE : aic_cfg->mode;
|
||||||
aime_set_mode(aic_cfg->mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
config_changed();
|
config_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,13 +8,14 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
|
#include "mode.h"
|
||||||
|
|
||||||
aic_cfg_t *aic_cfg;
|
aic_cfg_t *aic_cfg;
|
||||||
|
|
||||||
static aic_cfg_t default_cfg = {
|
static aic_cfg_t default_cfg = {
|
||||||
.light = { .min = 24, .max = 128, .rgb = true, .led = true },
|
.light = { .min = 24, .max = 128, .rgb = true, .led = true },
|
||||||
.virtual_aic = true,
|
.virtual_aic = true,
|
||||||
.mode = 0,
|
.mode = MODE_AUTO,
|
||||||
};
|
};
|
||||||
|
|
||||||
aic_runtime_t aic_runtime;
|
aic_runtime_t aic_runtime;
|
||||||
@ -25,6 +26,12 @@ static void config_loaded()
|
|||||||
aic_cfg->light = default_cfg.light;
|
aic_cfg->light = default_cfg.light;
|
||||||
config_changed();
|
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()
|
void config_changed()
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <mode.h>
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
struct {
|
struct {
|
||||||
uint8_t min;
|
uint8_t min;
|
||||||
@ -23,6 +25,7 @@ typedef struct __attribute__((packed)) {
|
|||||||
|
|
||||||
typedef volatile struct {
|
typedef volatile struct {
|
||||||
bool debug;
|
bool debug;
|
||||||
|
reader_mode_t mode;
|
||||||
} aic_runtime_t;
|
} aic_runtime_t;
|
||||||
|
|
||||||
extern aic_cfg_t *aic_cfg;
|
extern aic_cfg_t *aic_cfg;
|
||||||
|
@ -84,9 +84,9 @@ static void putc_trap(uint8_t byte)
|
|||||||
|
|
||||||
static aime_putc_func aime_putc = putc_trap;
|
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()
|
const char *aime_get_mode_string()
|
||||||
|
57
firmware/src/lib/mode.c
Normal file
57
firmware/src/lib/mode.c
Normal 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";
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,11 @@
|
|||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
|
|
||||||
|
#include <nfc.h>
|
||||||
|
#include <mode.h>
|
||||||
|
#include <aime.h>
|
||||||
|
#include <bana.h>
|
||||||
|
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
@ -30,11 +35,6 @@
|
|||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "keypad.h"
|
#include "keypad.h"
|
||||||
|
|
||||||
#include "nfc.h"
|
|
||||||
|
|
||||||
#include "aime.h"
|
|
||||||
#include "bana.h"
|
|
||||||
|
|
||||||
#define DEBUG(...) if (aic_runtime.debug) printf(__VA_ARGS__)
|
#define DEBUG(...) if (aic_runtime.debug) printf(__VA_ARGS__)
|
||||||
|
|
||||||
static struct {
|
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()
|
static void aime_run()
|
||||||
{
|
{
|
||||||
aime_poll_data();
|
aime_poll_data();
|
||||||
|
aime_detect_mode();
|
||||||
|
|
||||||
if (aime.pos > 0) {
|
if (aime.pos > 0) {
|
||||||
uint8_t buf[64];
|
uint8_t buf[64];
|
||||||
memcpy(buf, aime.buf, aime.pos);
|
memcpy(buf, aime.buf, aime.pos);
|
||||||
int count = aime.pos;
|
int count = aime.pos;
|
||||||
aime.pos = 0;
|
switch (aic_runtime.mode) {
|
||||||
|
case MODE_AIME0:
|
||||||
for (int i = 0; i < count; i++) {
|
case MODE_AIME1:
|
||||||
if ((aic_cfg->mode & 0xf0) == 0) {
|
aime_sub_mode(aic_runtime.mode == MODE_AIME0 ? 0 : 1);
|
||||||
aime_feed(buf[i]);
|
for (int i = 0; i < count; i++) {
|
||||||
} else {
|
aime_feed(buf[i]);
|
||||||
bana_feed(buf[i]);
|
}
|
||||||
}
|
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_init(cdc_aime_putc);
|
||||||
aime_virtual_aic(aic_cfg->virtual_aic);
|
aime_virtual_aic(aic_cfg->virtual_aic);
|
||||||
|
|
||||||
if ((aic_cfg->mode & 0x0f) == 0) {
|
|
||||||
aime_set_mode(aic_cfg->mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bana_init(cdc_aime_putc);
|
bana_init(cdc_aime_putc);
|
||||||
|
|
||||||
cli_init("aic_pico>", "\n << AIC Pico >>\n"
|
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)
|
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||||
{
|
{
|
||||||
|
DEBUG("\nCDC Line State: %d %d", dtr, rts);
|
||||||
aime_fast_expire();
|
aime_fast_expire();
|
||||||
bana_fast_expire();
|
bana_fast_expire();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user