wiegand_read.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 == 37 || bit_count == 40) {
  60. wiegand_stop_read(app);
  61. scene_manager_next_scene(app->scene_manager, WiegandDataScene);
  62. } else {
  63. // No data, clear
  64. bit_count = 0;
  65. }
  66. }
  67. FURI_CRITICAL_EXIT();
  68. }
  69. void wiegand_read_scene_on_enter(void* context) {
  70. App* app = context;
  71. widget_reset(app->widget);
  72. widget_add_string_element(app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Read Wiegand");
  73. widget_add_string_element(
  74. app->widget, 0, 25, AlignLeft, AlignTop, FontSecondary, "Waiting for signal...");
  75. widget_add_string_element(
  76. app->widget, 0, 45, AlignLeft, AlignTop, FontSecondary, "D0/Green/A4");
  77. widget_add_string_element(
  78. app->widget, 0, 53, AlignLeft, AlignTop, FontSecondary, "D1/White/A7");
  79. wiegand_start_read(app);
  80. view_dispatcher_switch_to_view(app->view_dispatcher, WiegandWidgetView);
  81. }
  82. void wiegand_read_scene_on_exit(void* context) {
  83. App* app = context;
  84. wiegand_stop_read(app);
  85. }