wiegand_read.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "../wiegand.h"
  2. void wiegand_isr_d0(void* context) {
  3. UNUSED(context);
  4. uint32_t time = DWT->CYCCNT;
  5. bool rise = furi_hal_gpio_read(pinD0);
  6. data[bit_count] = 0;
  7. if(rise) {
  8. data_rise[bit_count] = time;
  9. if(bit_count < MAX_BITS) {
  10. bit_count++;
  11. }
  12. } else {
  13. data_fall[bit_count] = time;
  14. }
  15. }
  16. void wiegand_isr_d1(void* context) {
  17. UNUSED(context);
  18. uint32_t time = DWT->CYCCNT;
  19. bool rise = furi_hal_gpio_read(pinD1);
  20. data[bit_count] = 1;
  21. if(rise) {
  22. data_rise[bit_count] = time;
  23. if(bit_count < MAX_BITS) {
  24. bit_count++;
  25. }
  26. } else {
  27. data_fall[bit_count] = time;
  28. }
  29. }
  30. void wiegand_start_read(void* context) {
  31. App* app = context;
  32. data_saved = false;
  33. bit_count = 0;
  34. furi_hal_gpio_init_simple(pinD0, GpioModeInterruptRiseFall);
  35. furi_hal_gpio_init_simple(pinD1, GpioModeInterruptRiseFall);
  36. furi_hal_gpio_add_int_callback(pinD0, wiegand_isr_d0, NULL);
  37. furi_hal_gpio_add_int_callback(pinD1, wiegand_isr_d1, NULL);
  38. furi_timer_start(app->timer, 100);
  39. }
  40. void wiegand_stop_read(void* context) {
  41. App* app = context;
  42. furi_hal_gpio_remove_int_callback(pinD0);
  43. furi_hal_gpio_remove_int_callback(pinD1);
  44. furi_hal_gpio_init_simple(pinD0, GpioModeAnalog);
  45. furi_hal_gpio_init_simple(pinD1, GpioModeAnalog);
  46. furi_timer_stop(app->timer);
  47. }
  48. void wiegand_timer_callback(void* context) {
  49. App* app = context;
  50. uint32_t duration = DWT->CYCCNT;
  51. const uint32_t one_millisecond = 64000;
  52. if(bit_count == 0) {
  53. return;
  54. }
  55. duration -= data_fall[bit_count - 1];
  56. FURI_CRITICAL_ENTER();
  57. if(duration > 25 * one_millisecond) {
  58. if(bit_count == 4 || bit_count == 8 || bit_count == 24 || bit_count == 26 ||
  59. bit_count == 32 || bit_count == 34 || bit_count == 35 || bit_count == 36 ||
  60. bit_count == 37 || bit_count == 40 || bit_count == 48) {
  61. wiegand_stop_read(app);
  62. scene_manager_next_scene(app->scene_manager, WiegandDataScene);
  63. } else {
  64. // No data, clear
  65. bit_count = 0;
  66. }
  67. }
  68. FURI_CRITICAL_EXIT();
  69. }
  70. void wiegand_read_scene_on_enter(void* context) {
  71. App* app = context;
  72. widget_reset(app->widget);
  73. widget_add_string_element(app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Read Wiegand");
  74. widget_add_string_element(
  75. app->widget, 0, 25, AlignLeft, AlignTop, FontSecondary, "Waiting for signal...");
  76. widget_add_string_element(
  77. app->widget, 0, 45, AlignLeft, AlignTop, FontSecondary, "D0/Green/A4");
  78. widget_add_string_element(
  79. app->widget, 0, 53, AlignLeft, AlignTop, FontSecondary, "D1/White/A7");
  80. wiegand_start_read(app);
  81. view_dispatcher_switch_to_view(app->view_dispatcher, WiegandWidgetView);
  82. }
  83. void wiegand_read_scene_on_exit(void* context) {
  84. App* app = context;
  85. wiegand_stop_read(app);
  86. }