Initial commit
[kk_librfid.git] / firmware / src / pcd / .svn / text-base / rc632_highlevel.c.svn-base
blob14a2a2ad629b4c767d360302a55067f5ff91a3d1
1 /* Generic Philips CL RC632 Routines
2  * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by 
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  */
20 #ifdef DEBUG
21 #undef DEBUG
22 #endif
24 #include <sys/types.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <cl_rc632.h>
28 #include "rc632.h"
29 #include <os/dbgu.h>
30 #include <librfid/rfid_layer2_iso14443a.h>
31 #include <librfid/rfid_protocol_mifare_classic.h>
33 /* initially we use the same values as cm5121 */
34 #define OPENPCD_CW_CONDUCTANCE          0x3f
35 #define OPENPCD_MOD_CONDUCTANCE         0x3f
36 #define OPENPCD_14443A_BITPHASE         0xa9
37 #define OPENPCD_14443A_THRESHOLD        0xff
38 #define OPENPCD_14443B_BITPHASE         0xad
39 #define OPENPCD_14443B_THRESHOLD        0xff
41 #define RC632_TMO_AUTH1 14000
43 #define RC632_TIMEOUT_FUZZ_FACTOR       10
45 #define USE_IRQ
47 #define ENTER()         DEBUGPCRF("entering")
48 struct rfid_asic rc632;
50 static int 
51 rc632_set_bit_mask(struct rfid_asic_handle *handle, 
52                    u_int8_t reg, u_int8_t mask, u_int8_t val)
54         int ret;
55         u_int8_t tmp;
57         ret = opcd_rc632_reg_read(handle, reg, &tmp);
58         if (ret < 0)
59                 return ret;
61         /* if bits are already like we want them, abort */
62         if ((tmp & mask) == val)
63                 return 0;
65         return opcd_rc632_reg_write(handle, reg, (tmp & ~mask)|(val & mask));
68 int 
69 rc632_turn_on_rf(struct rfid_asic_handle *handle)
71         ENTER();
72         return opcd_rc632_set_bits(handle, RC632_REG_TX_CONTROL, 0x03);
75 int 
76 rc632_turn_off_rf(struct rfid_asic_handle *handle)
78         ENTER();
79         return opcd_rc632_clear_bits(handle, RC632_REG_TX_CONTROL, 0x03);
82 static int
83 rc632_power_up(struct rfid_asic_handle *handle)
85         ENTER();
86         return opcd_rc632_clear_bits(handle, RC632_REG_CONTROL, 
87                                 RC632_CONTROL_POWERDOWN);
90 static int
91 rc632_power_down(struct rfid_asic_handle *handle)
93         return opcd_rc632_set_bits(handle, RC632_REG_CONTROL,
94                               RC632_CONTROL_POWERDOWN);
97 #define MAX_WRITE_LEN   16      /* see Sec. 18.6.1.2 of RC632 Spec Rev. 3.2. */
99 int
100 rc632_write_eeprom(struct rfid_asic_handle *handle, 
101                    u_int16_t addr, u_int8_t len, u_int8_t *data)
103         u_int8_t sndbuf[MAX_WRITE_LEN + 2];
104         u_int8_t reg;
105         int ret;
107         if (len > MAX_WRITE_LEN)
108                 return -EINVAL;
109         if (addr < 0x10)
110                 return -EPERM;
111         if (addr > 0x1ff)
112                 return -EINVAL;
114         sndbuf[0] = addr & 0x00ff;      /* LSB */
115         sndbuf[1] = addr >> 8;          /* MSB */
116         memcpy(&sndbuf[2], data, len);
118         ret = opcd_rc632_fifo_write(handle, len + 2, sndbuf, 0x03);
119         if (ret < 0)
120                 return ret;
122         ret = opcd_rc632_reg_write(handle, RC632_REG_COMMAND, RC632_CMD_WRITE_E2);
123         if (ret < 0)
124                 return ret;
125         
126         ret = opcd_rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &reg);
127         if (ret < 0)
128                 return ret;
130         if (reg & RC632_ERR_FLAG_ACCESS_ERR)
131                 return -EPERM;
133         while (1) {
134                 ret = opcd_rc632_reg_read(handle, RC632_REG_SECONDARY_STATUS, &reg);
135                 if (ret < 0)
136                         return ret;
138                 if (reg & RC632_SEC_ST_E2_READY) {
139                         /* the E2Write command must be terminated, See sec. 18.6.1.3 */
140                         ret = opcd_rc632_reg_write(handle, RC632_REG_COMMAND, RC632_CMD_IDLE);
141                         break;
142                 }
143         }
144         
145         return ret;
149 rc632_read_eeprom(struct rfid_asic_handle *handle, u_int16_t addr, u_int8_t len,
150                   u_int8_t *recvbuf)
152         u_int8_t sndbuf[3];
153         u_int8_t err;
154         int ret;
156         sndbuf[0] = (addr & 0xff);
157         sndbuf[1] = addr >> 8;
158         sndbuf[2] = len;
160         ret = opcd_rc632_fifo_write(handle, 3, sndbuf, 0x03);
161         if (ret < 0)
162                 return ret;
164         ret = opcd_rc632_reg_write(handle, RC632_REG_COMMAND, RC632_CMD_READ_E2);
165         if (ret < 0)
166                 return ret;
168         /* usleep(20000); */
170         ret = opcd_rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &err);
171         if (err & RC632_ERR_FLAG_ACCESS_ERR)
172                 return -EPERM;
173         
174         ret = opcd_rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, &err);
175         if (err < len)
176                 len = err;
178         ret = opcd_rc632_fifo_read(handle, len, recvbuf);
179         if (ret < 0)
180                 return ret;
182         return len;
185 #define RC632_E2_PRODUCT_TYPE   0
186 #define RC632_E2_PRODUCT_SERIAL 8
187 #define RC632_E2_RS_MAX_P       14
189 int rc632_get_serial(struct rfid_asic_handle *handle,
190                      u_int32_t *serial)
192         return rc632_read_eeprom(handle, RC632_E2_PRODUCT_SERIAL, 
193                                  4, (u_int8_t *)serial);