summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/rfid/rfid.h4
-rw-r--r--include/rfid/rfid_asic_rc632.h1
-rw-r--r--include/rfid/rfid_layer2_iso14443a.h11
-rw-r--r--include/rfid/rfid_reader.h1
-rw-r--r--src/rc632.h3
-rw-r--r--src/rfid_asic_rc632.c135
-rw-r--r--src/rfid_layer2_iso14443a.c12
-rw-r--r--src/rfid_proto_tcl.c42
-rw-r--r--src/rfid_reader_cm5121.c20
9 files changed, 201 insertions, 28 deletions
diff --git a/include/rfid/rfid.h b/include/rfid/rfid.h
index 6bb5b58..6717ef8 100644
--- a/include/rfid/rfid.h
+++ b/include/rfid/rfid.h
@@ -15,8 +15,12 @@ enum rfid_frametype {
#define DEBUGPC(x, args ...) fprintf(stderr, x, ## args)
extern const char *rfid_hexdump(const void *data, unsigned int len);
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
+#endif /* __LIBRFID__ */
+
int rfid_init();
#endif /* _RFID_H */
diff --git a/include/rfid/rfid_asic_rc632.h b/include/rfid/rfid_asic_rc632.h
index 315fee2..e156814 100644
--- a/include/rfid/rfid_asic_rc632.h
+++ b/include/rfid/rfid_asic_rc632.h
@@ -52,6 +52,7 @@ struct rfid_asic_rc632 {
struct iso14443a_anticol_cmd *cmd,
unsigned int *bit_of_col);
int (*set_speed)(struct rfid_asic_handle *h,
+ unsigned int tx,
unsigned int speed);
} iso14443a;
struct {
diff --git a/include/rfid/rfid_layer2_iso14443a.h b/include/rfid/rfid_layer2_iso14443a.h
index bd078ad..fc79bca 100644
--- a/include/rfid/rfid_layer2_iso14443a.h
+++ b/include/rfid/rfid_layer2_iso14443a.h
@@ -2,14 +2,15 @@
#define _RFID_ISO14443A_H
enum rfid_14443a_opt {
- RFID_OPT_14443A_SPEED = 0x00000001,
+ RFID_OPT_14443A_SPEED_RX = 0x00000001,
+ RFID_OPT_14443A_SPEED_TX = 0x00000002,
};
enum rfid_14443_opt_speed {
- RFID_14443A_SPEED_106K,
- RFID_14443A_SPEED_212K,
- RFID_14443A_SPEED_424K,
- RFID_14443A_SPEED_848K,
+ RFID_14443A_SPEED_106K = 0x01,
+ RFID_14443A_SPEED_212K = 0x02,
+ RFID_14443A_SPEED_424K = 0x04,
+ RFID_14443A_SPEED_848K = 0x08,
};
#ifdef __LIBRFID__
diff --git a/include/rfid/rfid_reader.h b/include/rfid/rfid_reader.h
index 364425c..78d07e4 100644
--- a/include/rfid/rfid_reader.h
+++ b/include/rfid/rfid_reader.h
@@ -26,6 +26,7 @@ struct rfid_reader {
struct iso14443a_anticol_cmd *cmd,
unsigned int *bit_of_col);
int (*set_speed)(struct rfid_reader_handle *h,
+ unsigned int tx,
unsigned int speed);
unsigned int speed;
} iso14443a;
diff --git a/src/rc632.h b/src/rc632.h
index 0bd5b00..977b0ee 100644
--- a/src/rc632.h
+++ b/src/rc632.h
@@ -116,7 +116,7 @@ enum rc632_reg_coder_control {
RC632_CDRCTRL_TXCD_14443A = 0x01,
RC632_CDRCTRL_TXCD_ICODE_STD = 0x04,
-#define RC632_CDRDTRL_RATE_MASK 0x38
+#define RC632_CDRCTRL_RATE_MASK 0x38
RC632_CDRCTRL_RATE_848K = 0x00,
RC632_CDRCTRL_RATE_424K = 0x08,
RC632_CDRCTRL_RATE_212K = 0x10,
@@ -151,6 +151,7 @@ enum rc632_reg_rx_control1 {
RC632_RXCTRL1_ISO15693 = 0x08,
RC632_RXCTRL1_ISO14443 = 0x10,
+#define RC632_RXCTRL1_SUBCP_MASK 0xe0
RC632_RXCTRL1_SUBCP_1 = 0x00,
RC632_RXCTRL1_SUBCP_2 = 0x20,
RC632_RXCTRL1_SUBCP_4 = 0x40,
diff --git a/src/rfid_asic_rc632.c b/src/rfid_asic_rc632.c
index e794a38..6de9c11 100644
--- a/src/rfid_asic_rc632.c
+++ b/src/rfid_asic_rc632.c
@@ -96,6 +96,23 @@ rc632_set_bits(struct rfid_asic_handle *handle,
return rc632_reg_write(handle, reg, (tmp|val)&0xff);
}
+static int
+rc632_set_bit_mask(struct rfid_asic_handle *handle,
+ u_int8_t reg, u_int8_t mask, u_int8_t val)
+{
+ int ret;
+ u_int8_t tmp;
+
+ ret = rc632_reg_read(handle, reg, &tmp);
+ if (ret < 0)
+ return ret;
+
+ /* if bits are already like we want them, abort */
+ if ((tmp & mask) == val)
+ return 0;
+
+ return rc632_reg_write(handle, reg, (tmp & ~mask)|(val & mask));
+}
static int
rc632_clear_bits(struct rfid_asic_handle *handle,
@@ -739,20 +756,126 @@ rc632_iso14443a_transcieve_acf(struct rfid_asic_handle *handle,
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 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 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,
+ },
+};
+
static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle,
+ unsigned int tx,
u_int8_t rate)
{
int rc;
u_int8_t reg;
- rc = rc632_reg_read(handle, RC632_REG_CODER_CONTROL, &reg);
- if (rc < 0)
- return rc;
- reg &= ~RC632_CDRDTRL_RATE_MASK;
- reg |= (rate & RC632_CDRDTRL_RATE_MASK);
+ 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 rc632_reg_write(handle, RC632_REG_CODER_CONTROL, reg);
+ return 0;
}
static int rc632_iso14443b_init(struct rfid_asic_handle *handle)
diff --git a/src/rfid_layer2_iso14443a.c b/src/rfid_layer2_iso14443a.c
index d33b316..64a860f 100644
--- a/src/rfid_layer2_iso14443a.c
+++ b/src/rfid_layer2_iso14443a.c
@@ -260,9 +260,17 @@ iso14443a_setopt(struct rfid_layer2_handle *handle, int optname,
unsigned int speed;
switch (optname) {
- case RFID_OPT_14443A_SPEED:
+ case RFID_OPT_14443A_SPEED_RX:
+ if (!rdr->iso14443a.set_speed)
+ return -ENOTSUP;
speed = *(unsigned int *)optval;
- ret = rdr->iso14443a.set_speed(handle->rh, speed);
+ ret = rdr->iso14443a.set_speed(handle->rh, 0, speed);
+ break;
+ case RFID_OPT_14443A_SPEED_TX:
+ if (!rdr->iso14443a.set_speed)
+ return -ENOTSUP;
+ speed = *(unsigned int *)optval;
+ ret = rdr->iso14443a.set_speed(handle->rh, 1, speed);
break;
};
diff --git a/src/rfid_proto_tcl.c b/src/rfid_proto_tcl.c
index 2be20d9..0587611 100644
--- a/src/rfid_proto_tcl.c
+++ b/src/rfid_proto_tcl.c
@@ -36,7 +36,7 @@
#include "rfid_iso14443_common.h"
-#if 1
+#if 0
#ifdef DEBUGP
#undef DEBUGP
#define DEBUGP(x, ...)
@@ -234,27 +234,45 @@ static unsigned char d_to_di(struct rfid_protocol_handle *h, unsigned char D)
return DI;
}
+static unsigned int di_to_speed(unsigned char DI)
+{
+ switch (DI) {
+ case PPS_DIV_8:
+ return RFID_14443A_SPEED_848K;
+ break;
+ case PPS_DIV_4:
+ return RFID_14443A_SPEED_424K;
+ break;
+ case PPS_DIV_2:
+ return RFID_14443A_SPEED_212K;
+ break;
+ case PPS_DIV_1:
+ return RFID_14443A_SPEED_106K;
+ break;
+ }
+}
/* start a PPS run (autimatically configure highest possible speed */
static int
tcl_do_pps(struct rfid_protocol_handle *h)
{
-#if 1
int ret;
unsigned char ppss[3];
unsigned char pps_response[1];
unsigned int rx_len = 1;
unsigned char Dr, Ds, DrI, DsI;
- unsigned int optlen = 0;
+ unsigned int speed;
if (h->priv.tcl.state != TCL_STATE_ATS_RCVD)
return -1;
Dr = h->priv.tcl.ta & 0x07;
Ds = h->priv.tcl.ta & 0x70 >> 4;
+ DEBUGP("Dr = 0x%x, Ds = 0x%x\n", Dr, Ds);
if (Dr != Ds && !(h->priv.tcl.ta & 0x80)) {
- /* device supports different divisors for rx and tx, but not ?!? */
+ /* device supports different divisors for rx and tx, but not
+ * really ?!? */
DEBUGP("PICC has contradictory TA, aborting PPS\n");
return -1;
};
@@ -267,6 +285,7 @@ tcl_do_pps(struct rfid_protocol_handle *h)
/* FIXME: deal with different speed for each direction */
DrI = d_to_di(h, Dr);
DsI = d_to_di(h, Ds);
+ DEBUGP("DrI = 0x%x, DsI = 0x%x\n", DrI, DsI);
ppss[2] = (ppss[2] & 0xf0) | (DrI | DsI << 2);
@@ -281,13 +300,18 @@ tcl_do_pps(struct rfid_protocol_handle *h)
return -1;
}
- ret = rfid_layer2_setopt(h->l2h, RFID_OPT_14443A_SPEED,
- NULL, &optlen);
+ speed = di_to_speed(DrI);
+
+ ret = rfid_layer2_setopt(h->l2h, RFID_OPT_14443A_SPEED_RX,
+ &speed, sizeof(speed));
+ if (ret < 0)
+ return ret;
+
+ ret = rfid_layer2_setopt(h->l2h, RFID_OPT_14443A_SPEED_TX,
+ &speed, sizeof(speed));
if (ret < 0)
return ret;
- h->priv.tcl.state = TCL_STATE_ESTABLISHED;
-#endif
return 0;
}
@@ -438,6 +462,8 @@ tcl_connect(struct rfid_protocol_handle *h)
break;
}
+ h->priv.tcl.state = TCL_STATE_ESTABLISHED;
+
return 0;
}
diff --git a/src/rfid_reader_cm5121.c b/src/rfid_reader_cm5121.c
index f2a8b9a..8baf013 100644
--- a/src/rfid_reader_cm5121.c
+++ b/src/rfid_reader_cm5121.c
@@ -219,28 +219,36 @@ cm5121_14443a_init(struct rfid_reader_handle *rh)
}
static int
-cm5121_14443a_set_speed(struct rfid_reader_handle *rh, unsigned int speed)
+cm5121_14443a_set_speed(struct rfid_reader_handle *rh,
+ unsigned int tx,
+ unsigned int speed)
{
u_int8_t rate;
+ DEBUGP("setting rate: ");
switch (speed) {
case RFID_14443A_SPEED_106K:
- rate = RC632_CDRCTRL_RATE_106K;
+ rate = 0x00;
+ DEBUGPC("106K\n");
break;
case RFID_14443A_SPEED_212K:
- rate = RC632_CDRCTRL_RATE_212K;
+ rate = 0x01;
+ DEBUGPC("212K\n");
break;
case RFID_14443A_SPEED_424K:
- rate = RC632_CDRCTRL_RATE_424K;
+ rate = 0x02;
+ DEBUGPC("424K\n");
break;
case RFID_14443A_SPEED_848K:
- rate = RC632_CDRCTRL_RATE_848K;
+ rate = 0x03;
+ DEBUGPC("848K\n");
break;
default:
return -EINVAL;
break;
}
- return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah, rate);
+ return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
+ tx, rate);
}
static int
personal git repositories of Harald Welte. Your mileage may vary