[FL-1616] RFID: fix HID emulation (#610)

* Rfid: fixed HID emulation by adding zero pulse every 4 bits
* Rfid: HID emulation fixed with DSP based FSK oscillator.
This commit is contained in:
SG 2021-07-30 21:12:36 +10:00 committed by GitHub
parent e9e29e0e0c
commit fb80f9537f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 37 deletions

View file

@ -7,7 +7,6 @@ void EncoderHID_H10301::init(const uint8_t* data, const uint8_t data_size) {
hid.encode(data, data_size, reinterpret_cast<uint8_t*>(&card_data), sizeof(card_data) * 3);
card_data_index = 0;
bit_index = 0;
}
void EncoderHID_H10301::write_bit(bool bit, uint8_t position) {
@ -24,39 +23,24 @@ void EncoderHID_H10301::write_raw_bit(bool bit, uint8_t position) {
}
void EncoderHID_H10301::get_next(bool* polarity, uint16_t* period, uint16_t* pulse) {
// hid 0 is 6 cycles by 8 clocks
const uint8_t hid_0_period = 8;
const uint8_t hid_0_count = 6;
// hid 1 is 5 cycles by 10 clocks
const uint8_t hid_1_period = 10;
const uint8_t hid_1_count = 5;
uint8_t bit = (card_data[card_data_index / 32] >> (31 - (card_data_index % 32))) & 1;
bool bit = (card_data[card_data_index / 32] >> (31 - (card_data_index % 32))) & 1;
*polarity = true;
if(bit) {
*period = hid_1_period;
*pulse = hid_1_period / 2;
bit_index++;
if(bit_index >= hid_1_count) {
bit_index = 0;
card_data_index++;
if(card_data_index >= (32 * card_data_max)) {
card_data_index = 0;
}
}
} else {
*period = hid_0_period;
*pulse = hid_0_period / 2;
bit_index++;
if(bit_index >= hid_0_count) {
bit_index = 0;
card_data_index++;
if(card_data_index >= (32 * card_data_max)) {
card_data_index = 0;
}
bool advance = fsk->next(bit, period);
if(advance) {
card_data_index++;
if(card_data_index >= (32 * card_data_max)) {
card_data_index = 0;
}
}
*polarity = true;
*pulse = *period / 2;
}
EncoderHID_H10301::EncoderHID_H10301() {
fsk = new OscFSK(8, 10, 50);
}
EncoderHID_H10301::~EncoderHID_H10301() {
delete fsk;
}

View file

@ -1,5 +1,6 @@
#pragma once
#include "encoder-generic.h"
#include "osc-fsk.h"
class EncoderHID_H10301 : public EncoderGeneric {
public:
@ -10,15 +11,16 @@ public:
* @param data_size must be 3
*/
void init(const uint8_t* data, const uint8_t data_size) final;
void get_next(bool* polarity, uint16_t* period, uint16_t* pulse) final;
EncoderHID_H10301();
~EncoderHID_H10301();
private:
static const uint8_t card_data_max = 3;
uint32_t card_data[card_data_max];
uint8_t card_data_index;
uint8_t bit_index;
void write_bit(bool bit, uint8_t position);
void write_raw_bit(bool bit, uint8_t position);
OscFSK* fsk;
};

View file

@ -0,0 +1,20 @@
#include "osc-fsk.h"
OscFSK::OscFSK(uint16_t _freq_low, uint16_t _freq_hi, uint16_t _osc_phase_max)
: freq{_freq_low, _freq_hi}
, osc_phase_max(_osc_phase_max) {
osc_phase_current = 0;
}
bool OscFSK::next(bool bit, uint16_t* period) {
bool advance = false;
*period = freq[bit];
osc_phase_current += *period;
if(osc_phase_current > osc_phase_max) {
advance = true;
osc_phase_current -= osc_phase_max;
}
return advance;
}

View file

@ -0,0 +1,30 @@
#pragma once
#include <stdint.h>
/**
* This code tries to fit the periods into a given number of cycles (phases) by taking cycles from the next cycle of periods.
*/
class OscFSK {
public:
/**
* Get next period
* @param bit bit value
* @param period return period
* @return bool whether to advance to the next bit
*/
bool next(bool bit, uint16_t* period);
/**
* FSK ocillator constructor
*
* @param freq_low bit 0 freq
* @param freq_hi bit 1 freq
* @param osc_phase_max max oscillator phase
*/
OscFSK(uint16_t freq_low, uint16_t freq_hi, uint16_t osc_phase_max);
private:
const uint16_t freq[2];
const uint16_t osc_phase_max;
int32_t osc_phase_current;
};

View file

@ -31,7 +31,7 @@ void api_hal_rfid_pins_emulate() {
// pull rfid antenna from carrier side
hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo);
hal_gpio_write(&gpio_rfid_carrier_out, true);
hal_gpio_write(&gpio_rfid_carrier_out, false);
}
void api_hal_rfid_pins_read() {