From 28eb4a57d93f2cf13d3693ce4dba677f22cbf1cc Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 15 Oct 2006 20:21:40 +0000 Subject: - add svn:ignore property to make 'svn st' output more realistic - remove old copy+paste+edit port of parts of librfid - add ability to directly link librfid.a from mainline librfid - make usb string descriptors optional again (config.h) - fix TC_CDIV to reset correctly on swtrig (For OpenPICC) - temporarily re-implement ep0_send_data() in pcd_enumerate.c - make UDP_PUPv4 switching conditional to PCD - introduce DEBUG_UNBUFFERED define in dbgu.c - fix some signed/unsigned/typecast related compiler warnings - remove dead code from src/os/led.c - implement a 'mdelay' and 'usleep' stub function (FIXME!) - rename rc632_... functions into opcd_rc632_... to avoid confusion - introduce new 'main_librfid' TARGET - make main_{reqa,analog} work with librfid rather than old code - introduce mroe debugging options for FIQ handler code in Cstartup_app - lots of PICC work that doesn't need comments now git-svn-id: https://svn.openpcd.org:2342/trunk@266 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- firmware/src/pcd/main_analog.c | 20 +- firmware/src/pcd/main_dumbreader.c | 6 +- firmware/src/pcd/main_librfid.c | 215 +++++ firmware/src/pcd/main_pwm.c | 28 +- firmware/src/pcd/main_reqa.c | 75 +- firmware/src/pcd/rc632.c | 94 +- firmware/src/pcd/rc632.h | 25 +- firmware/src/pcd/rc632_highlevel.c | 1364 +----------------------------- firmware/src/pcd/rc632_highlevel.h | 19 + firmware/src/pcd/rfid_layer2_iso14443a.c | 319 ------- 10 files changed, 383 insertions(+), 1782 deletions(-) create mode 100644 firmware/src/pcd/main_librfid.c create mode 100644 firmware/src/pcd/rc632_highlevel.h delete mode 100644 firmware/src/pcd/rfid_layer2_iso14443a.c (limited to 'firmware/src/pcd') diff --git a/firmware/src/pcd/main_analog.c b/firmware/src/pcd/main_analog.c index 799a98b..0f61693 100644 --- a/firmware/src/pcd/main_analog.c +++ b/firmware/src/pcd/main_analog.c @@ -34,6 +34,16 @@ #include #include #include +#include + +#include +#include +#include + +#define RAH NULL + +static struct rfid_reader_handle *rh; +static struct rfid_layer2_handle *l2h; void _init_func(void) { @@ -43,9 +53,11 @@ void _init_func(void) rc632_turn_on_rf(RAH); /* FIXME: do we need this? */ DEBUGPCRF("initializing 14443A operation"); - rc632_iso14443a_init(RAH); + rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); + l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A); + /* Switch to 848kBps (1subcp / bit) */ - //rc632_clear_bits(RAH, RC632_REG_RX_CONTROL1, RC632_RXCTRL1_SUBCP_MASK); + //opcd_rc632_clear_bits(RAH, RC632_REG_RX_CONTROL1, RC632_RXCTRL1_SUBCP_MASK); } int _main_dbgu(char key) @@ -76,7 +88,7 @@ int _main_dbgu(char key) 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); + opcd_rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, ana_out_sel); } return ret; @@ -91,7 +103,7 @@ void _main_func(void) trigger_pulse(); - if (rc632_iso14443a_transceive_sf(RAH, ISO14443A_SF_CMD_WUPA, &atqa) < 0) { + if (iso14443a_transceive_sf(l2h, ISO14443A_SF_CMD_WUPA, &atqa) < 0) { DEBUGPCRF("error during transceive_sf"); led_switch(1, 0); } else { diff --git a/firmware/src/pcd/main_dumbreader.c b/firmware/src/pcd/main_dumbreader.c index d5db8a5..dab4d77 100644 --- a/firmware/src/pcd/main_dumbreader.c +++ b/firmware/src/pcd/main_dumbreader.c @@ -28,6 +28,8 @@ #include "../openpcd.h" #include +#define RAH NULL + void _init_func(void) { rc632_init(); @@ -48,13 +50,13 @@ int _main_dbgu(char key) break; case '5': - rc632_reg_read(RAH, RC632_REG_RX_WAIT, &value); + opcd_rc632_reg_read(RAH, RC632_REG_RX_WAIT, &value); DEBUGPCR("Reading RC632 Reg RxWait: 0x%02xr", value); break; case '6': DEBUGPCR("Writing RC632 Reg RxWait: 0x55"); - rc632_reg_write(RAH, RC632_REG_RX_WAIT, 0x55); + opcd_rc632_reg_write(RAH, RC632_REG_RX_WAIT, 0x55); break; case '7': rc632_dump(); diff --git a/firmware/src/pcd/main_librfid.c b/firmware/src/pcd/main_librfid.c new file mode 100644 index 0000000..8bb7ccb --- /dev/null +++ b/firmware/src/pcd/main_librfid.c @@ -0,0 +1,215 @@ +/* main_librfid - OpenPCD firmware using in-firmware librfid + * + * (C) 2006 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +//#include "rc632.h" +#include +#include +#include +#include +#include + +#include "../openpcd.h" + +static struct rfid_reader_handle *rh; +static struct rfid_layer2_handle *l2h; +static struct rfid_protocol_handle *ph; + +void _init_func(void) +{ + trigger_init(); + rc632_init(); + rc632_test(); + DEBUGP("opening reader "); +#if 1 + rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); + DEBUGP("rh=%p ", rh); +#endif + led_switch(2, 1); +} + +int _main_dbgu(char key) +{ + int ret = -EINVAL; + return ret; +} + +struct openpcd_l2_connectinfo { + u_int32_t proto_supported; + + u_int8_t speed_rx; + u_int8_t speed_tx; + + u_int8_t uid_len; + u_int8_t uid[10]; +} __attribute__ ((packed)); + +struct openpcd_proto_connectinfo { +} __attribute__ ((packed)); + +struct openpcd_proto_tcl_connectinfo { + u_int8_t fsc; + u_int8_t fsd; + u_int8_t ta; + u_int8_t sfgt; + + u_int8_t flags; + u_int8_t cid; + u_int8_t nad; + + u_int8_t ats_tot_len; + u_int8_t ats_snippet[0]; +} __attribute__ ((packed)); + +static int init_proto(void) +{ + struct req_ctx *detect_rctx; + struct openpcd_hdr *opcdh; + struct openpcd_l2_connectinfo *l2c; + struct openpcd_proto_connectinfo *pc; + unsigned int size; + + l2h = rfid_layer2_scan(rh); + if (!l2h) + return 0; + + DEBUGP("l2='%s' ", rfid_layer2_name(l2h)); + + detect_rctx = req_ctx_find_get(0, RCTX_STATE_FREE, + RCTX_STATE_LIBRFID_BUSY); + if (detect_rctx) { + unsigned int uid_len; + opcdh = (struct openpcd_hdr *) detect_rctx->data; + l2c = (struct openpcd_l2_connectinfo *) + (char *) opcdh + sizeof(opcdh); + l2c->uid_len = sizeof(l2c->uid); + opcdh->cmd = OPENPCD_CMD_LRFID_DETECT_IRQ; + opcdh->flags = 0x00; + opcdh->reg = 0x03; + opcdh->val = l2h->l2->id; + +#if 0 + /* copy UID / PUPI into data section */ + rfid_layer2_getopt(l2h, RFID_OPT_LAYER2_UID, (void *)l2c->uid, + &uid_len); + l2c->uid_len = uid_len & 0xff; + + size = sizeof(l2c->proto_supported); + rfid_layer2_getopt(l2h, RFID_OPT_LAYER2_PROTO_SUPP, + &l2c->proto_supported, &size); + + detect_rctx->tot_len = sizeof(*opcdh) + sizeof(*l2c); + + switch (l2h->l2->id) { + case RFID_LAYER2_ISO14443A: + break; + case RFID_LAYER2_ISO14443B: + break; + case RFID_LAYER2_ISO15693: + break; + } +#endif + req_ctx_set_state(detect_rctx, RCTX_STATE_UDP_EP3_PENDING); + } + ph = rfid_protocol_scan(l2h); + if (!ph) + return 3; + + DEBUGP("p='%s' ", rfid_protocol_name(ph)); + detect_rctx = req_ctx_find_get(0, RCTX_STATE_FREE, + RCTX_STATE_LIBRFID_BUSY); + if (detect_rctx) { + opcdh = (struct openpcd_hdr *) detect_rctx->data; + pc = (struct openpcd_proto_connectinfo *) + ((char *) opcdh + sizeof(*opcdh)); + detect_rctx->tot_len = sizeof(*opcdh) + sizeof(*pc); + opcdh->cmd = OPENPCD_CMD_LRFID_DETECT_IRQ; + opcdh->flags = 0x00; + opcdh->reg = 0x04; + opcdh->val = ph->proto->id; + /* copy L4 info into data section */ + +#if 0 + switch (ph->proto->id) { + case RFID_PROTOCOL_TCL: { + struct openpcd_proto_tcl_connectinfo *ptc + = (struct openpcd_proto_tcl_connectinfo *) + ((char *) ph + sizeof(*ph)); + unsigned int space; + detect_rctx->tot_len += sizeof(*ptc); + space = detect_rctx->size - sizeof(*opcdh)-sizeof(*pc); + size = space; + rfid_protocol_getopt(ph, RFID_OPT_P_TCL_ATS, + &ptc->ats_snippet, &size); + if (size == space) { + /* we've only copied part of the ATS */ + size = sizeof(ptc->ats_tot_len); + rfid_protocol_getopt(ph, + RFID_OPT_P_TCL_ATS_LEN, + &ptc->ats_tot_len, &size); + } else { + ptc->ats_tot_len = size; + } + + } break; + } +#endif + req_ctx_set_state(detect_rctx, RCTX_STATE_UDP_EP3_PENDING); + } + led_switch(1, 1); + + return 4; +} + +static int opcd_lrfid_usb_in(struct req_ctx *rctx) +{ + struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data; + return 0; +} + + +void _main_func(void) +{ + int ret; + + usb_out_process(); + usb_in_process(); + + ret = init_proto(); + + if (ret >= 4) + rfid_protocol_close(ph); + if (ret >= 3) + rfid_layer2_close(l2h); + + rc632_turn_off_rf(NULL); + { volatile int i; for (i = 0; i < 0x3ffff; i++) ; } + rc632_turn_on_rf(NULL); + + led_switch(1, 0); + led_toggle(2); +} diff --git a/firmware/src/pcd/main_pwm.c b/firmware/src/pcd/main_pwm.c index 58010ee..7db6b72 100644 --- a/firmware/src/pcd/main_pwm.c +++ b/firmware/src/pcd/main_pwm.c @@ -37,6 +37,8 @@ #include #endif +#define RAH NULL + static u_int8_t force_100ask = 1; static u_int8_t mod_conductance = 0x3f; static u_int8_t cw_conductance = 0x3f; @@ -48,7 +50,7 @@ static u_int8_t pwm_freq_idx = 0; static void rc632_modulate_mfin() { - rc632_reg_write(RAH, RC632_REG_TX_CONTROL, + opcd_rc632_reg_write(RAH, RC632_REG_TX_CONTROL, RC632_TXCTRL_MOD_SRC_MFIN|RC632_TXCTRL_TX2_INV| RC632_TXCTRL_TX1_RF_EN|RC632_TXCTRL_TX2_RF_EN); } @@ -178,41 +180,41 @@ int _main_dbgu(char key) DEBUGPCRF("%sabling Force100ASK", force_100ask ? "Dis":"En"); if (force_100ask) { force_100ask = 0; - rc632_clear_bits(RAH, RC632_REG_TX_CONTROL, - RC632_TXCTRL_FORCE_100_ASK); + opcd_rc632_clear_bits(RAH, RC632_REG_TX_CONTROL, + RC632_TXCTRL_FORCE_100_ASK); } else { force_100ask = 1; - rc632_set_bits(RAH, RC632_REG_TX_CONTROL, - RC632_TXCTRL_FORCE_100_ASK); + opcd_rc632_set_bits(RAH, RC632_REG_TX_CONTROL, + RC632_TXCTRL_FORCE_100_ASK); } return 0; break; case 'v': if (mod_conductance > 0) { mod_conductance--; - rc632_reg_write(RAH, RC632_REG_MOD_CONDUCTANCE, - rsrel_table[mod_conductance]); + opcd_rc632_reg_write(RAH, RC632_REG_MOD_CONDUCTANCE, + rsrel_table[mod_conductance]); } break; case 'b': if (mod_conductance < 0x3f) { mod_conductance++; - rc632_reg_write(RAH, RC632_REG_MOD_CONDUCTANCE, - rsrel_table[mod_conductance]); + opcd_rc632_reg_write(RAH, RC632_REG_MOD_CONDUCTANCE, + rsrel_table[mod_conductance]); } break; case 'g': if (cw_conductance > 0) { cw_conductance--; - rc632_reg_write(RAH, RC632_REG_CW_CONDUCTANCE, - rsrel_table[cw_conductance]); + opcd_rc632_reg_write(RAH, RC632_REG_CW_CONDUCTANCE, + rsrel_table[cw_conductance]); } break; case 'h': if (cw_conductance < 0x3f) { cw_conductance++; - rc632_reg_write(RAH, RC632_REG_CW_CONDUCTANCE, - rsrel_table[cw_conductance]); + opcd_rc632_reg_write(RAH, RC632_REG_CW_CONDUCTANCE, + rsrel_table[cw_conductance]); } break; case '?': diff --git a/firmware/src/pcd/main_reqa.c b/firmware/src/pcd/main_reqa.c index 9f46569..717926a 100644 --- a/firmware/src/pcd/main_reqa.c +++ b/firmware/src/pcd/main_reqa.c @@ -33,6 +33,10 @@ #include #include #include +#include + +#include +#include #include "../openpcd.h" @@ -40,6 +44,11 @@ #include "tc.h" #endif +#define RAH NULL + +static struct rfid_reader_handle *rh; +static struct rfid_layer2_handle *l2h; + void _init_func(void) { trigger_init(); @@ -52,7 +61,8 @@ void _init_func(void) DEBUGPCRF("turning on RF"); rc632_turn_on_rf(RAH); DEBUGPCRF("initializing 14443A operation"); - rc632_iso14443a_init(RAH); + rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); + l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A); } #define MODE_REQA 0x01 @@ -62,21 +72,30 @@ void _init_func(void) static volatile int mode = MODE_REQA; -static const char frame_14443a[] = { 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; +static const char frame_14443a[] = { + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, +}; static void reg_inc(u_int8_t reg) { u_int8_t val; - rc632_reg_read(RAH, reg, &val); - rc632_reg_write(RAH, reg, val++); + opcd_rc632_reg_read(RAH, reg, &val); + opcd_rc632_reg_write(RAH, reg, val++); DEBUGPCRF("reg 0x%02x = 0x%02x", reg, val); } static void reg_dec(u_int8_t reg) { u_int8_t val; - rc632_reg_read(RAH, reg, &val); - rc632_reg_write(RAH, reg, val--); + opcd_rc632_reg_read(RAH, reg, &val); + opcd_rc632_reg_write(RAH, reg, val--); DEBUGPCRF("reg 0x%02x = 0x%02x", reg, val); } @@ -100,7 +119,7 @@ static u_int16_t cdivs[] = { 128, 64, 32, 16 }; int _main_dbgu(char key) { int ret = 0; - static int cdiv_idx = 0; + static int cdiv_idx = 2; switch (key) { case '?': @@ -137,7 +156,8 @@ int _main_dbgu(char key) if (ana_out_sel > 0) { ana_out_sel--; DEBUGPCR("switching to analog output mode 0x%x\n", ana_out_sel); - rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, ana_out_sel); + opcd_rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, + ana_out_sel); } ret = 1; break; @@ -145,7 +165,8 @@ int _main_dbgu(char key) if (ana_out_sel < 0xc) { ana_out_sel++; DEBUGPCR("switching to analog output mode 0x%x\n", ana_out_sel); - rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, ana_out_sel); + opcd_rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, + ana_out_sel); } ret = 1; break; @@ -153,7 +174,7 @@ int _main_dbgu(char key) if (mfout_sel > 0) { mfout_sel--; DEBUGPCR("switching to MFOUT mode 0x%x\n", mfout_sel); - rc632_reg_write(RAH, RC632_REG_MFOUT_SELECT, mfout_sel); + opcd_rc632_reg_write(RAH, RC632_REG_MFOUT_SELECT, mfout_sel); } ret = 1; break; @@ -161,7 +182,7 @@ int _main_dbgu(char key) if (mfout_sel < 5) { mfout_sel++; DEBUGPCR("switching to MFOUT mode 0x%x\n", mfout_sel); - rc632_reg_write(RAH, RC632_REG_MFOUT_SELECT, mfout_sel); + opcd_rc632_reg_write(RAH, RC632_REG_MFOUT_SELECT, mfout_sel); } ret = 1; break; @@ -208,27 +229,17 @@ void _main_func(void) { int status; struct iso14443a_atqa atqa; - struct rfid_layer2_handle l2h; volatile int i; - memset(&atqa, 0, sizeof(atqa)); - - /* fake layer2 handle initialization */ - memset(&l2h, 0, sizeof(l2h)); - l2h.l2 = &rfid_layer2_iso14443a; - l2h.priv.iso14443a.state = ISO14443A_STATE_NONE; - l2h.priv.iso14443a.level = ISO14443A_LEVEL_NONE; - /* FIXME: why does this only work every second attempt without reset or * power-cycle? */ - rc632_turn_off_rf(); + //rc632_turn_off_rf(); //rc632_reset(); - rc632_turn_on_rf(); + //rc632_turn_on_rf(); - rc632_iso14443a_init(RAH); - rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, ana_out_sel); - rc632_reg_write(RAH, RC632_REG_MFOUT_SELECT, mfout_sel); - for (i = 0; i < 0x3ffff; i++) {} + opcd_rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, ana_out_sel); + opcd_rc632_reg_write(RAH, RC632_REG_MFOUT_SELECT, mfout_sel); + for (i = 0; i < 0xfffff; i++) {} //rc632_dump(); #ifdef WITH_TC tc_cdiv_print(); @@ -236,21 +247,21 @@ void _main_func(void) switch (mode) { case MODE_REQA: - status = rc632_iso14443a_transceive_sf(RAH, ISO14443A_SF_CMD_REQA, &atqa); + status = iso14443a_transceive_sf(l2h, ISO14443A_SF_CMD_REQA, &atqa); if (status < 0) DEBUGPCRF("error during transceive_sf REQA"); else DEBUGPCRF("received ATQA: %s", hexdump((char *)&atqa, sizeof(atqa))); break; case MODE_WUPA: - status = rc632_iso14443a_transceive_sf(RAH, ISO14443A_SF_CMD_WUPA, &atqa); + status = iso14443a_transceive_sf(l2h, ISO14443A_SF_CMD_WUPA, &atqa); if (status < 0) DEBUGPCRF("error during transceive_sf WUPA"); else DEBUGPCRF("received WUPA: %s", hexdump((char *)&atqa, sizeof(atqa))); break; case MODE_ANTICOL: - status = rfid_layer2_iso14443a.fn.open(&l2h); + status = rfid_layer2_open(l2h); if (status < 0) DEBUGPCR("error during anticol"); else @@ -260,11 +271,11 @@ void _main_func(void) { char rx_buf[4]; int rx_len = sizeof(rx_buf); - rfid_layer2_iso14443a.fn.setopt(&l2h, RFID_OPT_14443A_SPEED_RX, + rfid_layer2_setopt(l2h, RFID_OPT_14443A_SPEED_RX, &speed_idx, sizeof(speed_idx)); - rfid_layer2_iso14443a.fn.setopt(&l2h, RFID_OPT_14443A_SPEED_TX, + rfid_layer2_setopt(l2h, RFID_OPT_14443A_SPEED_TX, &speed_idx, sizeof(speed_idx)); - rfid_layer2_iso14443a.fn.transceive(&l2h, RFID_14443A_FRAME_REGULAR, + rfid_layer2_transceive(l2h, RFID_14443A_FRAME_REGULAR, &frame_14443a, sizeof(frame_14443a), &rx_buf, &rx_len, 1, 0); } diff --git a/firmware/src/pcd/rc632.c b/firmware/src/pcd/rc632.c index 5287300..731574c 100644 --- a/firmware/src/pcd/rc632.c +++ b/firmware/src/pcd/rc632.c @@ -38,6 +38,8 @@ #include #include "rc632.h" +#include + #define NOTHING do {} while(0) #if 0 @@ -102,6 +104,9 @@ static int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len, return -1; } + /* disable RC632 interrupt because it wants to do SPI transactions */ + AT91F_AIC_DisableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632); + AT91F_SPI_ReceiveFrame(pSPI, rx_data, tx_len, NULL, 0); AT91F_SPI_SendFrame(pSPI, tx_data, tx_len, NULL, 0); @@ -113,6 +118,9 @@ static int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len, while (! (pSPI->SPI_SR & AT91C_SPI_ENDRX)) ; + /* Re-enable RC632 interrupts */ + AT91F_AIC_EnableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632); + DEBUGPSPI("DMA Xfer finished rx=%s\r\n", hexdump(rx_data, tx_len)); *rx_len = tx_len; @@ -178,19 +186,12 @@ static u_int8_t spi_inbuf[SPI_MAX_XFER_LEN]; #define FIFO_ADDR (RC632_REG_FIFO_DATA << 1) -struct rc632 { - u_int16_t flags; - struct fifo fifo; -}; -#define RC632_F_FIFO_TX 0x0001 -static struct rc632 rc632; - #define RC632_WRITE_ADDR(x) ((x << 1) & 0x7e) /* RC632 access primitives */ -int rc632_reg_write(struct rfid_asic_handle *hdl, - u_int8_t addr, u_int8_t data) +int opcd_rc632_reg_write(struct rfid_asic_handle *hdl, + u_int8_t addr, u_int8_t data) { u_int16_t rx_len = 2; @@ -201,17 +202,16 @@ int rc632_reg_write(struct rfid_asic_handle *hdl, spi_outbuf[0] = addr; spi_outbuf[1] = data; - //spi_transceive(spi_outbuf, 2, NULL, NULL); return spi_transceive(spi_outbuf, 2, spi_inbuf, &rx_len); } #define RC632_REGSET_START 0x10 #define RC632_REGSET_END 0x3f #define RC632_REGSET_MAXSIZE (RC632_REGSET_END-RC632_REGSET_START) -static char regset_buf[RC632_REGSET_MAXSIZE * 2]; +static u_int8_t regset_buf[RC632_REGSET_MAXSIZE * 2]; -int rc632_reg_write_set(struct rfid_asic_handle *hdl, - u_int8_t *regs, int len) +int opcd_rc632_reg_write_set(struct rfid_asic_handle *hdl, + u_int8_t *regs, int len) { u_int8_t i, j = 0; u_int16_t rx_len; @@ -231,8 +231,8 @@ int rc632_reg_write_set(struct rfid_asic_handle *hdl, return spi_transceive(regset_buf, j, spi_inbuf, &rx_len); } -int rc632_fifo_write(struct rfid_asic_handle *hdl, - u_int8_t len, u_int8_t *data, u_int8_t flags) +int opcd_rc632_fifo_write(struct rfid_asic_handle *hdl, + u_int8_t len, u_int8_t *data, u_int8_t flags) { u_int16_t rx_len = sizeof(spi_inbuf); if (len > sizeof(spi_outbuf)-1) @@ -246,8 +246,8 @@ int rc632_fifo_write(struct rfid_asic_handle *hdl, return spi_transceive(spi_outbuf, len+1, spi_inbuf, &rx_len); } -int rc632_reg_read(struct rfid_asic_handle *hdl, - u_int8_t addr, u_int8_t *val) +int opcd_rc632_reg_read(struct rfid_asic_handle *hdl, + u_int8_t addr, u_int8_t *val) { u_int16_t rx_len = 2; @@ -264,15 +264,15 @@ int rc632_reg_read(struct rfid_asic_handle *hdl, return 0; } -int rc632_fifo_read(struct rfid_asic_handle *hdl, - u_int8_t max_len, u_int8_t *data) +int opcd_rc632_fifo_read(struct rfid_asic_handle *hdl, + u_int8_t max_len, u_int8_t *data) { int ret; u_int8_t fifo_length; u_int8_t i; u_int16_t rx_len; - ret = rc632_reg_read(hdl, RC632_REG_FIFO_LENGTH, &fifo_length); + ret = opcd_rc632_reg_read(hdl, RC632_REG_FIFO_LENGTH, &fifo_length); if (ret < 0) return ret; @@ -295,34 +295,34 @@ int rc632_fifo_read(struct rfid_asic_handle *hdl, return rx_len-1; } -int rc632_set_bits(struct rfid_asic_handle *hdl, +int opcd_rc632_set_bits(struct rfid_asic_handle *hdl, u_int8_t reg, u_int8_t bits) { u_int8_t val; int ret; - ret = rc632_reg_read(hdl, reg, &val); + ret = opcd_rc632_reg_read(hdl, reg, &val); if (ret < 0) return ret; val |= bits; - return rc632_reg_write(hdl, reg, val); + return opcd_rc632_reg_write(hdl, reg, val); } -int rc632_clear_bits(struct rfid_asic_handle *hdl, +int opcd_rc632_clear_bits(struct rfid_asic_handle *hdl, u_int8_t reg, u_int8_t bits) { u_int8_t val; int ret; - ret = rc632_reg_read(hdl, reg, &val); + ret = opcd_rc632_reg_read(hdl, reg, &val); if (ret < 0) return ret; val &= ~bits; - return rc632_reg_write(hdl, reg, val); + return opcd_rc632_reg_write(hdl, reg, val); } /* RC632 interrupt handling */ @@ -334,11 +334,11 @@ static void rc632_irq(void) u_int8_t cause; /* CL RC632 has interrupted us */ - rc632_reg_read(RAH, RC632_REG_INTERRUPT_RQ, &cause); + opcd_rc632_reg_read(NULL, RC632_REG_INTERRUPT_RQ, &cause); /* ACK all interrupts */ - //rc632_reg_write(RAH, RC632_REG_INTERRUPT_RQ, cause); - rc632_reg_write(RAH, RC632_REG_INTERRUPT_RQ, RC632_INT_TIMER); + //rc632_reg_write(NULL, RC632_REG_INTERRUPT_RQ, cause); + opcd_rc632_reg_write(NULL, RC632_REG_INTERRUPT_RQ, RC632_INT_TIMER); DEBUGP("rc632_irq: "); if (cause & RC632_INT_LOALERT) { @@ -369,7 +369,7 @@ static void rc632_irq(void) irq_rctx = req_ctx_find_get(0, RCTX_STATE_FREE, RCTX_STATE_RC632IRQ_BUSY); if (!irq_rctx) { - DEBUGPCRF("NO RCTX!\n"); + DEBUGPCRF("NO RCTX!"); /* disable rc632 interrupt until RCTX is free */ AT91F_AIC_DisableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632); return; @@ -415,13 +415,13 @@ void rc632_reset(void) /* wait for startup phase to finish */ while (1) { u_int8_t val; - rc632_reg_read(RAH, RC632_REG_COMMAND, &val); + opcd_rc632_reg_read(NULL, RC632_REG_COMMAND, &val); if (val == 0x00) break; } /* turn off register paging */ - rc632_reg_write(RAH, RC632_REG_PAGE0, 0x00); + opcd_rc632_reg_write(NULL, RC632_REG_PAGE0, 0x00); } static int rc632_usb_in(struct req_ctx *rctx) @@ -434,7 +434,7 @@ static int rc632_usb_in(struct req_ctx *rctx) switch (poh->cmd) { case OPENPCD_CMD_READ_REG: - rc632_reg_read(RAH, poh->reg, &poh->val); + opcd_rc632_reg_read(NULL, poh->reg, &poh->val); DEBUGP("READ REG(0x%02x)=0x%02x ", poh->reg, poh->val); /* register read always has to provoke a response */ poh->flags &= OPENPCD_FLAG_RESPOND; @@ -448,7 +448,7 @@ static int rc632_usb_in(struct req_ctx *rctx) if (req_len > MAX_PAYLOAD_LEN) { pih_len = MAX_PAYLOAD_LEN; remain_len -= pih_len; - rc632_fifo_read(RAH, pih_len, poh->data); + opcd_rc632_fifo_read(NULL, pih_len, poh->data); rctx->tot_len += pih_len; DEBUGP("READ FIFO(len=%u)=%s ", req_len, hexdump(poh->data, pih_len)); @@ -466,7 +466,7 @@ static int rc632_usb_in(struct req_ctx *rctx) rctx->tot_len = sizeof(*poh); pih_len = remain_len; - rc632_fifo_read(RAH, pih_len, poh->data); + opcd_rc632_fifo_read(NULL, pih_len, poh->data); rctx->tot_len += pih_len; DEBUGP("READ FIFO(len=%u)=%s ", pih_len, hexdump(poh->data, pih_len)); @@ -474,7 +474,7 @@ static int rc632_usb_in(struct req_ctx *rctx) * body will do this after switch statement */ } else { #endif - poh->val = rc632_fifo_read(RAH, req_len, poh->data); + poh->val = opcd_rc632_fifo_read(NULL, req_len, poh->data); rctx->tot_len += poh->val; DEBUGP("READ FIFO(len=%u)=%s ", poh->val, hexdump(poh->data, poh->val)); @@ -483,16 +483,16 @@ static int rc632_usb_in(struct req_ctx *rctx) break; case OPENPCD_CMD_WRITE_REG: DEBUGP("WRITE_REG(0x%02x, 0x%02x) ", poh->reg, poh->val); - rc632_reg_write(RAH, poh->reg, poh->val); + opcd_rc632_reg_write(NULL, poh->reg, poh->val); break; case OPENPCD_CMD_WRITE_REG_SET: DEBUGP("WRITE_REG_SET(%s) ", hexdump(poh->data, len)); - rc632_reg_write_set(RAH, poh->data, len); + opcd_rc632_reg_write_set(NULL, poh->data, len); break; case OPENPCD_CMD_WRITE_FIFO: DEBUGP("WRITE FIFO(len=%u): %s ", len, hexdump(poh->data, len)); - rc632_fifo_write(RAH, len, poh->data, 0); + opcd_rc632_fifo_write(NULL, len, poh->data, 0); break; case OPENPCD_CMD_READ_VFIFO: DEBUGP("READ VFIFO "); @@ -504,11 +504,11 @@ static int rc632_usb_in(struct req_ctx *rctx) break; case OPENPCD_CMD_REG_BITS_CLEAR: DEBUGP("CLEAR BITS "); - poh->val = rc632_clear_bits(RAH, poh->reg, poh->val); + poh->val = opcd_rc632_clear_bits(NULL, poh->reg, poh->val); break; case OPENPCD_CMD_REG_BITS_SET: DEBUGP("SET BITS "); - poh->val = rc632_set_bits(RAH, poh->reg, poh->val); + poh->val = opcd_rc632_set_bits(NULL, poh->reg, poh->val); break; case OPENPCD_CMD_DUMP_REGS: DEBUGP("DUMP REGS "); @@ -575,13 +575,13 @@ void rc632_init(void) rc632_reset(); /* configure IRQ pin */ - rc632_reg_write(RAH, RC632_REG_IRQ_PIN_CONFIG, - RC632_IRQCFG_CMOS|RC632_IRQCFG_INV); + opcd_rc632_reg_write(NULL, RC632_REG_IRQ_PIN_CONFIG, + RC632_IRQCFG_CMOS|RC632_IRQCFG_INV); /* enable interrupts */ - rc632_reg_write(RAH, RC632_REG_INTERRUPT_EN, RC632_INT_TIMER); + opcd_rc632_reg_write(NULL, RC632_REG_INTERRUPT_EN, RC632_INT_TIMER); /* configure AUX to test signal four */ - rc632_reg_write(RAH, RC632_REG_TEST_ANA_SELECT, 0x04); + opcd_rc632_reg_write(NULL, RC632_REG_TEST_ANA_SELECT, 0x04); usb_hdlr_register(&rc632_usb_in, OPENPCD_CMD_CLS_RC632); }; @@ -602,8 +602,8 @@ static int rc632_reg_write_verify(struct rfid_asic_handle *hdl, { u_int8_t tmp; - rc632_reg_write(hdl, reg, val); - rc632_reg_read(hdl, reg, &tmp); + opcd_rc632_reg_write(hdl, reg, val); + opcd_rc632_reg_read(hdl, reg, &tmp); DEBUGPCRF("reg=0x%02x, write=0x%02x, read=0x%02x ", reg, val, tmp); diff --git a/firmware/src/pcd/rc632.h b/firmware/src/pcd/rc632.h index 1a4dc22..bb56d18 100644 --- a/firmware/src/pcd/rc632.h +++ b/firmware/src/pcd/rc632.h @@ -4,19 +4,20 @@ #include #include #include +#include -extern int rc632_reg_write(struct rfid_asic_handle *hdl, - u_int8_t addr, u_int8_t data); -extern int rc632_fifo_write(struct rfid_asic_handle *hdl, - u_int8_t len, u_int8_t *data, u_int8_t flags); -extern int rc632_reg_read(struct rfid_asic_handle *hdl, - u_int8_t addr, u_int8_t *val); -extern int rc632_fifo_read(struct rfid_asic_handle *hdl, - u_int8_t max_len, u_int8_t *data); -extern int rc632_clear_bits(struct rfid_asic_handle *hdl, - u_int8_t reg, u_int8_t bits); -extern int rc632_set_bits(struct rfid_asic_handle *hdl, - u_int8_t reg, u_int8_t bits); +extern int opcd_rc632_reg_write(struct rfid_asic_handle *hdl, + u_int8_t addr, u_int8_t data); +extern int opcd_rc632_fifo_write(struct rfid_asic_handle *hdl, + u_int8_t len, u_int8_t *data, u_int8_t flags); +extern int opcd_rc632_reg_read(struct rfid_asic_handle *hdl, + u_int8_t addr, u_int8_t *val); +extern int opcd_rc632_fifo_read(struct rfid_asic_handle *hdl, + u_int8_t max_len, u_int8_t *data); +extern int opcd_rc632_clear_bits(struct rfid_asic_handle *hdl, + u_int8_t reg, u_int8_t bits); +extern int opcd_rc632_set_bits(struct rfid_asic_handle *hdl, + u_int8_t reg, u_int8_t bits); extern void rc632_init(void); extern void rc632_exit(void); diff --git a/firmware/src/pcd/rc632_highlevel.c b/firmware/src/pcd/rc632_highlevel.c index 0701da2..b83f52b 100644 --- a/firmware/src/pcd/rc632_highlevel.c +++ b/firmware/src/pcd/rc632_highlevel.c @@ -54,7 +54,7 @@ rc632_set_bit_mask(struct rfid_asic_handle *handle, int ret; u_int8_t tmp; - ret = rc632_reg_read(handle, reg, &tmp); + ret = opcd_rc632_reg_read(handle, reg, &tmp); if (ret < 0) return ret; @@ -62,317 +62,38 @@ rc632_set_bit_mask(struct rfid_asic_handle *handle, if ((tmp & mask) == val) return 0; - return rc632_reg_write(handle, reg, (tmp & ~mask)|(val & mask)); + return opcd_rc632_reg_write(handle, reg, (tmp & ~mask)|(val & mask)); } int rc632_turn_on_rf(struct rfid_asic_handle *handle) { ENTER(); - return rc632_set_bits(handle, RC632_REG_TX_CONTROL, 0x03); + return opcd_rc632_set_bits(handle, RC632_REG_TX_CONTROL, 0x03); } int rc632_turn_off_rf(struct rfid_asic_handle *handle) { ENTER(); - return rc632_clear_bits(handle, RC632_REG_TX_CONTROL, 0x03); + return opcd_rc632_clear_bits(handle, RC632_REG_TX_CONTROL, 0x03); } static int rc632_power_up(struct rfid_asic_handle *handle) { ENTER(); - return rc632_clear_bits(handle, RC632_REG_CONTROL, + return opcd_rc632_clear_bits(handle, RC632_REG_CONTROL, RC632_CONTROL_POWERDOWN); } static int rc632_power_down(struct rfid_asic_handle *handle) { - return rc632_set_bits(handle, RC632_REG_CONTROL, + return opcd_rc632_set_bits(handle, RC632_REG_CONTROL, RC632_CONTROL_POWERDOWN); } -/* calculate best 8bit prescaler and divisor for given usec timeout */ -static int best_prescaler(u_int64_t timeout, u_int8_t *prescaler, - u_int8_t *divisor) -{ - u_int8_t best_presc, best_divisor, i; - int64_t smallest_diff; - - smallest_diff = 0x7fffffffffffffff; - best_presc = 0; - - for (i = 0; i < 21; i++) { - u_int64_t clk, tmp_div, res; - int64_t diff; - clk = 13560000 / (1 << i); - tmp_div = (clk * timeout) / 1000000; - tmp_div++; - - if (tmp_div > 0xff) - continue; - - res = 1000000 / (clk / tmp_div); - diff = res - timeout; - - if (diff < 0) - continue; - - if (diff < smallest_diff) { - best_presc = i; - best_divisor = tmp_div; - smallest_diff = diff; - } - } - - *prescaler = best_presc; - *divisor = best_divisor; - - DEBUGPCRF("timeout %u usec, prescaler = %u, divisor = %u", timeout, best_presc, best_divisor); - - return 0; -} - -static int -rc632_timer_set(struct rfid_asic_handle *handle, - u_int64_t timeout) -{ - int ret; - u_int8_t prescaler, divisor; - - ret = best_prescaler(timeout*RC632_TIMEOUT_FUZZ_FACTOR, - &prescaler, &divisor); - - ret = rc632_reg_write(handle, RC632_REG_TIMER_CLOCK, - prescaler & 0x1f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_TIMER_CONTROL, - RC632_TMR_START_TX_END|RC632_TMR_STOP_RX_BEGIN); - - /* clear timer irq bit */ - ret |= rc632_set_bits(handle, RC632_REG_INTERRUPT_RQ, RC632_INT_TIMER); - -#ifdef USE_IRQ_ - /* enable interrupt for expired timer */ - ret |= rc632_reg_write(handle, RC632_REG_INTERRUPT_EN, - RC632_INT_TIMER|RC632_INT_SET); -#endif - - ret |= rc632_reg_write(handle, RC632_REG_TIMER_RELOAD, divisor); - - return ret; -} - -/* Wait until RC632 is idle or TIMER IRQ has happened */ -static int rc632_wait_idle_timer(struct rfid_asic_handle *handle) -{ - int ret; - u_int8_t irq, cmd; - - while (1) { - ret = rc632_reg_read(handle, RC632_REG_INTERRUPT_RQ, &irq); - if (ret < 0) - return ret; - - /* FIXME: currently we're lazy: If we actually received - * something even after the timer expired, we accept it */ - if (irq & RC632_INT_TIMER && !(irq & RC632_INT_RX)) { - u_int8_t foo; - rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &foo); - DEBUGPCRF("TIMER && !INT_RX, PRIM_STATUS=0x%02x", foo); - if (foo & 0x04) { - rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &foo); - DEBUGPCRF("ERROR_FLAG=0x%02x, returning timeout", foo); - } - - return -ETIMEDOUT; - } - - ret = rc632_reg_read(handle, RC632_REG_COMMAND, &cmd); - if (ret < 0) - return ret; - - if (cmd == 0 || irq & RC632_INT_RX) - return 0; - - /* poll every millisecond */ - /* FIXME usleep(1000);*/ - } -} - -/* Stupid RC632 implementations don't evaluate interrupts but poll the - * command register for "status idle" */ -static int -rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) -{ - u_int8_t cmd = 0xff; - int ret, cycles = 0; -#define USLEEP_PER_CYCLE 128 - - while (cmd != 0) { - ret = rc632_reg_read(handle, RC632_REG_COMMAND, &cmd); - if (ret < 0) - return ret; - - if (cmd == 0) { - /* FIXME: read second time ?? */ - return 0; - } - - { - u_int8_t foo; - rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &foo); - if (foo & 0x04) - rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &foo); - } - - /* Abort after some timeout */ - if (cycles > timeout*RC632_TIMEOUT_FUZZ_FACTOR/USLEEP_PER_CYCLE) { - return -ETIMEDOUT; - } - - cycles++; - usleep(USLEEP_PER_CYCLE); - } - - return 0; -} - -static int -rc632_transmit(struct rfid_asic_handle *handle, - const u_int8_t *buf, - u_int8_t len, - u_int64_t timeout) -{ - int ret, cur_len; - const u_int8_t *cur_buf = buf; - - if (len > 64) - cur_len = 64; - else - cur_len = len; - - do { - ret = rc632_fifo_write(handle, cur_len, cur_buf, 0x03); - if (ret < 0) - return ret; - - if (cur_buf == buf) { - /* only start transmit first time */ - ret = rc632_reg_write(handle, RC632_REG_COMMAND, - RC632_CMD_TRANSMIT); - if (ret < 0) - return ret; - } - - cur_buf += cur_len; - if (cur_buf < buf + len) { - cur_len = buf - cur_buf; - if (cur_len > 64) - cur_len = 64; - } else - cur_len = 0; - - } while (cur_len); - - return rc632_wait_idle(handle, timeout); -} - -static int -tcl_toggle_pcb(struct rfid_asic_handle *handle) -{ - // FIXME: toggle something between 0x0a and 0x0b - return 0; -} - -static int -rc632_transceive(struct rfid_asic_handle *handle, - const u_int8_t *tx_buf, - u_int8_t tx_len, - u_int8_t *rx_buf, - u_int8_t *rx_len, - u_int64_t timer, - unsigned int toggle) -{ - int ret, cur_tx_len; - const u_int8_t *cur_tx_buf = tx_buf; - - DEBUGPCRF("tx_len=%u, rx_len=%u, timer=%llu", tx_len, *rx_len, timer); - - if (tx_len > 64) - cur_tx_len = 64; - else - cur_tx_len = tx_len; - - ret = rc632_reg_write(handle, RC632_REG_COMMAND, 0x00); - /* clear all interrupts */ - ret = rc632_reg_write(handle, RC632_REG_INTERRUPT_RQ, 0x7f); - if (ret < 0) - return ret; - - ret = rc632_timer_set(handle, timer); - if (ret < 0) - return ret; - - do { - ret = rc632_fifo_write(handle, cur_tx_len, cur_tx_buf, 0x03); - if (ret < 0) - return ret; - - if (cur_tx_buf == tx_buf) { - ret = rc632_reg_write(handle, RC632_REG_COMMAND, - RC632_CMD_TRANSCEIVE); - if (ret < 0) - return ret; - } - - cur_tx_buf += cur_tx_len; - if (cur_tx_buf < tx_buf + tx_len) { - u_int8_t fifo_fill; - ret = rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, - &fifo_fill); - if (ret < 0) - return ret; - - cur_tx_len = 64 - fifo_fill; - DEBUGPCRF("refilling tx fifo with %u bytes", cur_tx_len); - } else - cur_tx_len = 0; - - } while (cur_tx_len); - - if (toggle == 1) - tcl_toggle_pcb(handle); - - ret = rc632_wait_idle_timer(handle); - if (ret < 0) - return ret; - - ret = rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, rx_len); - if (ret < 0) - return ret; - - DEBUGPCRF("rx_len = %u\n", *rx_len); - - if (*rx_len == 0) { - u_int8_t tmp, tmp2; - - rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &tmp); - rc632_reg_read(handle, RC632_REG_CHANNEL_REDUNDANCY, &tmp2); - - DEBUGPCRF("rx_len == 0, error_flag=0x%02x, channel_red=0x%02x", - tmp, tmp2); - - return -1; - } - - return rc632_fifo_read(handle, *rx_len, rx_buf); -} - int rc632_read_eeprom(struct rfid_asic_handle *handle, u_int16_t addr, u_int8_t len, u_int8_t *recvbuf) @@ -385,1094 +106,31 @@ rc632_read_eeprom(struct rfid_asic_handle *handle, u_int16_t addr, u_int8_t len, sndbuf[1] = addr >> 8; sndbuf[2] = len; - ret = rc632_fifo_write(handle, 3, sndbuf, 0x03); + ret = opcd_rc632_fifo_write(handle, 3, sndbuf, 0x03); if (ret < 0) return ret; - ret = rc632_reg_write(handle, RC632_REG_COMMAND, RC632_CMD_READ_E2); + ret = opcd_rc632_reg_write(handle, RC632_REG_COMMAND, RC632_CMD_READ_E2); if (ret < 0) return ret; /* usleep(20000); */ - ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &err); + ret = opcd_rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &err); if (err & RC632_ERR_FLAG_ACCESS_ERR) return -EPERM; - ret = rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, &err); + ret = opcd_rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, &err); if (err < len) len = err; - ret = rc632_fifo_read(handle, len, recvbuf); + ret = opcd_rc632_fifo_read(handle, len, recvbuf); if (ret < 0) return ret; return len; } -static int -rc632_calc_crc16_from(struct rfid_asic_handle *handle) -{ - u_int8_t sndbuf[2] = { 0x01, 0x02 }; - u_int8_t crc_lsb = 0x00 , crc_msb = 0x00; - int ret; - - ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_LSB, 0x12); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_MSB, 0xe0); - if (ret < 0) - return ret; - - ret = rc632_fifo_write(handle, sizeof(sndbuf), sndbuf, 3); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_COMMAND, RC632_CMD_CALC_CRC); - if (ret < 0) - return ret; - - usleep(10000); // FIXME: no checking for cmd completion? - - ret = rc632_reg_read(handle, RC632_REG_CRC_RESULT_LSB, &crc_lsb); - if (ret < 0) - return ret; - - ret = rc632_reg_read(handle, RC632_REG_CRC_RESULT_MSB, &crc_msb); - if (ret < 0) - return ret; - - // FIXME: what to do with crc result? - return ret; -} - - -int -rc632_register_dump(struct rfid_asic_handle *handle, u_int8_t *buf) -{ - int ret; - u_int8_t i; - - for (i = 0; i <= 0x3f; i++) { - ret = rc632_reg_read(handle, i, &buf[i]); - // do we want error checks? - } - return 0; -} - - -#if 0 -static int -rc632_init(struct rfid_asic_handle *ah) -{ - int ret; - - /* switch off rf (make sure PICCs are reset at init time) */ - ret = rc632_power_down(ah); - if (ret < 0) - return ret; - - usleep(10000); - - /* switch on rf */ - ret = rc632_power_up(ah); - if (ret < 0) - return ret; - - /* disable register paging */ - ret = rc632_reg_write(ah, 0x00, 0x00); - if (ret < 0) - return ret; - - /* set some sane default values */ - ret = rc632_reg_write(ah, 0x11, 0x5b); - if (ret < 0) - return ret; - - /* switch on rf */ - ret = rc632_turn_on_rf(ah); - if (ret < 0) - return ret; - - return 0; -} - -static int -rc632_fini(struct rfid_asic_handle *ah) -{ - int ret; - - /* switch off rf */ - ret = rc632_turn_off_rf(ah); - if (ret < 0) - return ret; - - ret = rc632_power_down(ah); - if (ret < 0) - return ret; - - return 0; -} -#endif - - -/* - * Philips CL RC632 primitives for ISO 14443-A compliant PICC's - * - * (C) 2005 by Harald Welte - * - */ - -int -rc632_iso14443a_init(struct rfid_asic_handle *handle) -{ - int ret; - - // FIXME: some fifo work (drain fifo?) - - /* flush fifo (our way) */ - ret = rc632_reg_write(handle, RC632_REG_CONTROL, 0x01); - - ret = rc632_reg_write(handle, RC632_REG_TX_CONTROL, - (RC632_TXCTRL_TX1_RF_EN | - RC632_TXCTRL_TX2_RF_EN | - RC632_TXCTRL_TX2_INV | - RC632_TXCTRL_FORCE_100_ASK | - RC632_TXCTRL_MOD_SRC_INT)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CW_CONDUCTANCE, - OPENPCD_CW_CONDUCTANCE); - if (ret < 0) - return ret; - - /* Since FORCE_100_ASK is set (cf mc073930.pdf), this line may be left out? */ - ret = rc632_reg_write(handle, RC632_REG_MOD_CONDUCTANCE, - OPENPCD_MOD_CONDUCTANCE); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CODER_CONTROL, - (RC632_CDRCTRL_TXCD_14443A | - RC632_CDRCTRL_RATE_106K)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH, 0x13); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_TYPE_B_FRAMING, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_CONTROL1, - (RC632_RXCTRL1_GAIN_35DB | - RC632_RXCTRL1_ISO14443 | - RC632_RXCTRL1_SUBCP_8)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_DECODER_CONTROL, - (RC632_DECCTRL_MANCHESTER | - RC632_DECCTRL_RXFR_14443A)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_BIT_PHASE, - OPENPCD_14443A_BITPHASE); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_THRESHOLD, - OPENPCD_14443A_THRESHOLD); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_BPSK_DEM_CONTROL, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_CONTROL2, - (RC632_RXCTRL2_DECSRC_INT | - RC632_RXCTRL2_CLK_Q)); - if (ret < 0) - return ret; - - /* Omnikey proprietary driver has 0x03, but 0x06 is the default reset value ?!? */ - ret = rc632_reg_write(handle, RC632_REG_RX_WAIT, 0x06); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_PARITY_ENABLE | - RC632_CR_PARITY_ODD)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_LSB, 0x63); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_MSB, 0x63); - if (ret < 0) - return ret; - - return 0; -} - -static int -rc632_iso14443a_fini(struct iso14443a_handle *handle_14443) -{ - -#if 0 - ret = rc632_turn_off_rf(handle); - if (ret < 0) - return ret; -#endif - - - return 0; -} - - -/* issue a 14443-3 A PCD -> PICC command in a short frame, such as REQA, WUPA */ -int -rc632_iso14443a_transceive_sf(struct rfid_asic_handle *handle, - u_int8_t cmd, - struct iso14443a_atqa *atqa) -{ - int ret; - u_int8_t tx_buf[1]; - u_int8_t rx_len = 2; - - DEBUGPCRF(""); - memset(atqa, 0, sizeof(*atqa)); - - tx_buf[0] = cmd; - - /* transfer only 7 bits of last byte in frame */ - ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING, 0x07); - if (ret < 0) - return ret; - - ret = rc632_clear_bits(handle, RC632_REG_CONTROL, - RC632_CONTROL_CRYPTO1_ON); - if (ret < 0) - return ret; - -#if 0 - ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_PARITY_ENABLE | - RC632_CR_PARITY_ODD)); -#else - ret = rc632_clear_bits(handle, RC632_REG_CHANNEL_REDUNDANCY, - RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE); - -#endif - if (ret < 0) - return ret; - - ret = rc632_transceive(handle, tx_buf, sizeof(tx_buf), - (u_int8_t *)atqa, &rx_len, - ISO14443A_FDT_ANTICOL_LAST1, 0); - if (ret < 0) { - DEBUGPCRF("error during rc632_transceive()"); - return ret; - } - - /* switch back to normal 8bit last byte */ - ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING, 0x00); - if (ret < 0) - return ret; - - if (rx_len != 2) { - DEBUGPCRF("rx_len(%d) != 2", rx_len); - return -1; - } - - return 0; -} - -/* transceive regular frame */ -int -rc632_iso14443ab_transceive(struct rfid_asic_handle *handle, - unsigned int frametype, - const u_int8_t *tx_buf, unsigned int tx_len, - u_int8_t *rx_buf, unsigned int *rx_len, - u_int64_t timeout, unsigned int flags) -{ - int ret; - u_int8_t rxl = *rx_len & 0xff; - u_int8_t channel_red; - - DEBUGPCRF("tx_len=%u, rx_len=%u", tx_len, *rx_len); - - memset(rx_buf, 0, *rx_len); - - switch (frametype) { - case RFID_14443A_FRAME_REGULAR: - case RFID_MIFARE_FRAME: - channel_red = RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE - |RC632_CR_PARITY_ENABLE|RC632_CR_PARITY_ODD; - break; - case RFID_14443B_FRAME_REGULAR: - channel_red = RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE - |RC632_CR_CRC3309; - break; -#if 0 - case RFID_MIFARE_FRAME: - channel_red = RC632_CR_PARITY_ENABLE|RC632_CR_PARITY_ODD; - break; -#endif - default: - return -EINVAL; - break; - } - ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY, - channel_red); - if (ret < 0) - return ret; - - ret = rc632_transceive(handle, tx_buf, tx_len, rx_buf, &rxl, timeout, 0); - *rx_len = rxl; - if (ret < 0) - return ret; - - - return 0; -} - -/* transceive anti collission bitframe */ -int -rc632_iso14443a_transceive_acf(struct rfid_asic_handle *handle, - struct iso14443a_anticol_cmd *acf, - unsigned int *bit_of_col) -{ - int ret; - u_int8_t rx_buf[64]; - u_int8_t rx_len = sizeof(rx_buf); - u_int8_t rx_align = 0, tx_last_bits, tx_bytes; - u_int8_t boc; - u_int8_t error_flag; - *bit_of_col = ISO14443A_BITOFCOL_NONE; - memset(rx_buf, 0, sizeof(rx_buf)); - - /* disable mifare cryto */ - ret = rc632_clear_bits(handle, RC632_REG_CONTROL, - RC632_CONTROL_CRYPTO1_ON); - if (ret < 0) - return ret; - - /* disable CRC summing */ -#if 0 - ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_PARITY_ENABLE | - RC632_CR_PARITY_ODD)); -#else - ret = rc632_clear_bits(handle, RC632_REG_CHANNEL_REDUNDANCY, - RC632_CR_TX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE); -#endif - if (ret < 0) - return ret; - - tx_last_bits = acf->nvb & 0x0f; /* lower nibble indicates bits */ - tx_bytes = acf->nvb >> 4; - if (tx_last_bits) { - tx_bytes++; - rx_align = (tx_last_bits+1) % 8;/* rx frame complements tx */ - } - - //rx_align = 8 - tx_last_bits;/* rx frame complements tx */ - - /* set RxAlign and TxLastBits*/ - ret = rc632_reg_write(handle, RC632_REG_BIT_FRAMING, - (rx_align << 4) | (tx_last_bits)); - if (ret < 0) - return ret; - - ret = rc632_transceive(handle, (u_int8_t *)acf, tx_bytes, - rx_buf, &rx_len, 0x32, 0); - if (ret < 0) - return ret; - - /* bitwise-OR the two halves of the split byte */ - acf->uid_bits[tx_bytes-2] = ( - (acf->uid_bits[tx_bytes-2] & (0xff >> (8-tx_last_bits))) - | rx_buf[0]); - /* copy the rest */ - memcpy(&acf->uid_bits[tx_bytes+1-2], &rx_buf[1], rx_len-1); - - /* determine whether there was a collission */ - ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &error_flag); - if (ret < 0) - return ret; - - if (error_flag & RC632_ERR_FLAG_COL_ERR) { - /* retrieve bit of collission */ - ret = rc632_reg_read(handle, RC632_REG_COLL_POS, &boc); - if (ret < 0) - return ret; - - /* bit of collission relative to start of part 1 of - * anticollision frame (!) */ - *bit_of_col = 2*8 + boc; - } - - return 0; -} - -enum rc632_rate { - RC632_RATE_106 = 0x00, - RC632_RATE_212 = 0x01, - RC632_RATE_424 = 0x02, - RC632_RATE_848 = 0x03, -}; - -struct rx_config { - u_int8_t subc_pulses; - u_int8_t rx_coding; - u_int8_t rx_threshold; - u_int8_t bpsk_dem_ctrl; -}; - -struct tx_config { - u_int8_t rate; - u_int8_t mod_width; -}; - -static const struct rx_config rx_configs[] = { - { - .subc_pulses = RC632_RXCTRL1_SUBCP_8, - .rx_coding = RC632_DECCTRL_MANCHESTER, - .rx_threshold = 0x88, - .bpsk_dem_ctrl = 0x00, - }, - { - .subc_pulses = RC632_RXCTRL1_SUBCP_4, - .rx_coding = RC632_DECCTRL_BPSK, - .rx_threshold = 0x50, - .bpsk_dem_ctrl = 0x0c, - }, - { - .subc_pulses = RC632_RXCTRL1_SUBCP_2, - .rx_coding = RC632_DECCTRL_BPSK, - .rx_threshold = 0x50, - .bpsk_dem_ctrl = 0x0c, - }, - { - .subc_pulses = RC632_RXCTRL1_SUBCP_1, - .rx_coding = RC632_DECCTRL_BPSK, - .rx_threshold = 0x50, - .bpsk_dem_ctrl = 0x0c, - }, -}; - -static const struct tx_config tx_configs[] = { - { - .rate = RC632_CDRCTRL_RATE_106K, - .mod_width = 0x13, - }, - { - .rate = RC632_CDRCTRL_RATE_212K, - .mod_width = 0x07, - }, - { - .rate = RC632_CDRCTRL_RATE_424K, - .mod_width = 0x03, - }, - { - .rate = RC632_CDRCTRL_RATE_848K, - .mod_width = 0x01, - }, -}; - -int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle, - unsigned int tx, - u_int8_t rate) -{ - int rc; - u_int8_t reg; - - - if (!tx) { - /* Rx */ - if (rate > ARRAY_SIZE(rx_configs)) - return -EINVAL; - - rc = rc632_set_bit_mask(handle, RC632_REG_RX_CONTROL1, - RC632_RXCTRL1_SUBCP_MASK, - rx_configs[rate].subc_pulses); - if (rc < 0) - return rc; - - rc = rc632_set_bit_mask(handle, RC632_REG_DECODER_CONTROL, - RC632_DECCTRL_BPSK, - rx_configs[rate].rx_coding); - if (rc < 0) - return rc; - - rc = rc632_reg_write(handle, RC632_REG_RX_THRESHOLD, - rx_configs[rate].rx_threshold); - if (rc < 0) - return rc; - - if (rx_configs[rate].rx_coding == RC632_DECCTRL_BPSK) { - rc = rc632_reg_write(handle, - RC632_REG_BPSK_DEM_CONTROL, - rx_configs[rate].bpsk_dem_ctrl); - if (rc < 0) - return rc; - } - } else { - /* Tx */ - if (rate > ARRAY_SIZE(tx_configs)) - return -EINVAL; - - rc = rc632_set_bit_mask(handle, RC632_REG_CODER_CONTROL, - RC632_CDRCTRL_RATE_MASK, - tx_configs[rate].rate); - if (rc < 0) - return rc; - - rc = rc632_reg_write(handle, RC632_REG_MOD_WIDTH, - tx_configs[rate].mod_width); - if (rc < 0) - return rc; - } - - return 0; -} - -static int rc632_iso14443b_init(struct rfid_asic_handle *handle) -{ - int ret; - - // FIXME: some FIFO work - - /* flush fifo (our way) */ - ret = rc632_reg_write(handle, RC632_REG_CONTROL, 0x01); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_TX_CONTROL, - (RC632_TXCTRL_TX1_RF_EN | - RC632_TXCTRL_TX2_RF_EN | - RC632_TXCTRL_TX2_INV | - RC632_TXCTRL_MOD_SRC_INT)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CW_CONDUCTANCE, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_MOD_CONDUCTANCE, 0x04); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CODER_CONTROL, - (RC632_CDRCTRL_TXCD_NRZ | - RC632_CDRCTRL_RATE_14443B)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH, 0x13); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_TYPE_B_FRAMING, - (RC632_TBFRAMING_SOF_11L_3H | - (6 << RC632_TBFRAMING_SPACE_SHIFT) | - RC632_TBFRAMING_EOF_11)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_CONTROL1, - (RC632_RXCTRL1_GAIN_35DB | - RC632_RXCTRL1_ISO14443 | - RC632_RXCTRL1_SUBCP_8)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_DECODER_CONTROL, - (RC632_DECCTRL_BPSK | - RC632_DECCTRL_RXFR_14443B)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_BIT_PHASE, - OPENPCD_14443B_BITPHASE); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_THRESHOLD, - OPENPCD_14443B_THRESHOLD); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_BPSK_DEM_CONTROL, - ((0x2 & RC632_BPSKD_TAUB_MASK)<> 4; - key12[i * 2 + 1] = (~ln << 4) | ln; - key12[i * 2] = (~hn << 4) | hn; - } - return 0; -} - -static int -rc632_mifare_set_key(struct rfid_asic_handle *h, const u_int8_t *key) -{ - u_int8_t coded_key[RFID_MIFARE_KEY_CODED_LEN]; - u_int8_t reg; - int ret; - - ret = rc632_mifare_transform_key(key, coded_key); - if (ret < 0) - return ret; - - ret = rc632_fifo_write(h, RFID_MIFARE_KEY_CODED_LEN, coded_key, 0x03); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_LOAD_KEY); - if (ret < 0) - return ret; - - ret = rc632_wait_idle(h, RC632_TMO_AUTH1); - if (ret < 0) - return ret; - - ret = rc632_reg_read(h, RC632_REG_ERROR_FLAG, ®); - if (ret < 0) - return ret; - - if (reg & RC632_ERR_FLAG_KEY_ERR) - return -EINVAL; - - return 0; -} - -static int -rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno, - u_int8_t block) -{ - int ret; - struct mifare_authcmd acmd; - u_int8_t reg; - - if (cmd != RFID_CMD_MIFARE_AUTH1A && cmd != RFID_CMD_MIFARE_AUTH1B) - return -EINVAL; - - /* Initialize acmd */ - acmd.block_address = block & 0xff; - acmd.auth_cmd = cmd; - //acmd.serno = htonl(serno); - acmd.serno = serno; - - /* Clear Rx CRC */ - ret = rc632_clear_bits(h, RC632_REG_CHANNEL_REDUNDANCY, - RC632_CR_RX_CRC_ENABLE); - if (ret < 0) - return ret; - - /* Send Authent1 Command */ - ret = rc632_fifo_write(h, sizeof(acmd), (unsigned char *)&acmd, 0x03); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_AUTHENT1); - if (ret < 0) - return ret; - - /* Wait until transmitter is idle */ - ret = rc632_wait_idle(h, RC632_TMO_AUTH1); - if (ret < 0) - return ret; - - ret = rc632_reg_read(h, RC632_REG_SECONDARY_STATUS, ®); - if (ret < 0) - return ret; - if (reg & 0x07) - return -EIO; - - /* Clear Tx CRC */ - ret = rc632_clear_bits(h, RC632_REG_CHANNEL_REDUNDANCY, - RC632_CR_TX_CRC_ENABLE); - if (ret < 0) - return ret; - - /* Send Authent2 Command */ - ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_AUTHENT2); - if (ret < 0) - return ret; - - /* Wait until transmitter is idle */ - ret = rc632_wait_idle(h, RC632_TMO_AUTH1); - if (ret < 0) - return ret; - - /* Check whether authentication was successful */ - ret = rc632_reg_read(h, RC632_REG_CONTROL, ®); - if (ret < 0) - return ret; - - if (!(reg & RC632_CONTROL_CRYPTO1_ON)) - return -EACCES; - - return 0; - -} - -/* transceive regular frame */ -static int -rc632_mifare_transceive(struct rfid_asic_handle *handle, - const u_int8_t *tx_buf, unsigned int tx_len, - u_int8_t *rx_buf, unsigned int *rx_len, - u_int64_t timeout, unsigned int flags) -{ - int ret; - u_int8_t rxl = *rx_len & 0xff; - - DEBUGP("entered\n"); - memset(rx_buf, 0, *rx_len); - -#if 1 - ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_PARITY_ENABLE | - RC632_CR_PARITY_ODD | - RC632_CR_TX_CRC_ENABLE | - RC632_CR_RX_CRC_ENABLE)); -#else - ret = rc632_clear_bits(handle, RC632_REG_CHANNEL_REDUNDANCY, - RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE); -#endif - if (ret < 0) - return ret; - - ret = rc632_transceive(handle, tx_buf, tx_len, rx_buf, &rxl, 0x32, 0); - *rx_len = rxl; - if (ret < 0) - return ret; - - - return 0; -} - #define RC632_E2_PRODUCT_TYPE 0 #define RC632_E2_PRODUCT_SERIAL 8 #define RC632_E2_RS_MAX_P 14 diff --git a/firmware/src/pcd/rc632_highlevel.h b/firmware/src/pcd/rc632_highlevel.h new file mode 100644 index 0000000..40e80e0 --- /dev/null +++ b/firmware/src/pcd/rc632_highlevel.h @@ -0,0 +1,19 @@ +#ifndef _RC632_HIGHLEVEL_H +#define _RC632_HIGHLEVEL_H + +#include +#include + +int +rc632_turn_on_rf(struct rfid_asic_handle *handle); + +int +rc632_turn_off_rf(struct rfid_asic_handle *handle); + +int +rc632_read_eeprom(struct rfid_asic_handle *handle, u_int16_t addr, u_int8_t len, + u_int8_t *recvbuf); + +int rc632_get_serial(struct rfid_asic_handle *handle, + u_int32_t *serial); +#endif /* _RC632_HIGHLEVEL_H */ diff --git a/firmware/src/pcd/rfid_layer2_iso14443a.c b/firmware/src/pcd/rfid_layer2_iso14443a.c deleted file mode 100644 index d4f910d..0000000 --- a/firmware/src/pcd/rfid_layer2_iso14443a.c +++ /dev/null @@ -1,319 +0,0 @@ -/* ISO 14443-3 A anticollision implementation - * (C) 2005-2006 by Harald Welte - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 -#include -#include -#include - -#include -#include -//#include -#include - -#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; - DEBUGPCRF(""); - - 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; - DEBUGPCRF(""); - - 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) -{ - DEBUGPCRF("tx_len=%u, rx_len=%u", tx_len, *rx_len); - return rc632_iso14443ab_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 = %d\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 = %d\n", bit_of_col); - if (ret < 0) - return ret; - } - - iso14443a_code_nvb_bits(&acf.nvb, 7*8); - rx_len = sizeof(sak); - 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, - }, -}; -- cgit v1.2.3