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:
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_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
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}/..)
|
||||
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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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
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 "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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user