Project

General

Profile

Statistics
| Branch: | Revision:

root / toolbox / rfid.c @ master

History | View | Annotate | Download (2.03 KB)

1 12ea39cc Tom Mullins
#include <string.h>
2 6ca98a3f Tom Mullins
#include <stdint.h>
3 9b2b6d91 Tom Mullins
#include <util/delay.h>
4
#include "rfid.h"
5
#include "serial.h"
6
7 2f795968 Tom Mullins
#define MF_SELECT_CMD 0x83
8
9
static uint8_t select_cmd[] = {0xFF, 0, 1, MF_SELECT_CMD, MF_SELECT_CMD + 1};
10 6fbe093f Tom Mullins
11
#define FRAME_SIZE(data_size) ((data_size)+4)
12 2f795968 Tom Mullins
#define RFID_DATA_SIZE (RFID_SERNO_SIZE+2)
13
#define MAX_FRAME_SIZE FRAME_SIZE(RFID_DATA_SIZE)
14 6fbe093f Tom Mullins
15
#define RESP_START    0
16
#define RESP_RESERVED 1
17
#define RESP_LENGTH   2
18
#define RESP_CMD      3
19
#define RESP_DATA     4
20
static uint8_t response[MAX_FRAME_SIZE];
21
static uint8_t resp_idx;
22 9b2b6d91 Tom Mullins
23 6ca98a3f Tom Mullins
static uint8_t serno[RFID_SERNO_SIZE];
24 9b2b6d91 Tom Mullins
25
static void zero_serno() {
26
  int i;
27
  for (i = 0; i < RFID_SERNO_SIZE; i++) {
28
    serno[i] = 0;
29
  }
30
}
31
32
void rfid_init() {
33
  serial_init();
34
}
35
36 bbf2f5ad Tom Mullins
void rfid_start_read() {
37 6fbe093f Tom Mullins
  resp_idx = 0;
38 bbf2f5ad Tom Mullins
  serial_flush();
39 2f795968 Tom Mullins
  serial_write(select_cmd, sizeof(select_cmd));
40 6fbe093f Tom Mullins
}
41
42
char parse_response() {
43
  uint8_t sum;
44
  int resp_csum, i;
45
46 2f795968 Tom Mullins
  if (response[RESP_CMD] != MF_SELECT_CMD) {
47
    // invalid response, ignore
48 6fbe093f Tom Mullins
    zero_serno();
49
    return 0;
50
  }
51
52 2f795968 Tom Mullins
  if (response[RESP_LENGTH] != RFID_DATA_SIZE) {
53
    // wrong response length, assume there's no card
54
    zero_serno();
55
    return 1;
56
  }
57
58 6fbe093f Tom Mullins
  resp_csum = response[RESP_LENGTH] + RESP_CMD;
59
  sum = 0;
60
  for (i = RESP_LENGTH; i < resp_csum; i++) {
61
    sum += response[i];
62
  }
63
  if (response[resp_csum] != sum) {
64 2f795968 Tom Mullins
    zero_serno();
65
    return 0;
66 6fbe093f Tom Mullins
  }
67
68
  memcpy(serno, &response[RESP_DATA+1], RFID_SERNO_SIZE);
69
  return 1;
70 532ba0bd Tom Mullins
}
71
72
char rfid_poll() {
73
  int c;
74
75 6ca98a3f Tom Mullins
  while ((c = serial_read()) >= 0) {
76 532ba0bd Tom Mullins
77 6fbe093f Tom Mullins
    if (resp_idx < sizeof(response)) {
78
      response[resp_idx] = c;
79 532ba0bd Tom Mullins
    }
80 6fbe093f Tom Mullins
    resp_idx++;
81 532ba0bd Tom Mullins
82 6fbe093f Tom Mullins
    if (resp_idx == 1) {
83
84
      // restart if the frame start is invalid
85
      if (response[RESP_START] != 0xFF) {
86
        resp_idx = 0;
87
      }
88 532ba0bd Tom Mullins
89 6fbe093f Tom Mullins
    } else if (resp_idx > RESP_LENGTH) {
90
91
      // check if we're done with current packet
92
      if (resp_idx >= FRAME_SIZE(response[RESP_LENGTH])) {
93 2f795968 Tom Mullins
        rfid_start_read();
94 6fbe093f Tom Mullins
        if (parse_response()) {
95
          return 1;
96
        }
97
      }
98
99
    }
100 9b2b6d91 Tom Mullins
  }
101 532ba0bd Tom Mullins
102
  return 0;
103 9b2b6d91 Tom Mullins
}
104
105 6ca98a3f Tom Mullins
void rfid_get_serno(uint8_t *buf) {
106 12ea39cc Tom Mullins
  memcpy(buf, serno, sizeof(serno));
107
}