-
Notifications
You must be signed in to change notification settings - Fork 13
/
ds2411_dev.c
1147 lines (983 loc) · 36.8 KB
/
ds2411_dev.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Copyright (c) 2006 by ARES Inria. All Rights Reserved */
/**
* \file ds2411_dev.c
* \brief Maxim DS2411 device
* \author Eric Fleury, Antoine Fraboulet
* \date 2006
**/
/***
NAME
ds2411_dev
PURPOSE
NOTES
HISTORY
efleury - Jan 31, 2006: Created.
***/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "arch/common/hardware.h"
#include "devices/ds2411/ds2411.h"
#include "devices/ds2411/ds2411_dev.h"
/***************************************************/
/***************************************************/
#define DEBUG_CMD 0
#define DEBUG_ME_HARDER 0
#define DEBUG_WIRE 0
#define DEBUG_CRC 0
#define DEBUG_SERIAL 0
#define HW_DMSG_DSTATE(x...) \
do { \
HW_DMSG_DS2411("ds2411: ======================================================\n"); \
HW_DMSG_DS2411(x); \
HW_DMSG_DS2411("ds2411: ======================================================\n"); \
} while(0)
#if DEBUG_CMD != 0
#define HW_DMSG_DS2411(x...) HW_DMSG_DEV(x)
#else
#define HW_DMSG_DS2411(x...) do {} while(0)
#endif
#if DEBUG_ME_HARDER != 0
#define HW_DMSG_DSH(x...) HW_DMSG_DS2411(x)
#else
#define HW_DMSG_DSH(x...) do {} while(0)
#endif
#if DEBUG_WIRE != 0
#define HW_DMSG_WIRE(x...) HW_DMSG_DS2411(x)
#else
#define HW_DMSG_WIRE(x...) do {} while(0)
#endif
#if DEBUG_CRC != 0
#define HW_DMSG_CRC(x...) HW_DMSG_DS2411(x)
#else
#define HW_DMSG_CRC(x...) do {} while(0)
#endif
#if DEBUG_SERIAL != 0
#define HW_DMSG_SER(x...) HW_DMSG_DS2411(x)
#else
#define HW_DMSG_SER(x...) do {} while(0)
#endif
/***************************************************/
/***************************************************/
/***************************/
/* Global variables */
/***************************/
tracer_id_t TRACER_DS2411;
/***************************/
/* Time unit factors */
/***************************/
#define MILLI *1000*1000llu
#define MICRO *1000llu
#define NANO *1llu
/***************************/
/* Standard speed settings */
/***************************/
/* TIME from DS2411 - page 2-3 */
/* Reset Low time */
#define ONEWIRE_RSTL_MIN (480 MICRO)
#define ONEWIRE_RSTL_MAX (660 MICRO) /* changed from 640 to 660 for Contiki2.4 */
/* Presence detect High time */
#define ONEWIRE_PDH_MIN ( 15 MICRO)
#define ONEWIRE_PDH_MAX ( 60 MICRO)
/* Presence detect Low time */
#define ONEWIRE_PDL_MIN ( 60 MICRO)
#define ONEWIRE_PDL_MAX (240 MICRO)
/* Presence detect Fall time */
#define ONEWIRE_FPD_MIN (400 NANO)
#define ONEWIRE_FPD_MAX ( 8 MICRO)
/* Presence detect sample time */
#define ONEWIRE_MSP_MIN ( 6 MICRO)
#define ONEWIRE_MSP_MAX ( 10 MICRO)
/* Rising Edge HoldOff */
#define ONEWIRE_REH_MIN (1250 NANO)
#define ONEWIRE_REH_MAX ( 5 MICRO)
/* Recovery time */
#define ONEWIRE_REC ( 5 MICRO)
/* Timeslot duration */
#define ONEWIRE_SLOT_MIN ( 65 MICRO)
#define ONEWIRE_SLOT_MAX ( 70 MICRO)
/* Write 0 low time */
#define ONEWIRE_W0L_MIN ( 60 MICRO)
#define ONEWIRE_W0L_MAX (120 MICRO)
/* Write 1 low time */
#define ONEWIRE_W1L_MIN ( 4 MICRO) /* changed from 5 to 4 for contiki2.4 */
#define ONEWIRE_W1L_MAX ( 15 MICRO)
/* Read Low time */
#define ONEWIRE_RL_MIN ( 4 MICRO) /* changed from 6 to 4 for contiki2.4 */
#define ONEWIRE_RL_MAX ( 15 MICRO)
/* Read Sample time */
#define ONEWIRE_MSR_MIN ( 1 MICRO)
#define ONEWIRE_MSR_MAX ( 15 MICRO)
/****************************************/
/* Need to add overdrive speed settings */
/****************************************/
/* enum onewire_timing_enum_t { */
/* /\* Reset Low time *\/ */
/* _ONEWIRE_RSTL_MIN = 0, */
/* _ONEWIRE_RSTL_MAX = 1, */
/* /\* Presence detect High time *\/ */
/* _ONEWIRE_PDH_MIN = 2, */
/* _ONEWIRE_PDH_MAX = 3, */
/* /\* Presence detect Low time *\/ */
/* _ONEWIRE_PDL_MIN = 4, */
/* _ONEWIRE_PDL_MAX = 5, */
/* /\* Presence detect Fall time *\/ */
/* _ONEWIRE_FPD_MIN = 6, */
/* _ONEWIRE_FPD_MAX = 7, */
/* /\* Presence detect sample time *\/ */
/* _ONEWIRE_MSP_MIN = 8, */
/* _ONEWIRE_MSP_MAX = 9, */
/* /\* Rising Edge HoldOff *\/ */
/* _ONEWIRE_REH_MIN = 10, */
/* _ONEWIRE_REH_MAX = 11, */
/* /\* Recovery time *\/ */
/* _ONEWIRE_REC = 12, */
/* /\* Timeslot duration *\/ */
/* _ONEWIRE_SLOT = 13, */
/* /\* Write 0 low time *\/ */
/* _ONEWIRE_W0L_MIN = 14, */
/* _ONEWIRE_W0L_MAX = 15, */
/* /\* Write 1 low time *\/ */
/* _ONEWIRE_W1L_MIN = 16, */
/* _ONEWIRE_W1L_MAX = 17, */
/* /\* Read Low time *\/ */
/* _ONEWIRE_RL_MIN = 18, */
/* _ONEWIRE_RL_MAX = 19, */
/* /\* Read Sample time *\/ */
/* _ONEWIRE_MSR_MIN = 20, */
/* _ONEWIRE_MSR_MAX = 21 */
/* }; */
/*
static uint64_t onewire_timings[2][22] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
*/
enum onewire_mode_enum_t {
ONEWIRE_SPEED_STD = 0,
ONEWIRE_SPEED_OVD = 1
};
enum onewire_command_enum_t {
ONEWIRE_CMD_NONE = 0x00,
ONEWIRE_READ_ROM = 0x33,
ONEWIRE_SEARCH_ROM = 0xF0,
ONEWIRE_OVERDRIVE_SKIP_ROM = 0x3C
};
enum onewire_trans_enum_t {
ONEWIRE_TRANS_LOW = 0,
ONEWIRE_TRANS_HIGH = 1,
ONEWIRE_TRANS_NONE = 2,
};
enum onewire_lvl0_state_enum_t {
ONEWIRE_LVL0_RESET = 0,
ONEWIRE_LVL0_READ_COMMAND = 1,
ONEWIRE_LVL0_DEVICE
};
enum onewire_reset_state_enum_t {
ONEWIRE_RESET_WAIT = 0,
ONEWIRE_RESET_PULSE ,
ONEWIRE_PRESENCE_PULSE ,
ONEWIRE_PRESENCE_PULSE_END ,
ONEWIRE_PRESENCE_PULSE_REC ,
};
enum onewire_rcmd_state_enum_t {
ONEWIRE_RCMD_INIT = 0,
ONEWIRE_RCMD_READ ,
};
enum onewire_signal_state_enum_t {
ONEWIRE_WAITING_LOW = 0,
ONEWIRE_WAITING_HIGH ,
ONEWIRE_WRITE_ENDSLOT ,
ONEWIRE_READ_VAL ,
ONEWIRE_READ_HOLD ,
ONEWIRE_READ_REC
};
enum onewire_wire_enum_t {
ONEWIRE_INPUT_LOW = 0,
ONEWIRE_INPUT_HIGH = 1,
ONEWIRE_INPUT_OPEN = 2,
};
typedef enum onewire_lvl0_state_enum_t onewire_lvl0_state_t;
typedef enum onewire_reset_state_enum_t onewire_reset_state_t;
typedef enum onewire_rcmd_state_enum_t onewire_rcmd_state_t;
typedef enum onewire_signal_state_enum_t onewire_signal_state_t;
typedef enum onewire_wire_enum_t onewire_wire_t;
typedef enum onewire_trans_enum_t onewire_trans_t;
typedef enum onewire_mode_enum_t onewire_mode_t;
typedef enum onewire_command_enum_t onewire_command_t;
typedef enum onewire_timing_enum_t onewire_timing_t;
enum ds2411_readrom_state_enum_t {
DS2411_READROM_INIT = 0,
DS2411_READROM_READ ,
};
enum ds2411_searchrom_state_enum_t {
DS2411_SEARCHROM_INIT = 0,
DS2411_SEARCHROM_hoho
};
typedef enum ds2411_readrom_state_enum_t ds2411_readrom_state_t;
typedef enum ds2411_searchrom_state_enum_t ds2411_searchrom_state_t;
/***************************************************/
/***************************************************/
/***************************************************/
struct ds2411_dev_t
{
/****************************/
/* 1 wire protocol handling */
/****************************/
onewire_mode_t speed; /* communication speed mode */
/* onewire main protocol state */
uint64_t time_in; /* Time when the DS2411 entered in the current state */
onewire_lvl0_state_t state; /* Current state of 1wire protocol */
onewire_reset_state_t state_reset; /* reset / presence automata state */
onewire_rcmd_state_t state_rcmd; /* read command automata */
onewire_command_t command; /* current command */
/* write/read automata */
onewire_signal_state_t state_signal; /* signal state : write0, write1, read automata */
uint8_t buf; /* value read so far (i.e. from bit 0 to current_bit) */
uint8_t buf_bitnum; /* bit number that we try to read/write */
/* write 0 or write 1 automata helpers */
uint64_t write_time_remain;/* used for write_one and write_zero */
unsigned int write_bit; /* used for write_one and write_zero */
/* wire interface with MCU */
onewire_wire_t wire; /* wire state */
int read; /* speed read update: 1 if something has to be read */
onewire_trans_t read_trans; /* 0: high to low, 1: low to high, 2: none */
int write; /* speed write updates: 1 if we follow a write */
onewire_trans_t write_trans; /* 0: high to low, 1: low to high, 2: none */
/************************/
/* DS2411 specific part */
/************************/
ds2411_serial_number_t id; /* uniq serial number of the DS2411 */
ds2411_readrom_state_t state_readrom;
int state_readrom_bytenumber;
ds2411_searchrom_state_t state_searchrom;
};
#define DS2411_DATA ((struct ds2411_dev_t*)machine.device[dev].data)
#define DS2411_SPEED (DS2411_DATA->speed)
#define DS2411_COMMAND (DS2411_DATA->command)
#define DS2411_LVL0_STATE (DS2411_DATA->state)
#define DS2411_RESET_STATE (DS2411_DATA->state_reset)
#define DS2411_RCMD_STATE (DS2411_DATA->state_rcmd)
#define DS2411_SIGNAL_STATE (DS2411_DATA->state_signal)
#define DS2411_WIRE_STATE (DS2411_DATA->wire)
#define DS2411_READ_VALID (DS2411_DATA->read)
#define DS2411_READ_TRANS (DS2411_DATA->read_trans)
#define DS2411_WRITE_VALID (DS2411_DATA->write)
#define DS2411_WRITE_TRANS (DS2411_DATA->write_trans)
#define DS2411_TIME_IN (DS2411_DATA->time_in)
#define DS2411_WTIME_REMAIN (DS2411_DATA->write_time_remain)
#define DS2411_WBIT (DS2411_DATA->write_bit)
#define DS2411_ID (DS2411_DATA->id)
#define DS2411_BUF (DS2411_DATA->buf)
#define DS2411_BUF_BITNUM (DS2411_DATA->buf_bitnum)
#define DS2411_READROM_STATE (DS2411_DATA->state_readrom)
#define DS2411_READROM_BYTENUM (DS2411_DATA->state_readrom_bytenumber)
#define DS2411_SEARCHROM_STATE (DS2411_DATA->state_searchrom)
/* 7 6 5 4 3 2 1 0 */
#define SERIAL_DEFAULT_ID "0f:07:06:05:04:03:02:01"
#define SERIAL_MASK_STR "xx:xx:xx:xx:xx:xx:xx:xx"
#define SERIAL_ID_STR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
/***************************************************/
/***************************************************/
/***************************************************/
/*
* CRC x8 + x5 + x4 + 1
*
* Numerical Recipies in C : the art of scientific computing
* ch 20.3 Cyclic Redundancy and Other Checksums (page 896)
*
*/
static uint8_t onewire_crc8_byte( uint8_t crc, uint8_t byte )
{
int i;
crc ^= byte;
HW_DMSG_CRC("ds2411:crc: 0: crc 0x%02x\n",crc);
for( i=0; i<8; i++ )
{
if( crc & 1 )
crc = (crc >> 1) ^ 0x8c;
else
crc >>= 1;
HW_DMSG_CRC("ds2411:crc: %d: crc 0x%02x\n",i+1,crc);
}
return crc;
}
static uint8_t onewire_crc8_bytes( uint8_t crc, uint8_t* bytes, uint8_t len )
{
uint8_t* end = bytes+len;
while( bytes != end )
{
crc = onewire_crc8_byte( crc, *bytes );
HW_DMSG_CRC("ds2411:crc: byte 0x%02x crc 0x%02x\n",*bytes,crc);
bytes++;
}
return crc;
}
/***************************************************/
/***************************************************/
/***************************************************/
static uint8_t ds2411_crc(ds2411_serial_number_t *id)
{
uint8_t crc = 0;
crc = onewire_crc8_bytes(crc, id->raw, 7);
return crc;
}
/***************************************************/
/***************************************************/
/***************************************************/
static int ds2411_check_crc(ds2411_serial_number_t *id)
{
return ds2411_crc(id) == id->fields.crc;
}
/***************************************************/
/***************************************************/
/***************************************************/
char* ds2411_id_to_str(ds2411_serial_number_t *id)
{
static char idstr[] = SERIAL_MASK_STR;
sprintf(idstr,SERIAL_ID_STR,
id->fields.crc,
id->fields.serial5, id->fields.serial4,
id->fields.serial3, id->fields.serial2,
id->fields.serial1, id->fields.serial0,
id->fields.family);
return idstr;
}
/***************************************************/
/***************************************************/
/***************************************************/
static ds2411_serial_number_t ds2411_str_to_id(char *serial)
{
int n;
ds2411_serial_number_t id;
unsigned int i0,i1,i2,i3,i4,i5,i6,i7;
if (serial == NULL)
{
serial = SERIAL_DEFAULT_ID;
}
memset(&id, 0, sizeof(ds2411_serial_number_t));
n = sscanf(serial,SERIAL_ID_STR, &i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
if (n != DS2411_REG_NUMBER_LEN)
{
serial = SERIAL_DEFAULT_ID;
ERROR("DS2411: wrong serial id format, set by default to %s\n", serial);
sscanf(serial,SERIAL_ID_STR, &i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
}
id.fields.crc = i0;
id.fields.serial5 = i1;
id.fields.serial4 = i2;
id.fields.serial3 = i3;
id.fields.serial2 = i4;
id.fields.serial1 = i5;
id.fields.serial0 = i6;
id.fields.family = i7;
HW_DMSG_SER("DS2411: id = %s\n", ds2411_id_to_str(&id));
if (! ds2411_check_crc(&id))
{
WARNING("DS2411: crc is not valid, should be 0x%x\n",ds2411_crc(&id));
}
return id;
}
/***************************************************/
/***************************************************/
/***************************************************/
int ds2411_device_size(void)
{
return sizeof(struct ds2411_dev_t);
}
/***************************************************/
/***************************************************/
/***************************************************/
int ds2411_delete(int UNUSED dev)
{
return 0;
}
/***************************************************/
/***************************************************/
/***************************************************/
int ds2411_reset(int dev)
{
ds2411_serial_number_t id;
id = DS2411_ID;
memset(DS2411_DATA, 0, sizeof(*(DS2411_DATA)));
DS2411_ID = id;
DS2411_LVL0_STATE = ONEWIRE_LVL0_RESET;
DS2411_TIME_IN = MACHINE_TIME_GET_NANO();
DS2411_WIRE_STATE = ONEWIRE_INPUT_HIGH;
DS2411_READ_VALID = 0;
tracer_event_record(TRACER_DS2411,1);
return 0;
}
/***************************************************/
/***************************************************/
/***************************************************/
int ds2411_power_down(int UNUSED dev)
{
return 0;
}
/***************************************************/
/***************************************************/
/***************************************************/
int ds2411_power_up(int dev)
{
return ds2411_reset(dev);
}
/***************************************************/
/***************************************************/
/***************************************************/
/* read from MCU */
void ds2411_read(int dev, uint32_t *mask, uint32_t *val)
{
if (DS2411_READ_VALID)
{
*mask = 1;
*val = DS2411_WIRE_STATE;
tracer_event_record(TRACER_DS2411,DS2411_WIRE_STATE);
DS2411_READ_VALID = 0;
HW_DMSG_WIRE("ds2411: read from MCU %s [%"PRId64"]\n",
(*val & DS2411_D) ? "HIGH":"LOW", MACHINE_TIME_GET_NANO());
}
else
{
* mask = 0;
}
}
/***************************************************/
/***************************************************/
/***************************************************/
/* write from MCU */
void ds2411_write(int dev, uint32_t mask, uint32_t val)
{
if (mask & DS2411_D)
{
/* 1 is HIGH, 0 is LOW */
if (DS2411_WIRE_STATE != (val & DS2411_D))
{
DS2411_WRITE_TRANS = val & DS2411_D;
DS2411_WRITE_VALID = 1;
DS2411_WIRE_STATE = val & DS2411_D;
tracer_event_record(TRACER_DS2411,(val & DS2411_D));
HW_DMSG_WIRE("ds2411: write from MCU %s [+%"PRId64"]\n",
(val & DS2411_D) ? "HIGH":"LOW",
MACHINE_TIME_GET_NANO() - DS2411_TIME_IN);
}
}
}
/***************************************************/
/***************************************************/
/***************************************************/
#define CANCEL_OPERATION(dev) \
do { \
DS2411_READ_VALID = 1; \
DS2411_READ_TRANS = ONEWIRE_TRANS_HIGH; \
DS2411_WIRE_STATE = ONEWIRE_INPUT_HIGH; \
} while (0)
#define GO_WAIT_RESET(dev) \
do { \
CANCEL_OPERATION(dev); \
DS2411_LVL0_STATE = ONEWIRE_LVL0_RESET; \
DS2411_RESET_STATE = ONEWIRE_RESET_WAIT; \
} while(0)
#define RESET_ON_BAD_WIRE_STATE(dev,expected,time) \
do { \
if (DS2411_WIRE_STATE != expected) { \
GO_WAIT_RESET(dev); \
HW_DMSG_DS2411("ds2411: ====== bad wire state [%" PRId64 "]\n",time); \
} \
} while(0)
/***************************************************/
/***************************************************/
/***************************************************/
/* Handles onewire signals during a RESET and PRESENCE PULSE */
static void update_onewire_reset_state(int dev, uint64_t current_time, uint64_t time_in_state)
{
switch (DS2411_RESET_STATE)
{
case ONEWIRE_RESET_WAIT: /* IDLE */
if (DS2411_WRITE_TRANS == ONEWIRE_TRANS_LOW)
{
DS2411_RESET_STATE = ONEWIRE_RESET_PULSE;
DS2411_TIME_IN = current_time;
HW_DMSG_DSH("ds2411: GO RESET_PULSE\n");
}
break;
case ONEWIRE_RESET_PULSE: /* waiting for HIGH */
if (DS2411_WRITE_VALID && (DS2411_WRITE_TRANS == ONEWIRE_TRANS_HIGH))
{
if (time_in_state < ONEWIRE_RSTL_MIN)
{
GO_WAIT_RESET(dev);
HW_DMSG_DS2411("ds2411: reset_pulse canceled, up too early [+%"PRId64" < %"PRId64"]\n",
time_in_state, ONEWIRE_RSTL_MIN);
}
else if (time_in_state > ONEWIRE_RSTL_MAX)
{
GO_WAIT_RESET(dev);
HW_DMSG_DS2411("ds2411: reset_pulse canceled, up too late [+%"PRId64" > %"PRId64"]\n",
time_in_state, ONEWIRE_RSTL_MAX);
}
else
{
DS2411_RESET_STATE = ONEWIRE_PRESENCE_PULSE;
DS2411_TIME_IN = current_time;
HW_DMSG_DSH("ds2411: GO PRESENCE_PULSE MSP [+%"PRId64"]\n",time_in_state);
}
}
break;
case ONEWIRE_PRESENCE_PULSE: /* waiting MSP before sending PRESENCE_PULSE : 6µs */
if (time_in_state > ONEWIRE_MSP_MIN && DS2411_WIRE_STATE == ONEWIRE_INPUT_HIGH)
{
DS2411_RESET_STATE = ONEWIRE_PRESENCE_PULSE_END;
DS2411_TIME_IN = current_time;
DS2411_READ_VALID = 1;
DS2411_READ_TRANS = ONEWIRE_TRANS_LOW;
DS2411_WIRE_STATE = ONEWIRE_INPUT_LOW;
HW_DMSG_DSH("ds2411: GO PRESENCE_PULSE, wire low [+%"PRId64"]\n",time_in_state);
}
else { RESET_ON_BAD_WIRE_STATE(dev,ONEWIRE_INPUT_HIGH,time_in_state); }
break;
case ONEWIRE_PRESENCE_PULSE_END:
if (time_in_state > ONEWIRE_PDL_MAX && DS2411_WIRE_STATE == ONEWIRE_INPUT_LOW)
{
DS2411_RESET_STATE = ONEWIRE_PRESENCE_PULSE_REC;
DS2411_TIME_IN = current_time;
DS2411_READ_VALID = 1;
DS2411_READ_TRANS = ONEWIRE_TRANS_HIGH;
DS2411_WIRE_STATE = ONEWIRE_INPUT_HIGH;
HW_DMSG_DSH("ds2411: GO PRESENCE_PULSE_REC, wire high [+%"PRId64"]\n",time_in_state);
}
else { RESET_ON_BAD_WIRE_STATE(dev,ONEWIRE_INPUT_LOW,time_in_state); }
break;
case ONEWIRE_PRESENCE_PULSE_REC:
if (time_in_state > ONEWIRE_REC && DS2411_WIRE_STATE == ONEWIRE_INPUT_HIGH)
{
DS2411_LVL0_STATE = ONEWIRE_LVL0_READ_COMMAND;
DS2411_RCMD_STATE = ONEWIRE_RCMD_INIT;
DS2411_RESET_STATE = ONEWIRE_RESET_WAIT;
DS2411_TIME_IN = current_time;
HW_DMSG_DSH("ds2411: GO COMMAND, wire high [+%"PRId64"]\n",time_in_state);
}
else { RESET_ON_BAD_WIRE_STATE(dev,ONEWIRE_INPUT_HIGH,time_in_state); }
break;
}
}
/***************************************************/
/***************************************************/
/***************************************************/
/* Handles onewire signals during Write0, Write1, keep track of RESET PULSE */
void update_onewire_write_signal(int dev, uint64_t current_time, uint64_t time_in_state)
{
switch (DS2411_SIGNAL_STATE)
{
case ONEWIRE_WAITING_LOW:
if (DS2411_WRITE_VALID && (DS2411_WIRE_STATE == ONEWIRE_INPUT_LOW))
{ /* starting something */
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_HIGH;
HW_DMSG_DSH("ds2411: GO SIGNAL_WAITING_HIGH (start write) [%"PRId64"]\n",
MACHINE_TIME_GET_NANO());
}
break;
case ONEWIRE_WAITING_HIGH:
if (DS2411_WRITE_VALID && (DS2411_WIRE_STATE == ONEWIRE_INPUT_HIGH))
{
if (time_in_state >= ONEWIRE_W1L_MIN && time_in_state <= ONEWIRE_W1L_MAX)
{ /* write 1 or read */
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_WRITE_ENDSLOT;
int64_t rem = ONEWIRE_SLOT_MAX - time_in_state;
DS2411_WTIME_REMAIN = (rem > 0) ? rem : 0;
DS2411_WBIT = 1;
HW_DMSG_DSH("ds2411: GO WRITE_ENDSLOT (1) [+%" PRId64 "][remain %"PRId64"]\n",
time_in_state,DS2411_WTIME_REMAIN);
}
else if (time_in_state >= ONEWIRE_W0L_MIN && time_in_state <= ONEWIRE_W0L_MAX)
{ /* write 0 */
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_WRITE_ENDSLOT;
int64_t rem = ONEWIRE_SLOT_MAX - time_in_state;
DS2411_WTIME_REMAIN = (rem > 0) ? rem : 0;
DS2411_WBIT = 0;
HW_DMSG_DSH("ds2411: GO WRITE_ENDSLOT (0) [+%" PRId64 "][remain %"PRId64"]\n",
time_in_state,DS2411_WTIME_REMAIN);
}
else if (time_in_state >= ONEWIRE_RSTL_MIN && time_in_state <= ONEWIRE_RSTL_MAX)
{ /* we have reset request */
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_LOW;
DS2411_LVL0_STATE = ONEWIRE_LVL0_RESET;
DS2411_RESET_STATE = ONEWIRE_PRESENCE_PULSE;
HW_DMSG_DSH("ds2411: GO PRESENCE_PULSE (during write) [+%" PRId64 "]\n",time_in_state);
}
else
{
GO_WAIT_RESET(dev);
HW_DMSG_DSH("ds2411: ** HIGH at wrong time during WRITE [+%" PRId64 "]\n",time_in_state);
}
}
break;
case ONEWIRE_WRITE_ENDSLOT: /* wait write end slot */
if (time_in_state >= DS2411_WTIME_REMAIN)
{
DS2411_TIME_IN = current_time;
DS2411_BUF |= (DS2411_WBIT << DS2411_BUF_BITNUM);
DS2411_BUF_BITNUM += 1;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_LOW;
HW_DMSG_DS2411("ds2411: ** WRITE %d ** [0x%02x,%d]\n",DS2411_WBIT,DS2411_BUF,DS2411_BUF_BITNUM);
HW_DMSG_DSH("ds2411: GO WAITING_LOW [%" PRId64 "]\n",time_in_state);
}
break;
case ONEWIRE_READ_VAL:
case ONEWIRE_READ_HOLD:
case ONEWIRE_READ_REC:
ERROR("ds2411: ERROR, should no be in ONEWIRE_READ state\n");
break;
}
}
/***************************************************/
/***************************************************/
/***************************************************/
/* Handles onewire state during READ COMMAND (8 bits) */
static void update_onewire_read_command_state(int dev, uint64_t current_time, uint64_t time_in_state)
{
switch (DS2411_RCMD_STATE)
{
case ONEWIRE_RCMD_INIT:
DS2411_BUF = 0;
DS2411_BUF_BITNUM = 0;
DS2411_RCMD_STATE = ONEWIRE_RCMD_READ;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_LOW;
/* fall through */
case ONEWIRE_RCMD_READ:
update_onewire_write_signal(dev,current_time,time_in_state);
if (DS2411_BUF_BITNUM == 8) /* the command is complete */
{
DS2411_COMMAND = DS2411_BUF;
DS2411_BUF_BITNUM = 0;
DS2411_RCMD_STATE = ONEWIRE_RCMD_INIT;
switch (DS2411_BUF)
{
case ONEWIRE_READ_ROM: /* 0x33 */
DS2411_LVL0_STATE = ONEWIRE_LVL0_DEVICE;
DS2411_READROM_STATE = DS2411_READROM_INIT;
HW_DMSG_DS2411("ds2411: *****************\n");
HW_DMSG_DS2411("ds2411: READ_ROM received\n");
HW_DMSG_DS2411("ds2411: *****************\n");
break;
case ONEWIRE_SEARCH_ROM: /* 0xF0 */
ERROR("ds2411: **************************\n");
ERROR("ds2411: Search ROM not implemented\n");
ERROR("ds2411: **************************\n");
GO_WAIT_RESET(dev);
break;
case ONEWIRE_OVERDRIVE_SKIP_ROM: /* 3C */
ERROR("ds2411: ****************************\n");
ERROR("ds2411: Overdrive mode not supported\n");
ERROR("ds2411: ****************************\n");
GO_WAIT_RESET(dev);
break;
default:
ERROR("ds2411: ****************************\n");
ERROR("ds2411: Unknown command 0x%02x \n",DS2411_BUF);
ERROR("ds2411: ****************************\n");
GO_WAIT_RESET(dev);
break;
}
}
break;
}
}
/***************************************************/
/***************************************************/
/***************************************************/
/* Handles onewire signals during READ, keep track of RESET pulse */
void update_onewire_read_signal(int dev, uint64_t current_time, uint64_t time_in_state)
{
switch (DS2411_SIGNAL_STATE)
{
case ONEWIRE_WAITING_LOW:
if (DS2411_WRITE_VALID && (DS2411_WIRE_STATE == ONEWIRE_INPUT_LOW))
{ /* starting something */
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_HIGH;
HW_DMSG_DSH("ds2411: GO SIGNAL_WAITING_HIGH (start read)\n");
}
break;
case ONEWIRE_WAITING_HIGH:
if (DS2411_WRITE_VALID && (DS2411_WIRE_STATE == ONEWIRE_INPUT_HIGH))
{
if (time_in_state >= ONEWIRE_RL_MIN && time_in_state <= ONEWIRE_RL_MAX)
{ /* write 1 or read */
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_READ_VAL;
/* DS2411_WTIME_REMAIN = ONEWIRE_RL_MAX - time_in_state; */
DS2411_WTIME_REMAIN = 0;
DS2411_WBIT = 1;
HW_DMSG_DSH("ds2411: GO READ_VAL, waiting end of RL time [+%"PRId64"]\n",time_in_state);
}
else if (time_in_state >= ONEWIRE_RSTL_MIN && time_in_state <= ONEWIRE_RSTL_MAX)
{ /* we have reset request */
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_LOW;
DS2411_LVL0_STATE = ONEWIRE_LVL0_RESET;
DS2411_RESET_STATE = ONEWIRE_PRESENCE_PULSE;
HW_DMSG_DSH("ds2411: GO PRESENCE_PULSE (during read) [+%"PRId64"]\n",time_in_state);
}
else
{
GO_WAIT_RESET(dev);
HW_DMSG_DS2411("ds2411: ** HIGH at wrong time during READ [+%"PRId64"]\n",time_in_state);
}
}
break;
case ONEWIRE_READ_VAL: /* End of RL */
if (time_in_state >= DS2411_WTIME_REMAIN) /* ok, now we write */
{
DS2411_TIME_IN = current_time;
DS2411_SIGNAL_STATE = ONEWIRE_READ_HOLD;
DS2411_WBIT = (DS2411_BUF & (1 << DS2411_BUF_BITNUM)) && 1;
if (DS2411_WBIT == 0) /* LSB first */
{
DS2411_READ_VALID = 1;
DS2411_READ_TRANS = ONEWIRE_TRANS_LOW;
DS2411_WIRE_STATE = ONEWIRE_INPUT_LOW;
}
else
{
DS2411_READ_VALID = 1;
DS2411_READ_TRANS = ONEWIRE_TRANS_HIGH;
DS2411_WIRE_STATE = ONEWIRE_INPUT_HIGH;
}
HW_DMSG_DSH("ds2411: GO READ_HOLD, value on wire is %s [+%"PRId64"]\n",
DS2411_WBIT ? "HIGH": "LOW" ,time_in_state);
}
else if (DS2411_WRITE_VALID)
{
ERROR("ds2411: MCU should not change value while end of RL [+%"PRId64"]\n",time_in_state);
GO_WAIT_RESET(dev);
}
break;
case ONEWIRE_READ_HOLD:
if (time_in_state >= ONEWIRE_MSR_MAX)
{
if (DS2411_WBIT == 0 && DS2411_WIRE_STATE == ONEWIRE_INPUT_LOW)
{
DS2411_READ_VALID = 1;
DS2411_READ_TRANS = ONEWIRE_TRANS_HIGH;
DS2411_WIRE_STATE = ONEWIRE_INPUT_HIGH;
}
else if (DS2411_WBIT == 1 && DS2411_WIRE_STATE == ONEWIRE_INPUT_HIGH)
{
/* so far, so good */
}
else
{
ERROR("ds2411: WIRE is not in good state at end of READ_HOLD\n");
GO_WAIT_RESET(dev);
}
DS2411_SIGNAL_STATE = ONEWIRE_READ_REC;
HW_DMSG_DSH("ds2411: GO READ_REC [+%"PRId64"]\n",time_in_state);
}
else if (DS2411_WRITE_VALID && (DS2411_WIRE_STATE != DS2411_WBIT))
{
ERROR("ds2411: MCU should not change value while MRS [+%"PRId64"]\n",time_in_state);
GO_WAIT_RESET(dev);
}
break;
case ONEWIRE_READ_REC:
if (time_in_state >= ONEWIRE_REC)
{
HW_DMSG_DS2411("ds2411: ** READ %d done ** [0x%02x,%d]\n",DS2411_WBIT,DS2411_BUF,DS2411_BUF_BITNUM);
DS2411_BUF_BITNUM += 1;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_LOW;
}
break;
case ONEWIRE_WRITE_ENDSLOT: /* wait write end slot */
ERROR("ds2411: ERROR, should no be in ONEWIRE_WRITE state\n");
GO_WAIT_RESET(dev);
break;
}
}
/******************************************************************************************************/
/******************************************************************************************************/
/*** DS2411 specific protocol part ********************************************************************/
/******************************************************************************************************/
/******************************************************************************************************/
static void update_ds2411_state_readrom(int dev, uint64_t current_time, uint64_t time_in_state)
{
switch (DS2411_READROM_STATE)
{
case DS2411_READROM_INIT:
/* ds2411 serial state */
DS2411_READROM_BYTENUM = 0;
DS2411_READROM_STATE = DS2411_READROM_READ;
/* read state */
DS2411_BUF = DS2411_ID.raw[0];
DS2411_BUF_BITNUM = 0;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_LOW;
HW_DMSG_DSTATE("ds2411: GO READROM_READ : 0x%02x (%d)\n",DS2411_BUF,DS2411_READROM_BYTENUM);
HW_DMSG_SER("ds2411:serial: sending 0x%02x\n",DS2411_BUF);
/* fall through */
case DS2411_READROM_READ:
update_onewire_read_signal(dev,current_time,time_in_state);
/*
* Family : 1 byte
* Serial : 6 bytes
* CRC : 1 byte
*/
if (DS2411_BUF_BITNUM == 8) /* byte has been read */
{
if (DS2411_READROM_BYTENUM < 7) /* still something to read */
{
DS2411_READROM_BYTENUM += 1;
DS2411_BUF = DS2411_ID.raw[DS2411_READROM_BYTENUM];
DS2411_BUF_BITNUM = 0;
DS2411_SIGNAL_STATE = ONEWIRE_WAITING_LOW;
HW_DMSG_SER("ds2411:serial: sending 0x%02x\n",DS2411_BUF);
HW_DMSG_DSTATE("ds2411: READ ROM next byte : 0x%02x (%d)\n",
DS2411_BUF,DS2411_READROM_BYTENUM);
}
else
{
DS2411_READROM_BYTENUM = 0;
HW_DMSG_DSTATE("ds2411: READ ROM finished\n");
// INFO("ds2411: READ ROM finished\n");
GO_WAIT_RESET(dev);
}
}
break;
}
}
/***************************************************/
/***************************************************/
/***************************************************/
static void update_ds2411_state(int dev, uint64_t current_time, uint64_t time_in_state)
{
switch (DS2411_COMMAND)
{
case ONEWIRE_READ_ROM:
update_ds2411_state_readrom(dev,current_time,time_in_state);
break;
case ONEWIRE_SEARCH_ROM:
ERROR("ds2411: **************************\n");