[FL-1058] Low frequency RFID app [Indala 40134 Encoder] (#447)
* App Lfrfid: Rename encoder to match extact protocol. * Api-hal-gpio: fix alt fn config * Api-hal-gpio: fixed fix * App Lfrfid: indala 40134 timer stage
This commit is contained in:
		
							parent
							
								
									c880f90eb5
								
							
						
					
					
						commit
						ffd4948ae2
					
				| @ -1,7 +1,7 @@ | |||||||
| #include "encoder-hid.h" | #include "encoder-hid-h10301.h" | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| 
 | 
 | ||||||
| void EncoderHID::init(const uint8_t* data, const uint8_t data_size) { | void EncoderHID_H10301::init(const uint8_t* data, const uint8_t data_size) { | ||||||
|     furi_check(data_size == 3); |     furi_check(data_size == 3); | ||||||
| 
 | 
 | ||||||
|     card_data[0] = 0; |     card_data[0] = 0; | ||||||
| @ -73,12 +73,12 @@ void EncoderHID::init(const uint8_t* data, const uint8_t data_size) { | |||||||
|     bit_index = 0; |     bit_index = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EncoderHID::write_bit(bool bit, uint8_t position) { | void EncoderHID_H10301::write_bit(bool bit, uint8_t position) { | ||||||
|     write_raw_bit(bit, position + 0); |     write_raw_bit(bit, position + 0); | ||||||
|     write_raw_bit(!bit, position + 1); |     write_raw_bit(!bit, position + 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EncoderHID::write_raw_bit(bool bit, uint8_t position) { | void EncoderHID_H10301::write_raw_bit(bool bit, uint8_t position) { | ||||||
|     if(bit) { |     if(bit) { | ||||||
|         card_data[position / 32] |= 1UL << (31 - (position % 32)); |         card_data[position / 32] |= 1UL << (31 - (position % 32)); | ||||||
|     } else { |     } else { | ||||||
| @ -86,7 +86,7 @@ void EncoderHID::write_raw_bit(bool bit, uint8_t position) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EncoderHID::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
 |     // hid 0 is 6 cycles by 8 clocks
 | ||||||
|     const uint8_t hid_0_period = 8; |     const uint8_t hid_0_period = 8; | ||||||
|     const uint8_t hid_0_count = 6; |     const uint8_t hid_0_count = 6; | ||||||
| @ -1,7 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "encoder-generic.h" | #include "encoder-generic.h" | ||||||
| 
 | 
 | ||||||
| class EncoderHID : public EncoderGeneric { | class EncoderHID_H10301 : public EncoderGeneric { | ||||||
| public: | public: | ||||||
|     /**
 |     /**
 | ||||||
|      * @brief init data to emulate |      * @brief init data to emulate | ||||||
							
								
								
									
										34
									
								
								applications/lf-rfid/helpers/encoder-indala-40134.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								applications/lf-rfid/helpers/encoder-indala-40134.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | #include "encoder-indala-40134.h" | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | void EncoderIndala_40134::init(const uint8_t* data, const uint8_t data_size) { | ||||||
|  |     card_data = 0b1010000000000000000000000000000011010000010010001000011000110010; | ||||||
|  | 
 | ||||||
|  |     last_bit = card_data & 1; | ||||||
|  |     card_data_index = 0; | ||||||
|  |     current_polarity = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void EncoderIndala_40134::get_next(bool* polarity, uint16_t* period, uint16_t* pulse) { | ||||||
|  |     *period = 2; | ||||||
|  |     *pulse = 1; | ||||||
|  |     *polarity = current_polarity; | ||||||
|  | 
 | ||||||
|  |     bit_clock_index++; | ||||||
|  |     if(bit_clock_index >= clock_per_bit) { | ||||||
|  |         bit_clock_index = 0; | ||||||
|  | 
 | ||||||
|  |         bool current_bit = (card_data >> (63 - card_data_index)) & 1; | ||||||
|  | 
 | ||||||
|  |         if(current_bit != last_bit) { | ||||||
|  |             current_polarity = !current_polarity; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         last_bit = current_bit; | ||||||
|  | 
 | ||||||
|  |         card_data_index++; | ||||||
|  |         if(card_data_index >= 64) { | ||||||
|  |             card_data_index = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "encoder-generic.h" | #include "encoder-generic.h" | ||||||
| 
 | 
 | ||||||
| class EncoderIndala : public EncoderGeneric { | class EncoderIndala_40134 : public EncoderGeneric { | ||||||
| public: | public: | ||||||
|     /**
 |     /**
 | ||||||
|      * @brief init data to emulate |      * @brief init data to emulate | ||||||
| @ -17,6 +17,7 @@ private: | |||||||
|     uint64_t card_data; |     uint64_t card_data; | ||||||
|     uint8_t card_data_index; |     uint8_t card_data_index; | ||||||
|     uint8_t bit_clock_index; |     uint8_t bit_clock_index; | ||||||
|     bool last_polarity; |     bool last_bit; | ||||||
|  |     bool current_polarity; | ||||||
|     static const uint8_t clock_per_bit = 16; |     static const uint8_t clock_per_bit = 16; | ||||||
| }; | }; | ||||||
| @ -1,27 +0,0 @@ | |||||||
| #include "encoder-indala.h" |  | ||||||
| #include <furi.h> |  | ||||||
| 
 |  | ||||||
| void EncoderIndala::init(const uint8_t* data, const uint8_t data_size) { |  | ||||||
|     card_data = 0b1010000000000000000000000000000010011101111110011001001001010010; |  | ||||||
|     last_polarity = card_data & 1; |  | ||||||
|     card_data_index = 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void EncoderIndala::get_next(bool* polarity, uint16_t* period, uint16_t* pulse) { |  | ||||||
|     bool new_bit = (card_data >> (63 - card_data_index)) & 1; |  | ||||||
| 
 |  | ||||||
|     *period = 2; |  | ||||||
|     *pulse = 1; |  | ||||||
|     *polarity = (new_bit != last_polarity); |  | ||||||
| 
 |  | ||||||
|     bit_clock_index++; |  | ||||||
|     if(bit_clock_index >= clock_per_bit) { |  | ||||||
|         bit_clock_index = 0; |  | ||||||
|         last_polarity = *polarity; |  | ||||||
| 
 |  | ||||||
|         card_data_index++; |  | ||||||
|         if(card_data_index >= 64) { |  | ||||||
|             card_data_index = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -4,47 +4,6 @@ extern TIM_HandleTypeDef htim1; | |||||||
| /*
 | /*
 | ||||||
| static uint16_t times_index = 0; | static uint16_t times_index = 0; | ||||||
| 
 | 
 | ||||||
| constexpr uint16_t hid_237_34672_count = 528; |  | ||||||
| constexpr uint8_t hid_237_34672[hid_237_34672_count] = { |  | ||||||
|     8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, |  | ||||||
|     10, 10, 10, 10, 10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8, |  | ||||||
|     8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8, |  | ||||||
|     10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, |  | ||||||
|     10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8,  8,  8,  8,  8, |  | ||||||
|     8,  8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8, |  | ||||||
|     8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8, |  | ||||||
|     8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8, |  | ||||||
|     8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, |  | ||||||
|     10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8,  8,  8,  8, |  | ||||||
|     8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8, |  | ||||||
|     10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  8,  8, |  | ||||||
|     8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, |  | ||||||
|     10, 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, |  | ||||||
|     8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  10, 10, |  | ||||||
|     10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, |  | ||||||
|     10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, |  | ||||||
|     10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  8,  8,  8, |  | ||||||
|     8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, |  | ||||||
|     8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  10, |  | ||||||
|     10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, |  | ||||||
|     10, 10, 8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8,  8,  8,  8,  8,  8, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static void callback_hid(void* _hw, void* ctx) { |  | ||||||
|     //RfidTimerEmulator* _this = static_cast<RfidTimerEmulator*>(ctx);
 |  | ||||||
|     TIM_HandleTypeDef* hw = static_cast<TIM_HandleTypeDef*>(_hw); |  | ||||||
| 
 |  | ||||||
|     if(hw == &htim1) { |  | ||||||
|         hw->Instance->ARR = hid_237_34672[times_index] - 1; |  | ||||||
|         hw->Instance->CCR1 = hid_237_34672[times_index] / 2; // - 1
 |  | ||||||
| 
 |  | ||||||
|         times_index++; |  | ||||||
|         if(times_index >= hid_237_34672_count) { |  | ||||||
|             times_index = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t arr; |     uint8_t arr; | ||||||
|     uint8_t ccr; |     uint8_t ccr; | ||||||
| @ -347,10 +306,10 @@ void RfidTimerEmulator::start(Type type) { | |||||||
|         case Type::EM: |         case Type::EM: | ||||||
|             current_encoder->init(em_data, 5); |             current_encoder->init(em_data, 5); | ||||||
|             break; |             break; | ||||||
|         case Type::HID: |         case Type::HID_H10301: | ||||||
|             current_encoder->init(hid_data, 3); |             current_encoder->init(hid_data, 3); | ||||||
|             break; |             break; | ||||||
|         case Type::Indala: |         case Type::Indala_40134: | ||||||
|             current_encoder->init(nullptr, 5); |             current_encoder->init(nullptr, 5); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ | |||||||
| #include "key-info.h" | #include "key-info.h" | ||||||
| #include "encoder-generic.h" | #include "encoder-generic.h" | ||||||
| #include "encoder-emmarine.h" | #include "encoder-emmarine.h" | ||||||
| #include "encoder-hid.h" | #include "encoder-hid-h10301.h" | ||||||
| #include "encoder-indala.h" | #include "encoder-indala-40134.h" | ||||||
| #include "pulse-joiner.h" | #include "pulse-joiner.h" | ||||||
| #include <map> | #include <map> | ||||||
| 
 | 
 | ||||||
| @ -12,8 +12,8 @@ class RfidTimerEmulator { | |||||||
| public: | public: | ||||||
|     enum class Type : uint8_t { |     enum class Type : uint8_t { | ||||||
|         EM, |         EM, | ||||||
|         HID, |         HID_H10301, | ||||||
|         Indala, |         Indala_40134, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     RfidTimerEmulator(); |     RfidTimerEmulator(); | ||||||
| @ -27,8 +27,8 @@ private: | |||||||
| 
 | 
 | ||||||
|     std::map<Type, EncoderGeneric*> encoders = { |     std::map<Type, EncoderGeneric*> encoders = { | ||||||
|         {Type::EM, new EncoderEM()}, |         {Type::EM, new EncoderEM()}, | ||||||
|         {Type::HID, new EncoderHID()}, |         {Type::HID_H10301, new EncoderHID_H10301()}, | ||||||
|         {Type::Indala, new EncoderIndala()}, |         {Type::Indala_40134, new EncoderIndala_40134()}, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     PulseJoiner pulse_joiner; |     PulseJoiner pulse_joiner; | ||||||
|  | |||||||
| @ -10,11 +10,11 @@ void LfrfidSceneEmulateHID::on_enter(LfrfidApp* app) { | |||||||
| 
 | 
 | ||||||
|     Popup* popup = view_manager->get_popup(); |     Popup* popup = view_manager->get_popup(); | ||||||
|     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); |     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); | ||||||
|     app->set_text_store("HID emulation"); |     app->set_text_store("HID H10301 emulation"); | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); | ||||||
|     app->get_emulator()->start(RfidTimerEmulator::Type::HID); |     app->get_emulator()->start(RfidTimerEmulator::Type::HID_H10301); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LfrfidSceneEmulateHID::on_event(LfrfidApp* app, LfrfidEvent* event) { | bool LfrfidSceneEmulateHID::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||||
|  | |||||||
| @ -10,11 +10,11 @@ void LfrfidSceneEmulateIndala::on_enter(LfrfidApp* app) { | |||||||
| 
 | 
 | ||||||
|     Popup* popup = view_manager->get_popup(); |     Popup* popup = view_manager->get_popup(); | ||||||
|     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); |     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); | ||||||
|     app->set_text_store("Indala emulation"); |     app->set_text_store("Indala 40134 emulation"); | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); | ||||||
|     app->get_emulator()->start(RfidTimerEmulator::Type::Indala); |     app->get_emulator()->start(RfidTimerEmulator::Type::Indala_40134); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LfrfidSceneEmulateIndala::on_event(LfrfidApp* app, LfrfidEvent* event) { | bool LfrfidSceneEmulateIndala::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||||
|  | |||||||
| @ -33,6 +33,14 @@ | |||||||
| 
 | 
 | ||||||
| static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER]; | static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER]; | ||||||
| 
 | 
 | ||||||
|  | static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) { | ||||||
|  |     uint8_t pin_num = 0; | ||||||
|  |     for(pin_num = 0; pin_num < GPIO_NUMBER; pin_num++) { | ||||||
|  |         if(gpio->pin & (1 << pin_num)) break; | ||||||
|  |     } | ||||||
|  |     return pin_num; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void hal_gpio_init( | void hal_gpio_init( | ||||||
|     const GpioPin* gpio, |     const GpioPin* gpio, | ||||||
|     const GpioMode mode, |     const GpioMode mode, | ||||||
| @ -120,7 +128,7 @@ void hal_gpio_init_alt( | |||||||
|     LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); |     LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); | ||||||
| 
 | 
 | ||||||
|     // set alternate function
 |     // set alternate function
 | ||||||
|     if(gpio->pin < 8) { |     if(hal_gpio_get_pin_num(gpio) < 8) { | ||||||
|         LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); |         LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); | ||||||
|     } else { |     } else { | ||||||
|         LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); |         LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); | ||||||
| @ -128,14 +136,6 @@ void hal_gpio_init_alt( | |||||||
|     __enable_irq(); |     __enable_irq(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) { |  | ||||||
|     uint8_t pin_num = 0; |  | ||||||
|     for(pin_num = 0; pin_num < GPIO_NUMBER; pin_num++) { |  | ||||||
|         if(gpio->pin & (1 << pin_num)) break; |  | ||||||
|     } |  | ||||||
|     return pin_num; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { | void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { | ||||||
|     furi_assert(gpio); |     furi_assert(gpio); | ||||||
|     furi_assert(cb); |     furi_assert(cb); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG