blanks_writer.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. #include "blanks_writer.h"
  2. class RW1990_1 {
  3. public:
  4. constexpr static const uint8_t CMD_WRITE_RECORD_FLAG = 0xD1;
  5. constexpr static const uint8_t CMD_READ_RECORD_FLAG = 0xB5;
  6. constexpr static const uint8_t CMD_WRITE_ROM = 0xD5;
  7. };
  8. class RW1990_2 {
  9. public:
  10. constexpr static const uint8_t CMD_WRITE_RECORD_FLAG = 0x1D;
  11. constexpr static const uint8_t CMD_READ_RECORD_FLAG = 0x1E;
  12. constexpr static const uint8_t CMD_WRITE_ROM = 0xD5;
  13. };
  14. class TM2004 {
  15. public:
  16. constexpr static const uint8_t CMD_READ_STATUS = 0xAA;
  17. constexpr static const uint8_t CMD_READ_MEMORY = 0xF0;
  18. constexpr static const uint8_t CMD_WRITE_ROM = 0x3C;
  19. constexpr static const uint8_t CMD_FINALIZATION = 0x35;
  20. constexpr static const uint8_t ANSWER_READ_MEMORY = 0xF5;
  21. };
  22. class TM01 {
  23. public:
  24. constexpr static const uint8_t CMD_WRITE_RECORD_FLAG = 0xC1;
  25. constexpr static const uint8_t CMD_WRITE_ROM = 0xC5;
  26. constexpr static const uint8_t CMD_SWITCH_TO_CYFRAL = 0xCA;
  27. constexpr static const uint8_t CMD_SWITCH_TO_METAKOM = 0xCB;
  28. };
  29. class DS1990 {
  30. public:
  31. constexpr static const uint8_t CMD_READ_ROM = 0x33;
  32. };
  33. #include <stdio.h>
  34. #include <stdarg.h>
  35. #include <string.h>
  36. #include <api-hal.h>
  37. void BlanksWriter::onewire_release(void) {
  38. gpio_write(gpio, true);
  39. }
  40. void BlanksWriter::onewire_write_one_bit(bool value, uint32_t delay = 10000) {
  41. onewire->write_bit(value);
  42. delay_us(delay);
  43. onewire_release();
  44. }
  45. BlanksWriter::BlanksWriter(const GpioPin* one_wire_gpio) {
  46. gpio = one_wire_gpio;
  47. onewire = new OneWireMaster(gpio);
  48. }
  49. BlanksWriter::~BlanksWriter() {
  50. free(onewire);
  51. }
  52. WriterResult BlanksWriter::write(KeyType type, const uint8_t* key, uint8_t key_length) {
  53. uint8_t write_result = -1;
  54. WriterResult result = WR_ERROR;
  55. bool same_key = false;
  56. osKernelLock();
  57. bool presence = onewire->reset();
  58. osKernelUnlock();
  59. if(presence) {
  60. switch(type) {
  61. case KeyType::KEY_DS1990:
  62. same_key = compare_key_ds1990(key, key_length);
  63. if(!same_key) {
  64. // currently we can write:
  65. // RW1990, TM08v2, TM08vi-2 by write_1990_1()
  66. // RW2004, RW2004 with EEPROM by write_TM2004();
  67. if(write_result != 1) {
  68. write_result = write_1990_1(key, key_length);
  69. }
  70. if(write_result != 1) {
  71. write_result = write_1990_2(key, key_length);
  72. }
  73. if(write_result != 1) {
  74. write_result = write_TM2004(key, key_length);
  75. }
  76. if(write_result == 1) {
  77. result = WR_OK;
  78. } else if(write_result == 0) {
  79. result = WR_ERROR;
  80. }
  81. } else {
  82. write_result = 0;
  83. result = WR_SAME_KEY;
  84. }
  85. break;
  86. default:
  87. break;
  88. }
  89. }
  90. return result;
  91. }
  92. bool BlanksWriter::write_TM2004(const uint8_t* key, uint8_t key_length) {
  93. uint8_t answer;
  94. bool result = true;
  95. osKernelLock();
  96. __disable_irq();
  97. // write rom, addr is 0x0000
  98. onewire->reset();
  99. onewire->write(TM2004::CMD_WRITE_ROM);
  100. onewire->write(0x00);
  101. onewire->write(0x00);
  102. // write key
  103. for(uint8_t i = 0; i < key_length; i++) {
  104. // write key byte
  105. onewire->write(key[i]);
  106. answer = onewire->read();
  107. // TODO: check answer CRC
  108. // pulse indicating that data is correct
  109. delay_us(600);
  110. onewire_write_one_bit(1, 50000);
  111. // read writed key byte
  112. answer = onewire->read();
  113. // check that writed and readed are same
  114. if(key[i] != answer) {
  115. result = false;
  116. break;
  117. }
  118. }
  119. onewire->reset();
  120. __enable_irq();
  121. osKernelUnlock();
  122. return result;
  123. }
  124. bool BlanksWriter::write_1990_1(const uint8_t* key, uint8_t key_length) {
  125. bool result = true;
  126. osKernelLock();
  127. __disable_irq();
  128. // unlock
  129. onewire->reset();
  130. onewire->write(RW1990_1::CMD_WRITE_RECORD_FLAG);
  131. delay_us(10);
  132. onewire_write_one_bit(0, 5000);
  133. // write key
  134. onewire->reset();
  135. onewire->write(RW1990_1::CMD_WRITE_ROM);
  136. for(uint8_t i = 0; i < key_length; i++) {
  137. // inverted key for RW1990.1
  138. write_byte_ds1990(~key[i]);
  139. delay_us(30000);
  140. }
  141. // lock
  142. onewire->write(RW1990_1::CMD_WRITE_RECORD_FLAG);
  143. onewire_write_one_bit(1);
  144. __enable_irq();
  145. osKernelUnlock();
  146. if(!compare_key_ds1990(key, key_length)) {
  147. result = false;
  148. }
  149. return result;
  150. }
  151. bool BlanksWriter::write_1990_2(const uint8_t* key, uint8_t key_length) {
  152. bool result = true;
  153. osKernelLock();
  154. __disable_irq();
  155. // unlock
  156. onewire->reset();
  157. onewire->write(RW1990_2::CMD_WRITE_RECORD_FLAG);
  158. delay_us(10);
  159. onewire_write_one_bit(1, 5000);
  160. // write key
  161. onewire->reset();
  162. onewire->write(RW1990_2::CMD_WRITE_ROM);
  163. for(uint8_t i = 0; i < key_length; i++) {
  164. write_byte_ds1990(key[i]);
  165. delay_us(30000);
  166. }
  167. // lock
  168. onewire->write(RW1990_2::CMD_WRITE_RECORD_FLAG);
  169. onewire_write_one_bit(0);
  170. __enable_irq();
  171. osKernelUnlock();
  172. if(!compare_key_ds1990(key, key_length)) {
  173. result = false;
  174. }
  175. return result;
  176. }
  177. // TODO: untested
  178. bool BlanksWriter::write_TM01(KeyType type, const uint8_t* key, uint8_t key_length) {
  179. bool result = true;
  180. osKernelLock();
  181. __disable_irq();
  182. // unlock
  183. onewire->reset();
  184. onewire->write(TM01::CMD_WRITE_RECORD_FLAG);
  185. onewire_write_one_bit(1, 10000);
  186. // write key
  187. onewire->reset();
  188. onewire->write(TM01::CMD_WRITE_ROM);
  189. // TODO: key types
  190. //if(type == KEY_METAKOM || type == KEY_CYFRAL) {
  191. //} else {
  192. for(uint8_t i = 0; i < key_length; i++) {
  193. write_byte_ds1990(key[i]);
  194. delay_us(10000);
  195. }
  196. //}
  197. // lock
  198. onewire->write(TM01::CMD_WRITE_RECORD_FLAG);
  199. onewire_write_one_bit(0, 10000);
  200. __enable_irq();
  201. osKernelUnlock();
  202. if(!compare_key_ds1990(key, key_length)) {
  203. result = false;
  204. }
  205. osKernelLock();
  206. __disable_irq();
  207. if(type == KEY_METAKOM || type == KEY_CYFRAL) {
  208. onewire->reset();
  209. if(type == KEY_CYFRAL)
  210. onewire->write(TM01::CMD_SWITCH_TO_CYFRAL);
  211. else
  212. onewire->write(TM01::CMD_SWITCH_TO_METAKOM);
  213. onewire_write_one_bit(1);
  214. }
  215. __enable_irq();
  216. osKernelUnlock();
  217. return result;
  218. }
  219. void BlanksWriter::write_byte_ds1990(uint8_t data) {
  220. for(uint8_t n_bit = 0; n_bit < 8; n_bit++) {
  221. onewire->write_bit(data & 1);
  222. onewire_release();
  223. delay_us(5000);
  224. data = data >> 1;
  225. }
  226. }
  227. bool BlanksWriter::compare_key_ds1990(const uint8_t* key, uint8_t key_length) {
  228. uint8_t buff[key_length];
  229. bool result = false;
  230. osKernelLock();
  231. bool presence = onewire->reset();
  232. osKernelUnlock();
  233. if(presence) {
  234. osKernelLock();
  235. __disable_irq();
  236. onewire->write(DS1990::CMD_READ_ROM);
  237. onewire->read_bytes(buff, key_length);
  238. __enable_irq();
  239. osKernelUnlock();
  240. result = true;
  241. for(uint8_t i = 0; i < 8; i++) {
  242. if(key[i] != buff[i]) {
  243. result = false;
  244. break;
  245. }
  246. }
  247. }
  248. return result;
  249. }
  250. void BlanksWriter::start() {
  251. onewire->start();
  252. }
  253. void BlanksWriter::stop() {
  254. onewire->stop();
  255. }