LibDriver EM4095
Loading...
Searching...
No Matches
driver_em4095.c
Go to the documentation of this file.
1
36
37#include "driver_em4095.h"
38
42#define CHIP_NAME "EM Microelectronic EM4095"
43#define MANUFACTURER_NAME "EM Microelectronic"
44#define SUPPLY_VOLTAGE_MIN 4.1f
45#define SUPPLY_VOLTAGE_MAX 5.5f
46#define MAX_CURRENT 300.0f
47#define TEMPERATURE_MIN -40.0f
48#define TEMPERATURE_MAX 110.0f
49#define DRIVER_VERSION 1000
50
56static void a_em4095_time_diff(em4095_handle_t *handle)
57{
58 uint16_t i;
59 uint16_t len;
60
61 len = handle->decode_len - 1; /* len - 1 */
62 for (i = 0; i < len; i++) /* diff all time */
63 {
64 int64_t diff;
65
66 diff = (int64_t)((int64_t)handle->decode[i + 1].t.s -
67 (int64_t)handle->decode[i].t.s) * 1000000 +
68 (int64_t)((int64_t)handle->decode[i + 1].t.us -
69 (int64_t)handle->decode[i].t.us); /* diff time */
70 handle->decode[i].diff_us = (uint32_t)diff; /* save the time diff */
71 }
72}
73
84static uint8_t a_read_sync(em4095_handle_t *handle)
85{
86 uint8_t res;
87
88 if (handle->start_flag < 1) /* check start flag */
89 {
90 uint8_t level;
91
92 res = handle->demod_gpio_read(&level); /* read gpio level */
93 if (res != 0) /* check result */
94 {
95 handle->debug_print("em4095: demod gpio read failed.\n"); /* demod gpio read failed */
96
97 return 1; /* return error */
98 }
99 if (handle->last_bit != level) /* check last bit */
100 {
101 handle->last_bit = level; /* save bit */
102 handle->start_flag++; /* start flag++ */
103 if (handle->start_flag >= 1) /* check flag */
104 {
105 goto start; /* goto flag */
106 }
107
108 return 2; /* return error */
109 }
110 else
111 {
112 return 3; /* return error */
113 }
114 }
115
116 start:
117 handle->div_len++; /* div length++ */
118 if (handle->div_len >= handle->div) /* wait for div */
119 {
120 handle->div_len = 0; /* init to 0 */
121
122 return 0; /* success return 0 */
123 }
124 else
125 {
126 return 2; /* return error */
127 }
128}
129
138static uint8_t a_write_sync(em4095_handle_t *handle)
139{
140 handle->div_len++; /* div length++ */
141 if (handle->div_len >= handle->div) /* wait for div */
142 {
143 handle->div_len = 0; /* init to 0 */
144
145 return 0; /* success return 0 */
146 }
147 else
148 {
149 return 2; /* return error */
150 }
151}
152
164{
165 uint8_t res;
166 int64_t diff;
168
169 if (handle == NULL) /* check handle */
170 {
171 return 2; /* return error */
172 }
173 if (handle->inited != 1) /* check handle initialization */
174 {
175 return 3; /* return error */
176 }
177
178 if (handle->mode == EM4095_MODE_READ) /* read mode */
179 {
180 uint8_t level;
181
182 if (a_read_sync(handle) != 0) /* wait read sync */
183 {
184 return 0; /* success return 0 */
185 }
186 res = handle->timestamp_read(&t); /* timestamp read */
187 if (res != 0) /* check result */
188 {
189 handle->debug_print("em4095: timestamp read failed.\n"); /* timestamp read failed */
190
191 return 1; /* return error */
192 }
193 res = handle->demod_gpio_read(&level); /* read gpio level */
194 if (res != 0) /* check result */
195 {
196 handle->debug_print("em4095: demod gpio read failed.\n"); /* demod gpio read failed */
197
198 return 1; /* return error */
199 }
200 diff = (int64_t)((int64_t)t.s -
201 (int64_t)handle->last_time.s) * 1000000 +
202 (int64_t)((int64_t)t.us - (int64_t)handle->last_time.us); /* now - last time */
203 if (diff - (int64_t)200000L >= 0) /* if over 1s, force reset */
204 {
205 handle->decode_len = 0; /* reset the decode */
206 }
207 if (handle->decode_len >= (EM4095_MAX_LENGTH - 1)) /* check the max length */
208 {
209 handle->decode_len = 0; /* reset the decode */
210 }
211 handle->decode[handle->decode_len].t.s = t.s; /* save s */
212 handle->decode[handle->decode_len].t.us = t.us; /* save us */
213 handle->decode[handle->decode_len].level = level; /* save level */
214 handle->decode_len++; /* length++ */
215 handle->last_time.s = t.s; /* save last time */
216 handle->last_time.us = t.us; /* save last time */
217 if (handle->decode_len >= handle->len) /* check length */
218 {
219 res = handle->shd_gpio_write(1); /* goto sleep mode */
220 if (res != 0) /* check result */
221 {
222 handle->debug_print("em4095: shd gpio write failed.\n"); /* shd gpio write failed */
223
224 return 1; /* return error */
225 }
226 a_em4095_time_diff(handle); /* get time diff */
227 handle->receive_callback((em4095_mode_t)handle->mode,
228 handle->decode,
229 handle->decode_len); /* run the callback */
230 handle->mode = EM4095_MODE_IDLE; /* set idle mode */
231 }
232 }
233 else if (handle->mode == EM4095_MODE_WRITE) /* write mode */
234 {
235 uint8_t level;
236
237 if (a_write_sync(handle) != 0) /* wait write sync */
238 {
239 return 0; /* success return 0 */
240 }
241 res = handle->timestamp_read(&t); /* timestamp read */
242 if (res != 0) /* check result */
243 {
244 handle->debug_print("em4095: timestamp read failed.\n"); /* timestamp read failed */
245
246 return 1; /* return error */
247 }
248 handle->decode[handle->len].t.s = t.s; /* save s */
249 handle->decode[handle->len].t.us = t.us; /* save us */
250 level = handle->decode[handle->len].level; /* get decode level */
251 handle->len++; /* length++ */
252 if (handle->last_bit != level) /* if not the set level */
253 {
254 res = handle->mod_gpio_write(level); /* mod gpio write level */
255 if (res != 0) /* check result */
256 {
257 handle->debug_print("em4095: mod gpio write failed.\n"); /* mod gpio write */
258
259 return 1; /* return error */
260 }
261 }
262 handle->last_bit = level; /* save last bit */
263 if (handle->len >= handle->decode_len) /* check length */
264 {
265 res = handle->shd_gpio_write(1); /* goto sleep mode */
266 if (res != 0) /* check result */
267 {
268 handle->debug_print("em4095: shd gpio write failed.\n"); /* shd gpio write failed */
269
270 return 1; /* return error */
271 }
272 a_em4095_time_diff(handle); /* get time diff */
273 handle->receive_callback((em4095_mode_t)handle->mode,
274 handle->decode,
275 handle->decode_len); /* run the callback */
276 handle->mode = EM4095_MODE_IDLE; /* set idle mode */
277 }
278 }
279 else
280 {
281
282 }
283
284 return 0; /* success return 0 */
285}
286
298{
299 uint8_t res;
301
302 if (handle == NULL) /* check handle */
303 {
304 return 2; /* return error */
305 }
306 if (handle->debug_print == NULL) /* check debug_print */
307 {
308 return 3; /* return error */
309 }
310 if (handle->demod_gpio_init == NULL) /* check demod_gpio_init */
311 {
312 handle->debug_print("em4095: demod_gpio_init is null.\n"); /* demod_gpio_init is null */
313
314 return 3; /* return error */
315 }
316 if (handle->demod_gpio_deinit == NULL) /* check demod_gpio_deinit */
317 {
318 handle->debug_print("em4095: demod_gpio_deinit is null.\n"); /* demod_gpio_deinit is null */
319
320 return 3; /* return error */
321 }
322 if (handle->demod_gpio_read == NULL) /* check demod_gpio_read */
323 {
324 handle->debug_print("em4095: demod_gpio_read is null.\n"); /* demod_gpio_read is null */
325
326 return 3; /* return error */
327 }
328 if (handle->mod_gpio_init == NULL) /* check mod_gpio_init */
329 {
330 handle->debug_print("em4095: mod_gpio_init is null.\n"); /* mod_gpio_init is null */
331
332 return 3; /* return error */
333 }
334 if (handle->mod_gpio_deinit == NULL) /* check mod_gpio_deinit */
335 {
336 handle->debug_print("em4095: mod_gpio_deinit is null.\n"); /* mod_gpio_deinit is null */
337
338 return 3; /* return error */
339 }
340 if (handle->mod_gpio_write == NULL) /* check mod_gpio_write */
341 {
342 handle->debug_print("em4095: mod_gpio_write is null.\n"); /* mod_gpio_write is null */
343
344 return 3; /* return error */
345 }
346 if (handle->shd_gpio_init == NULL) /* check shd_gpio_init */
347 {
348 handle->debug_print("em4095: shd_gpio_init is null.\n"); /* shd_gpio_init is null */
349
350 return 3; /* return error */
351 }
352 if (handle->shd_gpio_deinit == NULL) /* check shd_gpio_deinit */
353 {
354 handle->debug_print("em4095: shd_gpio_deinit is null.\n"); /* shd_gpio_deinit is null */
355
356 return 3; /* return error */
357 }
358 if (handle->shd_gpio_write == NULL) /* check shd_gpio_write */
359 {
360 handle->debug_print("em4095: shd_gpio_write is null.\n"); /* shd_gpio_write is null */
361
362 return 3; /* return error */
363 }
364 if (handle->timestamp_read == NULL) /* check timestamp_read */
365 {
366 handle->debug_print("em4095: timestamp_read is null.\n"); /* timestamp_read is null */
367
368 return 3; /* return error */
369 }
370 if (handle->delay_ms == NULL) /* check delay_ms */
371 {
372 handle->debug_print("em4095: delay_ms is null.\n"); /* delay_ms is null */
373
374 return 3; /* return error */
375 }
376 if (handle->receive_callback == NULL) /* check receive_callback */
377 {
378 handle->debug_print("em4095: receive_callback is null.\n"); /* receive_callback is null */
379
380 return 3; /* return error */
381 }
382
383 res = handle->demod_gpio_init(); /* demod gpio init */
384 if (res != 0) /* check the result */
385 {
386 handle->debug_print("em4095: demod gpio init failed.\n"); /* demod gpio init failed */
387
388 return 1; /* return error */
389 }
390 res = handle->mod_gpio_init(); /* mod gpio init */
391 if (res != 0) /* check the result */
392 {
393 handle->debug_print("em4095: mod gpio init failed.\n"); /* mod gpio init failed */
394 (void)handle->demod_gpio_deinit(); /* demod gpio deinit */
395
396 return 1; /* return error */
397 }
398 res = handle->shd_gpio_init(); /* shd gpio init */
399 if (res != 0) /* check the result */
400 {
401 handle->debug_print("em4095: shd gpio init failed.\n"); /* shd gpio init failed */
402 (void)handle->demod_gpio_deinit(); /* demod gpio deinit */
403 (void)handle->mod_gpio_deinit(); /* mod gpio deinit */
404
405 return 1; /* return error */
406 }
407 res = handle->shd_gpio_write(1); /* goto sleep mode */
408 if (res != 0) /* check the result */
409 {
410 handle->debug_print("em4095: shd gpio write failed.\n"); /* shd gpio write failed */
411 (void)handle->demod_gpio_deinit(); /* demod gpio deinit */
412 (void)handle->mod_gpio_deinit(); /* mod gpio deinit */
413 (void)handle->shd_gpio_deinit(); /* shd gpio deinit */
414
415 return 1; /* return error */
416 }
417 res = handle->timestamp_read(&t); /* timestamp read */
418 if (res != 0) /* check result */
419 {
420 handle->debug_print("em4095: timestamp read failed.\n"); /* timestamp read failed */
421 (void)handle->demod_gpio_deinit(); /* demod gpio deinit */
422 (void)handle->mod_gpio_deinit(); /* mod gpio deinit */
423 (void)handle->shd_gpio_deinit(); /* shd gpio deinit */
424
425 return 1; /* return error */
426 }
427 handle->last_time.s = t.s; /* save last time */
428 handle->last_time.us = t.us; /* save last time */
429 handle->decode_len = 0; /* init 0 */
430 handle->mode = 0; /* set idle mode */
431 handle->len = 0; /* init 0 */
432 handle->div = 1; /* init 1 */
433 handle->div_len = 0; /* init 0 */
434 handle->start_flag = 0; /* flag not start */
435 handle->last_bit = 0; /* init 0 */
436 handle->inited = 1; /* flag inited */
437
438 return 0; /* success return 0 */
439}
440
452{
453 uint8_t res;
454
455 if (handle == NULL) /* check handle */
456 {
457 return 2; /* return error */
458 }
459 if (handle->inited != 1) /* check handle initialization */
460 {
461 return 3; /* return error */
462 }
463
464 res = handle->shd_gpio_write(1); /* goto sleep mode */
465 if (res != 0) /* check the result */
466 {
467 handle->debug_print("em4095: shd gpio write failed.\n"); /* shd gpio write failed */
468
469 return 1; /* return error */
470 }
471 res = handle->demod_gpio_deinit(); /* demod gpio deinit */
472 if (res != 0) /* check the result */
473 {
474 handle->debug_print("em4095: demod gpio deinit failed.\n"); /* demod gpio deinit failed */
475
476 return 1; /* return error */
477 }
478 res = handle->mod_gpio_deinit(); /* mod gpio deinit */
479 if (res != 0) /* check the result */
480 {
481 handle->debug_print("em4095: mod gpio deinit failed.\n"); /* mod gpio deinit failed */
482
483 return 1; /* return error */
484 }
485 res = handle->shd_gpio_deinit(); /* shd gpio deinit */
486 if (res != 0) /* check the result */
487 {
488 handle->debug_print("em4095: shd gpio deinit failed.\n"); /* shd gpio deinit failed */
489
490 return 1; /* return error */
491 }
492 handle->inited = 0; /* flag close */
493
494 return 0; /* success return 0 */
495}
496
508{
509 uint8_t res;
510
511 if (handle == NULL) /* check handle */
512 {
513 return 2; /* return error */
514 }
515 if (handle->inited != 1) /* check handle initialization */
516 {
517 return 3; /* return error */
518 }
519
520 res = handle->shd_gpio_write(1); /* goto sleep mode */
521 if (res != 0) /* check the result */
522 {
523 handle->debug_print("em4095: shd gpio write failed.\n"); /* shd gpio write failed */
524
525 return 1; /* return error */
526 }
527
528 return 0; /* success return 0 */
529}
530
542{
543 uint8_t res;
544
545 if (handle == NULL) /* check handle */
546 {
547 return 2; /* return error */
548 }
549 if (handle->inited != 1) /* check handle initialization */
550 {
551 return 3; /* return error */
552 }
553
554 res = handle->shd_gpio_write(0); /* exit sleep mode */
555 if (res != 0) /* check the result */
556 {
557 handle->debug_print("em4095: shd gpio write failed.\n"); /* shd gpio write failed */
558
559 return 1; /* return error */
560 }
561
562 return 0; /* success return 0 */
563}
564
576uint8_t em4095_set_div(em4095_handle_t *handle, uint32_t clock_div)
577{
578 if (handle == NULL) /* check handle */
579 {
580 return 2; /* return error */
581 }
582 if (handle->inited != 1) /* check handle initialization */
583 {
584 return 3; /* return error */
585 }
586 if (clock_div == 0) /* check the div */
587 {
588 handle->debug_print("em4095: div can't be 0.\n"); /* div can't be 0 */
589
590 return 4; /* return error */
591 }
592
593 handle->div = clock_div; /* set div */
594
595 return 0; /* success return 0 */
596}
597
608uint8_t em4095_get_div(em4095_handle_t *handle, uint32_t *clock_div)
609{
610 if (handle == NULL) /* check handle */
611 {
612 return 2; /* return error */
613 }
614 if (handle->inited != 1) /* check handle initialization */
615 {
616 return 3; /* return error */
617 }
618
619 *clock_div = handle->div; /* set div */
620
621 return 0; /* success return 0 */
622}
623
636uint8_t em4095_read(em4095_handle_t *handle, uint16_t len)
637{
638 uint8_t res;
639 uint8_t level;
641
642 if (handle == NULL) /* check handle */
643 {
644 return 2; /* return error */
645 }
646 if (handle->inited != 1) /* check handle initialization */
647 {
648 return 3; /* return error */
649 }
650 if (len > EM4095_MAX_LENGTH) /* check length */
651 {
652 handle->debug_print("em4095: len > %d.\n", EM4095_MAX_LENGTH); /* len is too long */
653
654 return 4; /* return error */
655 }
656
657 res = handle->timestamp_read(&t); /* timestamp read */
658 if (res != 0) /* check result */
659 {
660 handle->debug_print("em4095: timestamp read failed.\n"); /* timestamp read failed */
661
662 return 1; /* return error */
663 }
664 res = handle->mod_gpio_write(0); /* mod gpio write level */
665 if (res != 0) /* check result */
666 {
667 handle->debug_print("em4095: mod gpio write failed.\n"); /* mod gpio write */
668
669 return 1; /* return error */
670 }
671 handle->last_time.s = t.s; /* save last time */
672 handle->last_time.us = t.us; /* save last time */
673 handle->decode_len = 0; /* init 0 */
674 handle->len = len; /* set read length */
675 handle->div_len = 0; /* init 0 */
676 handle->mode = EM4095_MODE_READ; /* set read mode */
677 handle->start_flag = 0; /* flag not start */
678 res = handle->demod_gpio_read(&level); /* read gpio level */
679 if (res != 0) /* check result */
680 {
681 handle->debug_print("em4095: demod gpio read failed.\n"); /* demod gpio read failed */
682
683 return 1; /* return error */
684 }
685 handle->last_bit = level; /* init level */
686
687 return 0; /* success return 0 */
688}
689
703uint8_t em4095_write(em4095_handle_t *handle, uint8_t *buf, uint16_t len)
704{
705 uint8_t res;
706 uint16_t i;
708
709 if (handle == NULL) /* check handle */
710 {
711 return 2; /* return error */
712 }
713 if (handle->inited != 1) /* check handle initialization */
714 {
715 return 3; /* return error */
716 }
717
718 if (len > EM4095_MAX_LENGTH) /* check length */
719 {
720 handle->debug_print("em4095: len > %d.\n", EM4095_MAX_LENGTH); /* len is too long */
721
722 return 4; /* return error */
723 }
724
725 res = handle->timestamp_read(&t); /* timestamp read */
726 if (res != 0) /* check result */
727 {
728 handle->debug_print("em4095: timestamp read failed.\n"); /* timestamp read failed */
729
730 return 1; /* return error */
731 }
732 res = handle->mod_gpio_write(0); /* mod gpio write level */
733 if (res != 0) /* check result */
734 {
735 handle->debug_print("em4095: mod gpio write failed.\n"); /* mod gpio write */
736
737 return 1; /* return error */
738 }
739 handle->last_time.s = t.s; /* save last time */
740 handle->last_time.us = t.us; /* save last time */
741 handle->decode_len = 0; /* init 0 */
742 for (i = 0; i < len; i++) /* set data */
743 {
744 handle->decode[handle->decode_len].level = buf[i]; /* save data */
745 handle->decode_len++; /* length++ */
746 }
747 handle->len = 0; /* set write length */
748 handle->div_len = 0; /* init 0 */
749 handle->mode = EM4095_MODE_WRITE; /* set write mode */
750 handle->start_flag = 0; /* flag not start */
751 handle->last_bit = 0; /* init 0 */
752
753 return 0; /* success return 0 */
754}
755
767uint8_t em4095_copy_decode_buffer(em4095_handle_t *handle, uint8_t *buf, uint16_t *len)
768{
769 uint16_t i;
770
771 if (handle == NULL) /* check handle */
772 {
773 return 2; /* return error */
774 }
775 if (handle->inited != 1) /* check handle initialization */
776 {
777 return 3; /* return error */
778 }
779
780 for (i = 0; i < handle->decode_len; i++) /* copy all */
781 {
782 buf[i] = handle->decode[i].level; /* copy to buffer */
783 }
784 *len = handle->decode_len; /* set length */
785
786 return 0; /* success return 0 */
787}
788
798{
799 if (info == NULL) /* check handle */
800 {
801 return 2; /* return error */
802 }
803
804 memset(info, 0, sizeof(em4095_info_t)); /* initialize em4095 info structure */
805 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
806 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
807 strncpy(info->interface, "GPIO", 8); /* copy interface name */
808 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
809 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
810 info->max_current_ma = MAX_CURRENT; /* set maximum current */
811 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
812 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
813 info->driver_version = DRIVER_VERSION; /* set driver version */
814
815 return 0; /* success return 0 */
816}
#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 em4095 header file
uint8_t em4095_init(em4095_handle_t *handle)
initialize the chip
struct em4095_handle_s em4095_handle_t
em4095 handle structure definition
struct em4095_time_s em4095_time_t
em4095 time structure definition
uint8_t em4095_get_div(em4095_handle_t *handle, uint32_t *clock_div)
get irq div
uint8_t em4095_irq_handler(em4095_handle_t *handle)
irq handler
uint8_t em4095_copy_decode_buffer(em4095_handle_t *handle, uint8_t *buf, uint16_t *len)
copy decode buffer
uint8_t em4095_write(em4095_handle_t *handle, uint8_t *buf, uint16_t len)
write data
uint8_t em4095_power_down(em4095_handle_t *handle)
power down
#define EM4095_MAX_LENGTH
em4095 max length definition
uint8_t em4095_read(em4095_handle_t *handle, uint16_t len)
read data
uint8_t em4095_set_div(em4095_handle_t *handle, uint32_t clock_div)
set irq div
uint8_t em4095_power_on(em4095_handle_t *handle)
power on
em4095_mode_t
em4095 mode enumeration definition
uint8_t em4095_deinit(em4095_handle_t *handle)
close the chip
struct em4095_info_s em4095_info_t
em4095 information structure definition
uint8_t em4095_info(em4095_info_t *info)
get chip's information
@ EM4095_MODE_IDLE
@ EM4095_MODE_WRITE
@ EM4095_MODE_READ
em4095_time_t t
uint8_t(* shd_gpio_init)(void)
em4095_time_t last_time
void(* delay_ms)(uint32_t ms)
uint8_t(* demod_gpio_init)(void)
void(* debug_print)(const char *const fmt,...)
uint8_t(* shd_gpio_deinit)(void)
uint8_t(* shd_gpio_write)(uint8_t data)
em4095_decode_t decode[EM4095_MAX_LENGTH]
void(* receive_callback)(em4095_mode_t mode, em4095_decode_t *buf, uint16_t len)
uint8_t(* mod_gpio_write)(uint8_t data)
uint8_t(* demod_gpio_deinit)(void)
uint8_t(* demod_gpio_read)(uint8_t *data)
uint8_t(* timestamp_read)(em4095_time_t *t)
uint8_t(* mod_gpio_deinit)(void)
uint8_t(* mod_gpio_init)(void)
float supply_voltage_max_v
uint32_t driver_version
char manufacturer_name[32]
float supply_voltage_min_v
char chip_name[32]