From 9d0d7022e5f789000de7ac062e8da33a44d5b7f2 Mon Sep 17 00:00:00 2001
From: "(no author)" <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>
Date: Fri, 28 Jul 2006 11:03:33 +0000
Subject: - move all librfid-imported header files into include/librfid/ -
 import rfid_layer2_iso14443a.c from librfid - fix definition of 14443A ATQA
 to be __attribute__((packed)); - fix SPI DMA routines (hopefully!) -
 introduce new 'hexdump' function for creating hexdump debug output - move
 clearing SPI/UDP interrupt code to end of function to prevent re-entrance -
 declare spi_transceive() functions static - add hexdump debug output to DMA
 spi_transceive - remove tx_buf/rx_buf buffers and rather use
 spi_inbuf/spi_outbuf - add new "main_analog.c" program to use 'q' and 'w' to
 select analog output - increase interrupt stack to 1k - add _main_dbgu()
 function to allow 'main' programs to extend supported dbgu cmds - remove old
 DEBUG_TOGGLE_LED code from main.c - print ATQA that is received after
 successful REQA transceive in main_reqa.c - add OLIMEX make define so we can
 do "make TARGET=main_dumbreader OLIMEX=1"

git-svn-id: https://svn.openpcd.org:2342/trunk@51 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
---
 openpcd/firmware/Makefile                          |   8 +-
 openpcd/firmware/include/librfid/rfid.h            |  24 ++
 openpcd/firmware/include/librfid/rfid_layer2.h     |  76 +++++
 .../include/librfid/rfid_layer2_iso14443a.h        |  87 ++++++
 .../include/librfid/rfid_layer2_iso14443b.h        |  85 ++++++
 .../include/librfid/rfid_layer2_iso15693.h         |  55 ++++
 .../include/librfid/rfid_protocol_mifare_classic.h |  28 ++
 openpcd/firmware/include/rfid.h                    |  14 -
 openpcd/firmware/include/rfid_layer2_iso14443a.h   |  86 ------
 .../include/rfid_protocol_mifare_classic.h         |  28 --
 openpcd/firmware/src/dbgu.c                        |  27 +-
 openpcd/firmware/src/dbgu.h                        |   1 +
 openpcd/firmware/src/main.c                        |   8 -
 openpcd/firmware/src/main.h                        |   8 +
 openpcd/firmware/src/main_analog.c                 |  77 +++++
 openpcd/firmware/src/main_dumbreader.c             |   6 +
 openpcd/firmware/src/main_reqa.c                   |  13 +-
 openpcd/firmware/src/pcd_enumerate.c               |   4 +-
 openpcd/firmware/src/pio_irq.c                     |   1 +
 openpcd/firmware/src/rc632.c                       | 101 ++++---
 openpcd/firmware/src/rc632.h                       |   2 +-
 openpcd/firmware/src/rc632_highlevel.c             |  12 +-
 openpcd/firmware/src/rfid_layer2_iso14443a.c       | 316 +++++++++++++++++++++
 openpcd/firmware/src/start/Cstartup.S              |   2 +-
 24 files changed, 878 insertions(+), 191 deletions(-)
 create mode 100644 openpcd/firmware/include/librfid/rfid.h
 create mode 100644 openpcd/firmware/include/librfid/rfid_layer2.h
 create mode 100644 openpcd/firmware/include/librfid/rfid_layer2_iso14443a.h
 create mode 100644 openpcd/firmware/include/librfid/rfid_layer2_iso14443b.h
 create mode 100644 openpcd/firmware/include/librfid/rfid_layer2_iso15693.h
 create mode 100644 openpcd/firmware/include/librfid/rfid_protocol_mifare_classic.h
 delete mode 100644 openpcd/firmware/include/rfid.h
 delete mode 100644 openpcd/firmware/include/rfid_layer2_iso14443a.h
 delete mode 100644 openpcd/firmware/include/rfid_protocol_mifare_classic.h
 create mode 100644 openpcd/firmware/src/main.h
 create mode 100644 openpcd/firmware/src/main_analog.c
 create mode 100644 openpcd/firmware/src/rfid_layer2_iso14443a.c

diff --git a/openpcd/firmware/Makefile b/openpcd/firmware/Makefile
index 681e522..c9c793e 100644
--- a/openpcd/firmware/Makefile
+++ b/openpcd/firmware/Makefile
@@ -77,6 +77,8 @@ SRCARM  = lib/lib_AT91SAM7.c src/pcd_enumerate.c src/fifo.c src/dbgu.c \
 	  src/trigger.c src/main.c src/syscalls.c \
 	  src/$(TARGET).c src/start/Cstartup_SAM7.c 
 
+SRCARM += src/rfid_layer2_iso14443a.c
+
 # List C++ source files here.
 # use file-extension cpp for C++-files (use extension .cpp)
 CPPSRC = 
@@ -141,8 +143,10 @@ AT91LIBNOWARN = yes
 CSTANDARD = -std=gnu99
 
 # Place -D or -U options for C here
-CDEFS =  -D$(RUN_MODE) -D__MS_types__ -DDEBUG 
-#CDEFS += -DOLIMEX
+CDEFS =  -D$(RUN_MODE) -D__MS_types__ -D__LIBRFID__ -DDEBUG 
+ifdef OLIMEX
+CDEFS += -DOLIMEX
+endif
 
 # Place -I options here
 CINCS = -Iinclude -Isrc
diff --git a/openpcd/firmware/include/librfid/rfid.h b/openpcd/firmware/include/librfid/rfid.h
new file mode 100644
index 0000000..eb96378
--- /dev/null
+++ b/openpcd/firmware/include/librfid/rfid.h
@@ -0,0 +1,24 @@
+#ifndef _RFID_H
+#define _RFID_H
+
+#include "dbgu.h"
+
+#define rfid_hexdump hexdump
+
+enum rfid_frametype {
+	RFID_14443A_FRAME_REGULAR,
+	RFID_14443B_FRAME_REGULAR,
+	RFID_MIFARE_FRAME,
+};
+
+struct rfid_asic_handle {
+};
+
+struct rfid_asic {
+};
+
+#define RAH NULL
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#endif
diff --git a/openpcd/firmware/include/librfid/rfid_layer2.h b/openpcd/firmware/include/librfid/rfid_layer2.h
new file mode 100644
index 0000000..3dd54a2
--- /dev/null
+++ b/openpcd/firmware/include/librfid/rfid_layer2.h
@@ -0,0 +1,76 @@
+#ifndef _RFID_LAYER2_H
+#define _RFID_LAYER2_H
+
+#include <sys/types.h>
+#include <librfid/rfid.h>
+
+struct rfid_layer2_handle;
+struct rfid_reader_handle;
+
+enum rfid_layer2_id {
+	RFID_LAYER2_NONE,
+	RFID_LAYER2_ISO14443A,
+	RFID_LAYER2_ISO14443B,
+	RFID_LAYER2_ISO15693,
+};
+
+struct rfid_layer2_handle *rfid_layer2_init(struct rfid_reader_handle *rh,
+					    unsigned int id);
+int rfid_layer2_open(struct rfid_layer2_handle *l2h);
+int rfid_layer2_transceive(struct rfid_layer2_handle *l2h,
+			   enum rfid_frametype frametype,
+			   const unsigned char *tx_buf, unsigned int tx_len,
+			   unsigned char *rx_buf, unsigned int *rx_len,
+			   u_int64_t timeout, unsigned int flags);
+int rfid_layer2_close(struct rfid_layer2_handle *l2h);
+int rfid_layer2_fini(struct rfid_layer2_handle *l2h);
+int rfid_layer2_getopt(struct rfid_layer2_handle *ph, int optname,
+			void *optval, unsigned int *optlen);
+int rfid_layer2_setopt(struct rfid_layer2_handle *ph, int optname,
+			const void *optval, unsigned int optlen);
+
+#ifdef __LIBRFID__
+
+#include <librfid/rfid_layer2_iso14443a.h>
+#include <librfid/rfid_layer2_iso14443b.h>
+#include <librfid/rfid_layer2_iso15693.h>
+
+struct rfid_layer2 {
+	unsigned int id;
+	char *name;
+
+	struct {
+		struct rfid_layer2_handle *(*init)(struct rfid_reader_handle *h);
+		int (*open)(struct rfid_layer2_handle *h);
+		int (*transceive)(struct rfid_layer2_handle *h,
+				  enum rfid_frametype frametype,
+				  const unsigned char *tx_buf, 
+				  unsigned int tx_len, unsigned char *rx_buf, 
+				  unsigned int *rx_len, u_int64_t timeout,
+				  unsigned int flags);
+		int (*close)(struct rfid_layer2_handle *h);
+		int (*fini)(struct rfid_layer2_handle *h);
+		int (*getopt)(struct rfid_layer2_handle *h,
+			      int optname, void *optval, unsigned int *optlen);
+		int (*setopt)(struct rfid_layer2_handle *h,
+			      int optname, const void *optval,
+			      unsigned int optlen);
+	} fn;
+	struct rfid_layer2 *next;
+};
+
+struct rfid_layer2_handle {
+	struct rfid_reader_handle *rh;
+	unsigned char uid[10];	/* triple size 14443a id is 10 bytes */
+	unsigned int uid_len;
+	union {
+		struct iso14443a_handle iso14443a;
+		struct iso14443b_handle iso14443b;
+		struct iso15693_handle iso15693;
+	} priv;
+	struct rfid_layer2 *l2;
+};
+
+#endif /* __LIBRFID__ */
+
+#endif
diff --git a/openpcd/firmware/include/librfid/rfid_layer2_iso14443a.h b/openpcd/firmware/include/librfid/rfid_layer2_iso14443a.h
new file mode 100644
index 0000000..e1ecd36
--- /dev/null
+++ b/openpcd/firmware/include/librfid/rfid_layer2_iso14443a.h
@@ -0,0 +1,87 @@
+#ifndef _RFID_ISO14443A_H
+#define _RFID_ISO14443A_H
+
+
+enum rfid_14443a_opt {
+	RFID_OPT_14443A_SPEED_RX	= 0x00000001,
+	RFID_OPT_14443A_SPEED_TX	= 0x00000002,
+};
+
+enum rfid_14443_opt_speed {
+	RFID_14443A_SPEED_106K	= 0x01,
+	RFID_14443A_SPEED_212K	= 0x02,
+	RFID_14443A_SPEED_424K  = 0x04,
+	RFID_14443A_SPEED_848K  = 0x08,
+};
+
+#include <sys/types.h>
+
+/* protocol definitions */
+
+/* ISO 14443-3, Chapter 6.3.1 */
+enum iso14443a_sf_cmd {
+	ISO14443A_SF_CMD_REQA		= 0x26,
+	ISO14443A_SF_CMD_WUPA		= 0x52,
+	ISO14443A_SF_CMD_OPT_TIMESLOT	= 0x35,		/* Annex C */
+	/* 40 to 4f and 78 to 7f: proprietary */
+};
+
+struct iso14443a_atqa {
+	u_int8_t bf_anticol:5,
+		 rfu1:1,
+		 uid_size:2;
+	u_int8_t proprietary:4,
+		 rfu2:4;
+} __attribute__ ((packed));
+
+#define ISO14443A_HLTA		0x5000
+
+/* ISO 14443-3, Chapter 6.3.2 */
+struct iso14443a_anticol_cmd {
+	unsigned char		sel_code;
+	unsigned char		nvb;
+	unsigned char		uid_bits[5];
+} __attribute__ ((packed));
+
+enum iso14443a_anticol_sel_code {
+	ISO14443A_AC_SEL_CODE_CL1	= 0x93,
+	ISO14443A_AC_SEL_CODE_CL2	= 0x95,
+	ISO14443A_AC_SEL_CODE_CL3	= 0x97,
+};
+
+#define ISO14443A_BITOFCOL_NONE         0xffffffff
+
+struct iso14443a_handle {
+	unsigned int state;
+	unsigned int level;
+	unsigned int tcl_capable;
+};
+
+enum iso14443a_level {
+	ISO14443A_LEVEL_NONE,
+	ISO14443A_LEVEL_CL1,
+	ISO14443A_LEVEL_CL2,
+	ISO14443A_LEVEL_CL3,
+};
+
+enum iso14443a_state {
+	ISO14443A_STATE_ERROR,
+	ISO14443A_STATE_NONE,
+	ISO14443A_STATE_REQA_SENT,
+	ISO14443A_STATE_ATQA_RCVD,
+	ISO14443A_STATE_NO_BITFRAME_ANTICOL,
+	ISO14443A_STATE_ANTICOL_RUNNING,
+	ISO14443A_STATE_SELECTED,
+};
+
+/* Section 6.1.2 values in usec, rounded up to next usec */
+#define ISO14443A_FDT_ANTICOL_LAST1	92	/* 1236 / fc = 91.15 usec */
+#define ISO14443A_FDT_ANTICOL_LAST0	87	/* 1172 / fc = 86.43 usec */
+
+#define ISO14443_CARRIER_FREQ	13560000
+#define ISO14443A_FDT_OTHER_LAST1(n)	(((n*128+84)*1000000)/ISO14443_CARRIER_FREQ)
+
+#include <librfid/rfid_layer2.h>
+struct rfid_layer2 rfid_layer2_iso14443a;
+
+#endif /* _ISO14443A_H */
diff --git a/openpcd/firmware/include/librfid/rfid_layer2_iso14443b.h b/openpcd/firmware/include/librfid/rfid_layer2_iso14443b.h
new file mode 100644
index 0000000..5d6d979
--- /dev/null
+++ b/openpcd/firmware/include/librfid/rfid_layer2_iso14443b.h
@@ -0,0 +1,85 @@
+#ifndef _RFID_LAYER2_ISO14443B_H
+#define _RFID_LAYER2_ISO14443B_H
+
+#ifdef __LIBRFID__
+
+struct iso14443b_atqb {
+	unsigned char fifty;
+	unsigned char pupi[4];
+	unsigned char app_data[4];
+	struct {
+		unsigned char bit_rate_capability;
+		unsigned char protocol_type:4,
+			      max_frame_size:4;
+		unsigned char fo:2,
+			      adc:2,
+			      fwi:4;
+	} protocol_info;
+};
+
+struct iso14443b_attrib_hdr {
+	unsigned char one_d;
+	unsigned char identifier[4];
+	struct {
+		unsigned char rfu:2,
+			      sof:1,
+			      eof:1,
+			      min_tr1:2,
+			      min_tr0:2;
+	} param1;
+	struct {
+		unsigned char fsdi:4,
+			      spd_out:2,
+			      spd_in:2;
+	} param2;
+	struct {
+		unsigned char protocol_type:4,
+			      rfu:4;
+	} param3;
+	struct {
+		unsigned char cid:4,
+			      rfu:4;
+	} param4;
+};
+
+struct iso14443b_handle {
+	unsigned int tcl_capable; /* do we support T=CL */
+
+	unsigned int cid;	/* Card ID */
+
+	unsigned int fsc;	/* max. frame size card */
+	unsigned int fsd;	/* max. frame size reader */
+
+	unsigned int fwt;	/* frame waiting time (in usec) */
+
+	unsigned int mbl;	/* maximum buffer length */
+
+	unsigned int tr0;	/* pcd-eof to picc-subcarrier-on */
+	unsigned int tr1;	/* picc-subcarrier-on to picc-sof */
+
+	unsigned int flags;
+	unsigned int state;
+};
+
+enum {
+	ISO14443B_CID_SUPPORTED = 0x01,
+	ISO14443B_NAD_SUPPORTED = 0x02,
+};
+
+enum {
+	ISO14443B_STATE_ERROR,
+	ISO14443B_STATE_NONE,
+	ISO14443B_STATE_REQB_SENT,
+	ISO14443B_STATE_ATQB_RCVD,
+	ISO14443B_STATE_ATTRIB_SENT,
+	ISO14443B_STATE_SELECTED,
+	ISO14443B_STATE_HLTB_SENT,
+	ISO14443B_STATE_HALTED,
+};
+
+#include <librfid/rfid_layer2.h>
+struct rfid_layer2 rfid_layer2_iso14443b;
+
+#endif /* __LIBRFID__ */
+
+#endif
diff --git a/openpcd/firmware/include/librfid/rfid_layer2_iso15693.h b/openpcd/firmware/include/librfid/rfid_layer2_iso15693.h
new file mode 100644
index 0000000..d91b4ec
--- /dev/null
+++ b/openpcd/firmware/include/librfid/rfid_layer2_iso15693.h
@@ -0,0 +1,55 @@
+#ifndef _RFID_ISO15693_H
+#define _RFID_ISO15693_H
+
+#include <sys/types.h>
+
+/*
+07h = TagIt
+04h = I.CODE
+05h = Infineon
+02h = ST
+*/
+
+/* protocol definitions */
+
+struct iso15693_handle;
+
+struct iso15693_transport {
+	unsigned char	*name;
+
+	struct {
+		int (*init)(struct iso15693_handle *handle);
+		int (*fini)(struct iso15693_handle *handle);
+
+#if 0
+		int (*transceive_sf)(struct iso14443a_handle *handle,
+				     unsigned char cmd,
+				     struct iso14443a_atqa *atqa);
+		int (*transceive_acf)(struct iso14443a_handle *handle,
+				      struct iso14443a_anticol_cmd *acf,
+				      unsigned int *bit_of_col);
+#endif
+		int (*transceive)(struct iso15693_handle *handle,
+				  const unsigned char *tx_buf,
+				  unsigned int tx_len,
+				  unsigned char *rx_buf,
+				  unsigned int *rx_len);
+	} fn;
+
+	union {
+	} priv;
+};
+
+struct iso15693_handle {
+	unsigned int state;
+};
+
+enum iso15693_state {
+	ISO15693_STATE_ERROR,
+	ISO15693_STATE_NONE,
+};
+
+#include <librfid/rfid_layer2.h>
+extern struct rfid_layer2 rfid_layer2_iso15693;
+
+#endif /* _ISO15693_H */
diff --git a/openpcd/firmware/include/librfid/rfid_protocol_mifare_classic.h b/openpcd/firmware/include/librfid/rfid_protocol_mifare_classic.h
new file mode 100644
index 0000000..e6b2400
--- /dev/null
+++ b/openpcd/firmware/include/librfid/rfid_protocol_mifare_classic.h
@@ -0,0 +1,28 @@
+#ifndef _MIFARE_CLASSIC_H
+
+#define MIFARE_CL_KEYA_DEFAULT	"\xa0\xa1\xa2\xa3\xa4\xa5"
+#define MIFARE_CL_KEYB_DEFAULT	"\xb0\xb1\xb2\xb3\xb4\xb5"
+
+#define MIFARE_CL_KEYA_DEFAULT_INFINEON	"\xff\xff\xff\xff\xff\xff"
+#define MIFARE_CL_KEYB_DEFAULT_INFINEON MIFARE_CL_KEYA_DEFAULT_INFINEON
+
+#define MIFARE_CL_PAGE_MAX	0xff
+
+#define RFID_CMD_MIFARE_AUTH1A	0x60
+#define RFID_CMD_MIFARE_AUTH1B	0x61
+
+#ifdef __LIBRFID__
+
+extern struct rfid_protocol rfid_protocol_mfcl;
+
+
+#define MIFARE_CL_CMD_WRITE16	0xA0
+#define MIFARE_CL_CMD_READ	0x30
+
+#define MIFARE_CL_RESP_ACK	0x0a
+#define MIFARE_CL_RESP_NAK	0x00
+
+
+#endif /* __LIBRFID__ */
+
+#endif /* _MIFARE_CLASSIC_H */
diff --git a/openpcd/firmware/include/rfid.h b/openpcd/firmware/include/rfid.h
deleted file mode 100644
index 5684884..0000000
--- a/openpcd/firmware/include/rfid.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _RFID_H
-#define _RFID_H
-
-struct rfid_asic_handle {
-};
-
-struct rfid_asic {
-};
-
-#define RAH NULL
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#endif
diff --git a/openpcd/firmware/include/rfid_layer2_iso14443a.h b/openpcd/firmware/include/rfid_layer2_iso14443a.h
deleted file mode 100644
index 936d902..0000000
--- a/openpcd/firmware/include/rfid_layer2_iso14443a.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef _RFID_ISO14443A_H
-#define _RFID_ISO14443A_H
-
-enum rfid_frametype {
-	RFID_14443A_FRAME_REGULAR,
-	RFID_14443B_FRAME_REGULAR,
-	RFID_MIFARE_FRAME,
-};
-
-
-enum rfid_14443a_opt {
-	RFID_OPT_14443A_SPEED_RX	= 0x00000001,
-	RFID_OPT_14443A_SPEED_TX	= 0x00000002,
-};
-
-enum rfid_14443_opt_speed {
-	RFID_14443A_SPEED_106K	= 0x01,
-	RFID_14443A_SPEED_212K	= 0x02,
-	RFID_14443A_SPEED_424K  = 0x04,
-	RFID_14443A_SPEED_848K  = 0x08,
-};
-
-#include <sys/types.h>
-
-/* protocol definitions */
-
-/* ISO 14443-3, Chapter 6.3.1 */
-enum iso14443a_sf_cmd {
-	ISO14443A_SF_CMD_REQA		= 0x26,
-	ISO14443A_SF_CMD_WUPA		= 0x52,
-	ISO14443A_SF_CMD_OPT_TIMESLOT	= 0x35,		/* Annex C */
-	/* 40 to 4f and 78 to 7f: proprietary */
-};
-
-struct iso14443a_atqa {
-	u_int8_t bf_anticol:5,
-		 rfu1:1,
-		 uid_size:2;
-	u_int8_t proprietary:4,
-		 rfu2:4;
-};
-
-#define ISO14443A_HLTA		0x5000
-
-/* ISO 14443-3, Chapter 6.3.2 */
-struct iso14443a_anticol_cmd {
-	unsigned char		sel_code;
-	unsigned char		nvb;
-	unsigned char		uid_bits[5];
-};
-
-enum iso14443a_anticol_sel_code {
-	ISO14443A_AC_SEL_CODE_CL1	= 0x93,
-	ISO14443A_AC_SEL_CODE_CL2	= 0x95,
-	ISO14443A_AC_SEL_CODE_CL3	= 0x97,
-};
-
-#define ISO14443A_BITOFCOL_NONE         0xffffffff
-
-
-enum iso14443a_level {
-	ISO14443A_LEVEL_NONE,
-	ISO14443A_LEVEL_CL1,
-	ISO14443A_LEVEL_CL2,
-	ISO14443A_LEVEL_CL3,
-};
-
-enum iso14443a_state {
-	ISO14443A_STATE_ERROR,
-	ISO14443A_STATE_NONE,
-	ISO14443A_STATE_REQA_SENT,
-	ISO14443A_STATE_ATQA_RCVD,
-	ISO14443A_STATE_NO_BITFRAME_ANTICOL,
-	ISO14443A_STATE_ANTICOL_RUNNING,
-	ISO14443A_STATE_SELECTED,
-};
-
-/* Section 6.1.2 values in usec, rounded up to next usec */
-#define ISO14443A_FDT_ANTICOL_LAST1	92	/* 1236 / fc = 91.15 usec */
-#define ISO14443A_FDT_ANTICOL_LAST0	87	/* 1172 / fc = 86.43 usec */
-
-#define ISO14443_CARRIER_FREQ	13560000
-#define ISO14443A_FDT_OTHER_LAST1(n)	(((n*128+84)*1000000)/ISO14443_CARRIER_FREQ)
-
-
-#endif /* _ISO14443A_H */
diff --git a/openpcd/firmware/include/rfid_protocol_mifare_classic.h b/openpcd/firmware/include/rfid_protocol_mifare_classic.h
deleted file mode 100644
index e6b2400..0000000
--- a/openpcd/firmware/include/rfid_protocol_mifare_classic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _MIFARE_CLASSIC_H
-
-#define MIFARE_CL_KEYA_DEFAULT	"\xa0\xa1\xa2\xa3\xa4\xa5"
-#define MIFARE_CL_KEYB_DEFAULT	"\xb0\xb1\xb2\xb3\xb4\xb5"
-
-#define MIFARE_CL_KEYA_DEFAULT_INFINEON	"\xff\xff\xff\xff\xff\xff"
-#define MIFARE_CL_KEYB_DEFAULT_INFINEON MIFARE_CL_KEYA_DEFAULT_INFINEON
-
-#define MIFARE_CL_PAGE_MAX	0xff
-
-#define RFID_CMD_MIFARE_AUTH1A	0x60
-#define RFID_CMD_MIFARE_AUTH1B	0x61
-
-#ifdef __LIBRFID__
-
-extern struct rfid_protocol rfid_protocol_mfcl;
-
-
-#define MIFARE_CL_CMD_WRITE16	0xA0
-#define MIFARE_CL_CMD_READ	0x30
-
-#define MIFARE_CL_RESP_ACK	0x0a
-#define MIFARE_CL_RESP_NAK	0x00
-
-
-#endif /* __LIBRFID__ */
-
-#endif /* _MIFARE_CLASSIC_H */
diff --git a/openpcd/firmware/src/dbgu.c b/openpcd/firmware/src/dbgu.c
index 1b0ede0..a754f9e 100644
--- a/openpcd/firmware/src/dbgu.c
+++ b/openpcd/firmware/src/dbgu.c
@@ -15,10 +15,30 @@
 
 // Include Standard files
 #include <board.h>
+#include <interrupt_utils.h>
 #include "dbgu.h"
 #include "rc632.h"
 #include "openpcd.h"
 #include "led.h"
+#include "main.h"
+
+const char *
+hexdump(const void *data, unsigned int len)
+{
+	static char string[1024];
+	unsigned char *d = (unsigned char *) data;
+	unsigned int i, left;
+
+	string[0] = '\0';
+	left = sizeof(string);
+	for (i = 0; len--; i += 3) {
+		if (i >= sizeof(string) -4)
+			break;
+		snprintf(string+i, 4, " %02x", *d++);
+	}
+	return string;
+}
+
 #define USART_SYS_LEVEL 4
 /*---------------------------- Global Variable ------------------------------*/
 //*--------------------------1--------------------------------------------------
@@ -53,7 +73,7 @@ static void Send_reset(void)
 //*----------------------------------------------------------------------------
 static void DBGU_irq_handler(void)
 {
-	char value;
+	static char value;
 
 	AT91F_DBGU_Get(&value);
 	switch (value) {
@@ -96,8 +116,11 @@ static void DBGU_irq_handler(void)
 	case '7':
 		rc632_dump();
 		break;
+	case '8':
+		break;
 	default:
-		AT91F_DBGU_Printk("\n\r");
+		if (_main_dbgu(value) < 0)
+			AT91F_DBGU_Printk("\n\r");
 		break;
 	}			// end switch
 }
diff --git a/openpcd/firmware/src/dbgu.h b/openpcd/firmware/src/dbgu.h
index 383e26d..8dd34be 100644
--- a/openpcd/firmware/src/dbgu.h
+++ b/openpcd/firmware/src/dbgu.h
@@ -21,6 +21,7 @@
 
 //* ----------------------- External Function Prototype -----------------------
 
+extern const char *hexdump(const void *data, unsigned int len);
 void AT91F_DBGU_Init(void);
 void AT91F_DBGU_Printk(	char *buffer);
 void AT91F_DBGU_Frame(	char *buffer);
diff --git a/openpcd/firmware/src/main.c b/openpcd/firmware/src/main.c
index 384bad9..182964f 100644
--- a/openpcd/firmware/src/main.c
+++ b/openpcd/firmware/src/main.c
@@ -5,8 +5,6 @@
 #include "led.h"
 #include "openpcd.h"
 
-#define DEBUG_TOGGLE_LED
-
 int main(void)
 {
 	/* initialize LED and debug unit */
@@ -30,12 +28,6 @@ int main(void)
 
 	DEBUGPCRF("entering main (idle) loop");
 	while (1) {
-#ifdef DEBUG_TOGGLE_LED
-		/* toggle LEDs */
-		led_toggle(1);
-		led_toggle(2);
-#endif
-
 		/* Call application specific main idle function */
 		_main_func();
 	}
diff --git a/openpcd/firmware/src/main.h b/openpcd/firmware/src/main.h
new file mode 100644
index 0000000..1adc8f6
--- /dev/null
+++ b/openpcd/firmware/src/main.h
@@ -0,0 +1,8 @@
+#ifndef _MAIN_H
+#define _MAIN_H
+
+extern void _init_func(void);
+extern int _main_dbgu(char key);
+extern void _main_func(void);
+
+#endif
diff --git a/openpcd/firmware/src/main_analog.c b/openpcd/firmware/src/main_analog.c
new file mode 100644
index 0000000..676e9fc
--- /dev/null
+++ b/openpcd/firmware/src/main_analog.c
@@ -0,0 +1,77 @@
+/* main_reqa - OpenPCD firmware for generating an endless loop of
+ * ISO 14443-A REQA packets.
+ *
+ * If a response is received from the PICC, LED1 (Red) will be switched
+ * on.  If no valid response has been received within the timeout of the
+ * receiver, LED1 (Red) will be switched off.
+ *
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <librfid/rfid_layer2_iso14443a.h>
+#include "rc632.h"
+#include "dbgu.h"
+#include "led.h"
+#include "trigger.h"
+#include "pcd_enumerate.h"
+#include "main.h"
+
+void _init_func(void)
+{
+	//udp_init();
+	trigger_init();
+	rc632_init();
+	DEBUGPCRF("turning on RF");
+	rc632_turn_on_rf(RAH);
+	/* FIXME: do we need this? */
+	DEBUGPCRF("initializing 14443A operation");
+	rc632_iso14443a_init(RAH);
+	/* Switch to 848kBps (1subcp / bit) */
+	rc632_clear_bits(RAH, RC632_REG_RX_CONTROL1, RC632_RXCTRL1_SUBCP_MASK);
+}
+
+int _main_dbgu(char key)
+{
+	static char ana_out_sel;
+	int ret = -EINVAL;
+
+	switch (key) {
+	case 'q':
+		ana_out_sel--;
+		ret = 1;
+		break;
+	case 'w':
+		ana_out_sel++;
+		ret = 1;
+		break;
+	}
+
+	if (ret == 1) {
+		ana_out_sel &= 0x0f;
+		DEBUGPCR("switching to analog output mode 0x%x\n", ana_out_sel);
+		rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, ana_out_sel);
+	}
+
+	return ret;
+}
+
+void _main_func(void)
+{
+#if 1
+	struct iso14443a_atqa atqa;
+
+	memset(&atqa, 0, sizeof(atqa));
+
+	trigger_pulse();
+
+	if (rc632_iso14443a_transceive_sf(RAH, ISO14443A_SF_CMD_WUPA, &atqa) < 0) {
+		DEBUGPCRF("error during transceive_sf");
+		led_switch(1, 0);
+	} else {
+		DEBUGPCRF("received ATQA: %s\n", hexdump((char *)&atqa, sizeof(atqa)));
+		led_switch(1, 1);
+	}
+#endif	
+	led_toggle(2);
+}
diff --git a/openpcd/firmware/src/main_dumbreader.c b/openpcd/firmware/src/main_dumbreader.c
index c165182..e59b4b6 100644
--- a/openpcd/firmware/src/main_dumbreader.c
+++ b/openpcd/firmware/src/main_dumbreader.c
@@ -7,6 +7,7 @@
 #include "led.h"
 #include "pcd_enumerate.h"
 #include "openpcd.h"
+#include "main.h"
 
 static int usb_in(struct req_ctx *rctx)
 {
@@ -80,6 +81,11 @@ void _init_func(void)
 	udp_init();
 }
 
+int _main_dbgu(char key)
+{
+	return -EINVAL;
+}
+
 void _main_func(void)
 {
 	struct req_ctx *rctx;
diff --git a/openpcd/firmware/src/main_reqa.c b/openpcd/firmware/src/main_reqa.c
index 1c375c3..cd1f162 100644
--- a/openpcd/firmware/src/main_reqa.c
+++ b/openpcd/firmware/src/main_reqa.c
@@ -7,13 +7,14 @@
  *
  */
 
+#include <errno.h>
+#include <string.h>
+#include <librfid/rfid_layer2_iso14443a.h>
 #include "rc632.h"
 #include "dbgu.h"
 #include "led.h"
 #include "trigger.h"
 #include "pcd_enumerate.h"
-#include <rfid_layer2_iso14443a.h>
-#include <string.h>
 
 void _init_func(void)
 {
@@ -26,6 +27,10 @@ void _init_func(void)
 	rc632_iso14443a_init(RAH);
 }
 
+int _main_dbgu(char key)
+{
+	return -EINVAL;
+}
 
 void _main_func(void)
 {
@@ -38,8 +43,10 @@ void _main_func(void)
 	if (rc632_iso14443a_transceive_sf(RAH, ISO14443A_SF_CMD_WUPA, &atqa) < 0) {
 		DEBUGPCRF("error during transceive_sf");
 		led_switch(1, 0);
-	} else
+	} else {
+		DEBUGPCRF("received ATQA: %s\n", hexdump((char *)&atqa, sizeof(atqa)));
 		led_switch(1, 1);
+	}
 	
 	led_toggle(2);
 }
diff --git a/openpcd/firmware/src/pcd_enumerate.c b/openpcd/firmware/src/pcd_enumerate.c
index 372ffa9..4dc096f 100644
--- a/openpcd/firmware/src/pcd_enumerate.c
+++ b/openpcd/firmware/src/pcd_enumerate.c
@@ -22,6 +22,7 @@
 #include <usb_ch9.h>
 #include <lib_AT91SAM7.h>
 #include <openpcd.h>
+#include <interrupt_utils.h>
 
 #include "pcd_enumerate.h"
 #include "openpcd.h"
@@ -137,8 +138,6 @@ static void udp_irq(void)
 
 	DEBUGP("udp_irq(imr=0x%04x, isr=0x%04x): ", pUDP->UDP_IMR, isr);
 
-	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_UDP);
-
 	if (isr & AT91C_UDP_ENDBUSRES) {
 		DEBUGP("ENDBUSRES ");
 		pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
@@ -229,6 +228,7 @@ static void udp_irq(void)
 	}
 
 	DEBUGP("END\r\n");
+	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_UDP);
 }
 
 /* Open USB Device Port  */
diff --git a/openpcd/firmware/src/pio_irq.c b/openpcd/firmware/src/pio_irq.c
index 3f73001..3e65561 100644
--- a/openpcd/firmware/src/pio_irq.c
+++ b/openpcd/firmware/src/pio_irq.c
@@ -1,4 +1,5 @@
 
+#include <interrupt_helper.h>
 #define NR_PIO 32
 
 static u_int8_t ffs(u_int32_t in)
diff --git a/openpcd/firmware/src/rc632.c b/openpcd/firmware/src/rc632.c
index b2b434e..29cd622 100644
--- a/openpcd/firmware/src/rc632.c
+++ b/openpcd/firmware/src/rc632.c
@@ -10,9 +10,10 @@
 
 #include <string.h>
 
-#include <include/lib_AT91SAM7.h>
-#include <include/cl_rc632.h>
-#include <include/openpcd.h>
+#include <lib_AT91SAM7.h>
+#include <cl_rc632.h>
+#include <openpcd.h>
+#include <interrupt_utils.h>
 #include "openpcd.h"
 #include "fifo.h"
 #include "dbgu.h"
@@ -22,13 +23,19 @@
 #if 1
 #define DEBUGPSPI DEBUGP
 #else
-#define	DEBUGPSPI(x, args ...) DEBUGP("")
+#define	DEBUGPSPI(x, args ...) 
 #endif
 
 /* SPI driver */
 
-//#define SPI_DEBUG_LOOPBACK
-//#define SPI_USES_DMA
+#ifdef OLIMEX
+#define SPI_DEBUG_LOOPBACK
+#endif
+
+#define SPI_USES_DMA
+#define SPI_DEBUG_LOOPBACK
+
+#define SPI_MAX_XFER_LEN	65
 
 static AT91PS_SPI pSPI = AT91C_BASE_SPI;
 
@@ -39,8 +46,6 @@ static void spi_irq(void)
 
 	DEBUGPSPI("spi_irq: 0x%08x ", status);
 
-	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SPI);
-
 	if (status & AT91C_SPI_OVRES)
 		DEBUGPSPI("Overrun ");
 	if (status & AT91C_SPI_MODF)
@@ -55,30 +60,43 @@ static void spi_irq(void)
 	}
 
 	DEBUGPSPI("\r\n");
+
+	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SPI);
 }
 
 #ifdef SPI_USES_DMA
-int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len, 
-		   u_int8_t *rx_data, u_int16_t *rx_len)
+static int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len, 
+			  u_int8_t *rx_data, u_int16_t *rx_len)
 {
-	DEBUGPSPI("spi_transcieve: Starting DMA Xfer: ");
-	AT91F_SPI_ReceiveFrame(pSPI, rx_data, *rx_len, NULL, 0);
+	//tx_len = *rx_len = 65;
+	DEBUGPSPI("DMA Xfer tx=%s\r\n", hexdump(tx_data, tx_len));
+	if (*rx_len < tx_len) {
+		DEBUGPCRF("rx_len=%u smaller tx_len=%u\n", *rx_len, tx_len);
+		return -1;
+	}
+	//AT91F_SPI_Disable(pSPI);
+
+	AT91F_SPI_ReceiveFrame(pSPI, rx_data, tx_len, NULL, 0);
 	AT91F_SPI_SendFrame(pSPI, tx_data, tx_len, NULL, 0);
+
 	AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI);
 	AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI);
+
 	pSPI->SPI_IER = AT91C_SPI_ENDTX|AT91C_SPI_ENDRX;
-	AT91F_SPI_Enable(pSPI);
+	//pSPI->SPI_IDR = AT91C_SPI_ENDTX|AT91C_SPI_ENDRX;
 
-	while (!(pSPI->SPI_SR & (AT91C_SPI_ENDRX|AT91C_SPI_ENDTX))) ;
 
-	DEBUGPSPI("DMA Xfer finished\r\n");
-	AT91F_SPI_Disable(pSPI);
+	while (! (pSPI->SPI_SR & AT91C_SPI_ENDRX)) ;
+
+	DEBUGPSPI("DMA Xfer finished rx=%s\r\n", hexdump(rx_data, tx_len));
+
+	*rx_len = tx_len;
 
 	return 0;
 }
 #else
 /* stupid polling transceiver routine */
-int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len, 
+static int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len, 
 		   u_int8_t *rx_data, u_int16_t *rx_len)
 {
 	u_int16_t tx_cur = 0;
@@ -95,7 +113,7 @@ int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len,
 		*rx_len = 0;
 	}
 
-	AT91F_SPI_Enable(pSPI);
+	//AT91F_SPI_Enable(pSPI);
 	while (1) { 
 		u_int32_t sr = pSPI->SPI_SR;
 		u_int8_t tmp;
@@ -112,7 +130,7 @@ int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len,
 		if (tx_cur >= tx_len && rx_cnt >= tx_len)
 			break;
 	}
-	AT91F_SPI_Disable(pSPI);
+	//AT91F_SPI_Disable(pSPI);
 	if (rx_data)
 		DEBUGPSPI("leave(%02x %02x)\r\n", rx_data[0], rx_data[1]);
 	else
@@ -130,8 +148,8 @@ int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len,
 /* static buffers used by RC632 access primitives below. 
  * Since we only have one */
 
-static u_int8_t spi_outbuf[64+1];
-static u_int8_t spi_inbuf[64+1];
+static u_int8_t spi_outbuf[SPI_MAX_XFER_LEN];
+static u_int8_t spi_inbuf[SPI_MAX_XFER_LEN];
 
 #define FIFO_ADDR (RC632_REG_FIFO_DATA << 1)
 
@@ -301,12 +319,14 @@ void rc632_power(u_int8_t up)
 
 void rc632_reset(void)
 {
-	int i;
+	volatile int i;
 
 	rc632_power(0);
 	for (i = 0; i < 0xfffff; i++)
 		{}
 	rc632_power(1);
+	for (i = 0; i < 0xfffff; i++)
+		{}
 
 	/* turn off register paging */
 	rc632_reg_write(RAH, RC632_REG_PAGE0, 0x00);
@@ -335,14 +355,17 @@ void rc632_init(void)
 #endif
 
 #ifdef SPI_DEBUG_LOOPBACK
-	AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED|AT91C_SPI_LLB);
+	AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED|
+				AT91C_SPI_MODFDIS|AT91C_SPI_LLB);
 #else
-	AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED);
+	AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED|
+				AT91C_SPI_MODFDIS);
 #endif
 	/* CPOL = 0, NCPHA = 1, CSAAT = 0, BITS = 0000, SCBR = 10 (4.8MHz), 
 	 * DLYBS = 0, DLYBCT = 0 */
 	//AT91F_SPI_CfgCs(pSPI, 0, AT91C_SPI_BITS_8|AT91C_SPI_NCPHA|(10<<8));
 	AT91F_SPI_CfgCs(pSPI, 0, AT91C_SPI_BITS_8|AT91C_SPI_NCPHA|(0x7f<<8));
+	AT91F_SPI_Enable(pSPI);
 
 	//AT91F_SPI_Reset(pSPI);
 
@@ -350,9 +373,10 @@ void rc632_init(void)
 	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632,
 			      OPENPCD_IRQ_PRIO_RC632,
 			      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &rc632_irq);
-	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_IRQ1);
+	AT91F_AIC_EnableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
 
 	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_RC632_RESET);
+
 	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_MFIN);
 	AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPCD_PIO_MFOUT);
 
@@ -363,15 +387,19 @@ void rc632_init(void)
 	irq_opcdh.len = 0x00;
 
 	rc632_reset();
+
+	/* configure AUX to test signal four */
+	rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, 0x04);
 };
 
+#if 0
 void rc632_exit(void)
 {
-	AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_IRQ1);
+	AT91F_AIC_DisableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
 	AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_SPI);
 	AT91F_SPI_Disable(pSPI);
 }
-
+#endif
 
 #ifdef DEBUG
 static int rc632_reg_write_verify(struct rfid_asic_handle *hdl,
@@ -387,30 +415,27 @@ static int rc632_reg_write_verify(struct rfid_asic_handle *hdl,
 	return (val == tmp);
 }
 
-static u_int8_t tx_buf[0x40+1];
-static u_int8_t rx_buf[0x40+1];
-
 int rc632_dump(void)
 {
 	u_int8_t i;
-	u_int16_t rx_len = sizeof(rx_buf);
+	u_int16_t rx_len = sizeof(spi_inbuf);
 
 	for (i = 0; i <= 0x3f; i++) {
-		tx_buf[i] = i << 1;
-		rx_buf[i] = 0x00;
+		spi_outbuf[i] = i << 1;
+		spi_inbuf[i] = 0x00;
 	}
 
 	/* MSB of first byte of read spi transfer is high */
-	tx_buf[0] |= 0x80;
+	spi_outbuf[0] |= 0x80;
 
 	/* last byte of read spi transfer is 0x00 */
-	tx_buf[0x40] = 0x00;
-	rx_buf[0x40] = 0x00;
+	spi_outbuf[0x40] = 0x00;
+	spi_inbuf[0x40] = 0x00;
 
-	spi_transceive(tx_buf, 0x41, rx_buf, &rx_len);
+	spi_transceive(spi_outbuf, 0x41, spi_inbuf, &rx_len);
 
 	for (i = 0; i < 0x3f; i++)
-		DEBUGPCR("REG 0x%02x = 0x%02x", i, rx_buf[i+1]);
+		DEBUGPCR("REG 0x%02x = 0x%02x", i, spi_inbuf[i+1]);
 	
 	return 0;
 }
diff --git a/openpcd/firmware/src/rc632.h b/openpcd/firmware/src/rc632.h
index ef5dfa7..7571012 100644
--- a/openpcd/firmware/src/rc632.h
+++ b/openpcd/firmware/src/rc632.h
@@ -3,7 +3,7 @@
 
 #include <sys/types.h>
 #include <cl_rc632.h>
-#include <rfid.h>
+#include <librfid/rfid.h>
 
 extern int rc632_reg_write(struct rfid_asic_handle *hdl,
 			   u_int8_t addr, u_int8_t data);
diff --git a/openpcd/firmware/src/rc632_highlevel.c b/openpcd/firmware/src/rc632_highlevel.c
index 136447e..dbb638b 100644
--- a/openpcd/firmware/src/rc632_highlevel.c
+++ b/openpcd/firmware/src/rc632_highlevel.c
@@ -25,8 +25,8 @@
 #include <cl_rc632.h>
 #include "rc632.h"
 #include "dbgu.h"
-#include <rfid_layer2_iso14443a.h>
-#include <rfid_protocol_mifare_classic.h>
+#include <librfid/rfid_layer2_iso14443a.h>
+#include <librfid/rfid_protocol_mifare_classic.h>
 
 /* initially we use the same values as cm5121 */
 #define OPENPCD_CW_CONDUCTANCE		0x3f
@@ -274,7 +274,7 @@ tcl_toggle_pcb(struct rfid_asic_handle *handle)
 	return 0;
 }
 
-static int
+int
 rc632_transceive(struct rfid_asic_handle *handle,
 		 const u_int8_t *tx_buf,
 		 u_int8_t tx_len,
@@ -861,9 +861,9 @@ static struct tx_config tx_configs[] = {
 	},
 };
 
-static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle,
-				     unsigned int tx,
-				     u_int8_t rate)
+int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle,
+			     unsigned int tx,
+			     u_int8_t rate)
 {
 	int rc;
 	u_int8_t reg;
diff --git a/openpcd/firmware/src/rfid_layer2_iso14443a.c b/openpcd/firmware/src/rfid_layer2_iso14443a.c
new file mode 100644
index 0000000..7d99dc9
--- /dev/null
+++ b/openpcd/firmware/src/rfid_layer2_iso14443a.c
@@ -0,0 +1,316 @@
+/* ISO 14443-3 A anticollision implementation
+ *
+ * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ *
+ */
+
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 
+ *  as published by the Free Software Foundation
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_layer2.h>
+//#include <librfid/rfid_reader.h>
+#include <librfid/rfid_layer2_iso14443a.h>
+
+#define TIMEOUT 1236
+
+/* Transceive a 7-bit short frame */
+static int
+iso14443a_transceive_sf(struct rfid_layer2_handle *handle,
+			 unsigned char cmd,
+			 struct iso14443a_atqa *atqa)
+{
+	//struct rfid_reader *rdr = handle->rh->reader;
+
+	return rc632_iso14443a_transceive_sf(handle->rh, cmd, atqa);
+}
+
+/* Transmit an anticollission bit frame */
+static int
+iso14443a_transceive_acf(struct rfid_layer2_handle *handle,
+			 struct iso14443a_anticol_cmd *acf,
+			 unsigned int *bit_of_col)
+{
+	//struct rfid_reader *rdr = handle->rh->reader;
+
+	return rc632_iso14443a_transceive_acf(handle->rh, acf, bit_of_col);
+}
+
+/* Transmit a regular frame */
+static int 
+iso14443a_transceive(struct rfid_layer2_handle *handle,
+		     enum rfid_frametype frametype, 
+			const unsigned char *tx_buf, unsigned int tx_len,
+			unsigned char *rx_buf, unsigned int *rx_len,
+			u_int64_t timeout, unsigned int flags)
+{
+	return rc632_transceive(handle->rh, frametype, tx_buf,
+				tx_len, rx_buf, rx_len, timeout, flags);
+}
+
+static int 
+iso14443a_code_nvb_bits(unsigned char *nvb, unsigned int bits)
+{
+	unsigned int byte_count = bits / 8;
+	unsigned int bit_count = bits % 8;
+
+	if (byte_count < 2 || byte_count > 7)
+		return -1;
+
+	*nvb = ((byte_count & 0xf) << 4) | bit_count;
+
+	return 0;
+}
+
+/* first bit is '1', second bit '2' */
+static void
+set_bit_in_field(unsigned char *bitfield, unsigned int bit)
+{
+	unsigned int byte_count = bit / 8;
+	unsigned int bit_count = bit % 8;
+
+	DEBUGP("bitfield=%p, byte_count=%u, bit_count=%u\n",
+			bitfield, byte_count, bit_count);
+	DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count));
+	*(bitfield+byte_count) |= 1 << (bit_count-1);
+	DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count));
+}
+
+static int
+iso14443a_anticol(struct rfid_layer2_handle *handle)
+{
+	int ret;
+	unsigned int uid_size;
+	struct iso14443a_handle *h = &handle->priv.iso14443a;
+	struct iso14443a_atqa atqa;
+	struct iso14443a_anticol_cmd acf;
+	unsigned int bit_of_col;
+	unsigned char sak[3];
+	unsigned int rx_len = sizeof(sak);
+	char *aqptr = (char *) &atqa;
+
+	memset(handle->uid, 0, sizeof(handle->uid));
+	memset(sak, 0, sizeof(sak));
+	memset(&atqa, 0, sizeof(atqa));
+	memset(&acf, 0, sizeof(acf));
+
+	ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_REQA, &atqa);
+	if (ret < 0) {
+		h->state = ISO14443A_STATE_REQA_SENT;
+		DEBUGP("error during transceive_sf: %d\n", ret);
+		return ret;
+	}
+	h->state = ISO14443A_STATE_ATQA_RCVD;
+
+	DEBUGP("ATQA: 0x%02x 0x%02x\n", *aqptr, *(aqptr+1));
+
+	if (!atqa.bf_anticol) {
+		h->state = ISO14443A_STATE_NO_BITFRAME_ANTICOL;
+		DEBUGP("no bitframe anticollission bits set, aborting\n");
+		return -1;
+	}
+
+	if (atqa.uid_size == 2 || atqa.uid_size == 3)
+		uid_size = 3;
+	else if (atqa.uid_size == 1)
+		uid_size = 2;
+	else
+		uid_size = 1;
+	
+	acf.sel_code = ISO14443A_AC_SEL_CODE_CL1;
+
+	h->state = ISO14443A_STATE_ANTICOL_RUNNING;
+	h->level = ISO14443A_LEVEL_CL1;
+
+cascade:
+	iso14443a_code_nvb_bits(&acf.nvb, 16);
+
+	ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col);
+	if (ret < 0)
+		return ret;
+	DEBUGP("bit_of_col = %u\n", bit_of_col);
+	
+	while (bit_of_col != ISO14443A_BITOFCOL_NONE) {
+		set_bit_in_field(&acf.uid_bits[0], bit_of_col-16);
+		iso14443a_code_nvb_bits(&acf.nvb, bit_of_col);
+		ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col);
+		DEBUGP("bit_of_col = %u\n", bit_of_col);
+		if (ret < 0)
+			return ret;
+	}
+
+	iso14443a_code_nvb_bits(&acf.nvb, 7*8);
+	ret = iso14443a_transceive(handle, RFID_14443A_FRAME_REGULAR,
+				   (unsigned char *)&acf, 7, 
+				   (unsigned char *) &sak, &rx_len,
+				   TIMEOUT, 0);
+	if (ret < 0)
+		return ret;
+
+	if (sak[0] & 0x04) {
+		/* Cascade bit set, UID not complete */
+		switch (acf.sel_code) {
+		case ISO14443A_AC_SEL_CODE_CL1:
+			/* cascading from CL1 to CL2 */
+			if (acf.uid_bits[0] != 0x88) {
+				DEBUGP("Cascade bit set, but UID0 != 0x88\n");
+				return -1;
+			}
+			memcpy(&handle->uid[0], &acf.uid_bits[1], 3);
+			acf.sel_code = ISO14443A_AC_SEL_CODE_CL2;
+			h->level = ISO14443A_LEVEL_CL2;
+			break;
+		case ISO14443A_AC_SEL_CODE_CL2:
+			/* cascading from CL2 to CL3 */
+			memcpy(&handle->uid[3], &acf.uid_bits[1], 3);
+			acf.sel_code = ISO14443A_AC_SEL_CODE_CL3;
+			h->level = ISO14443A_LEVEL_CL3;
+			break;
+		default:
+			DEBUGP("cannot cascade any further than CL3\n");
+			h->state = ISO14443A_STATE_ERROR;
+			return -1;
+			break;
+		}
+		goto cascade;
+
+	} else {
+		switch (acf.sel_code) {
+		case ISO14443A_AC_SEL_CODE_CL1:
+			/* single size UID (4 bytes) */
+			memcpy(&handle->uid[0], &acf.uid_bits[0], 4);
+			break;
+		case ISO14443A_AC_SEL_CODE_CL2:
+			/* double size UID (7 bytes) */
+			memcpy(&handle->uid[3], &acf.uid_bits[0], 4);
+			break;
+		case ISO14443A_AC_SEL_CODE_CL3:
+			/* triple size UID (10 bytes) */
+			memcpy(&handle->uid[6], &acf.uid_bits[0], 4);
+			break;
+		}
+	}
+
+	h->level = ISO14443A_LEVEL_NONE;
+	h->state = ISO14443A_STATE_SELECTED;
+
+	{
+		if (uid_size == 1)
+			handle->uid_len = 4;
+		else if (uid_size == 2)
+			handle->uid_len = 7;
+		else 
+			handle->uid_len = 10;
+
+		DEBUGP("UID %s\n", rfid_hexdump(handle->uid, handle->uid_len));
+	}
+
+	if (sak[0] & 0x20) {
+		DEBUGP("we have a T=CL compliant PICC\n");
+		h->tcl_capable = 1;
+	} else {
+		DEBUGP("we have a T!=CL PICC\n");
+		h->tcl_capable = 0;
+	}
+
+	return 0;
+}
+
+static int
+iso14443a_hlta(struct rfid_layer2_handle *handle)
+{
+	int ret;
+	unsigned char tx_buf[2] = { 0x50, 0x00 };
+	unsigned char rx_buf[10];
+	unsigned int rx_len = sizeof(rx_buf);
+
+	ret = iso14443a_transceive(handle, RFID_14443A_FRAME_REGULAR,
+				   tx_buf, sizeof(tx_buf),
+				   rx_buf, &rx_len, 1000 /* 1ms */, 0);
+	if (ret < 0) {
+		/* "error" case: we don't get somethng back from the card */
+		return 0;
+	}
+	return -1;
+}
+
+static int
+iso14443a_setopt(struct rfid_layer2_handle *handle, int optname,
+		 const void *optval, unsigned int optlen)
+{
+	int ret = -EINVAL;
+	unsigned int speed;
+
+	switch (optname) {
+	case RFID_OPT_14443A_SPEED_RX:
+		speed = *(unsigned int *)optval;
+		ret = rc632_iso14443a_set_speed(handle->rh, 0, speed);
+		break;
+	case RFID_OPT_14443A_SPEED_TX:
+		speed = *(unsigned int *)optval;
+		ret = rc632_iso14443a_set_speed(handle->rh, 1, speed);
+		break;
+	};
+
+	return ret;
+}
+
+
+static struct rfid_layer2_handle *
+iso14443a_init(struct rfid_reader_handle *rh)
+{
+	int ret;
+	struct rfid_layer2_handle *h = malloc(sizeof(*h));
+	if (!h)
+		return NULL;
+
+	h->l2 = &rfid_layer2_iso14443a;
+	h->rh = rh;
+	h->priv.iso14443a.state = ISO14443A_STATE_NONE;
+	h->priv.iso14443a.level = ISO14443A_LEVEL_NONE;
+
+	ret = rc632_iso14443a_init(h->rh);
+	if (ret < 0) {
+		free(h);
+		return NULL;
+	}
+
+	return h;
+}
+
+static int
+iso14443a_fini(struct rfid_layer2_handle *handle)
+{
+	free(handle);
+	return 0;
+}
+
+struct rfid_layer2 rfid_layer2_iso14443a = {
+	.id	= RFID_LAYER2_ISO14443A,
+	.name 	= "ISO 14443-3 A",
+	.fn	= {
+		.init 		= &iso14443a_init,
+		.open 		= &iso14443a_anticol,
+		.transceive 	= &iso14443a_transceive,
+		.close 		= &iso14443a_hlta,
+		.fini 		= &iso14443a_fini,
+		.setopt		= &iso14443a_setopt,
+	},
+};
diff --git a/openpcd/firmware/src/start/Cstartup.S b/openpcd/firmware/src/start/Cstartup.S
index d13dbd8..785a18c 100644
--- a/openpcd/firmware/src/start/Cstartup.S
+++ b/openpcd/firmware/src/start/Cstartup.S
@@ -16,7 +16,7 @@
 //*- 1.1 01/Apr/05 JPP    : save SPSR 
 //*-----------------------------------------------------------------------------*/
 
-     .equ   IRQ_Stack_Size,     0x00000060
+     .equ   IRQ_Stack_Size,     0x00000400
 
 /* #include "AT91SAM7S64_inc.h"	  */
 
-- 
cgit v1.2.3