rfid_reader.cpp 3.9 KB

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