implement and test baud rates of up to 848k
authorHarald Welte <laforge@gnumonks.org>
Tue, 8 Nov 2005 12:19:38 +0000 (12:19 +0000)
committerHarald Welte <laforge@gnumonks.org>
Tue, 8 Nov 2005 12:19:38 +0000 (12:19 +0000)
git-svn-id: https://svn.gnumonks.org/trunk/librfid@1663 e0336214-984f-0b4b-a45f-81c69e1f0ede

include/rfid/rfid.h
include/rfid/rfid_asic_rc632.h
include/rfid/rfid_layer2_iso14443a.h
include/rfid/rfid_reader.h
src/rc632.h
src/rfid_asic_rc632.c
src/rfid_layer2_iso14443a.c
src/rfid_proto_tcl.c
src/rfid_reader_cm5121.c

index 6bb5b58..6717ef8 100644 (file)
@@ -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 */
index 315fee2..e156814 100644 (file)
@@ -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 {
index bd078ad..fc79bca 100644 (file)
@@ -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__
index 364425c..78d07e4 100644 (file)
@@ -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;
index 0bd5b00..977b0ee 100644 (file)
@@ -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,
index e794a38..6de9c11 100644 (file)
@@ -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)
index d33b316..64a860f 100644 (file)
@@ -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;
        };
 
index 2be20d9..0587611 100644 (file)
@@ -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;
 }
 
index f2a8b9a..8baf013 100644 (file)
@@ -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