From fb80f9537f897ac1753f45a98c53f48442dcf188 Mon Sep 17 00:00:00 2001 From: SG Date: Fri, 30 Jul 2021 21:12:36 +1000 Subject: [PATCH] [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. --- .../lfrfid/helpers/encoder-hid-h10301.cpp | 50 +++++++------------ .../lfrfid/helpers/encoder-hid-h10301.h | 8 +-- applications/lfrfid/helpers/osc-fsk.cpp | 20 ++++++++ applications/lfrfid/helpers/osc-fsk.h | 30 +++++++++++ firmware/targets/f6/api-hal/api-hal-rfid.c | 2 +- 5 files changed, 73 insertions(+), 37 deletions(-) create mode 100644 applications/lfrfid/helpers/osc-fsk.cpp create mode 100644 applications/lfrfid/helpers/osc-fsk.h diff --git a/applications/lfrfid/helpers/encoder-hid-h10301.cpp b/applications/lfrfid/helpers/encoder-hid-h10301.cpp index f4c87ce7..a1275620 100644 --- a/applications/lfrfid/helpers/encoder-hid-h10301.cpp +++ b/applications/lfrfid/helpers/encoder-hid-h10301.cpp @@ -7,7 +7,6 @@ void EncoderHID_H10301::init(const uint8_t* data, const uint8_t data_size) { hid.encode(data, data_size, reinterpret_cast(&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; } diff --git a/applications/lfrfid/helpers/encoder-hid-h10301.h b/applications/lfrfid/helpers/encoder-hid-h10301.h index a3146dd5..98eec2f7 100644 --- a/applications/lfrfid/helpers/encoder-hid-h10301.h +++ b/applications/lfrfid/helpers/encoder-hid-h10301.h @@ -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; }; \ No newline at end of file diff --git a/applications/lfrfid/helpers/osc-fsk.cpp b/applications/lfrfid/helpers/osc-fsk.cpp new file mode 100644 index 00000000..780b77b2 --- /dev/null +++ b/applications/lfrfid/helpers/osc-fsk.cpp @@ -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; +} diff --git a/applications/lfrfid/helpers/osc-fsk.h b/applications/lfrfid/helpers/osc-fsk.h new file mode 100644 index 00000000..e9bd322b --- /dev/null +++ b/applications/lfrfid/helpers/osc-fsk.h @@ -0,0 +1,30 @@ +#pragma once +#include + +/** + * 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; +}; \ No newline at end of file diff --git a/firmware/targets/f6/api-hal/api-hal-rfid.c b/firmware/targets/f6/api-hal/api-hal-rfid.c index 9eaf521b..2d823cd5 100644 --- a/firmware/targets/f6/api-hal/api-hal-rfid.c +++ b/firmware/targets/f6/api-hal/api-hal-rfid.c @@ -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() {