1
|
AT91SAM7 firmware for RC632 based reader.
|
2
|
|
3
|
0. Architecture
|
4
|
|
5
|
We have a Philips CL RC632 connected via SPI to the AT91SAM7.
|
6
|
The AT91SAM7 has a USB device port that is connected to a USB host.
|
7
|
|
8
|
|
9
|
1. USB Protocol / Interface
|
10
|
|
11
|
The AT91SAM7 has four USB endpoints, of which one is used for the control pipe,
|
12
|
and three are available for the user application.
|
13
|
|
14
|
Ideally, the device will provide two configurations, each with one interface
|
15
|
providing three endpoints: IN, OUT, INTERRUPT.
|
16
|
|
17
|
|
18
|
|
19
|
2. Interface configurations
|
20
|
|
21
|
2.1 Dumb interface
|
22
|
|
23
|
In this mode, the AT91SAM7 acts as a stupid interface between SPI and USB. It
|
24
|
provides access to the following primitives:
|
25
|
|
26
|
- Write Register
|
27
|
- Read Register
|
28
|
- Write FIFO
|
29
|
- Read FIFO
|
30
|
- Write Virtual FIFO
|
31
|
- Read Virtual FIFO
|
32
|
- Signal Interrupt
|
33
|
|
34
|
Since the FIFO of the RC632 are only 64byte deep, and the USB latency is too
|
35
|
big to facilitate FIFO refill while transmit, esp. at 424/848kbps RFID bitrate,
|
36
|
the AT91SAM7 has to provide bigger 'virtual' FIFO buffers to the USB host.
|
37
|
|
38
|
Thus, the USB host can fill a 1024byte-sized buffer using multiple USB packets,
|
39
|
and then ask the AT91SAM7 to write the first 64bytes to the FIFO. The RC632
|
40
|
will be programmed by the USB host to generate FIFO Level interrupts, to which
|
41
|
the AT91SAM7 will react automatically and re-fill the RC632 FIFO until all host
|
42
|
data has been sent to the RC632.
|
43
|
|
44
|
For the FIFO RX path, the opposite pattern is used: The AT91SAM7 has a 1024 byte
|
45
|
sized buffer, into which data can be read from the FIFO.
|
46
|
|
47
|
|
48
|
2.2 Intelligent interface
|
49
|
|
50
|
This interface will be optionally implemented at some later point. It provides
|
51
|
a 14443 protocol implementation inside the AT91SAM7.
|
52
|
|
53
|
|
54
|
2. Interface configurations
|
55
|
|
56
|
2.1 Dumb interface
|
57
|
|
58
|
EP0 control
|
59
|
EP1 bulk in
|
60
|
EP2 bulk out
|
61
|
EP3 interrupt
|
62
|
|
63
|
|
64
|
3. USB Protocol
|
65
|
|
66
|
3.1 dumb interface
|
67
|
|
68
|
struct usb_pcd_out_hdr {
|
69
|
u_int8_t cmd; /* command */
|
70
|
u_int8_t flags;
|
71
|
u_int8_t reg; /* register */
|
72
|
u_int8_t res;
|
73
|
u_int16_t len;
|
74
|
u_int8_t data[0];
|
75
|
} __attribute__ ((packed));
|
76
|
|
77
|
#define USB_PCD_CMD_WRITE_REG 0x01
|
78
|
#define USB_PCD_CMD_WRITE_FIFO 0x02
|
79
|
#define USB_PCD_CMD_WRITE_VFIFO 0x03
|
80
|
#define USB_PCD_CMD_READ_REG 0x11
|
81
|
#define USB_PCD_CMD_READ_FIFO 0x12
|
82
|
#define USB_PCD_CMD_WRITE_VFIFO 0x13
|
83
|
|
84
|
TBD
|
85
|
|
86
|
3.2 Intelligent interface
|
87
|
|
88
|
TBD
|
89
|
|
90
|
|
91
|
4. Firmware code flow architecture
|
92
|
|
93
|
The general idea is to make the firmware as interrupt-driven as possible.
|
94
|
Synchronous waiting for I/O (SPI, USB, ...) should be avoided, and restricted
|
95
|
to slow path operations (such as USB configuration) only.
|
96
|
|
97
|
Another design goal is to avoid using a dynamic memory allocator. Dynamic
|
98
|
memory allocation can be costly, leads to all sorts of fragmentation problems,
|
99
|
and will lead to the question of what to do in the case of an OOM situation.
|
100
|
|
101
|
Therefore, all data structures such as buffers will be pre-allocated and
|
102
|
declared as static variables.
|
103
|
|
104
|
4.x Data structures
|
105
|
|
106
|
Any action of the PCD is host-driven. Therefore, the UDC maintains a set
|
107
|
(2..32) request context structures. Upon completion of a USB OUT EP DMA,
|
108
|
the corresponding request context is passed on to other parts of the code.
|
109
|
Once the reply to that request has been processed, the context structure
|
110
|
is released.
|
111
|
|
112
|
The context structures are statically allocated, and a single u_int32_t
|
113
|
represents a bitmask of busy context structures. ffs() or a similar function
|
114
|
is used to search for a free buffer using which the UDC RX DMA can be refilled.
|
115
|
|
116
|
|
117
|
4.1 Examples
|
118
|
|
119
|
4.1.1 Performing SPI Register Read
|
120
|
|
121
|
[ UDC has configured RX FIFO for reception of usb packets ]
|
122
|
- UDC issues interrupt that USB endpoint receive has completed (FIFO)
|
123
|
- UDC driver defragments multiple packets into one transfer [optional]
|
124
|
- UDC driver submits another buffer for DMA reception
|
125
|
- UDC driver parses PCD ommand header and calls rc632 API
|
126
|
- RC632 driver configures SPI DMA transceive
|
127
|
- End of UDC interrupt
|
128
|
- idle loop
|
129
|
- SPI DMA completion interrupt happens for TX [do nothing]
|
130
|
- SPI DMA completion interrupt happens for RX
|
131
|
- callback into UDC driver using request state data
|
132
|
- UDC driver sends IN packet/transfer back to host
|
133
|
- End of SPI DMA interrupt
|
134
|
|
135
|
4.1.2 Performing SPI register read
|
136
|
|
137
|
much like register write, although the deferred completion could be skipped and
|
138
|
the usb transfer approved immediately after having submitted the SPI write
|
139
|
request to the RC632
|
140
|
|
141
|
5.1.3 Performing FIFO read
|
142
|
|
143
|
much like register read. Only difference is size and duration of transfer
|
144
|
|
145
|
5.1.4 Performing FIFO write
|
146
|
|
147
|
much like register write. Only difference is size and duration of transfer
|
148
|
|
149
|
5.1.5 Performing virtual FIFO read
|
150
|
|
151
|
much like a FIFO write, but make sure to enable FIFO watermark IRQ in RC632.
|
152
|
|
153
|
5.1.6 Performing virtual FIFO write
|
154
|
|
155
|
much like a FIFO read, but make sure to enable FIFO watermark IRQ in RC632.
|
156
|
Response to USB host is only sent after the full virtual FIFO has been emptied
|
157
|
into the physical FIFO.
|
158
|
|
159
|
5.1.6 Reporting RC632 interrupts
|
160
|
|
161
|
Upon reception of a RC632 interrupt, the primary and secondary status registers
|
162
|
are read from the IRQ handler, and an USB packet on the Interrupt In enddpoint is
|
163
|
created and submitted for transmission.
|
164
|
|
165
|
Some special handling (filtering) of FIFO over/underrun interrupts has to be
|
166
|
implemented for transparent handling of the virtual FIFO.
|
167
|
|
168
|
5.1.7 Reporting virtual FIFO interrupts
|
169
|
|
170
|
The virtual FIFO itself can generate over/underrun interrupts on the USB. They
|
171
|
are signalled pretty much like real RC632 interrupts.
|
172
|
|
173
|
|
174
|
6. Interrupt priorities
|
175
|
|
176
|
UDC DMA low priority, since we don't want to overflow with usb packets?
|
177
|
SPI DMA higher than UDC since it might complete while in UDC code?
|
178
|
RC632_IRQ high priority, since FIFO refill might be required
|
179
|
DEBUG_UART do we want it to use IRQ at all? if yes it should have highest prio.
|
180
|
|