summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openpcd/firmware/Makefile8
-rw-r--r--openpcd/firmware/include/librfid/rfid.h (renamed from openpcd/firmware/include/rfid.h)10
-rw-r--r--openpcd/firmware/include/librfid/rfid_layer2.h76
-rw-r--r--openpcd/firmware/include/librfid/rfid_layer2_iso14443a.h (renamed from openpcd/firmware/include/rfid_layer2_iso14443a.h)17
-rw-r--r--openpcd/firmware/include/librfid/rfid_layer2_iso14443b.h85
-rw-r--r--openpcd/firmware/include/librfid/rfid_layer2_iso15693.h55
-rw-r--r--openpcd/firmware/include/librfid/rfid_protocol_mifare_classic.h (renamed from openpcd/firmware/include/rfid_protocol_mifare_classic.h)0
-rw-r--r--openpcd/firmware/src/dbgu.c27
-rw-r--r--openpcd/firmware/src/dbgu.h1
-rw-r--r--openpcd/firmware/src/main.c8
-rw-r--r--openpcd/firmware/src/main.h8
-rw-r--r--openpcd/firmware/src/main_analog.c77
-rw-r--r--openpcd/firmware/src/main_dumbreader.c6
-rw-r--r--openpcd/firmware/src/main_reqa.c13
-rw-r--r--openpcd/firmware/src/pcd_enumerate.c4
-rw-r--r--openpcd/firmware/src/pio_irq.c1
-rw-r--r--openpcd/firmware/src/rc632.c101
-rw-r--r--openpcd/firmware/src/rc632.h2
-rw-r--r--openpcd/firmware/src/rc632_highlevel.c12
-rw-r--r--openpcd/firmware/src/rfid_layer2_iso14443a.c316
-rw-r--r--openpcd/firmware/src/start/Cstartup.S2
21 files changed, 758 insertions, 71 deletions
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/rfid.h b/openpcd/firmware/include/librfid/rfid.h
index 5684884..eb96378 100644
--- a/openpcd/firmware/include/rfid.h
+++ b/openpcd/firmware/include/librfid/rfid.h
@@ -1,6 +1,16 @@
#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 {
};
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/rfid_layer2_iso14443a.h b/openpcd/firmware/include/librfid/rfid_layer2_iso14443a.h
index 936d902..e1ecd36 100644
--- a/openpcd/firmware/include/rfid_layer2_iso14443a.h
+++ b/openpcd/firmware/include/librfid/rfid_layer2_iso14443a.h
@@ -1,12 +1,6 @@
#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,
@@ -38,7 +32,7 @@ struct iso14443a_atqa {
uid_size:2;
u_int8_t proprietary:4,
rfu2:4;
-};
+} __attribute__ ((packed));
#define ISO14443A_HLTA 0x5000
@@ -47,7 +41,7 @@ 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,
@@ -57,6 +51,11 @@ enum iso14443a_anticol_sel_code {
#define ISO14443A_BITOFCOL_NONE 0xffffffff
+struct iso14443a_handle {
+ unsigned int state;
+ unsigned int level;
+ unsigned int tcl_capable;
+};
enum iso14443a_level {
ISO14443A_LEVEL_NONE,
@@ -82,5 +81,7 @@ enum iso14443a_state {
#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/rfid_protocol_mifare_classic.h b/openpcd/firmware/include/librfid/rfid_protocol_mifare_classic.h
index e6b2400..e6b2400 100644
--- a/openpcd/firmware/include/rfid_protocol_mifare_classic.h
+++ b/openpcd/firmware/include/librfid/rfid_protocol_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" */
personal git repositories of Harald Welte. Your mileage may vary