1 /* OpenPCD specific RC632 transport layer
3 * (C) 2006 by Harald Welte <laforge@gnumonks.org>
5 * The OpenPCD is an Atmel AT91SAM7Sxx based USB RFID reader.
6 * It's CL RC632 is connected via SPI. OpenPCD has multiple firmware
7 * images. This driver is for the "main_dumbreader" firmware.
10 * - put hdl from static variable into asic transport or reader handle
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2
16 * as published by the Free Software Foundation
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #include <librfid/rfid.h>
38 #include <librfid/rfid_reader.h>
39 #include <librfid/rfid_asic.h>
40 #include <librfid/rfid_asic_rc632.h>
41 #include <librfid/rfid_reader_openpcd.h>
47 #define SENDBUF_LEN (256+4+10) /* 256bytes max FSD/FSC, plus 4 bytes header,
48 plus 10 bytes reserve */
49 #define RECVBUF_LEN SENDBUF_LEN
51 static char snd_buf[SENDBUF_LEN];
52 static char rcv_buf[RECVBUF_LEN];
53 static struct openpcd_hdr *snd_hdr;
54 static struct openpcd_hdr *rcv_hdr;
57 static struct usb_device *dev;
58 static struct usb_dev_handle *hdl;
60 static int openpcd_send_command(u_int8_t cmd, u_int8_t reg, u_int8_t val,
61 u_int16_t len, const unsigned char *data)
69 snd_hdr->flags = OPENPCD_FLAG_RESPOND;
71 memcpy(snd_hdr->data, data, len);
73 cur = sizeof(*snd_hdr) + len;
75 return usb_bulk_write(hdl, OPENPCD_OUT_EP, (char *)snd_hdr, cur, 0);
78 static int openpcd_recv_reply(void)
82 ret = usb_bulk_read(hdl, OPENPCD_IN_EP, rcv_buf, sizeof(rcv_buf), 1000);
87 static int openpcd_xcv(u_int8_t cmd, u_int8_t reg, u_int8_t val,
88 u_int16_t len, const unsigned char *data)
92 ret = openpcd_send_command(cmd, reg, val, len, data);
95 if (ret < sizeof(sizeof(struct openpcd_hdr)))
98 return openpcd_recv_reply();
106 static const struct usb_id opcd_usb_ids[] = {
107 { .vid = 0x2342, .pid = 0x0001 }, /* prototypes */
108 { .vid = 0x16c0, .pid = 0x076b }, /* first official device id */
111 static struct usb_device *find_opcd_device(void)
115 for (bus = usb_busses; bus; bus = bus->next) {
116 struct usb_device *dev;
117 for (dev = bus->devices; dev; dev = dev->next) {
119 for (i = 0; i < ARRAY_SIZE(opcd_usb_ids); i++) {
120 const struct usb_id *id = &opcd_usb_ids[i];
121 if (dev->descriptor.idVendor == id->vid &&
122 dev->descriptor.idProduct == id->pid &&
123 dev->descriptor.bNumConfigurations == 1 &&
124 dev->config->iConfiguration == 0)
132 static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
133 unsigned char reg, unsigned char value)
137 DEBUGP("reg=0x%02x, val=%02x: ", reg, value);
139 ret = openpcd_xcv(OPENPCD_CMD_WRITE_REG, reg, value, 0, NULL);
141 DEBUGPC("ERROR sending command\n");
148 static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
150 unsigned char *value)
154 DEBUGP("reg=0x%02x, ", reg);
156 ret = openpcd_xcv(OPENPCD_CMD_READ_REG, reg, 0, 0, NULL);
158 DEBUGPC("ERROR sending command\n");
162 if (ret < sizeof(struct openpcd_hdr)) {
163 DEBUGPC("ERROR: short packet\n");
167 *value = rcv_hdr->val;
168 DEBUGPC("val=%02x: OK\n", *value);
173 static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
174 unsigned char num_bytes,
181 ret = openpcd_xcv(OPENPCD_CMD_READ_FIFO, 0x00, num_bytes, 0, NULL);
183 DEBUGPC("ERROR sending command\n");
186 DEBUGPC("ret = %d\n", ret);
188 memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr));
189 DEBUGPC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr),
190 rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr)));
195 static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
197 const unsigned char *bytes,
202 DEBUGP("len=%u, data=%s\n", len, rfid_hexdump(bytes, len));
203 ret = openpcd_xcv(OPENPCD_CMD_WRITE_FIFO, 0, 0, len, bytes);
208 static int openpcd_transceive(struct rfid_reader_handle *rh,
209 enum rfid_frametype frametype,
210 const unsigned char *tx_data, unsigned int tx_len,
211 unsigned char *rx_data, unsigned int *rx_len,
212 u_int64_t timeout, unsigned int flags)
214 return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype,
220 static int openpcd_transceive_sf(struct rfid_reader_handle *rh,
221 unsigned char cmd, struct iso14443a_atqa *atqa)
223 return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah,
229 openpcd_transceive_acf(struct rfid_reader_handle *rh,
230 struct iso14443a_anticol_cmd *cmd,
231 unsigned int *bit_of_col)
233 return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah,
238 openpcd_14443a_init(struct rfid_reader_handle *rh)
240 return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
244 openpcd_14443a_set_speed(struct rfid_reader_handle *rh,
250 DEBUGP("setting rate: ");
252 case RFID_14443A_SPEED_106K:
256 case RFID_14443A_SPEED_212K:
260 case RFID_14443A_SPEED_424K:
264 case RFID_14443A_SPEED_848K:
272 return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
277 openpcd_14443b_init(struct rfid_reader_handle *rh)
279 return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
283 openpcd_15693_init(struct rfid_reader_handle *rh)
285 return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
289 openpcd_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
291 return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
295 openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
296 u_int32_t serno, u_int8_t block)
298 return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah,
302 struct rfid_asic_transport openpcd_ccid = {
303 .name = "OpenPCD Dumb USB Protocol",
306 .reg_write = &openpcd_reg_write,
307 .reg_read = &openpcd_reg_read,
308 .fifo_write = &openpcd_fifo_write,
309 .fifo_read = &openpcd_fifo_read,
314 static struct rfid_reader_handle *
315 openpcd_open(void *data)
317 struct rfid_reader_handle *rh;
318 struct rfid_asic_transport_handle *rath;
320 snd_hdr = (struct openpcd_hdr *)snd_buf;
321 rcv_hdr = (struct openpcd_hdr *)rcv_buf;
324 if (!usb_find_busses())
326 if (!usb_find_devices())
329 dev = find_opcd_device();
331 DEBUGP("No matching USB device found\n");
337 DEBUGP("Can't open USB device\n");
341 if (usb_claim_interface(hdl, 0) < 0) {
342 DEBUGP("Can't claim interface\n");
347 rh = malloc(sizeof(*rh));
350 memset(rh, 0, sizeof(*rh));
352 rath = malloc(sizeof(*rath));
355 memset(rath, 0, sizeof(*rath));
357 rath->rat = &openpcd_ccid;
358 rh->reader = &rfid_reader_openpcd;
360 rh->ah = rc632_open(rath);
364 DEBUGP("returning %p\n", rh);
376 openpcd_close(struct rfid_reader_handle *rh)
378 struct rfid_asic_transport_handle *rath = rh->ah->rath;
387 struct rfid_reader rfid_reader_openpcd = {
388 .name = "OpenPCD RFID Reader",
389 .id = RFID_READER_OPENPCD,
390 .open = &openpcd_open,
391 .close = &openpcd_close,
392 .transceive = &openpcd_transceive,
394 .init = &openpcd_14443a_init,
395 .transceive_sf = &openpcd_transceive_sf,
396 .transceive_acf = &openpcd_transceive_acf,
397 .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
398 RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
399 .set_speed = &openpcd_14443a_set_speed,
402 .init = &openpcd_14443b_init,
405 .setkey = &openpcd_mifare_setkey,
406 .auth = &openpcd_mifare_auth,