LibDriver BPC
Loading...
Searching...
No Matches
driver_bpc.c
Go to the documentation of this file.
1
36
37#include "driver_bpc.h"
38#include <stdlib.h>
39
43#define CHIP_NAME "China BPC"
44#define MANUFACTURER_NAME "China"
45#define SUPPLY_VOLTAGE_MIN 2.7f
46#define SUPPLY_VOLTAGE_MAX 5.5f
47#define MAX_CURRENT 1.5f
48#define TEMPERATURE_MIN -40.0f
49#define TEMPERATURE_MAX 125.0f
50#define DRIVER_VERSION 1000
51
55#define BPC_CHECK_START_FRAME_MIN (1600 * 1000)
56#define BPC_CHECK_START_FRAME_MAX (1900 * 1000)
57#define BPC_CHECK_FRAME_TIME (1000 * 1000)
58#define BPC_CHECK_DATA_0 (100 * 1000)
59#define BPC_CHECK_DATA_1 (200 * 1000)
60#define BPC_CHECK_DATA_2 (300 * 1000)
61#define BPC_CHECK_DATA_3 (400 * 1000)
62
72static inline uint8_t a_check_frame(uint32_t check, uint32_t t)
73{
74 if (abs((int)((int)check - (int)t)) > (int)((float)(t) * BPC_MAX_RANGE)) /* check the time */
75 {
76 return 1; /* check failed */
77 }
78 else
79 {
80 return 0; /* success return 0 */
81 }
82}
83
93static inline uint8_t a_check_frame2(uint32_t check, uint32_t remain_check, uint32_t t)
94{
95 uint32_t total;
96
97 total = check + remain_check; /* get the total time */
98 if (((float)(total) < (float)(BPC_CHECK_FRAME_TIME) * (1.0f - BPC_MAX_RANGE)) ||
99 ((float)(total) > (float)(BPC_CHECK_FRAME_TIME) * (1.0f + BPC_MAX_RANGE))) /* check range */
100 {
101 return 1; /* check failed */
102 }
103
104 if (abs((int)((int)check - (int)t)) > (int)((float)(t) * BPC_MAX_RANGE)) /* check the time */
105 {
106 return 1; /* check failed */
107 }
108 else
109 {
110 return 0; /* success return 0 */
111 }
112}
113
123static inline uint8_t a_check_start_frame(uint32_t check)
124{
125 if (((float)(check) > (float)(BPC_CHECK_START_FRAME_MIN) * (1.0f - BPC_MAX_START_RANGE)) &&
126 ((float)(check) < (float)(BPC_CHECK_START_FRAME_MAX) * (1.0f + BPC_MAX_START_RANGE))) /* check range */
127 {
128 return 0; /* success return 0 */
129 }
130 else
131 {
132 return 1; /* check failed */
133 }
134}
135
141static void a_bpc_trace_decode(bpc_handle_t *handle)
142{
143 int64_t diff;
144
145 diff = (int64_t)((int64_t)handle->decode[0].t.s -
146 (int64_t)handle->last_time.s) * 1000000 +
147 (int64_t)((int64_t)handle->decode[0].t.us -
148 (int64_t)handle->last_time.us); /* diff time */
149 if (a_check_start_frame((uint32_t)diff) == 0) /* check diff time */
150 {
151 handle->decode_offset = 0; /* init 0 */
152 handle->decode_valid = 1; /* set valid */
153 handle->trace_valid = 0; /* set invalid */
154 }
155 else
156 {
157 handle->decode_len = 0; /* clear the buffer */
158 handle->decode_offset = 0; /* init 0 */
159 handle->decode_valid = 0; /* set invalid */
160 handle->trace_valid = 0; /* set invalid */
161 }
162}
163
169static void a_bpc_start_decode(bpc_handle_t *handle)
170{
171 uint16_t i;
172 uint16_t len;
173
174 len = handle->decode_len - 1; /* len - 1 */
175 for (i = 0; i < len; i++) /* diff all time */
176 {
177 int64_t diff;
178
179 diff = (int64_t)((int64_t)handle->decode[i + 1].t.s -
180 (int64_t)handle->decode[i].t.s) * 1000000 +
181 (int64_t)((int64_t)handle->decode[i + 1].t.us -
182 (int64_t)handle->decode[i].t.us); /* diff time */
183 handle->decode[i].diff_us = (uint32_t)diff; /* save the time diff */
184 if (a_check_start_frame((uint32_t)handle->decode[i].diff_us) == 0) /* check start frame */
185 {
186 handle->decode_valid = 1; /* set valid */
187 handle->decode_offset = (uint8_t)(i + 1); /* save offset */
188 }
189 }
190}
191
199static uint8_t a_bpc_data_decode(bpc_handle_t *handle, uint32_t diff_us, uint8_t *data)
200{
201 if (a_check_frame(diff_us, BPC_CHECK_DATA_0) == 0) /* check diff */
202 {
203 *data = 0; /* set data 0 */
204 }
205 else
206 {
207 if (a_check_frame(diff_us, BPC_CHECK_DATA_1) == 0) /* check start diff */
208 {
209 *data = 1; /* set data 1 */
210 }
211 else
212 {
213 if (a_check_frame(diff_us, BPC_CHECK_DATA_2) == 0) /* check start diff */
214 {
215 *data = 2; /* set data 2 */
216 }
217 else
218 {
219 if (a_check_frame(diff_us, BPC_CHECK_DATA_3) == 0) /* check start diff */
220 {
221 *data = 3; /* set data 3 */
222 }
223 else
224 {
225 return 1; /* return error */
226 }
227 }
228 }
229 }
230
231 return 0; /* success return 0 */
232}
233
242static uint8_t a_bpc_data_decode2(bpc_handle_t *handle, uint32_t diff_us, uint32_t remain_diff_us, uint8_t *data)
243{
244 if (a_check_frame2(diff_us, remain_diff_us, BPC_CHECK_DATA_0) == 0) /* check diff */
245 {
246 *data = 0; /* set data 0 */
247 }
248 else
249 {
250 if (a_check_frame2(diff_us, remain_diff_us, BPC_CHECK_DATA_1) == 0) /* check start diff */
251 {
252 *data = 1; /* set data 1 */
253 }
254 else
255 {
256 if (a_check_frame2(diff_us, remain_diff_us, BPC_CHECK_DATA_2) == 0) /* check start diff */
257 {
258 *data = 2; /* set data 2 */
259 }
260 else
261 {
262 if (a_check_frame2(diff_us, remain_diff_us, BPC_CHECK_DATA_3) == 0) /* check start diff */
263 {
264 *data = 3; /* set data 3 */
265 }
266 else
267 {
268 return 1; /* return error */
269 }
270 }
271 }
272 }
273
274 return 0; /* success return 0 */
275}
276
282static void a_bpc_decode(bpc_handle_t *handle)
283{
284 if (handle->decode_len - handle->decode_offset >= 38) /* if the min length */
285 {
286 uint8_t res;
287 uint8_t p1;
288 uint8_t p2;
289 uint8_t p3;
290 uint8_t p4;
291 uint8_t temp0;
292 uint8_t temp1;
293 uint8_t temp2;
294 uint8_t count;
295 uint16_t i;
296 uint16_t len;
297 uint16_t ind;
298 uint16_t parity;
299 bpc_t data = {0};
300
301 len = handle->decode_len - 1; /* len - 1 */
302 for (i = 0; i < len; i++) /* diff all time */
303 {
304 int64_t diff;
305
306 diff = (int64_t)((int64_t)handle->decode[i + 1].t.s -
307 (int64_t)handle->decode[i].t.s) * 1000000 +
308 (int64_t)((int64_t)handle->decode[i + 1].t.us -
309 (int64_t)handle->decode[i].t.us); /* diff time */
310 handle->decode[i].diff_us = (uint32_t)diff; /* save the time diff */
311 }
312
313 ind = handle->decode_offset; /* set start index */
314 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
315 (uint32_t)handle->decode[ind + 1].diff_us, &p1); /* get data */
316 if (res != 0) /* check the result */
317 {
318 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
319 data.year = 0; /* set 0 */
320 data.month = 0; /* set 0 */
321 data.day = 0; /* set 0 */
322 data.week = 0; /* set 0 */
323 data.hour = 0; /* set 0 */
324 data.minute = 0; /* set 0 */
325 data.second = 0; /* set 0 */
326 if (handle->receive_callback != NULL) /* not null */
327 {
328 handle->receive_callback(&data); /* run the callback */
329 }
330 handle->decode_len = 0; /* clear the buffer */
331 handle->decode_offset = 0; /* init 0 */
332 handle->decode_valid = 0; /* set invalid */
333 handle->trace_valid = 0; /* set invalid */
334
335 return; /* return */
336 }
337 ind += 2; /* index + 2 */
338 if (p1 == 0) /* 19 second */
339 {
340 data.second = 19; /* set 19s */
341 }
342 else if (p1 == 1) /* 39 second */
343 {
344 data.second = 39; /* set 39s */
345 }
346 else if (p1 == 2) /* 59 second */
347 {
348 data.second = 59; /* set 59s */
349 }
350 else /* invalid */
351 {
352 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
353 data.year = 0; /* set 0 */
354 data.month = 0; /* set 0 */
355 data.day = 0; /* set 0 */
356 data.week = 0; /* set 0 */
357 data.hour = 0; /* set 0 */
358 data.minute = 0; /* set 0 */
359 data.second = 0; /* set 0 */
360 if (handle->receive_callback != NULL) /* not null */
361 {
362 handle->receive_callback(&data); /* run the callback */
363 }
364
365 handle->decode_len = 0; /* clear the buffer */
366 handle->decode_offset = 0; /* init 0 */
367 handle->decode_valid = 0; /* set invalid */
368 handle->trace_valid = 0; /* set invalid */
369
370 return; /* return */
371 }
372
373 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
374 (uint32_t)handle->decode[ind + 1].diff_us, &p2); /* get data */
375 if (res != 0) /* check the result */
376 {
377 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
378 data.year = 0; /* set 0 */
379 data.month = 0; /* set 0 */
380 data.day = 0; /* set 0 */
381 data.week = 0; /* set 0 */
382 data.hour = 0; /* set 0 */
383 data.minute = 0; /* set 0 */
384 data.second = 0; /* set 0 */
385 if (handle->receive_callback != NULL) /* not null */
386 {
387 handle->receive_callback(&data); /* run the callback */
388 }
389
390 handle->decode_len = 0; /* clear the buffer */
391 handle->decode_offset = 0; /* init 0 */
392 handle->decode_valid = 0; /* set invalid */
393 handle->trace_valid = 0; /* set invalid */
394
395 return; /* return */
396 }
397 ind += 2; /* index + 2 */
398
399 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
400 (uint32_t)handle->decode[ind + 1].diff_us, &temp0); /* get data */
401 if (res != 0) /* check the result */
402 {
403 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
404 data.year = 0; /* set 0 */
405 data.month = 0; /* set 0 */
406 data.day = 0; /* set 0 */
407 data.week = 0; /* set 0 */
408 data.hour = 0; /* set 0 */
409 data.minute = 0; /* set 0 */
410 data.second = 0; /* set 0 */
411 if (handle->receive_callback != NULL) /* not null */
412 {
413 handle->receive_callback(&data); /* run the callback */
414 }
415
416 handle->decode_len = 0; /* clear the buffer */
417 handle->decode_offset = 0; /* init 0 */
418 handle->decode_valid = 0; /* set invalid */
419 handle->trace_valid = 0; /* set invalid */
420
421 return; /* return */
422 }
423 ind += 2; /* index + 2 */
424 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
425 (uint32_t)handle->decode[ind + 1].diff_us, &temp1); /* get data */
426 if (res != 0) /* check the result */
427 {
428 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
429 data.year = 0; /* set 0 */
430 data.month = 0; /* set 0 */
431 data.day = 0; /* set 0 */
432 data.week = 0; /* set 0 */
433 data.hour = 0; /* set 0 */
434 data.minute = 0; /* set 0 */
435 data.second = 0; /* set 0 */
436 if (handle->receive_callback != NULL) /* not null */
437 {
438 handle->receive_callback(&data); /* run the callback */
439 }
440
441 handle->decode_len = 0; /* clear the buffer */
442 handle->decode_offset = 0; /* init 0 */
443 handle->decode_valid = 0; /* set invalid */
444 handle->trace_valid = 0; /* set invalid */
445
446 return; /* return */
447 }
448 ind += 2; /* index + 2 */
449 data.hour = (temp0 << 2) | temp1; /* set hour */
450
451 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
452 (uint32_t)handle->decode[ind + 1].diff_us, &temp0); /* get data */
453 if (res != 0) /* check the result */
454 {
455 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
456 data.year = 0; /* set 0 */
457 data.month = 0; /* set 0 */
458 data.day = 0; /* set 0 */
459 data.week = 0; /* set 0 */
460 data.hour = 0; /* set 0 */
461 data.minute = 0; /* set 0 */
462 data.second = 0; /* set 0 */
463 if (handle->receive_callback != NULL) /* not null */
464 {
465 handle->receive_callback(&data); /* run the callback */
466 }
467
468 handle->decode_len = 0; /* clear the buffer */
469 handle->decode_offset = 0; /* init 0 */
470 handle->decode_valid = 0; /* set invalid */
471 handle->trace_valid = 0; /* set invalid */
472
473 return; /* return */
474 }
475 ind += 2; /* index + 2 */
476 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
477 (uint32_t)handle->decode[ind + 1].diff_us, &temp1); /* get data */
478 if (res != 0) /* check the result */
479 {
480 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
481 data.year = 0; /* set 0 */
482 data.month = 0; /* set 0 */
483 data.day = 0; /* set 0 */
484 data.week = 0; /* set 0 */
485 data.hour = 0; /* set 0 */
486 data.minute = 0; /* set 0 */
487 data.second = 0; /* set 0 */
488 if (handle->receive_callback != NULL) /* not null */
489 {
490 handle->receive_callback(&data); /* run the callback */
491 }
492
493 handle->decode_len = 0; /* clear the buffer */
494 handle->decode_offset = 0; /* init 0 */
495 handle->decode_valid = 0; /* set invalid */
496 handle->trace_valid = 0; /* set invalid */
497
498 return; /* return */
499 }
500 ind += 2; /* index + 2 */
501 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
502 (uint32_t)handle->decode[ind + 1].diff_us, &temp2); /* get data */
503 if (res != 0) /* check the result */
504 {
505 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
506 data.year = 0; /* set 0 */
507 data.month = 0; /* set 0 */
508 data.day = 0; /* set 0 */
509 data.week = 0; /* set 0 */
510 data.hour = 0; /* set 0 */
511 data.minute = 0; /* set 0 */
512 data.second = 0; /* set 0 */
513 if (handle->receive_callback != NULL) /* not null */
514 {
515 handle->receive_callback(&data); /* run the callback */
516 }
517
518 handle->decode_len = 0; /* clear the buffer */
519 handle->decode_offset = 0; /* init 0 */
520 handle->decode_valid = 0; /* set invalid */
521 handle->trace_valid = 0; /* set invalid */
522
523 return; /* return */
524 }
525 ind += 2; /* index + 2 */
526 data.minute = ((uint8_t)temp0 << 4) | ((uint8_t)temp1 << 2) | temp2; /* set minute */
527
528 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
529 (uint32_t)handle->decode[ind + 1].diff_us, &temp0); /* get data */
530 if (res != 0) /* check the result */
531 {
532 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
533 data.year = 0; /* set 0 */
534 data.month = 0; /* set 0 */
535 data.day = 0; /* set 0 */
536 data.week = 0; /* set 0 */
537 data.hour = 0; /* set 0 */
538 data.minute = 0; /* set 0 */
539 data.second = 0; /* set 0 */
540 if (handle->receive_callback != NULL) /* not null */
541 {
542 handle->receive_callback(&data); /* run the callback */
543 }
544
545 handle->decode_len = 0; /* clear the buffer */
546 handle->decode_offset = 0; /* init 0 */
547 handle->decode_valid = 0; /* set invalid */
548 handle->trace_valid = 0; /* set invalid */
549
550 return; /* return */
551 }
552 ind += 2; /* index + 2 */
553 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
554 (uint32_t)handle->decode[ind + 1].diff_us, &temp1); /* get data */
555 if (res != 0) /* check the result */
556 {
557 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
558 data.year = 0; /* set 0 */
559 data.month = 0; /* set 0 */
560 data.day = 0; /* set 0 */
561 data.week = 0; /* set 0 */
562 data.hour = 0; /* set 0 */
563 data.minute = 0; /* set 0 */
564 data.second = 0; /* set 0 */
565 if (handle->receive_callback != NULL) /* not null */
566 {
567 handle->receive_callback(&data); /* run the callback */
568 }
569
570 handle->decode_len = 0; /* clear the buffer */
571 handle->decode_offset = 0; /* init 0 */
572 handle->decode_valid = 0; /* set invalid */
573 handle->trace_valid = 0; /* set invalid */
574
575 return; /* return */
576 }
577 ind += 2; /* index + 2 */
578 data.week = (temp0 << 2) | temp1; /* set week */
579
580 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
581 (uint32_t)handle->decode[ind + 1].diff_us, &p3); /* get data */
582 if (res != 0) /* check the result */
583 {
584 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
585 data.year = 0; /* set 0 */
586 data.month = 0; /* set 0 */
587 data.day = 0; /* set 0 */
588 data.week = 0; /* set 0 */
589 data.hour = 0; /* set 0 */
590 data.minute = 0; /* set 0 */
591 data.second = 0; /* set 0 */
592 if (handle->receive_callback != NULL) /* not null */
593 {
594 handle->receive_callback(&data); /* run the callback */
595 }
596
597 handle->decode_len = 0; /* clear the buffer */
598 handle->decode_offset = 0; /* init 0 */
599 handle->decode_valid = 0; /* set invalid */
600 handle->trace_valid = 0; /* set invalid */
601
602 return; /* return */
603 }
604 ind += 2; /* index + 2 */
605
606 count = 0; /* init 0 */
607 parity = p1; /* set p1 */
608 while (parity != 0) /* check 0 */
609 {
610 count += parity & 0x1; /* add 1 */
611 parity >>= 1; /* right shift */
612 }
613 parity = p2; /* set p2 */
614 while (parity != 0) /* check 0 */
615 {
616 count += parity & 0x1; /* add 1 */
617 parity >>= 1; /* right shift */
618 }
619 parity = data.hour; /* set hour */
620 while (parity != 0) /* check 0 */
621 {
622 count += parity & 0x1; /* add 1 */
623 parity >>= 1; /* right shift */
624 }
625 parity = data.minute; /* set minute */
626 while (parity != 0) /* check 0 */
627 {
628 count += parity & 0x1; /* add 1 */
629 parity >>= 1; /* right shift */
630 }
631 parity = data.week; /* set week */
632 while (parity != 0) /* check 0 */
633 {
634 count += parity & 0x1; /* add 1 */
635 parity >>= 1; /* right shift */
636 }
637
638 if (p3 == 0) /* even, am */
639 {
640 if ((count % 2) != 0) /* check even */
641 {
642 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
643 data.year = 0; /* set 0 */
644 data.month = 0; /* set 0 */
645 data.day = 0; /* set 0 */
646 data.week = 0; /* set 0 */
647 data.hour = 0; /* set 0 */
648 data.minute = 0; /* set 0 */
649 data.second = 0; /* set 0 */
650 if (handle->receive_callback != NULL) /* not null */
651 {
652 handle->receive_callback(&data); /* run the callback */
653 }
654
655 handle->decode_len = 0; /* clear the buffer */
656 handle->decode_offset = 0; /* init 0 */
657 handle->decode_valid = 0; /* set invalid */
658 handle->trace_valid = 0; /* set invalid */
659
660 return; /* return */
661 }
662 }
663 else if (p3 == 1) /* odd, am */
664 {
665 if ((count % 2) == 0) /* check even */
666 {
667 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
668 data.year = 0; /* set 0 */
669 data.month = 0; /* set 0 */
670 data.day = 0; /* set 0 */
671 data.week = 0; /* set 0 */
672 data.hour = 0; /* set 0 */
673 data.minute = 0; /* set 0 */
674 data.second = 0; /* set 0 */
675 if (handle->receive_callback != NULL) /* not null */
676 {
677 handle->receive_callback(&data); /* run the callback */
678 }
679
680 handle->decode_len = 0; /* clear the buffer */
681 handle->decode_offset = 0; /* init 0 */
682 handle->decode_valid = 0; /* set invalid */
683 handle->trace_valid = 0; /* set invalid */
684
685 return; /* return */
686 }
687 }
688 else if (p3 == 2) /* even, pm */
689 {
690 if ((count % 2) != 0) /* check even */
691 {
692 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
693 data.year = 0; /* set 0 */
694 data.month = 0; /* set 0 */
695 data.day = 0; /* set 0 */
696 data.week = 0; /* set 0 */
697 data.hour = 0; /* set 0 */
698 data.minute = 0; /* set 0 */
699 data.second = 0; /* set 0 */
700 if (handle->receive_callback != NULL) /* not null */
701 {
702 handle->receive_callback(&data); /* run the callback */
703 }
704
705 handle->decode_len = 0; /* clear the buffer */
706 handle->decode_offset = 0; /* init 0 */
707 handle->decode_valid = 0; /* set invalid */
708 handle->trace_valid = 0; /* set invalid */
709
710 return; /* return */
711 }
712 data.hour += 12; /* add 12h */
713 }
714 else /* odd, pm */
715 {
716 if ((count % 2) == 0) /* check even */
717 {
718 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
719 data.year = 0; /* set 0 */
720 data.month = 0; /* set 0 */
721 data.day = 0; /* set 0 */
722 data.week = 0; /* set 0 */
723 data.hour = 0; /* set 0 */
724 data.minute = 0; /* set 0 */
725 data.second = 0; /* set 0 */
726 if (handle->receive_callback != NULL) /* not null */
727 {
728 handle->receive_callback(&data); /* run the callback */
729 }
730
731 handle->decode_len = 0; /* clear the buffer */
732 handle->decode_offset = 0; /* init 0 */
733 handle->decode_valid = 0; /* set invalid */
734 handle->trace_valid = 0; /* set invalid */
735
736 return; /* return */
737 }
738 data.hour += 12; /* add 12h */
739 }
740
741 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
742 (uint32_t)handle->decode[ind + 1].diff_us, &temp0); /* get data */
743 if (res != 0) /* check the result */
744 {
745 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
746 data.year = 0; /* set 0 */
747 data.month = 0; /* set 0 */
748 data.day = 0; /* set 0 */
749 data.week = 0; /* set 0 */
750 data.hour = 0; /* set 0 */
751 data.minute = 0; /* set 0 */
752 data.second = 0; /* set 0 */
753 if (handle->receive_callback != NULL) /* not null */
754 {
755 handle->receive_callback(&data); /* run the callback */
756 }
757
758 handle->decode_len = 0; /* clear the buffer */
759 handle->decode_offset = 0; /* init 0 */
760 handle->decode_valid = 0; /* set invalid */
761 handle->trace_valid = 0; /* set invalid */
762
763 return; /* return */
764 }
765 ind += 2; /* index + 2 */
766 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
767 (uint32_t)handle->decode[ind + 1].diff_us, &temp1); /* get data */
768 if (res != 0) /* check the result */
769 {
770 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
771 data.year = 0; /* set 0 */
772 data.month = 0; /* set 0 */
773 data.day = 0; /* set 0 */
774 data.week = 0; /* set 0 */
775 data.hour = 0; /* set 0 */
776 data.minute = 0; /* set 0 */
777 data.second = 0; /* set 0 */
778 if (handle->receive_callback != NULL) /* not null */
779 {
780 handle->receive_callback(&data); /* run the callback */
781 }
782
783 handle->decode_len = 0; /* clear the buffer */
784 handle->decode_offset = 0; /* init 0 */
785 handle->decode_valid = 0; /* set invalid */
786 handle->trace_valid = 0; /* set invalid */
787
788 return; /* return */
789 }
790 ind += 2; /* index + 2 */
791 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
792 (uint32_t)handle->decode[ind + 1].diff_us, &temp2); /* get data */
793 if (res != 0) /* check the result */
794 {
795 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
796 data.year = 0; /* set 0 */
797 data.month = 0; /* set 0 */
798 data.day = 0; /* set 0 */
799 data.week = 0; /* set 0 */
800 data.hour = 0; /* set 0 */
801 data.minute = 0; /* set 0 */
802 data.second = 0; /* set 0 */
803 if (handle->receive_callback != NULL) /* not null */
804 {
805 handle->receive_callback(&data); /* run the callback */
806 }
807
808 handle->decode_len = 0; /* clear the buffer */
809 handle->decode_offset = 0; /* init 0 */
810 handle->decode_valid = 0; /* set invalid */
811 handle->trace_valid = 0; /* set invalid */
812
813 return; /* return */
814 }
815 ind += 2; /* index + 2 */
816 data.day = ((uint8_t)temp0 << 4) | ((uint8_t)temp1 << 2) | temp2; /* set day */
817
818 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
819 (uint32_t)handle->decode[ind + 1].diff_us, &temp0); /* get data */
820 if (res != 0) /* check the result */
821 {
822 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
823 data.year = 0; /* set 0 */
824 data.month = 0; /* set 0 */
825 data.day = 0; /* set 0 */
826 data.week = 0; /* set 0 */
827 data.hour = 0; /* set 0 */
828 data.minute = 0; /* set 0 */
829 data.second = 0; /* set 0 */
830 if (handle->receive_callback != NULL) /* not null */
831 {
832 handle->receive_callback(&data); /* run the callback */
833 }
834
835 handle->decode_len = 0; /* clear the buffer */
836 handle->decode_offset = 0; /* init 0 */
837 handle->decode_valid = 0; /* set invalid */
838 handle->trace_valid = 0; /* set invalid */
839
840 return; /* return */
841 }
842 ind += 2; /* index + 2 */
843 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
844 (uint32_t)handle->decode[ind + 1].diff_us, &temp1); /* get data */
845 if (res != 0) /* check the result */
846 {
847 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
848 data.year = 0; /* set 0 */
849 data.month = 0; /* set 0 */
850 data.day = 0; /* set 0 */
851 data.week = 0; /* set 0 */
852 data.hour = 0; /* set 0 */
853 data.minute = 0; /* set 0 */
854 data.second = 0; /* set 0 */
855 if (handle->receive_callback != NULL) /* not null */
856 {
857 handle->receive_callback(&data); /* run the callback */
858 }
859
860 handle->decode_len = 0; /* clear the buffer */
861 handle->decode_offset = 0; /* init 0 */
862 handle->decode_valid = 0; /* set invalid */
863 handle->trace_valid = 0; /* set invalid */
864
865 return; /* return */
866 }
867 ind += 2; /* index + 2 */
868 data.month = (temp0 << 2) | temp1; /* set month */
869
870 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
871 (uint32_t)handle->decode[ind + 1].diff_us, &temp0); /* get data */
872 if (res != 0) /* check the result */
873 {
874 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
875 data.year = 0; /* set 0 */
876 data.month = 0; /* set 0 */
877 data.day = 0; /* set 0 */
878 data.week = 0; /* set 0 */
879 data.hour = 0; /* set 0 */
880 data.minute = 0; /* set 0 */
881 data.second = 0; /* set 0 */
882 if (handle->receive_callback != NULL) /* not null */
883 {
884 handle->receive_callback(&data); /* run the callback */
885 }
886
887 handle->decode_len = 0; /* clear the buffer */
888 handle->decode_offset = 0; /* init 0 */
889 handle->decode_valid = 0; /* set invalid */
890 handle->trace_valid = 0; /* set invalid */
891
892 return; /* return */
893 }
894 ind += 2; /* index + 2 */
895 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
896 (uint32_t)handle->decode[ind + 1].diff_us, &temp1); /* get data */
897 if (res != 0) /* check the result */
898 {
899 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
900 data.year = 0; /* set 0 */
901 data.month = 0; /* set 0 */
902 data.day = 0; /* set 0 */
903 data.week = 0; /* set 0 */
904 data.hour = 0; /* set 0 */
905 data.minute = 0; /* set 0 */
906 data.second = 0; /* set 0 */
907 if (handle->receive_callback != NULL) /* not null */
908 {
909 handle->receive_callback(&data); /* run the callback */
910 }
911
912 handle->decode_len = 0; /* clear the buffer */
913 handle->decode_offset = 0; /* init 0 */
914 handle->decode_valid = 0; /* set invalid */
915 handle->trace_valid = 0; /* set invalid */
916
917 return; /* return */
918 }
919 ind += 2; /* index + 2 */
920 res = a_bpc_data_decode2(handle, (uint32_t)handle->decode[ind].diff_us,
921 (uint32_t)handle->decode[ind + 1].diff_us, &temp2); /* get data */
922 if (res != 0) /* check the result */
923 {
924 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
925 data.year = 0; /* set 0 */
926 data.month = 0; /* set 0 */
927 data.day = 0; /* set 0 */
928 data.week = 0; /* set 0 */
929 data.hour = 0; /* set 0 */
930 data.minute = 0; /* set 0 */
931 data.second = 0; /* set 0 */
932 if (handle->receive_callback != NULL) /* not null */
933 {
934 handle->receive_callback(&data); /* run the callback */
935 }
936
937 handle->decode_len = 0; /* clear the buffer */
938 handle->decode_offset = 0; /* init 0 */
939 handle->decode_valid = 0; /* set invalid */
940 handle->trace_valid = 0; /* set invalid */
941
942 return; /* return */
943 }
944 ind += 2; /* index + 2 */
945 data.year = ((uint8_t)temp0 << 4) | ((uint8_t)temp1 << 2) | temp2; /* set day */
946
947 res = a_bpc_data_decode(handle, (uint32_t)handle->decode[ind].diff_us, &p4); /* get data */
948 if (res != 0) /* check the result */
949 {
950 data.status = BPC_STATUS_FRAME_INVALID; /* frame invalid */
951 data.year = 0; /* set 0 */
952 data.month = 0; /* set 0 */
953 data.day = 0; /* set 0 */
954 data.week = 0; /* set 0 */
955 data.hour = 0; /* set 0 */
956 data.minute = 0; /* set 0 */
957 data.second = 0; /* set 0 */
958 if (handle->receive_callback != NULL) /* not null */
959 {
960 handle->receive_callback(&data); /* run the callback */
961 }
962
963 handle->decode_len = 0; /* clear the buffer */
964 handle->decode_offset = 0; /* init 0 */
965 handle->decode_valid = 0; /* set invalid */
966 handle->trace_valid = 0; /* set invalid */
967
968 return; /* return */
969 }
970
971 count = 0; /* init 0 */
972 parity = data.day; /* set day */
973 while (parity != 0) /* check 0 */
974 {
975 count += parity & 0x1; /* add 1 */
976 parity >>= 1; /* right shift */
977 }
978 parity = data.month; /* set month */
979 while (parity != 0) /* check 0 */
980 {
981 count += parity & 0x1; /* add 1 */
982 parity >>= 1; /* right shift */
983 }
984 parity = data.year; /* set year */
985 while (parity != 0) /* check 0 */
986 {
987 count += parity & 0x1; /* add 1 */
988 parity >>= 1; /* right shift */
989 }
990 if (p4 == 0) /* even */
991 {
992 if ((count % 2) != 0) /* check even */
993 {
994 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
995 data.year = 0; /* set 0 */
996 data.month = 0; /* set 0 */
997 data.day = 0; /* set 0 */
998 data.week = 0; /* set 0 */
999 data.hour = 0; /* set 0 */
1000 data.minute = 0; /* set 0 */
1001 data.second = 0; /* set 0 */
1002 if (handle->receive_callback != NULL) /* not null */
1003 {
1004 handle->receive_callback(&data); /* run the callback */
1005 }
1006
1007 handle->decode_len = 0; /* clear the buffer */
1008 handle->decode_offset = 0; /* init 0 */
1009 handle->decode_valid = 0; /* set invalid */
1010 handle->trace_valid = 0; /* set invalid */
1011
1012 return; /* return */
1013 }
1014 data.year += 2000; /* add 2000 */
1015 }
1016 else if (p4 == 1) /* odd */
1017 {
1018 if ((count % 2) == 0) /* check even */
1019 {
1020 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
1021 data.year = 0; /* set 0 */
1022 data.month = 0; /* set 0 */
1023 data.day = 0; /* set 0 */
1024 data.week = 0; /* set 0 */
1025 data.hour = 0; /* set 0 */
1026 data.minute = 0; /* set 0 */
1027 data.second = 0; /* set 0 */
1028 if (handle->receive_callback != NULL) /* not null */
1029 {
1030 handle->receive_callback(&data); /* run the callback */
1031 }
1032
1033 handle->decode_len = 0; /* clear the buffer */
1034 handle->decode_offset = 0; /* init 0 */
1035 handle->decode_valid = 0; /* set invalid */
1036 handle->trace_valid = 0; /* set invalid */
1037
1038 return; /* return */
1039 }
1040 data.year += 2000; /* add 2000 */
1041 }
1042 else if (p4 == 2) /* even, year add */
1043 {
1044 if ((count % 2) != 0) /* check even */
1045 {
1046 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
1047 data.year = 0; /* set 0 */
1048 data.month = 0; /* set 0 */
1049 data.day = 0; /* set 0 */
1050 data.week = 0; /* set 0 */
1051 data.hour = 0; /* set 0 */
1052 data.minute = 0; /* set 0 */
1053 data.second = 0; /* set 0 */
1054 if (handle->receive_callback != NULL) /* not null */
1055 {
1056 handle->receive_callback(&data); /* run the callback */
1057 }
1058
1059 handle->decode_len = 0; /* clear the buffer */
1060 handle->decode_offset = 0; /* init 0 */
1061 handle->decode_valid = 0; /* set invalid */
1062 handle->trace_valid = 0; /* set invalid */
1063
1064 return; /* return */
1065 }
1066 data.year = ((uint16_t)1 << 6); /* add year */
1067 data.year += 2000; /* add 2000 */
1068 }
1069 else /* odd, year add */
1070 {
1071 if ((count % 2) == 0) /* check even */
1072 {
1073 data.status = BPC_STATUS_PARITY_ERR; /* frame invalid */
1074 data.year = 0; /* set 0 */
1075 data.month = 0; /* set 0 */
1076 data.day = 0; /* set 0 */
1077 data.week = 0; /* set 0 */
1078 data.hour = 0; /* set 0 */
1079 data.minute = 0; /* set 0 */
1080 data.second = 0; /* set 0 */
1081 if (handle->receive_callback != NULL) /* not null */
1082 {
1083 handle->receive_callback(&data); /* run the callback */
1084 }
1085
1086 handle->decode_len = 0; /* clear the buffer */
1087 handle->decode_offset = 0; /* init 0 */
1088 handle->decode_valid = 0; /* set invalid */
1089 handle->trace_valid = 0; /* set invalid */
1090
1091 return; /* return */
1092 }
1093 data.year = ((uint16_t)1 << 6); /* add year */
1094 data.year += 2000; /* add 2000 */
1095 }
1096
1097 if (data.week == 7) /* sunday is 7 in old version */
1098 {
1099 data.week = 0; /* set 0 */
1100 }
1101 data.status = BPC_STATUS_OK; /* set ok */
1102 if (handle->receive_callback != NULL) /* not null */
1103 {
1104 handle->receive_callback(&data); /* run the callback */
1105 }
1106
1107 handle->decode_len = 0; /* clear the buffer */
1108 handle->decode_offset = 0; /* init 0 */
1109 handle->decode_valid = 0; /* set invalid */
1110 handle->trace_valid = 1; /* set valid */
1111 }
1112}
1113
1125{
1126 uint8_t res;
1127 int64_t diff;
1128 bpc_time_t t;
1129
1130 if (handle == NULL) /* check handle */
1131 {
1132 return 2; /* return error */
1133 }
1134 if (handle->inited != 1) /* check handle initialization */
1135 {
1136 return 3; /* return error */
1137 }
1138
1139 res = handle->timestamp_read(&t); /* timestamp read */
1140 if (res != 0) /* check result */
1141 {
1142 handle->debug_print("bpc: timestamp read failed.\n"); /* timestamp read failed */
1143
1144 return 1; /* return error */
1145 }
1146 diff = (int64_t)((int64_t)t.s -
1147 (int64_t)handle->last_time.s) * 1000000 +
1148 (int64_t)((int64_t)t.us -
1149 (int64_t)handle->last_time.us); /* now - last time */
1150 if (diff - (int64_t)3000000L >= 0) /* if over 3s, force reset */
1151 {
1152 handle->decode_len = 0; /* reset the decode */
1153 handle->decode_offset = 0; /* set 0 */
1154 handle->decode_valid = 0; /* set invalid */
1155 handle->trace_valid = 0; /* set invalid */
1156 }
1157 if (handle->decode_len >= 76) /* check the max length */
1158 {
1159 handle->decode_len = 0; /* reset the decode */
1160 handle->decode_offset = 0; /* set 0 */
1161 handle->decode_valid = 0; /* set invalid */
1162 handle->trace_valid = 0; /* set invalid */
1163 }
1164 handle->decode[handle->decode_len].t.s = t.s; /* save s */
1165 handle->decode[handle->decode_len].t.us = t.us; /* save us */
1166 handle->decode_len++; /* length++ */
1167 if (handle->trace_valid != 0) /* check trace valid */
1168 {
1169 a_bpc_trace_decode(handle); /* try to trace decode */
1170 }
1171 if (handle->decode_len >= 38) /* check the end length */
1172 {
1173 if (handle->decode_valid != 0) /* check decode valid */
1174 {
1175 a_bpc_decode(handle); /* try to decode */
1176 }
1177 else
1178 {
1179 a_bpc_start_decode(handle); /* try to decode starter */
1180 }
1181 }
1182 handle->last_time.s = t.s; /* save last time */
1183 handle->last_time.us = t.us; /* save last time */
1184
1185 return 0; /* success return 0 */
1186}
1187
1198uint8_t bpc_init(bpc_handle_t *handle)
1199{
1200 uint8_t res;
1201 bpc_time_t t;
1202
1203 if (handle == NULL) /* check handle */
1204 {
1205 return 2; /* return error */
1206 }
1207 if (handle->debug_print == NULL) /* check debug_print */
1208 {
1209 return 3; /* return error */
1210 }
1211 if (handle->timestamp_read == NULL) /* check timestamp_read */
1212 {
1213 handle->debug_print("bpc: timestamp_read is null.\n"); /* timestamp_read is null */
1214
1215 return 3; /* return error */
1216 }
1217 if (handle->delay_ms == NULL) /* check delay_ms */
1218 {
1219 handle->debug_print("bpc: delay_ms is null.\n"); /* delay_ms is null */
1220
1221 return 3; /* return error */
1222 }
1223 if (handle->receive_callback == NULL) /* check receive_callback */
1224 {
1225 handle->debug_print("bpc: receive_callback is null.\n"); /* receive_callback is null */
1226
1227 return 3; /* return error */
1228 }
1229
1230 res = handle->timestamp_read(&t); /* timestamp read */
1231 if (res != 0) /* check result */
1232 {
1233 handle->debug_print("bpc: timestamp read failed.\n"); /* timestamp read failed */
1234
1235 return 1; /* return error */
1236 }
1237 handle->last_time.s = t.s; /* save last time */
1238 handle->last_time.us = t.us; /* save last time */
1239 handle->decode_len = 0; /* init 0 */
1240 handle->decode_offset = 0; /* init 0 */
1241 handle->decode_valid = 0; /* set invalid */
1242 handle->trace_valid = 0; /* set invalid */
1243 handle->inited = 1; /* flag inited */
1244
1245 return 0; /* success return 0 */
1246}
1247
1257uint8_t bpc_deinit(bpc_handle_t *handle)
1258{
1259 if (handle == NULL) /* check handle */
1260 {
1261 return 2; /* return error */
1262 }
1263 if (handle->inited != 1) /* check handle initialization */
1264 {
1265 return 3; /* return error */
1266 }
1267
1268 handle->inited = 0; /* flag close */
1269
1270 return 0; /* success return 0 */
1271}
1272
1281uint8_t bpc_info(bpc_info_t *info)
1282{
1283 if (info == NULL) /* check handle */
1284 {
1285 return 2; /* return error */
1286 }
1287
1288 memset(info, 0, sizeof(bpc_info_t)); /* initialize bpc info structure */
1289 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
1290 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
1291 strncpy(info->interface, "GPIO", 8); /* copy interface name */
1292 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
1293 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
1294 info->max_current_ma = MAX_CURRENT; /* set maximum current */
1295 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
1296 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
1297 info->driver_version = DRIVER_VERSION; /* set driver version */
1298
1299 return 0; /* success return 0 */
1300}
#define MAX_CURRENT
Definition driver_bpc.c:47
#define BPC_CHECK_DATA_1
Definition driver_bpc.c:59
#define BPC_CHECK_DATA_0
Definition driver_bpc.c:58
#define SUPPLY_VOLTAGE_MAX
Definition driver_bpc.c:46
#define BPC_CHECK_START_FRAME_MAX
Definition driver_bpc.c:56
#define BPC_CHECK_DATA_3
Definition driver_bpc.c:61
#define TEMPERATURE_MAX
Definition driver_bpc.c:49
#define BPC_CHECK_START_FRAME_MIN
frame check definition
Definition driver_bpc.c:55
#define BPC_CHECK_DATA_2
Definition driver_bpc.c:60
#define MANUFACTURER_NAME
Definition driver_bpc.c:44
#define TEMPERATURE_MIN
Definition driver_bpc.c:48
#define SUPPLY_VOLTAGE_MIN
Definition driver_bpc.c:45
#define BPC_CHECK_FRAME_TIME
Definition driver_bpc.c:57
#define CHIP_NAME
chip information definition
Definition driver_bpc.c:43
#define DRIVER_VERSION
Definition driver_bpc.c:50
driver bpc header file
uint8_t bpc_irq_handler(bpc_handle_t *handle)
irq handler
uint8_t bpc_info(bpc_info_t *info)
get chip's information
uint8_t bpc_init(bpc_handle_t *handle)
initialize the chip
struct bpc_handle_s bpc_handle_t
bpc handle structure definition
struct bpc_s bpc_t
bpc structure definition
struct bpc_time_s bpc_time_t
bpc time structure definition
struct bpc_info_s bpc_info_t
bpc information structure definition
uint8_t bpc_deinit(bpc_handle_t *handle)
close the chip
#define BPC_MAX_RANGE
bpc max range definition
Definition driver_bpc.h:70
#define BPC_MAX_START_RANGE
bpc max start range definition
Definition driver_bpc.h:63
@ BPC_STATUS_FRAME_INVALID
Definition driver_bpc.h:80
@ BPC_STATUS_OK
Definition driver_bpc.h:78
@ BPC_STATUS_PARITY_ERR
Definition driver_bpc.h:79
bpc_time_t t
Definition driver_bpc.h:112
uint32_t diff_us
Definition driver_bpc.h:113
uint8_t decode_valid
Definition driver_bpc.h:130
uint8_t decode_offset
Definition driver_bpc.h:129
uint8_t inited
Definition driver_bpc.h:125
void(* delay_ms)(uint32_t ms)
Definition driver_bpc.h:122
uint8_t trace_valid
Definition driver_bpc.h:131
bpc_decode_t decode[76]
Definition driver_bpc.h:126
void(* receive_callback)(bpc_t *data)
Definition driver_bpc.h:124
void(* debug_print)(const char *const fmt,...)
Definition driver_bpc.h:123
uint8_t(* timestamp_read)(bpc_time_t *t)
Definition driver_bpc.h:121
bpc_time_t last_time
Definition driver_bpc.h:128
uint16_t decode_len
Definition driver_bpc.h:127
float temperature_max
Definition driver_bpc.h:146
float supply_voltage_max_v
Definition driver_bpc.h:143
uint32_t driver_version
Definition driver_bpc.h:147
float temperature_min
Definition driver_bpc.h:145
float max_current_ma
Definition driver_bpc.h:144
char manufacturer_name[32]
Definition driver_bpc.h:140
float supply_voltage_min_v
Definition driver_bpc.h:142
char interface[8]
Definition driver_bpc.h:141
char chip_name[32]
Definition driver_bpc.h:139
uint8_t month
Definition driver_bpc.h:90
uint8_t week
Definition driver_bpc.h:92
uint16_t year
Definition driver_bpc.h:89
uint8_t day
Definition driver_bpc.h:91
uint8_t second
Definition driver_bpc.h:95
uint8_t minute
Definition driver_bpc.h:94
uint8_t status
Definition driver_bpc.h:88
uint8_t hour
Definition driver_bpc.h:93
uint64_t s
Definition driver_bpc.h:103
uint32_t us
Definition driver_bpc.h:104