123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * Author: hakanai
- *
- */
- #include <stdio.h>
- #include <string.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "driver/uart.h"
- #include "sdkconfig.h"
- #include "esp_log.h"
- #include "pn532hsu.h"
- //static const char *TAG = "PN532-DRV";
- enum pn532_init_state_enum {
- PN532_STATE_READ_RFSTATUS = 0,
- PN532_STATE_READ_VERSION,
- PN532_STATE_GET_STATUS,
- PN532_STATE_SET_SCANNING,
- PN532_STATE_COMPLETE
- };
- #define MAXBUFSIZ 64
- #ifdef CONFIG_PN532_DEBUG_ENABLE
- static void printbuf(uint8_t *buffer, uint16_t len) {
- for(uint16_t i = 0; i < len; i++){
- printf("%.2x ", buffer[i]);
- }
- }
- #define pprint(a, b, c) do { printf("%s: ", a); \
- printbuf(b, c); puts(""); } while(0)
- #endif
- static int send_packet(const uint8_t *buffer, uint16_t len) {
- uint8_t cmd[MAXBUFSIZ] = { 0 };
- uint8_t sum = 0xd4;
- int i;
- if (len > MAXBUFSIZ || len < 1)
- return ESP_FAIL;
- /* Make header */
- for (i = 0; i < 9; i++)
- cmd[i] = 0xff;
- /* Padding */
- cmd[i++] = 0x00;
- cmd[i++] = 0xff;
- /* Set length */
- cmd[i++] = len + 1;
- cmd[i++] = -(len + 1);
- /* Set target id */
- cmd[i++] = 0xd4;
- for (int j = 0; j < len; j++) {
- cmd[i++] = buffer[j];
- sum += buffer[j];
- }
- cmd[i++] = -(sum);
- cmd[i++] = 0xd4;
- if (uart_write_bytes(CONFIG_PN532_UART_PORT_NUM,
- (const char *) cmd, i) != i)
- return ESP_FAIL;
- #ifdef CONFIG_PN532_DEBUG_ENABLE
- pprint("sent", cmd, i);
- #endif
- return ESP_OK;
- }
- static uint16_t read_buffer(uint8_t *resp, uint16_t len) {
- uint8_t c[1];
- uint16_t index = 0; // Bytes we have read
- while (index < len) {
- if (uart_read_bytes(CONFIG_PN532_UART_PORT_NUM, c,
- 1, 100 / portTICK_PERIOD_MS) > 0) {
- resp[index++] = c[0];
- } else {
- break;
- }
- }
- return index;
- }
- static int recv_packet(uint8_t *buffer) {
- int len, j, i;
- const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0, 0, 0, 0xFF};
- uint8_t dlen[2];
- uint8_t sum;
- len = read_buffer(buffer, MAXBUFSIZ);
- #ifdef CONFIG_PN532_DEBUG_ENABLE
- pprint("recv", buffer, len);
- #endif
- i = sizeof(PN532_ACK);
- if (memcmp(buffer, PN532_ACK, i)) {
- /* ESP_LOGE(TAG, "Invalid frame");*/
- return ESP_FAIL;
- }
- dlen[0] = buffer[i++];
- dlen[1] = buffer[i++];
- if (len < 2 || (uint8_t)(dlen[0] + dlen[1]) != 0) {
- /* ESP_LOGE(TAG, "Incorrect length");*/
- return ESP_FAIL;
- }
- if (buffer[i++] != 0xd5) {
- /* ESP_LOGE(TAG, "Hostcheck failed");*/
- return ESP_FAIL;
- }
- dlen[0] -= 2;
- sum = 0xd5 + buffer[i++];
- for (j = 0; j < dlen[0]; j++) {
- sum += buffer[i + j];
- }
- if (((uint8_t)(sum + buffer[len - 2])) != 0 || buffer[len - 1] != 0) {
- /* ESP_LOGE(TAG, "Checksum error %d %d %d", buffer[len-1], sum, (uint8_t)(sum + buffer[len-1]));*/
- return ESP_FAIL;
- }
- for (j = 0; j < dlen[0]; j++) {
- buffer[j] = buffer[i++];
- }
- return dlen[0];
- }
- static int read_status() {
- const uint8_t cmd[2] = { 0x58, 0x00 };
- uint8_t buffer[MAXBUFSIZ] = { 0 };
- const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
- const uint8_t ack_len = sizeof(PN532_ACK);
- if (send_packet(cmd, 2) != ESP_OK) {
- return ESP_FAIL;
- }
- if (read_buffer(buffer, MAXBUFSIZ) != ack_len) {
- return ESP_FAIL;
- }
- if (memcmp(buffer, PN532_ACK, ack_len)) {
- return ESP_FAIL;
- }
- #ifdef CONFIG_PN532_DEBUG_ENABLE
- pprint("[ack]", buffer, ack_len);
- #endif
- return ESP_OK;
- }
- static int read_diagnose() {
- const uint8_t cmd[1] = { 0x04 };
- uint8_t buffer[MAXBUFSIZ] = { 0 };
- int rlen;
- if (send_packet(cmd, 1) != ESP_OK) {
- return ESP_FAIL;
- }
- if ((rlen = recv_packet(buffer)) < 1) {
- return ESP_FAIL;
- }
- return ESP_OK;
- }
- static int read_version() {
- const uint8_t cmd[1] = { 0x02 };
- uint8_t buffer[MAXBUFSIZ] = { 0 };
- int rlen;
- if (send_packet(cmd, 1) != ESP_OK) {
- return ESP_FAIL;
- }
- if ((rlen = recv_packet(buffer)) < 3) {
- return ESP_FAIL;
- }
- #ifdef CONFIG_PN532_DEBUG_ENABLE
- printf("PN532 ver %d.%d, features: %d\n",
- buffer[1], buffer[2], buffer[3]);
- #endif
- return ESP_OK;
- }
- static int set_scanning() {
- const uint8_t cmd[5] = { 0x32, 0x05, 0xff, 0x01, 0x10 };
- uint8_t buffer[MAXBUFSIZ] = { 0 };
- int rlen;
- if (send_packet(cmd, 5) != ESP_OK) {
- return ESP_FAIL;
- }
- if ((rlen = recv_packet(buffer)) != 0) {
- return ESP_FAIL;
- }
- #ifdef CONFIG_PN532_DEBUG_ENABLE
- printf("PN532 mode set\n");
- #endif
- return ESP_OK;
- }
- static int pn532_begin() {
- uint8_t test_state = PN532_STATE_READ_RFSTATUS;
- short tries = 0;
- while (tries++ < 200 && test_state != PN532_STATE_COMPLETE) {
- switch (test_state) {
- case PN532_STATE_READ_RFSTATUS:
- if (read_status() == ESP_OK)
- test_state = PN532_STATE_READ_VERSION;
- break;
- case PN532_STATE_READ_VERSION:
- if (read_version() == ESP_OK)
- test_state = PN532_STATE_GET_STATUS;
- break;
- case PN532_STATE_GET_STATUS:
- if (read_diagnose() == ESP_OK)
- test_state = PN532_STATE_SET_SCANNING;
- break;
- case PN532_STATE_SET_SCANNING:
- if (set_scanning() == ESP_OK) {
- test_state = PN532_STATE_COMPLETE;
- return ESP_OK;
- }
- break;
- }
- }
- return ESP_FAIL;
- }
- static int pn532_uart_init() {
- uart_config_t uart_config = {
- .baud_rate = 115200,
- .data_bits = UART_DATA_8_BITS,
- .parity = UART_PARITY_DISABLE,
- .stop_bits = UART_STOP_BITS_1,
- .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
- .source_clk = UART_SCLK_DEFAULT,
- };
- int intr_alloc_flags = 0;
- int err;
- #if CONFIG_UART_ISR_IN_IRAM
- intr_alloc_flags = ESP_INTR_FLAG_IRAM;
- #endif
- err = uart_driver_install(CONFIG_PN532_UART_PORT_NUM, 1024 * 2,
- 0, 0, NULL, intr_alloc_flags);
- if (err != ESP_OK)
- return err;
- err = uart_param_config(CONFIG_PN532_UART_PORT_NUM, &uart_config);
- if (err != ESP_OK)
- return err;
- err = uart_set_pin(CONFIG_PN532_UART_PORT_NUM,
- CONFIG_PN532_UART_TXD, CONFIG_PN532_UART_RXD, -1, -1);
- return err;
- }
- int pn532_read(uint8_t *buf, int len) {
- const uint8_t cmd[3] = { 0x4a, 0x02, 0x00 };
- uint8_t buffer[MAXBUFSIZ] = { 0 };
- int rlen;
- if (send_packet(cmd, 3) != ESP_OK) {
- return ESP_FAIL;
- }
- if ((rlen = recv_packet(buffer)) < 1) {
- return ESP_FAIL;
- }
- if (buffer[0] == 0x00) { // (No card) skip
- return ESP_FAIL;
- }
- if (rlen > len)
- return ESP_FAIL;
- memcpy(buf, buffer, rlen);
- #ifdef CONFIG_PN532_DEBUG_ENABLE
- printf("Read (%d) bytes:", rlen);
- printbuf(buffer, rlen);
- puts("");
- #endif
- return rlen;
- }
- int pn532_decode_card(uint8_t *buf, int buf_len, uint8_t *out) {
- uint8_t id_len;
- if (buf_len < 7 || buf_len > MAXBUFSIZ)
- return ESP_FAIL;
- id_len = buf[5];
- if ((id_len + 5) > buf_len)
- return ESP_FAIL;
- for (uint8_t i = 0; i < id_len; i++) {
- out[i] = buf[6 + i];
- }
- return id_len;
- }
- int pn532_init() {
- int err;
- err = pn532_uart_init();
- if (err != ESP_OK)
- return err;
- err = pn532_begin();
- return err;
- }
|