LibDriver EM4100
Loading...
Searching...
No Matches
driver_em4100.c
Go to the documentation of this file.
1
36
37#include "driver_em4100.h"
38
42#define CHIP_NAME "EM Microelectronic EM4100"
43#define MANUFACTURER_NAME "EM Microelectronic"
44#define SUPPLY_VOLTAGE_MIN 1.5f
45#define SUPPLY_VOLTAGE_MAX 7.5f
46#define MAX_CURRENT 10.0f
47#define TEMPERATURE_MIN -40.0f
48#define TEMPERATURE_MAX 85.0f
49#define DRIVER_VERSION 1000
50
64static uint8_t a_em4100_manchester_decode(uint8_t *input, uint16_t input_len, uint8_t *output, uint16_t *output_len)
65{
66 uint16_t i;
67 uint16_t start;
68 uint16_t l;
69 uint16_t cnt;
70
71 l = input_len; /* set input length */
72 for (i = 0; i < (l - 1); i++) /* check all */
73 {
74 if ((input[i] == 0x01) && (input[i + 1] == 0x01)) /* find header */
75 {
76 break; /* break */
77 }
78 }
79 if (i == (l - 1)) /* check length */
80 {
81 return 1; /* return error */
82 }
83 start = i + 1; /* set start point */
84 cnt = 0; /* init 0 */
85 for (i = start; i < (l - 1); i += 2) /* loop all */
86 {
87 if (cnt >= (*output_len)) /* check output length */
88 {
89 break; /* break */
90 }
91 if ((input[i] == 0x01) && (input[i + 1] == 0x00)) /* 1 */
92 {
93 output[cnt] = 1; /* set 1*/
94 cnt++; /* cnt++ */
95 }
96 else if ((input[i] == 0x00) && (input[i + 1] == 0x01)) /* 0 */
97 {
98 output[cnt] = 0; /* set 0 */
99 cnt++; /* cnt++ */
100 }
101 else
102 {
103 return 2; /* return error */
104 }
105 }
106 *output_len = cnt; /* copy to output length */
107
108 return 0; /* success return 0 */
109}
110
123static uint8_t a_em4100_raw_decode(uint8_t *input, uint16_t input_len, uint8_t *output, uint16_t *output_len)
124{
125 uint16_t i;
126 uint16_t start;
127 uint16_t l;
128 uint16_t cnt;
129
130 l = input_len; /* set input length */
131 for (i = 0; i < (l - 9); i++) /* check all */
132 {
133 if ((input[i + 0] == 0x01) && (input[i + 1] == 0x01) && (input[i + 2] == 0x01) &&
134 (input[i + 3] == 0x01) && (input[i + 4] == 0x01) && (input[i + 5] == 0x01) &&
135 (input[i + 6] == 0x01) && (input[i + 7] == 0x01) && (input[i + 8] == 0x01)) /* find header */
136 {
137 break; /* break */
138 }
139 }
140 if (i == (l - 9)) /* check length */
141 {
142 return 1; /* return error */
143 }
144 start = i; /* set start point */
145 cnt = 0; /* init 0 */
146 for (i = start; i < (l - 9); i++) /* loop all */
147 {
148 if (cnt >= (*output_len)) /* check output length */
149 {
150 break; /* break */
151 }
152 output[cnt] = input[i]; /* set data */
153 cnt++; /* cnt++ */
154 }
155 *output_len = cnt; /* copy to output length */
156
157 return 0; /* success return 0 */
158}
159
172static uint8_t a_em4100_frame_decode(uint8_t input[64], uint8_t output[5])
173{
174 uint16_t i;
175 uint16_t cnt;
176 uint8_t buf[10];
177
178 if ((input[0] != 0x01) || (input[1] != 0x01) || (input[2] != 0x01) ||
179 (input[3] != 0x01) || (input[4] != 0x01) || (input[5] != 0x01) ||
180 (input[6] != 0x01) || (input[7] != 0x01) || (input[8] != 0x01)) /* find header */
181 {
182 return 1; /* return error */
183 }
184 if (input[63] != 0) /* check stop bit */
185 {
186 return 2; /* return error */
187 }
188
189 cnt = 0; /* init 0 */
190 for (i = 9; i < 59; i += 5) /* loop all */
191 {
192 uint8_t t;
193 uint8_t check;
194
195 t = 0; /* init 0 */
196 check = 0; /* init 0 */
197 t |= input[i + 0] << 3; /* copy bit */
198 t |= input[i + 1] << 2; /* copy bit */
199 t |= input[i + 2] << 1; /* copy bit */
200 t |= input[i + 3] << 0; /* copy bit */
201 check = input[i + 0] ^ input[i + 1] ^ input[i + 2] ^
202 input[i + 3] ^ input[i + 4]; /* get check bit */
203 if (check != 0) /* check bit */
204 {
205 return 3; /* return error */
206 }
207 buf[cnt] = t; /* savt one group */
208 cnt++; /* cnt++ */
209 }
210 for (i = 0; i < 4; i++) /* loop all */
211 {
212 uint8_t check;
213
214 check = 0; /* init 0 */
215 check = input[9 + 0 * 5 + i] ^ input[9 + 1 * 5 + i] ^
216 input[9 + 2 * 5 + i] ^ input[9 + 3 * 5 + i] ^
217 input[9 + 4 * 5 + i] ^ input[9 + 5 * 5 + i] ^
218 input[9 + 6 * 5 + i] ^ input[9 + 7 * 5 + i] ^
219 input[9 + 8 * 5 + i] ^ input[9 + 9 * 5 + i] ^
220 input[9 + 10 * 5 + i]; /* get check */
221 if (check != 0) /* check bit */
222 {
223 return 3; /* return error */
224 }
225 }
226 for (i = 0; i < 5; i++) /* loop all */
227 {
228 output[i] = (buf[i * 2 + 0] << 4) | buf[i * 2 + 1]; /* copy data */
229 }
230
231 return 0; /* success return 0 */
232}
233
244static uint8_t a_em4100_read(em4100_handle_t *handle, uint8_t *buf, uint16_t len)
245{
246 if (handle->contactless_read(64, buf, len) != 0) /* contactless read */
247 {
248 return 1; /* return error */
249 }
250
251 return 0; /* success return 0 */
252}
253
265{
266 uint8_t res;
267
268 if (handle == NULL) /* check handle */
269 {
270 return 2; /* return error */
271 }
272 if (handle->debug_print == NULL) /* check debug_print */
273 {
274 return 3; /* return error */
275 }
276 if (handle->contactless_init == NULL) /* check contactless_init */
277 {
278 handle->debug_print("em4100: contactless_init is null.\n"); /* contactless_init is null */
279
280 return 3; /* return error */
281 }
282 if (handle->contactless_deinit == NULL) /* check contactless_deinit */
283 {
284 handle->debug_print("em4100: contactless_deinit is null.\n"); /* contactless_deinit is null */
285
286 return 3; /* return error */
287 }
288 if (handle->contactless_read == NULL) /* check contactless_read */
289 {
290 handle->debug_print("em4100: contactless_read is null.\n"); /* contactless_read is null */
291
292 return 3; /* return error */
293 }
294 if (handle->delay_ms == NULL) /* check delay_ms */
295 {
296 handle->debug_print("em4100: delay_ms is null.\n"); /* delay_ms is null */
297
298 return 3; /* return error */
299 }
300
301 res = handle->contactless_init(); /* contactless init */
302 if (res != 0) /* check the result */
303 {
304 handle->debug_print("em4100: contactless init failed.\n"); /* contactless init failed */
305
306 return 1; /* return error */
307 }
308 handle->inited = 1; /* flag inited */
309
310 return 0; /* success return 0 */
311}
312
324{
325 uint8_t res;
326
327 if (handle == NULL) /* check handle */
328 {
329 return 2; /* return error */
330 }
331 if (handle->inited != 1) /* check handle initialization */
332 {
333 return 3; /* return error */
334 }
335
336 res = handle->contactless_deinit(); /* contactless deinit */
337 if (res != 0) /* check the result */
338 {
339 handle->debug_print("em4100: contactless deinit failed.\n"); /* contactless deinit failed */
340
341 return 1; /* return error */
342 }
343 handle->inited = 0; /* flag close */
344
345 return 0; /* success return 0 */
346}
347
362uint8_t em4100_read(em4100_handle_t *handle, uint8_t id[5])
363{
364 uint8_t res;
365 uint16_t manchester_len;
366 uint16_t raw_len;
367
368 if (handle == NULL) /* check handle */
369 {
370 return 2; /* return error */
371 }
372 if (handle->inited != 1) /* check handle initialization */
373 {
374 return 3; /* return error */
375 }
376
377 res = a_em4100_read(handle, handle->buf, 256); /* read data */
378 if (res != 0) /* check result */
379 {
380 return 4; /* return error */
381 }
382 manchester_len = 128; /* read 128 bytes */
383 res = a_em4100_manchester_decode(handle->buf, 256, handle->manchester_buf, &manchester_len); /* manchester decode */
384 if (res != 0) /* check result */
385 {
386 return 1; /* return error */
387 }
388 raw_len = 64; /* read 64 bytes */
389 res = a_em4100_raw_decode(handle->manchester_buf, manchester_len, handle->raw_buf, &raw_len); /* raw decode */
390 if (res != 0) /* check result */
391 {
392 return 5; /* return error */
393 }
394 if (raw_len != 64) /* check output length */
395 {
396 return 5; /* return error */
397 }
398 res = a_em4100_frame_decode(handle->raw_buf, id); /* frame decode */
399 if (res != 0) /* check result */
400 {
401 return 6; /* return error */
402 }
403
404 return 0; /* success return 0 */
405}
406
417uint8_t em4100_print(em4100_handle_t *handle, uint8_t buf[5])
418{
419 uint32_t id;
420 uint16_t wiegand26;
421
422 if (handle == NULL) /* check handle */
423 {
424 return 2; /* return error */
425 }
426 if (handle->inited != 1) /* check handle initialization */
427 {
428 return 3; /* return error */
429 }
430
431 handle->debug_print("id: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\n",
432 buf[0], buf[1], buf[2], buf[3], buf[4]); /* output */
433 id = ((uint32_t)buf[1] << 24) | ((uint32_t)buf[2] << 16) |
434 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0); /* make id */
435 wiegand26 = ((uint16_t)buf[3] << 8) | ((uint16_t)buf[4] << 0); /* make wiegand26 */
436 handle->debug_print("%010d %03d, %05d.\n", id, buf[2], wiegand26); /* output */
437
438 return 0; /* success return 0 */
439}
440
450{
451 if (info == NULL) /* check handle */
452 {
453 return 2; /* return error */
454 }
455
456 memset(info, 0, sizeof(em4100_info_t)); /* initialize em4100 info structure */
457 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
458 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
459 strncpy(info->interface, "RF", 8); /* copy interface name */
460 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
461 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
462 info->max_current_ma = MAX_CURRENT; /* set maximum current */
463 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
464 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
465 info->driver_version = DRIVER_VERSION; /* set driver version */
466
467 return 0; /* success return 0 */
468}
#define MAX_CURRENT
#define SUPPLY_VOLTAGE_MAX
#define TEMPERATURE_MAX
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#define SUPPLY_VOLTAGE_MIN
#define CHIP_NAME
chip information definition
#define DRIVER_VERSION
driver em4100 header file
uint8_t em4100_deinit(em4100_handle_t *handle)
close the chip
struct em4100_info_s em4100_info_t
em4100 information structure definition
uint8_t em4100_info(em4100_info_t *info)
get chip's information
uint8_t em4100_init(em4100_handle_t *handle)
initialize the chip
struct em4100_handle_s em4100_handle_t
em4100 handle structure definition
uint8_t em4100_print(em4100_handle_t *handle, uint8_t buf[5])
print id
uint8_t em4100_read(em4100_handle_t *handle, uint8_t id[5])
read data
uint8_t buf[256]
uint8_t manchester_buf[128]
void(* delay_ms)(uint32_t ms)
uint8_t raw_buf[64]
void(* debug_print)(const char *const fmt,...)
uint8_t(* contactless_deinit)(void)
uint8_t(* contactless_read)(uint32_t clock_div, uint8_t *buf, uint16_t len)
uint8_t(* contactless_init)(void)
float temperature_max
float supply_voltage_max_v
uint32_t driver_version
float temperature_min
char manufacturer_name[32]
float supply_voltage_min_v
char interface[8]
char chip_name[32]