Hallo zusammen,
ich moechte an meinem AtMega1280 in einem Mikroelektronika BigAVR6 board
einen RFid Reader anschliessen. Dafuer habe ich mir das passende
Erweiterungsboard mit einem EM4095 gekauft und mich ans programmieren
gesetzt, das dauert jetzt leider schon mehrere Wochen. Ich schaffs
einfach nicht das Teil ordentlich zum laufen zu bringen.
Mein Ansatz:
RFid board an PORTK.
Interrupt auf out-pin.
Wenn fallende Flanke erkannt, interrupt auf clk-pin.
ab da zaehle ich im interrupt die clk zyklen. Jeden 64. Interrupt lese
ich ein Datenbit, und zwar einmal das untere und das naechste mal das
obere. Sind die beiden Bits unterschiedlich, steht die Information im
unteren Bit (invertierte Manchaster codierung).
Dann warte ich auf weitere acht einsen, das waere dann das startpaket.
Liegt eine null dazwischen, lege ich den Interrupt wieder auf den
out-pin und versuche mich neu zu synchronisieren.
Konnten 9 Einsen gelesen werden, starte ich die Daten zu lesen und in
einem Array abzulegen. Dabei ueberpruefe ich mit jedem 5. Bit die
paritaet der vorherigen 4 bits und zum schluss das Stop-bit.
Wenn bis zum Ende keine Paritaet verletzt wurde und das Stop-bit 0 ist,
uebergebe ich die Daten einem Handler der damit machen kann was er
moechte, ansonsten wird der Handler mit einem Fehlerstatus aufgerufen.
Das ganze scheint aber nicht zu funktionieren (der Handler wird nur sehr
selten mit SUCCESS aufgerufen und wenn dann mit falschen Daten). Ich
sitz jetzt schon 2 Wochen lang am debuggen und kann den Fehler einfach
nicht finden.
Wenn mir vielleicht jemand Helfen koennte? Vielleicht ist mein Ansatz ja
auch komplett falsch?
Header:
1 | #ifndef RFID_H
|
2 | #define RFID_H
|
3 |
|
4 | #define RFID_PORT (PORTK)
|
5 | #define RFID_PIN (PINK)
|
6 | #define RFID_DDR (DDRK)
|
7 | #define RFID_INT_CR (PCICR)
|
8 | #define RFID_INT_MSK (PCMSK2)
|
9 | #define RFID_INT_VECT (PCINT2_vect)
|
10 |
|
11 | #include "util.h"
|
12 | #include <avr/io.h>
|
13 | #include <stdlib.h>
|
14 | #include <stdbool.h>
|
15 | #include <avr/interrupt.h>
|
16 | #include <avr/sleep.h>
|
17 |
|
18 | typedef enum {
|
19 | VALID,
|
20 | INVALID,
|
21 | } status_t;
|
22 |
|
23 | //configuration and Handler registration
|
24 | error_t rfid_init(void (*decodeEvent)(status_t, uint8_t*));
|
25 |
|
26 | //interrupt enable and wake up RFid reader
|
27 | error_t rfid_enable(void);
|
28 |
|
29 | //put RFid reader to sleep and disable interrupts
|
30 | void rfid_disable(void);
|
31 |
|
32 | #endif
|
Code:
1 | #include "rfid.h"
|
2 |
|
3 | static void (*handler)(status_t, uint8_t*);
|
4 |
|
5 | static volatile uint8_t one_cnt = 0;
|
6 | static volatile uint8_t clk_cnt = 0;
|
7 | static volatile uint8_t data_cnt = 0;
|
8 | static volatile uint8_t row_cnt = 0;
|
9 | static volatile uint8_t lower_level = 0;
|
10 | static volatile uint8_t *data;
|
11 | static volatile uint8_t prev = 0;
|
12 | static volatile uint8_t checked = 1;
|
13 |
|
14 | error_t rfid_init(void (*_handler)(status_t, uint8_t*))
|
15 | {
|
16 | RFID_DDR = 0xFC;
|
17 | RFID_PORT = 0x07;
|
18 | RFID_INT_MSK = 0x01;
|
19 | handler = _handler;
|
20 | return SUCCESS;
|
21 | }
|
22 |
|
23 | error_t rfid_enable(void)
|
24 | {
|
25 | if(((RFID_INT_CR & 0x04) != 0) || ((RFID_PIN & 0x04) == 0))
|
26 | {
|
27 | return ERROR;
|
28 | }
|
29 | one_cnt = 0;
|
30 | clk_cnt = 0;
|
31 | data_cnt = 0;
|
32 | row_cnt = 0;
|
33 | lower_level = 0;
|
34 | prev = 0;
|
35 | checked = 1;
|
36 | RFID_INT_MSK = 0x01;
|
37 | RFID_INT_CR |= 0x04;
|
38 | RFID_PORT &= 0xFB;
|
39 | return SUCCESS;
|
40 | }
|
41 |
|
42 | void rfid_disable(void)
|
43 | {
|
44 | RFID_PORT |= 0x04;
|
45 | RFID_INT_CR &= 0xFB;
|
46 | }
|
47 |
|
48 | void inline __attribute__((always_inline)) use_data(void)
|
49 | {
|
50 | //parity
|
51 | if(checked != 1 && ((data_cnt & 0x03) == 0x00))
|
52 | {
|
53 | uint8_t val = data[row_cnt];
|
54 | if(((((val)^(val >> 1))^((val >> 2)^(val >>3)))&0x01) == lower_level)
|
55 | {
|
56 | data[row_cnt] &= 0x0F;
|
57 | row_cnt++;
|
58 | data[row_cnt] = 0;
|
59 | }
|
60 | else
|
61 | {
|
62 | handler(INVALID, (uint8_t*)data);
|
63 | one_cnt = 0;
|
64 | RFID_INT_MSK = 0x01;
|
65 | }
|
66 | //last parity
|
67 | if(data_cnt > 42)
|
68 | {
|
69 | val = 0;
|
70 | for(row_cnt = 0; row_cnt < 10; row_cnt++)
|
71 | val ^= data[row_cnt];
|
72 | if((lower_level == 0x00) && (((val ^ (data[10])) & 0x0F) == 0x00))
|
73 | {
|
74 | handler(VALID, (uint8_t*)(&data[2]));
|
75 | }
|
76 | else
|
77 | {
|
78 | handler(INVALID, (uint8_t*)data);
|
79 | }
|
80 | one_cnt = 0;
|
81 | RFID_INT_MSK = 0x01;
|
82 | }
|
83 | checked = 1;
|
84 | }
|
85 | else
|
86 | {
|
87 | data[row_cnt] = (data[row_cnt] << 1) | lower_level;
|
88 | //save data
|
89 | data_cnt++;
|
90 | checked = 0;
|
91 | }
|
92 | }
|
93 |
|
94 |
|
95 | ISR(RFID_INT_VECT, ISR_BLOCK){
|
96 | clk_cnt++;
|
97 | //Already had a one
|
98 | if(one_cnt != 0){
|
99 | //every 64th clk
|
100 | if((clk_cnt & 0x3F) == 0)
|
101 | {
|
102 | //second manchester bit
|
103 | if((clk_cnt & 0x40) == 0)
|
104 | {
|
105 | //toggle
|
106 | if(lower_level != (RFID_PIN & 0x01))
|
107 | {
|
108 | //need more ones
|
109 | if(one_cnt != 9)
|
110 | {
|
111 | //found another one
|
112 | if((RFID_PIN & 0x01) == 0x00)
|
113 | {
|
114 | one_cnt++;
|
115 | //last sync one?
|
116 | if(one_cnt == 9)
|
117 | {
|
118 | PORTL++;
|
119 | data_cnt = 0;
|
120 | data = malloc(11*sizeof(uint8_t));
|
121 | data[0] = 0;
|
122 | row_cnt = 0;
|
123 | data[0] = 0;
|
124 | checked = 1;
|
125 | }
|
126 | }
|
127 | //synchronisation lost
|
128 | else
|
129 | {
|
130 | one_cnt = 0;
|
131 | RFID_INT_MSK = 0x01;
|
132 | free((void*)data);
|
133 | }
|
134 | }
|
135 | else
|
136 | {
|
137 | use_data();
|
138 | }
|
139 | }
|
140 | }
|
141 | //first manchester bit
|
142 | else
|
143 | {
|
144 | lower_level = (RFID_PIN & 0x01);
|
145 | }
|
146 | }
|
147 | }
|
148 | else if((RFID_PIN & 0x01) == 0)
|
149 | {
|
150 | //first one. Needed to synchronize
|
151 | clk_cnt = 0x40;
|
152 | one_cnt = 1;
|
153 | lower_level = 0x01;
|
154 | //disable interrupt on out pin, synchronisation is done via clk
|
155 | RFID_INT_MSK = 0x02;
|
156 | }
|
157 | }
|