pn532hsu.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * This program is free software; you can redistribute it and/or
  3. * modify it under the terms of the GNU General Public License
  4. * as published by the Free Software Foundation; either version 2
  5. * of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. * Author: hakanai
  12. *
  13. */
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include "freertos/FreeRTOS.h"
  17. #include "freertos/task.h"
  18. #include "driver/uart.h"
  19. #include "sdkconfig.h"
  20. #include "esp_log.h"
  21. #include "pn532hsu.h"
  22. //static const char *TAG = "PN532-DRV";
  23. enum pn532_init_state_enum {
  24. PN532_STATE_READ_RFSTATUS = 0,
  25. PN532_STATE_READ_VERSION,
  26. PN532_STATE_GET_STATUS,
  27. PN532_STATE_SET_SCANNING,
  28. PN532_STATE_COMPLETE
  29. };
  30. #define MAXBUFSIZ 64
  31. #ifdef CONFIG_PN532_DEBUG_ENABLE
  32. static void printbuf(uint8_t *buffer, uint16_t len) {
  33. for(uint16_t i = 0; i < len; i++){
  34. printf("%.2x ", buffer[i]);
  35. }
  36. }
  37. #define pprint(a, b, c) do { printf("%s: ", a); \
  38. printbuf(b, c); puts(""); } while(0)
  39. #endif
  40. static int send_packet(const uint8_t *buffer, uint16_t len) {
  41. uint8_t cmd[MAXBUFSIZ] = { 0 };
  42. uint8_t sum = 0xd4;
  43. int i;
  44. if (len > MAXBUFSIZ || len < 1)
  45. return ESP_FAIL;
  46. /* Make header */
  47. for (i = 0; i < 9; i++)
  48. cmd[i] = 0xff;
  49. /* Padding */
  50. cmd[i++] = 0x00;
  51. cmd[i++] = 0xff;
  52. /* Set length */
  53. cmd[i++] = len + 1;
  54. cmd[i++] = -(len + 1);
  55. /* Set target id */
  56. cmd[i++] = 0xd4;
  57. for (int j = 0; j < len; j++) {
  58. cmd[i++] = buffer[j];
  59. sum += buffer[j];
  60. }
  61. cmd[i++] = -(sum);
  62. cmd[i++] = 0xd4;
  63. if (uart_write_bytes(CONFIG_PN532_UART_PORT_NUM,
  64. (const char *) cmd, i) != i)
  65. return ESP_FAIL;
  66. #ifdef CONFIG_PN532_DEBUG_ENABLE
  67. pprint("sent", cmd, i);
  68. #endif
  69. return ESP_OK;
  70. }
  71. static uint16_t read_buffer(uint8_t *resp, uint16_t len) {
  72. uint8_t c[1];
  73. uint16_t index = 0; // Bytes we have read
  74. while (index < len) {
  75. if (uart_read_bytes(CONFIG_PN532_UART_PORT_NUM, c,
  76. 1, 100 / portTICK_PERIOD_MS) > 0) {
  77. resp[index++] = c[0];
  78. } else {
  79. break;
  80. }
  81. }
  82. return index;
  83. }
  84. static int recv_packet(uint8_t *buffer) {
  85. int len, j, i;
  86. const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0, 0, 0, 0xFF};
  87. uint8_t dlen[2];
  88. uint8_t sum;
  89. len = read_buffer(buffer, MAXBUFSIZ);
  90. #ifdef CONFIG_PN532_DEBUG_ENABLE
  91. pprint("recv", buffer, len);
  92. #endif
  93. i = sizeof(PN532_ACK);
  94. if (memcmp(buffer, PN532_ACK, i)) {
  95. /* ESP_LOGE(TAG, "Invalid frame");*/
  96. return ESP_FAIL;
  97. }
  98. dlen[0] = buffer[i++];
  99. dlen[1] = buffer[i++];
  100. if (len < 2 || (uint8_t)(dlen[0] + dlen[1]) != 0) {
  101. /* ESP_LOGE(TAG, "Incorrect length");*/
  102. return ESP_FAIL;
  103. }
  104. if (buffer[i++] != 0xd5) {
  105. /* ESP_LOGE(TAG, "Hostcheck failed");*/
  106. return ESP_FAIL;
  107. }
  108. dlen[0] -= 2;
  109. sum = 0xd5 + buffer[i++];
  110. for (j = 0; j < dlen[0]; j++) {
  111. sum += buffer[i + j];
  112. }
  113. if (((uint8_t)(sum + buffer[len - 2])) != 0 || buffer[len - 1] != 0) {
  114. /* ESP_LOGE(TAG, "Checksum error %d %d %d", buffer[len-1], sum, (uint8_t)(sum + buffer[len-1]));*/
  115. return ESP_FAIL;
  116. }
  117. for (j = 0; j < dlen[0]; j++) {
  118. buffer[j] = buffer[i++];
  119. }
  120. return dlen[0];
  121. }
  122. static int read_status() {
  123. const uint8_t cmd[2] = { 0x58, 0x00 };
  124. uint8_t buffer[MAXBUFSIZ] = { 0 };
  125. const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
  126. const uint8_t ack_len = sizeof(PN532_ACK);
  127. if (send_packet(cmd, 2) != ESP_OK) {
  128. return ESP_FAIL;
  129. }
  130. if (read_buffer(buffer, MAXBUFSIZ) != ack_len) {
  131. return ESP_FAIL;
  132. }
  133. if (memcmp(buffer, PN532_ACK, ack_len)) {
  134. return ESP_FAIL;
  135. }
  136. #ifdef CONFIG_PN532_DEBUG_ENABLE
  137. pprint("[ack]", buffer, ack_len);
  138. #endif
  139. return ESP_OK;
  140. }
  141. static int read_diagnose() {
  142. const uint8_t cmd[1] = { 0x04 };
  143. uint8_t buffer[MAXBUFSIZ] = { 0 };
  144. int rlen;
  145. if (send_packet(cmd, 1) != ESP_OK) {
  146. return ESP_FAIL;
  147. }
  148. if ((rlen = recv_packet(buffer)) < 1) {
  149. return ESP_FAIL;
  150. }
  151. return ESP_OK;
  152. }
  153. static int read_version() {
  154. const uint8_t cmd[1] = { 0x02 };
  155. uint8_t buffer[MAXBUFSIZ] = { 0 };
  156. int rlen;
  157. if (send_packet(cmd, 1) != ESP_OK) {
  158. return ESP_FAIL;
  159. }
  160. if ((rlen = recv_packet(buffer)) < 3) {
  161. return ESP_FAIL;
  162. }
  163. #ifdef CONFIG_PN532_DEBUG_ENABLE
  164. printf("PN532 ver %d.%d, features: %d\n",
  165. buffer[1], buffer[2], buffer[3]);
  166. #endif
  167. return ESP_OK;
  168. }
  169. static int set_scanning() {
  170. const uint8_t cmd[5] = { 0x32, 0x05, 0xff, 0x01, 0x10 };
  171. uint8_t buffer[MAXBUFSIZ] = { 0 };
  172. int rlen;
  173. if (send_packet(cmd, 5) != ESP_OK) {
  174. return ESP_FAIL;
  175. }
  176. if ((rlen = recv_packet(buffer)) != 0) {
  177. return ESP_FAIL;
  178. }
  179. #ifdef CONFIG_PN532_DEBUG_ENABLE
  180. printf("PN532 mode set\n");
  181. #endif
  182. return ESP_OK;
  183. }
  184. static int pn532_begin() {
  185. uint8_t test_state = PN532_STATE_READ_RFSTATUS;
  186. short tries = 0;
  187. while (tries++ < 200 && test_state != PN532_STATE_COMPLETE) {
  188. switch (test_state) {
  189. case PN532_STATE_READ_RFSTATUS:
  190. if (read_status() == ESP_OK)
  191. test_state = PN532_STATE_READ_VERSION;
  192. break;
  193. case PN532_STATE_READ_VERSION:
  194. if (read_version() == ESP_OK)
  195. test_state = PN532_STATE_GET_STATUS;
  196. break;
  197. case PN532_STATE_GET_STATUS:
  198. if (read_diagnose() == ESP_OK)
  199. test_state = PN532_STATE_SET_SCANNING;
  200. break;
  201. case PN532_STATE_SET_SCANNING:
  202. if (set_scanning() == ESP_OK) {
  203. test_state = PN532_STATE_COMPLETE;
  204. return ESP_OK;
  205. }
  206. break;
  207. }
  208. }
  209. return ESP_FAIL;
  210. }
  211. static int pn532_uart_init() {
  212. uart_config_t uart_config = {
  213. .baud_rate = 115200,
  214. .data_bits = UART_DATA_8_BITS,
  215. .parity = UART_PARITY_DISABLE,
  216. .stop_bits = UART_STOP_BITS_1,
  217. .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
  218. .source_clk = UART_SCLK_DEFAULT,
  219. };
  220. int intr_alloc_flags = 0;
  221. int err;
  222. #if CONFIG_UART_ISR_IN_IRAM
  223. intr_alloc_flags = ESP_INTR_FLAG_IRAM;
  224. #endif
  225. err = uart_driver_install(CONFIG_PN532_UART_PORT_NUM, 1024 * 2,
  226. 0, 0, NULL, intr_alloc_flags);
  227. if (err != ESP_OK)
  228. return err;
  229. err = uart_param_config(CONFIG_PN532_UART_PORT_NUM, &uart_config);
  230. if (err != ESP_OK)
  231. return err;
  232. err = uart_set_pin(CONFIG_PN532_UART_PORT_NUM,
  233. CONFIG_PN532_UART_TXD, CONFIG_PN532_UART_RXD, -1, -1);
  234. return err;
  235. }
  236. int pn532_read(uint8_t *buf, int len) {
  237. const uint8_t cmd[3] = { 0x4a, 0x02, 0x00 };
  238. uint8_t buffer[MAXBUFSIZ] = { 0 };
  239. int rlen;
  240. if (send_packet(cmd, 3) != ESP_OK) {
  241. return ESP_FAIL;
  242. }
  243. if ((rlen = recv_packet(buffer)) < 1) {
  244. return ESP_FAIL;
  245. }
  246. if (buffer[0] == 0x00) { // (No card) skip
  247. return ESP_FAIL;
  248. }
  249. if (rlen > len)
  250. return ESP_FAIL;
  251. memcpy(buf, buffer, rlen);
  252. #ifdef CONFIG_PN532_DEBUG_ENABLE
  253. printf("Read (%d) bytes:", rlen);
  254. printbuf(buffer, rlen);
  255. puts("");
  256. #endif
  257. return rlen;
  258. }
  259. int pn532_decode_card(uint8_t *buf, int buf_len, uint8_t *out) {
  260. uint8_t id_len;
  261. if (buf_len < 7 || buf_len > MAXBUFSIZ)
  262. return ESP_FAIL;
  263. id_len = buf[5];
  264. if ((id_len + 5) > buf_len)
  265. return ESP_FAIL;
  266. for (uint8_t i = 0; i < id_len; i++) {
  267. out[i] = buf[6 + i];
  268. }
  269. return id_len;
  270. }
  271. int pn532_init() {
  272. int err;
  273. err = pn532_uart_init();
  274. if (err != ESP_OK)
  275. return err;
  276. err = pn532_begin();
  277. return err;
  278. }