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 | } |