[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:
		@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
								applications/lfrfid/helpers/osc-fsk.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								applications/lfrfid/helpers/osc-fsk.cpp
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								applications/lfrfid/helpers/osc-fsk.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								applications/lfrfid/helpers/osc-fsk.h
									
									
									
									
									
										Normal 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;
 | 
			
		||||
};
 | 
			
		||||
@@ -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() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user