move librfid to new location in repository
[librfid] / rfid_asic_rc632_14443a.c
1 /* 
2  * Philips CL RC632 primitives for ISO 14443-A compliant PICC's
3  *
4  * (C) 2005 by Harald Welte <laforge@gnumonks.org>
5  *
6  */
7
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include <rfid/rfid.h>
13 #include <rfid/rfid_asic_rc632.h>
14 #include <rfid/rfid_layer2_iso14443a.h>
15
16 #include "rc632.h"
17
18 #include "cm5121_rfid.h"        /* FIXME: this needs to be modular */
19
20 static int
21 rc632_iso14443a_init(struct rfid_asic_handle *handle)
22 {
23         int ret;
24
25 #if 0
26         ret = rc632_power_up(handle);
27         if (ret < 0)
28                 return ret;
29
30         ret = rc632_turn_on_rf(handle);
31         if (ret < 0)
32                 return ret;
33 #endif
34
35         // FIXME: some fifo work (drain fifo?)
36         
37         /* flush fifo (our way) */
38         ret = rc632_reg_write(handle, RC632_REG_CONTROL, 0x01);
39
40         ret = rc632_reg_write(handle, RC632_REG_TX_CONTROL,
41                         (RC632_TXCTRL_TX1_RF_EN |
42                          RC632_TXCTRL_TX2_RF_EN |
43                          RC632_TXCTRL_TX2_INV |
44                          RC632_TXCTRL_FORCE_100_ASK |
45                          RC632_TXCTRL_MOD_SRC_INT));
46         if (ret < 0)
47                 return ret;
48
49         ret = rc632_reg_write(handle, RC632_REG_CW_CONDUCTANCE,
50                                 CM5121_CW_CONDUCTANCE);
51         if (ret < 0)
52                 return ret;
53
54         ret = rc632_reg_write(handle, RC632_REG_MOD_CONDUCTANCE,
55                                 CM5121_MOD_CONDUCTANCE);
56         if (ret < 0)
57                 return ret;
58
59         ret = rc632_reg_write(handle, RC632_REG_CODER_CONTROL,
60                                 (RC632_CDRCTRL_TXCD_14443A |
61                                  RC632_CDRCTRL_RATE_106K));
62         if (ret < 0)
63                 return ret;
64
65         ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH, 0x13);
66         if (ret < 0)
67                 return ret;
68
69         ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH_SOF, 0x3f);
70         if (ret < 0)
71                 return ret;
72
73         ret = rc632_reg_write(handle, RC632_REG_TYPE_B_FRAMING, 0x00);
74         if (ret < 0)
75                 return ret;
76
77         ret = rc632_reg_write(handle, RC632_REG_RX_CONTROL1,
78                               (RC632_RXCTRL1_GAIN_35DB |
79                                RC632_RXCTRL1_ISO14443 |
80                                RC632_RXCTRL1_SUBCP_8));
81         if (ret < 0)
82                 return ret;
83
84         ret = rc632_reg_write(handle, RC632_REG_DECODER_CONTROL,
85                               (RC632_DECCTRL_MANCHESTER |
86                                RC632_DECCTRL_RXFR_14443A));
87         if (ret < 0)
88                 return ret;
89
90         ret = rc632_reg_write(handle, RC632_REG_BIT_PHASE,
91                                 CM5121_14443A_BITPHASE);
92         if (ret < 0)
93                 return ret;
94
95         ret = rc632_reg_write(handle, RC632_REG_RX_THRESHOLD,
96                                 CM5121_14443A_THRESHOLD);
97         if (ret < 0)
98                 return ret;
99
100         ret = rc632_reg_write(handle, RC632_REG_BPSK_DEM_CONTROL, 0x00);
101         if (ret < 0)
102                 return ret;
103                               
104         ret = rc632_reg_write(handle, RC632_REG_RX_CONTROL2,
105                               (RC632_RXCTRL2_DECSRC_INT |
106                                RC632_RXCTRL2_CLK_Q));
107         if (ret < 0)
108                 return ret;
109
110         ret = rc632_reg_write(handle, RC632_REG_RX_WAIT, 0x03);
111         if (ret < 0)
112                 return ret;
113
114         ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY,
115                               (RC632_CR_PARITY_ENABLE |
116                                RC632_CR_PARITY_ODD));
117         if (ret < 0)
118                 return ret;
119
120         ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_LSB, 0x63);
121         if (ret < 0)
122                 return ret;
123
124         ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_MSB, 0x63);
125         if (ret < 0)
126                 return ret;
127
128         return 0;
129 }
130
131 static int
132 rc632_iso14443a_fini(struct iso14443a_handle *handle_14443)
133 {
134
135 #if 0
136         ret = rc632_turn_off_rf(handle);
137         if (ret < 0)
138                 return ret;
139 #endif
140
141
142         return 0;
143 }
144
145 #if 0
146 int
147 rc632_iso14443a_select(struct rc632_handle *handle,
148                 unsigned char *retptr,
149         )
150 {
151         int ret;
152         unsigned char tx_buf[7];
153         unsigned char rx_buf[64];
154         unsigned char rx_len = 1;
155
156         memset(rx_buf, 0, sizeof(rx_buf));
157
158         tx_buf[0] = arg_8;
159         tx_buf[1] = 0x70;
160         (u_int32_t *)tx_buf[2] = arg_4;
161         tx_buf[6] = arg4+4;
162
163         /* disable mifare cryto */
164         ret = rc632_clear_bit(handle, RC632_REG_CONTROL,
165                                 RC632_CONTROL_CRYPTO1_ON);
166         if (ret < 0)
167                 return ret;
168
169         ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY,
170                                 (RC632_CR_PARITY_ENABLE |
171                                  RC632_CR_PARITY_ODD |
172                                  RC632_CR_TX_CRC_ENABLE |
173                                  RC632_CR_RX_CRC_ENABLE));
174         if (ret < 0)
175                 return ret;
176
177         ret = rc632_transcieve(handle, tx_buf, sizeof(tx_buf),
178                                 rx_buf, &rx_len, 0x32, 0);
179
180         if (ret < 0 || rx_len != 1)
181                 return ret;
182
183         *retptr = rx_buf[0];
184
185         return 0;
186 }
187
188 /* issue a 14443-3 A PCD -> PICC command, such as REQA, WUPA */
189 int
190 rc632_iso14443a_req(sutruct rc632_handle *handle, unsigned char req,
191                     unsigned char *resp)
192 {
193         int ret;
194         unsigned char tx_buf[1];
195         unsigned char rx_buf[0x40];
196         unsigned char rx_len = 2;
197
198         memset(rx_buf, 0, sizeof(rx_buf));
199
200         tx_buf[0] = req;
201
202         /* transfer only 7 bits of last byte in frame */
203         ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING, 0x07);
204         if (ret < 0)
205                 return ret;
206
207         
208         ret = rc632_clear_bits(handle, RC632_REG_CONTROL,
209                                 RC632_CONTROL_CRYPTO1_ON);
210         if (ret < 0)
211                 return ret;
212
213         ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY,
214                                 (RC632_CR_PARITY_ENABLE |
215                                  RC632_CR_PARITY_ODD));
216         if (ret < 0)
217                 return ret;
218
219         ret = rc632_transcieve(handle, tx_buf, sizeof(tx_buf), rx_buf,
220                                 &rx_len, 0x32, 0);
221         if (ret < 0)
222                 return ret;
223
224         /* switch back to normal 8bit last byte */
225         ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING, 0x00);
226         if (ret < 0)
227                 return ret;
228
229         if ((rx_len != 2) || (rx_buf[1] != 0xf0))
230                 return -1;
231
232         resp[0] = rx_buf[0];
233         resp[1] = rx_buf[1];
234         
235         return 0;
236 }
237 #endif
238
239 /* issue a 14443-3 A PCD -> PICC command in a short frame, such as REQA, WUPA */
240 static int
241 rc632_iso14443a_transcieve_sf(struct rfid_asic_handle *handle,
242                                 unsigned char cmd,
243                                 struct iso14443a_atqa *atqa)
244 {
245         int ret;
246         unsigned char tx_buf[1];
247         unsigned char rx_len = 2;
248
249         memset(atqa, 0, sizeof(atqa));
250
251         tx_buf[0] = cmd;
252
253         /* transfer only 7 bits of last byte in frame */
254         ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING, 0x07);
255         if (ret < 0)
256                 return ret;
257
258         
259         ret = rc632_clear_bits(handle, RC632_REG_CONTROL,
260                                 RC632_CONTROL_CRYPTO1_ON);
261         if (ret < 0)
262                 return ret;
263
264         ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY,
265                                 (RC632_CR_PARITY_ENABLE |
266                                  RC632_CR_PARITY_ODD));
267         if (ret < 0)
268                 return ret;
269
270         ret = rc632_transcieve(handle, tx_buf, sizeof(tx_buf),
271                                 (unsigned char *)atqa, &rx_len, 0x32, 0);
272         if (ret < 0) {
273                 DEBUGP("error during rc632_transcieve()\n");
274                 return ret;
275         }
276
277         /* switch back to normal 8bit last byte */
278         ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING, 0x00);
279         if (ret < 0)
280                 return ret;
281
282         if (rx_len != 2) {
283                 DEBUGP("rx_len(%d) != 2\n", rx_len);
284                 return -1;
285         }
286
287         return 0;
288 }
289
290 /* trasncieve regular frame */
291 static int
292 rc632_iso14443a_transcieve(struct rfid_asic_handle *handle,
293                            const unsigned char *tx_buf, unsigned int tx_len,
294                            unsigned char *rx_buf, unsigned int *rx_len,
295                            unsigned int timeout, unsigned int flags)
296 {
297         int ret;
298         unsigned char rxl = *rx_len & 0xff;
299
300         memset(rx_buf, 0, *rx_len);
301
302         ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY,
303                                 (RC632_CR_PARITY_ENABLE |
304                                  RC632_CR_PARITY_ODD |
305                                  RC632_CR_TX_CRC_ENABLE |
306                                  RC632_CR_RX_CRC_ENABLE));
307         if (ret < 0)
308                 return ret;
309
310         ret = rc632_transcieve(handle, tx_buf, tx_len, rx_buf, &rxl, 0x32, 0);
311         *rx_len = rxl;
312         if (ret < 0)
313                 return ret;
314
315
316         return 0; 
317 }
318
319 /* transcieve anti collission bitframe */
320 static int
321 rc632_iso14443a_transcieve_acf(struct rfid_asic_handle *handle,
322                                 struct iso14443a_anticol_cmd *acf,
323                                 unsigned int *bit_of_col)
324 {
325         int ret;
326         unsigned char rx_buf[64];
327         unsigned char rx_len = sizeof(rx_buf);
328         unsigned char rx_align = 0, tx_last_bits, tx_bytes;
329         unsigned char boc;
330         unsigned char error_flag;
331         *bit_of_col = ISO14443A_BITOFCOL_NONE;
332         memset(rx_buf, 0, sizeof(rx_buf));
333
334         /* disable mifare cryto */
335         ret = rc632_clear_bits(handle, RC632_REG_CONTROL,
336                                 RC632_CONTROL_CRYPTO1_ON);
337         if (ret < 0)
338                 return ret;
339
340         /* disalbe CRC summing */
341         ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY,
342                                 (RC632_CR_PARITY_ENABLE |
343                                  RC632_CR_PARITY_ODD));
344         if (ret < 0)
345                 return ret;
346
347         tx_last_bits = acf->nvb & 0x0f; /* lower nibble indicates bits */
348         tx_bytes = acf->nvb >> 4;
349         if (tx_last_bits) {
350                 tx_bytes++;
351                 rx_align = (tx_last_bits+1) % 8;/* rx frame complements tx */
352         }
353
354         //rx_align = 8 - tx_last_bits;/* rx frame complements tx */
355
356         /* set RxAlign and TxLastBits*/
357         ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING,
358                                 (rx_align << 4) | (tx_last_bits));
359         if (ret < 0)
360                 return ret;
361
362         ret = rc632_transcieve(handle, (unsigned char *)acf, tx_bytes,
363                                 rx_buf, &rx_len, 0x32, 0);
364         if (ret < 0)
365                 return ret;
366
367         /* bitwise-OR the two halves of the split byte */
368         acf->uid_bits[tx_bytes-2] = (
369                   (acf->uid_bits[tx_bytes-2] & (0xff >> (8-tx_last_bits)))
370                 | rx_buf[0]);
371         /* copy the rest */
372         memcpy(&acf->uid_bits[tx_bytes+1-2], &rx_buf[1], rx_len-1);
373
374         /* determine whether there was a collission */
375         ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &error_flag);
376         if (ret < 0)
377                 return ret;
378
379         if (error_flag & RC632_ERR_FLAG_COL_ERR) {
380                 /* retrieve bit of collission */
381                 ret = rc632_reg_read(handle, RC632_REG_COLL_POS, &boc);
382                 if (ret < 0)
383                         return ret;
384
385                 /* bit of collission relative to start of part 1 of 
386                  * anticollision frame (!) */
387                 *bit_of_col = 2*8 + boc;
388         }
389
390         return 0;
391 }
392
393