root / toolbox / rfid.c @ 2f795968
History | View | Annotate | Download (2.03 KB)
1 |
#include <string.h> |
---|---|
2 |
#include <stdint.h> |
3 |
#include <util/delay.h> |
4 |
#include "rfid.h" |
5 |
#include "serial.h" |
6 |
|
7 |
#define MF_SELECT_CMD 0x83 |
8 |
|
9 |
static uint8_t select_cmd[] = {0xFF, 0, 1, MF_SELECT_CMD, MF_SELECT_CMD + 1}; |
10 |
|
11 |
#define FRAME_SIZE(data_size) ((data_size)+4) |
12 |
#define RFID_DATA_SIZE (RFID_SERNO_SIZE+2) |
13 |
#define MAX_FRAME_SIZE FRAME_SIZE(RFID_DATA_SIZE)
|
14 |
|
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 |
|
23 |
static uint8_t serno[RFID_SERNO_SIZE];
|
24 |
|
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 |
void rfid_start_read() {
|
37 |
resp_idx = 0;
|
38 |
serial_flush(); |
39 |
serial_write(select_cmd, sizeof(select_cmd));
|
40 |
} |
41 |
|
42 |
char parse_response() {
|
43 |
uint8_t sum; |
44 |
int resp_csum, i;
|
45 |
|
46 |
if (response[RESP_CMD] != MF_SELECT_CMD) {
|
47 |
// invalid response, ignore
|
48 |
zero_serno(); |
49 |
return 0; |
50 |
} |
51 |
|
52 |
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 |
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 |
zero_serno(); |
65 |
return 0; |
66 |
} |
67 |
|
68 |
memcpy(serno, &response[RESP_DATA+1], RFID_SERNO_SIZE);
|
69 |
return 1; |
70 |
} |
71 |
|
72 |
char rfid_poll() {
|
73 |
int c;
|
74 |
|
75 |
while ((c = serial_read()) >= 0) { |
76 |
|
77 |
if (resp_idx < sizeof(response)) { |
78 |
response[resp_idx] = c; |
79 |
} |
80 |
resp_idx++; |
81 |
|
82 |
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 |
|
89 |
} 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 |
rfid_start_read(); |
94 |
if (parse_response()) {
|
95 |
return 1; |
96 |
} |
97 |
} |
98 |
|
99 |
} |
100 |
} |
101 |
|
102 |
return 0; |
103 |
} |
104 |
|
105 |
void rfid_get_serno(uint8_t *buf) {
|
106 |
memcpy(buf, serno, sizeof(serno));
|
107 |
} |