2
2
MIT License
3
3
4
4
Copyright (c) 2017 Tom Magnier
5
+ Modified 2018 by Nicolò Veronese
5
6
6
7
Permission is hereby granted, free of charge, to any person obtaining a copy
7
8
of this software and associated documentation files (the "Software"), to deal
@@ -26,92 +27,121 @@ SOFTWARE.
26
27
27
28
DS2431::DS2431 (OneWire &ow)
28
29
: _ow(ow)
29
- {
30
+ {
31
+ _skiprom = true ;
30
32
}
31
33
32
- void DS2431::begin (uint8_t serialNumber[8 ])
34
+ void DS2431::begin (uint8_t serialNumber[ONE_WIRE_MAC_SIZE ])
33
35
{
34
- memcpy (_serialNumber, serialNumber, 8 );
35
- _init = true ;
36
+ memcpy (_serialNumber, serialNumber, ONE_WIRE_MAC_SIZE );
37
+ _skiprom = false ;
36
38
}
37
39
38
- int DS2431::read (uint16_t address)
40
+ uint8_t DS2431::read (uint16_t address)
39
41
{
40
42
uint8_t res = 0xFF ;
43
+ read (address, &res, 1 );
41
44
42
- if (!read (address, &res, 1 ))
43
- return -1 ;
44
-
45
45
return res;
46
46
}
47
47
48
- bool DS2431::read (uint16_t address, uint8_t *buf, uint16_t len)
48
+ void DS2431::read (uint16_t address, uint8_t *buf, uint16_t len)
49
49
{
50
- if (!_init)
51
- return false ;
52
- _ow.reset ();
53
- _ow.select (_serialNumber);
50
+ _startTransmission ();
51
+
54
52
_ow.write (READ_MEMORY, 1 );
55
53
_ow.write (lowByte (address), 1 );
56
54
_ow.write (highByte (address), 1 );
57
55
58
56
for (int i = 0 ; i < len; i++)
59
- buf[i] = _ow.read ();
57
+ buf[i] = _ow.read ();
60
58
61
59
_ow.depower ();
62
-
63
- return true ;
64
60
}
65
61
66
- bool DS2431::write (uint16_t address, uint8_t buf[8 ])
62
+ bool DS2431::write (uint16_t address, const uint8_t *buf, uint16_t count, bool verify /* = 0 */ )
63
+ {
64
+ bool ret = _write (address, buf, count, verify);
65
+ _ow.depower ();
66
+ return ret;
67
+ }
68
+
69
+ bool DS2431::_write (uint16_t address, const uint8_t *buf, uint16_t count, bool verify)
67
70
{
68
- if (address >= EEPROM_SIZE || address % 8 != 0 ) // Address has to be aligned on an 8-byte boundary
71
+ uint8_t error_count = 0 ;
72
+ uint8_t buffer[DS2431_BUFFER_SIZE];
73
+ uint8_t crc16[DS2431_CRC_SIZE];
74
+
75
+ // Address has to be aligned on an 8-byte boundary
76
+ if (address >= DS2431_EEPROM_SIZE || address % 8 != 0 )
69
77
return false ;
70
78
71
- // Write scratchpad with CRC check
72
- uint8_t buffer[13 ];
79
+ // Prepare buffer data
73
80
buffer[0 ] = WRITE_SCRATCHPAD;
74
81
buffer[1 ] = lowByte (address);
75
82
buffer[2 ] = highByte (address);
76
- memcpy (&buffer[3 ], buf, 8 );
83
+ memcpy (&buffer[DS2431_CMD_SIZE ], buf, count );
77
84
78
- _ow. reset ();
79
- _ow. select (_serialNumber );
80
- _ow.write_bytes (buffer, 11 , 1 );
81
- _ow.read_bytes (&buffer[ 11 ], 2 ); // Read CRC-16
85
+ // Write scratchpad with CRC check
86
+ _startTransmission ( );
87
+ _ow.write_bytes (buffer, DS2431_CMD_SIZE + count , 1 ); // Write CMD + LSB Adr + MSB Adr
88
+ _ow.read_bytes (crc16, DS2431_CRC_SIZE ); // Read CRC-16
82
89
83
- if (!_ow.check_crc16 (buffer, 11 , &buffer[11 ]))
84
- return false ; // CRC not matching
90
+ if (!_ow.check_crc16 (buffer, DS2431_CMD_SIZE + count, crc16)){
91
+ verify = true ; // CRC not matching, try to read again
92
+ }
85
93
86
- // Read scratchpad
94
+ // Read verification
95
+ // Prepare buffer data
87
96
buffer[0 ] = READ_SCRATCHPAD;
97
+ do {
98
+ // Read scratchpad to compare with the data sent
99
+ _startTransmission ();
100
+ _ow.write (buffer[0 ], 1 ); // Write CMD
101
+ _ow.read_bytes (&buffer[1 ], DS2431_CMD_SIZE); // Read TA1, TA2, E/S, scratchpad
102
+
103
+ if (buffer[3 ] != DS2431_PF_MASK) {
104
+ verify = true ;
105
+ }
88
106
89
- _ow.reset ();
90
- _ow.select (_serialNumber);
91
- _ow.write (buffer[0 ], 1 );
92
- _ow.read_bytes (&buffer[1 ], 13 ); // Read TA1, TA2, E/S, scratchpad and CRC
107
+ if (verify) {
108
+ _ow.read_bytes (&buffer[4 ], count); // Read scratchpad
109
+ _ow.read_bytes (crc16, DS2431_CRC_SIZE); // Read CRC-16
93
110
94
- if (!_ow.check_crc16 (buffer, 12 , &buffer[12 ]))
95
- return false ; // CRC not matching. TODO this does not indicate that scratchpad data is invalid, retry read instead ?
111
+ if (!_ow.check_crc16 (buffer, 12 , crc16)) {
112
+ error_count++; // CRC not matching.
113
+ continue ;
114
+ }
96
115
97
- if (address != ((buffer[2 ] << 8 ) + buffer[1 ]))
98
- return false ; // Address not matching
116
+ if (address != ((buffer[2 ] << 8 ) + buffer[1 ])) {
117
+ return false ; // Address not matching
118
+ }
99
119
100
- if (buffer[3 ] != 0x07 )
101
- return false ; // Invalid transfer or data already copied (wrong value for E/S).
120
+ if (buffer[3 ] != DS2431_PF_MASK) {
121
+ return false ; // Invalid transfer or data already copied (wrong value for E/S).
122
+ }
102
123
103
- if (memcmp (&buffer[4 ], buf, 8 ) != 0 )
104
- return false ; // Data in the scratchpad is invalid.
124
+ if (memcmp (&buffer[4 ], buf, 8 ) != 0 ) {
125
+ return false ; // Data in the scratchpad is invalid.
126
+ }
127
+ }
128
+
129
+ break ;
130
+ } while (error_count < DS2431_READ_RETRY);
131
+
132
+ // Prepare buffer data
133
+ buffer[0 ] = COPY_SCRATCHPAD;
105
134
106
135
// Copy scratchpad
107
- _ow.reset ();
108
- _ow.select (_serialNumber);
109
- _ow.write (COPY_SCRATCHPAD, 1 );
110
- _ow.write_bytes (&buffer[1 ], 3 , 1 ); // Send authorization code (TA1, TA2, E/S)
136
+ _startTransmission ();
137
+ _ow.write_bytes (buffer, DS2431_CMD_SIZE + 1 , 1 ); // Send authorization code (TA1, TA2, E/S)
111
138
delay (15 ); // t_PROG = 12.5ms worst case.
112
139
113
- if (_ow.read () != 0xAA )
140
+ uint8_t res = _ow.read ();
141
+
142
+ if (res != DS2431_WRITE_MASK) {
114
143
return false ;
144
+ }
115
145
116
146
return true ;
117
147
}
0 commit comments