rfid-reader.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "rfid-reader.h"
  2. #include <furi.h>
  3. #include <api-hal.h>
  4. #include <stm32wbxx_ll_cortex.h>
  5. #include <tim.h>
  6. extern COMP_HandleTypeDef hcomp1;
  7. /**
  8. * @brief private violation assistant for RfidReader
  9. */
  10. struct RfidReaderAccessor {
  11. static void decode(RfidReader& rfid_reader, bool polarity) {
  12. rfid_reader.decode(polarity);
  13. }
  14. };
  15. void RfidReader::decode(bool polarity) {
  16. uint32_t current_dwt_value = DWT->CYCCNT;
  17. uint32_t period = current_dwt_value - last_dwt_value;
  18. last_dwt_value = current_dwt_value;
  19. //decoder_gpio_out.process_front(polarity, period);
  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. api_hal_rfid_change_read_config(62500.0f, 0.25f);
  45. break;
  46. case Type::Indala:
  47. type = Type::Normal;
  48. api_hal_rfid_change_read_config(125000.0f, 0.5f);
  49. break;
  50. }
  51. switch_timer_reset();
  52. }
  53. static void comparator_trigger_callback(void* hcomp, void* comp_ctx) {
  54. COMP_HandleTypeDef* _hcomp = static_cast<COMP_HandleTypeDef*>(hcomp);
  55. RfidReader* _this = static_cast<RfidReader*>(comp_ctx);
  56. if(hcomp == &hcomp1) {
  57. RfidReaderAccessor::decode(
  58. *_this, (HAL_COMP_GetOutputLevel(_hcomp) == COMP_OUTPUT_LEVEL_HIGH));
  59. }
  60. }
  61. RfidReader::RfidReader() {
  62. }
  63. void RfidReader::start() {
  64. type = Type::Normal;
  65. api_hal_rfid_pins_read();
  66. api_hal_rfid_tim_read(125000, 0.5);
  67. api_hal_rfid_tim_read_start();
  68. start_comparator();
  69. switch_timer_reset();
  70. last_readed_count = 0;
  71. }
  72. void RfidReader::start_forced(RfidReader::Type _type) {
  73. type = _type;
  74. switch(type) {
  75. case Type::Normal:
  76. start();
  77. break;
  78. case Type::Indala:
  79. api_hal_rfid_pins_read();
  80. api_hal_rfid_tim_read(62500.0f, 0.25f);
  81. api_hal_rfid_tim_read_start();
  82. start_comparator();
  83. switch_timer_reset();
  84. last_readed_count = 0;
  85. break;
  86. }
  87. }
  88. void RfidReader::stop() {
  89. api_hal_rfid_pins_reset();
  90. api_hal_rfid_tim_read_stop();
  91. api_hal_rfid_tim_reset();
  92. stop_comparator();
  93. }
  94. bool RfidReader::read(LfrfidKeyType* _type, uint8_t* data, uint8_t data_size) {
  95. bool result = false;
  96. bool something_readed = false;
  97. // reading
  98. if(decoder_em.read(data, data_size)) {
  99. *_type = LfrfidKeyType::KeyEM4100;
  100. something_readed = true;
  101. }
  102. if(decoder_hid26.read(data, data_size)) {
  103. *_type = LfrfidKeyType::KeyH10301;
  104. something_readed = true;
  105. }
  106. if(decoder_indala.read(data, data_size)) {
  107. *_type = LfrfidKeyType::KeyI40134;
  108. something_readed = true;
  109. }
  110. // validation
  111. if(something_readed) {
  112. switch_timer_reset();
  113. if(last_readed_type == *_type && memcmp(last_readed_data, data, data_size) == 0) {
  114. last_readed_count = last_readed_count + 1;
  115. if(last_readed_count > 2) {
  116. result = true;
  117. }
  118. } else {
  119. last_readed_type = *_type;
  120. memcpy(last_readed_data, data, data_size);
  121. last_readed_count = 0;
  122. }
  123. }
  124. // mode switching
  125. if(switch_timer_elapsed()) {
  126. switch_mode();
  127. last_readed_count = 0;
  128. }
  129. return result;
  130. }
  131. bool RfidReader::detect() {
  132. bool detected = false;
  133. if(detect_ticks > 10) {
  134. detected = true;
  135. }
  136. detect_ticks = 0;
  137. return detected;
  138. }
  139. bool RfidReader::any_read() {
  140. return last_readed_count > 0;
  141. }
  142. void RfidReader::start_comparator(void) {
  143. api_interrupt_add(comparator_trigger_callback, InterruptTypeComparatorTrigger, this);
  144. last_dwt_value = DWT->CYCCNT;
  145. hcomp1.Init.InputMinus = COMP_INPUT_MINUS_1_2VREFINT;
  146. hcomp1.Init.InputPlus = COMP_INPUT_PLUS_IO1;
  147. hcomp1.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED;
  148. hcomp1.Init.Hysteresis = COMP_HYSTERESIS_HIGH;
  149. hcomp1.Init.BlankingSrce = COMP_BLANKINGSRC_NONE;
  150. hcomp1.Init.Mode = COMP_POWERMODE_MEDIUMSPEED;
  151. hcomp1.Init.WindowMode = COMP_WINDOWMODE_DISABLE;
  152. hcomp1.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING_FALLING;
  153. if(HAL_COMP_Init(&hcomp1) != HAL_OK) {
  154. Error_Handler();
  155. }
  156. HAL_COMP_Start(&hcomp1);
  157. }
  158. void RfidReader::stop_comparator(void) {
  159. HAL_COMP_Stop(&hcomp1);
  160. api_interrupt_remove(comparator_trigger_callback, InterruptTypeComparatorTrigger);
  161. }