diff options
-rw-r--r-- | include/rfid/rfid.h | 4 | ||||
-rw-r--r-- | include/rfid/rfid_asic_rc632.h | 1 | ||||
-rw-r--r-- | include/rfid/rfid_layer2_iso14443a.h | 11 | ||||
-rw-r--r-- | include/rfid/rfid_reader.h | 1 | ||||
-rw-r--r-- | src/rc632.h | 3 | ||||
-rw-r--r-- | src/rfid_asic_rc632.c | 135 | ||||
-rw-r--r-- | src/rfid_layer2_iso14443a.c | 12 | ||||
-rw-r--r-- | src/rfid_proto_tcl.c | 42 | ||||
-rw-r--r-- | src/rfid_reader_cm5121.c | 20 |
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, ®); - 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 |