Просмотр исходного кода

[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.
SG 4 лет назад
Родитель
Сommit
fb80f9537f

+ 17 - 33
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<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;
 }

+ 5 - 3
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;
 };

+ 20 - 0
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;
+}

+ 30 - 0
applications/lfrfid/helpers/osc-fsk.h

@@ -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;
+};

+ 1 - 1
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() {