rfid_writer.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "rfid_writer.h"
  2. #include "protocols/protocol_ioprox.h"
  3. #include <furi_hal.h>
  4. #include "protocols/protocol_emmarin.h"
  5. #include "protocols/protocol_hid_h10301.h"
  6. #include "protocols/protocol_indala_40134.h"
  7. /**
  8. * @brief all timings are specified in field clocks (field clock = 125 kHz, 8 us)
  9. *
  10. */
  11. class T55xxTiming {
  12. public:
  13. constexpr static const uint16_t wait_time = 400;
  14. constexpr static const uint8_t start_gap = 30;
  15. constexpr static const uint8_t write_gap = 18;
  16. constexpr static const uint8_t data_0 = 24;
  17. constexpr static const uint8_t data_1 = 56;
  18. constexpr static const uint16_t program = 700;
  19. };
  20. class T55xxCmd {
  21. public:
  22. constexpr static const uint8_t opcode_page_0 = 0b10;
  23. constexpr static const uint8_t opcode_page_1 = 0b11;
  24. constexpr static const uint8_t opcode_reset = 0b00;
  25. };
  26. RfidWriter::RfidWriter() {
  27. }
  28. RfidWriter::~RfidWriter() {
  29. }
  30. void RfidWriter::start() {
  31. furi_hal_rfid_tim_read(125000, 0.5);
  32. furi_hal_rfid_pins_read();
  33. furi_hal_rfid_tim_read_start();
  34. // do not ground the antenna
  35. furi_hal_rfid_pin_pull_release();
  36. }
  37. void RfidWriter::stop() {
  38. furi_hal_rfid_tim_read_stop();
  39. furi_hal_rfid_tim_reset();
  40. furi_hal_rfid_pins_reset();
  41. }
  42. void RfidWriter::write_gap(uint32_t gap_time) {
  43. furi_hal_rfid_tim_read_stop();
  44. furi_hal_delay_us(gap_time * 8);
  45. furi_hal_rfid_tim_read_start();
  46. }
  47. void RfidWriter::write_bit(bool value) {
  48. if(value) {
  49. furi_hal_delay_us(T55xxTiming::data_1 * 8);
  50. } else {
  51. furi_hal_delay_us(T55xxTiming::data_0 * 8);
  52. }
  53. write_gap(T55xxTiming::write_gap);
  54. }
  55. void RfidWriter::write_byte(uint8_t value) {
  56. for(uint8_t i = 0; i < 8; i++) {
  57. write_bit((value >> i) & 1);
  58. }
  59. }
  60. void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data) {
  61. furi_hal_delay_us(T55xxTiming::wait_time * 8);
  62. // start gap
  63. write_gap(T55xxTiming::start_gap);
  64. // opcode
  65. switch(page) {
  66. case 0:
  67. write_bit(1);
  68. write_bit(0);
  69. break;
  70. case 1:
  71. write_bit(1);
  72. write_bit(1);
  73. break;
  74. default:
  75. furi_check(false);
  76. break;
  77. }
  78. // lock bit
  79. write_bit(lock_bit);
  80. // data
  81. for(uint8_t i = 0; i < 32; i++) {
  82. write_bit((data >> (31 - i)) & 1);
  83. }
  84. // block address
  85. write_bit((block >> 2) & 1);
  86. write_bit((block >> 1) & 1);
  87. write_bit((block >> 0) & 1);
  88. furi_hal_delay_us(T55xxTiming::program * 8);
  89. furi_hal_delay_us(T55xxTiming::wait_time * 8);
  90. write_reset();
  91. }
  92. void RfidWriter::write_reset() {
  93. write_gap(T55xxTiming::start_gap);
  94. write_bit(1);
  95. write_bit(0);
  96. }
  97. void RfidWriter::write_em(const uint8_t em_data[5]) {
  98. ProtocolEMMarin em_card;
  99. uint64_t em_encoded_data;
  100. em_card.encode(em_data, 5, reinterpret_cast<uint8_t*>(&em_encoded_data), sizeof(uint64_t));
  101. const uint32_t em_config_block_data = 0b00000000000101001000000001000000;
  102. FURI_CRITICAL_ENTER();
  103. write_block(0, 0, false, em_config_block_data);
  104. write_block(0, 1, false, em_encoded_data);
  105. write_block(0, 2, false, em_encoded_data >> 32);
  106. write_reset();
  107. FURI_CRITICAL_EXIT();
  108. }
  109. void RfidWriter::write_hid(const uint8_t hid_data[3]) {
  110. ProtocolHID10301 hid_card;
  111. uint32_t card_data[3];
  112. hid_card.encode(hid_data, 3, reinterpret_cast<uint8_t*>(&card_data), sizeof(card_data) * 3);
  113. const uint32_t hid_config_block_data = 0b00000000000100000111000001100000;
  114. FURI_CRITICAL_ENTER();
  115. write_block(0, 0, false, hid_config_block_data);
  116. write_block(0, 1, false, card_data[0]);
  117. write_block(0, 2, false, card_data[1]);
  118. write_block(0, 3, false, card_data[2]);
  119. write_reset();
  120. FURI_CRITICAL_EXIT();
  121. }
  122. /** Endian fixup. Translates an ioprox block into a t5577 block */
  123. static uint32_t ioprox_encode_block(const uint8_t block_data[4]) {
  124. uint8_t raw_card_data[] = {block_data[3], block_data[2], block_data[1], block_data[0]};
  125. return *reinterpret_cast<uint32_t*>(&raw_card_data);
  126. }
  127. void RfidWriter::write_ioprox(const uint8_t ioprox_data[4]) {
  128. ProtocolIoProx ioprox_card;
  129. uint8_t encoded_data[8];
  130. ioprox_card.encode(ioprox_data, 4, encoded_data, sizeof(encoded_data));
  131. const uint32_t ioprox_config_block_data = 0b00000000000101000111000001000000;
  132. FURI_CRITICAL_ENTER();
  133. write_block(0, 0, false, ioprox_config_block_data);
  134. write_block(0, 1, false, ioprox_encode_block(&encoded_data[0]));
  135. write_block(0, 2, false, ioprox_encode_block(&encoded_data[4]));
  136. write_reset();
  137. FURI_CRITICAL_EXIT();
  138. }
  139. void RfidWriter::write_indala(const uint8_t indala_data[3]) {
  140. ProtocolIndala40134 indala_card;
  141. uint32_t card_data[2];
  142. indala_card.encode(
  143. indala_data, 3, reinterpret_cast<uint8_t*>(&card_data), sizeof(card_data) * 2);
  144. const uint32_t indala_config_block_data = 0b00000000000010000001000001000000;
  145. FURI_CRITICAL_ENTER();
  146. write_block(0, 0, false, indala_config_block_data);
  147. write_block(0, 1, false, card_data[0]);
  148. write_block(0, 2, false, card_data[1]);
  149. write_reset();
  150. FURI_CRITICAL_EXIT();
  151. }