rfid_reader.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include "rfid_reader.h"
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <stm32wbxx_ll_cortex.h>
  5. #include <tim.h>
  6. /**
  7. * @brief private violation assistant for RfidReader
  8. */
  9. struct RfidReaderAccessor {
  10. static void decode(RfidReader& rfid_reader, bool polarity) {
  11. rfid_reader.decode(polarity);
  12. }
  13. };
  14. void RfidReader::decode(bool polarity) {
  15. uint32_t current_dwt_value = DWT->CYCCNT;
  16. uint32_t period = current_dwt_value - last_dwt_value;
  17. last_dwt_value = current_dwt_value;
  18. #ifdef RFID_GPIO_DEBUG
  19. decoder_gpio_out.process_front(polarity, period);
  20. #endif
  21. switch(type) {
  22. case Type::Normal:
  23. decoder_em.process_front(polarity, period);
  24. decoder_hid26.process_front(polarity, period);
  25. break;
  26. case Type::Indala:
  27. decoder_em.process_front(polarity, period);
  28. decoder_hid26.process_front(polarity, period);
  29. decoder_indala.process_front(polarity, period);
  30. break;
  31. }
  32. detect_ticks++;
  33. }
  34. bool RfidReader::switch_timer_elapsed() {
  35. const uint32_t seconds_to_switch = osKernelGetTickFreq() * 2.0f;
  36. return (osKernelGetTickCount() - switch_os_tick_last) > seconds_to_switch;
  37. }
  38. void RfidReader::switch_timer_reset() {
  39. switch_os_tick_last = osKernelGetTickCount();
  40. }
  41. void RfidReader::switch_mode() {
  42. switch(type) {
  43. case Type::Normal:
  44. type = Type::Indala;
  45. furi_hal_rfid_change_read_config(62500.0f, 0.25f);
  46. break;
  47. case Type::Indala:
  48. type = Type::Normal;
  49. furi_hal_rfid_change_read_config(125000.0f, 0.5f);
  50. break;
  51. }
  52. switch_timer_reset();
  53. }
  54. static void comparator_trigger_callback(bool level, void* comp_ctx) {
  55. RfidReader* _this = static_cast<RfidReader*>(comp_ctx);
  56. RfidReaderAccessor::decode(*_this, !level);
  57. }
  58. RfidReader::RfidReader() {
  59. }
  60. void RfidReader::start() {
  61. type = Type::Normal;
  62. furi_hal_rfid_pins_read();
  63. furi_hal_rfid_tim_read(125000, 0.5);
  64. furi_hal_rfid_tim_read_start();
  65. start_comparator();
  66. switch_timer_reset();
  67. last_readed_count = 0;
  68. }
  69. void RfidReader::start_forced(RfidReader::Type _type) {
  70. start();
  71. if(_type == Type::Indala) {
  72. switch_mode();
  73. }
  74. }
  75. void RfidReader::stop() {
  76. furi_hal_rfid_pins_reset();
  77. furi_hal_rfid_tim_read_stop();
  78. furi_hal_rfid_tim_reset();
  79. stop_comparator();
  80. }
  81. bool RfidReader::read(LfrfidKeyType* _type, uint8_t* data, uint8_t data_size, bool switch_enable) {
  82. bool result = false;
  83. bool something_readed = false;
  84. // reading
  85. if(decoder_em.read(data, data_size)) {
  86. *_type = LfrfidKeyType::KeyEM4100;
  87. something_readed = true;
  88. }
  89. if(decoder_hid26.read(data, data_size)) {
  90. *_type = LfrfidKeyType::KeyH10301;
  91. something_readed = true;
  92. }
  93. if(decoder_indala.read(data, data_size)) {
  94. *_type = LfrfidKeyType::KeyI40134;
  95. something_readed = true;
  96. }
  97. // validation
  98. if(something_readed) {
  99. switch_timer_reset();
  100. if(last_readed_type == *_type && memcmp(last_readed_data, data, data_size) == 0) {
  101. last_readed_count = last_readed_count + 1;
  102. if(last_readed_count > 2) {
  103. result = true;
  104. }
  105. } else {
  106. last_readed_type = *_type;
  107. memcpy(last_readed_data, data, data_size);
  108. last_readed_count = 0;
  109. }
  110. }
  111. // mode switching
  112. if(switch_enable && switch_timer_elapsed()) {
  113. switch_mode();
  114. last_readed_count = 0;
  115. }
  116. return result;
  117. }
  118. bool RfidReader::detect() {
  119. bool detected = false;
  120. if(detect_ticks > 10) {
  121. detected = true;
  122. }
  123. detect_ticks = 0;
  124. return detected;
  125. }
  126. bool RfidReader::any_read() {
  127. return last_readed_count > 0;
  128. }
  129. void RfidReader::start_comparator(void) {
  130. furi_hal_rfid_comp_set_callback(comparator_trigger_callback, this);
  131. last_dwt_value = DWT->CYCCNT;
  132. furi_hal_rfid_comp_start();
  133. }
  134. void RfidReader::stop_comparator(void) {
  135. furi_hal_rfid_comp_stop();
  136. furi_hal_rfid_comp_set_callback(NULL, NULL);
  137. }