[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:
		
							parent
							
								
									e9e29e0e0c
								
							
						
					
					
						commit
						fb80f9537f
					
				| @ -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); |     hid.encode(data, data_size, reinterpret_cast<uint8_t*>(&card_data), sizeof(card_data) * 3); | ||||||
| 
 | 
 | ||||||
|     card_data_index = 0; |     card_data_index = 0; | ||||||
|     bit_index = 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EncoderHID_H10301::write_bit(bool bit, uint8_t position) { | 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) { | void EncoderHID_H10301::get_next(bool* polarity, uint16_t* period, uint16_t* pulse) { | ||||||
|     // hid 0 is 6 cycles by 8 clocks
 |     uint8_t bit = (card_data[card_data_index / 32] >> (31 - (card_data_index % 32))) & 1; | ||||||
|     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; |  | ||||||
| 
 | 
 | ||||||
|     bool bit = (card_data[card_data_index / 32] >> (31 - (card_data_index % 32))) & 1; |     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; |     *polarity = true; | ||||||
|     if(bit) { |     *pulse = *period / 2; | ||||||
|         *period = hid_1_period; | } | ||||||
|         *pulse = hid_1_period / 2; |  | ||||||
| 
 | 
 | ||||||
|         bit_index++; | EncoderHID_H10301::EncoderHID_H10301() { | ||||||
|         if(bit_index >= hid_1_count) { |     fsk = new OscFSK(8, 10, 50); | ||||||
|             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++; | EncoderHID_H10301::~EncoderHID_H10301() { | ||||||
|         if(bit_index >= hid_0_count) { |     delete fsk; | ||||||
|             bit_index = 0; |  | ||||||
|             card_data_index++; |  | ||||||
|             if(card_data_index >= (32 * card_data_max)) { |  | ||||||
|                 card_data_index = 0; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "encoder-generic.h" | #include "encoder-generic.h" | ||||||
|  | #include "osc-fsk.h" | ||||||
| 
 | 
 | ||||||
| class EncoderHID_H10301 : public EncoderGeneric { | class EncoderHID_H10301 : public EncoderGeneric { | ||||||
| public: | public: | ||||||
| @ -10,15 +11,16 @@ public: | |||||||
|      * @param data_size must be 3 |      * @param data_size must be 3 | ||||||
|      */ |      */ | ||||||
|     void init(const uint8_t* data, const uint8_t data_size) final; |     void init(const uint8_t* data, const uint8_t data_size) final; | ||||||
| 
 |  | ||||||
|     void get_next(bool* polarity, uint16_t* period, uint16_t* pulse) final; |     void get_next(bool* polarity, uint16_t* period, uint16_t* pulse) final; | ||||||
|  |     EncoderHID_H10301(); | ||||||
|  |     ~EncoderHID_H10301(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     static const uint8_t card_data_max = 3; |     static const uint8_t card_data_max = 3; | ||||||
|     uint32_t card_data[card_data_max]; |     uint32_t card_data[card_data_max]; | ||||||
|     uint8_t card_data_index; |     uint8_t card_data_index; | ||||||
|     uint8_t bit_index; |  | ||||||
| 
 |  | ||||||
|     void write_bit(bool bit, uint8_t position); |     void write_bit(bool bit, uint8_t position); | ||||||
|     void write_raw_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
 |     // pull rfid antenna from carrier side
 | ||||||
|     hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo); |     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() { | void api_hal_rfid_pins_read() { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG