t5577.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "t5577.h"
  2. #include <furi.h>
  3. #include <furi_hal_rfid.h>
  4. #include <stdint.h>
  5. #define T5577_TIMING_WAIT_TIME 400
  6. #define T5577_TIMING_START_GAP 30
  7. #define T5577_TIMING_WRITE_GAP 18
  8. #define T5577_TIMING_DATA_0 24
  9. #define T5577_TIMING_DATA_1 56
  10. #define T5577_TIMING_PROGRAM 700
  11. #define T5577_OPCODE_PAGE_0 0b10
  12. #define T5577_OPCODE_PAGE_1 0b11
  13. #define T5577_OPCODE_RESET 0b00
  14. static void t5577_start() {
  15. furi_hal_rfid_tim_read_start(125000, 0.5);
  16. // do not ground the antenna
  17. furi_hal_rfid_pin_pull_release();
  18. }
  19. static void t5577_stop() {
  20. furi_hal_rfid_tim_read_stop();
  21. furi_hal_rfid_pins_reset();
  22. }
  23. static void t5577_write_gap(uint32_t gap_time) {
  24. furi_hal_rfid_tim_read_pause();
  25. furi_delay_us(gap_time * 8);
  26. furi_hal_rfid_tim_read_continue();
  27. }
  28. static void t5577_write_bit(bool value) {
  29. if(value) {
  30. furi_delay_us(T5577_TIMING_DATA_1 * 8);
  31. } else {
  32. furi_delay_us(T5577_TIMING_DATA_0 * 8);
  33. }
  34. t5577_write_gap(T5577_TIMING_WRITE_GAP);
  35. }
  36. static void t5577_write_opcode(uint8_t value) {
  37. t5577_write_bit((value >> 1) & 1);
  38. t5577_write_bit((value >> 0) & 1);
  39. }
  40. static void t5577_write_reset() {
  41. t5577_write_gap(T5577_TIMING_START_GAP);
  42. t5577_write_bit(1);
  43. t5577_write_bit(0);
  44. }
  45. static void t5577_write_block_pass(
  46. uint8_t block,
  47. bool lock_bit,
  48. uint32_t data,
  49. bool with_pass,
  50. uint32_t password) {
  51. furi_delay_us(T5577_TIMING_WAIT_TIME * 8);
  52. // start gap
  53. t5577_write_gap(T5577_TIMING_START_GAP);
  54. // opcode for page 0
  55. t5577_write_opcode(T5577_OPCODE_PAGE_0);
  56. // password
  57. if(with_pass) {
  58. for(uint8_t i = 0; i < 32; i++) {
  59. t5577_write_bit((password >> (31 - i)) & 1);
  60. }
  61. }
  62. // lock bit
  63. t5577_write_bit(lock_bit);
  64. // data
  65. for(uint8_t i = 0; i < 32; i++) {
  66. t5577_write_bit((data >> (31 - i)) & 1);
  67. }
  68. // block address
  69. t5577_write_bit((block >> 2) & 1);
  70. t5577_write_bit((block >> 1) & 1);
  71. t5577_write_bit((block >> 0) & 1);
  72. furi_delay_us(T5577_TIMING_PROGRAM * 8);
  73. furi_delay_us(T5577_TIMING_WAIT_TIME * 8);
  74. t5577_write_reset();
  75. }
  76. static void t5577_write_block_simple(uint8_t block, bool lock_bit, uint32_t data) {
  77. t5577_write_block_pass(block, lock_bit, data, false, 0);
  78. }
  79. void t5577_write(LFRFIDT5577Data* data) {
  80. t5577_start();
  81. FURI_CRITICAL_ENTER();
  82. for(size_t i = 0; i < data->blocks_to_write; i++) {
  83. t5577_write_block_simple(i, false, data->block[i]);
  84. }
  85. t5577_write_reset();
  86. FURI_CRITICAL_EXIT();
  87. t5577_stop();
  88. }
  89. void t5577_write_with_mask(LFRFIDT5577Data* data) {
  90. t5577_start();
  91. FURI_CRITICAL_ENTER();
  92. uint8_t mask = data->mask;
  93. for(size_t i = 0; i < data->blocks_to_write; i++) {
  94. bool need_to_write = mask & 1;
  95. mask >>= 1;
  96. FURI_LOG_D(
  97. "WRITIND",
  98. "%08lX. i = %u. needtowrite: %u, mask: %u",
  99. data->block[i],
  100. i,
  101. need_to_write,
  102. mask);
  103. if(!need_to_write) continue;
  104. t5577_write_block_simple(i, false, data->block[i]);
  105. }
  106. t5577_write_reset();
  107. FURI_CRITICAL_EXIT();
  108. t5577_stop();
  109. }
  110. void t5577_write_with_pass(LFRFIDT5577Data* data, uint32_t password) {
  111. t5577_start();
  112. FURI_CRITICAL_ENTER();
  113. for(size_t i = 0; i < data->blocks_to_write; i++) {
  114. t5577_write_block_pass(i, false, data->block[i], true, password);
  115. }
  116. t5577_write_reset();
  117. FURI_CRITICAL_EXIT();
  118. t5577_stop();
  119. }