@@ -36,16 +36,9 @@ int ECC508Class::random(byte data[], size_t length)
36
36
}
37
37
38
38
while (length) {
39
- _wire->beginTransmission (_address);
40
- _wire->write (0x03 );
41
- _wire->write (0x07 );
42
- _wire->write (0x1b );
43
- _wire->write (0x00 );
44
- _wire->write (0x00 );
45
- _wire->write (0x00 );
46
- _wire->write (0x24 );
47
- _wire->write (0xcd );
48
- _wire->endTransmission ();
39
+ if (!sendCommand (0x1b , 0x00 , 0x0000 )) {
40
+ return 0 ;
41
+ }
49
42
50
43
delay (23 );
51
44
@@ -117,18 +110,11 @@ int ECC508Class::version()
117
110
return 0 ;
118
111
}
119
112
120
- _wire->beginTransmission (_address);
121
- _wire->write (0x03 );
122
- _wire->write (0x07 );
123
- _wire->write (0x30 );
124
- _wire->write (0x00 );
125
- _wire->write (0x00 );
126
- _wire->write (0x00 );
127
- _wire->write (0x03 );
128
- _wire->write (0x5d );
129
- _wire->endTransmission ();
113
+ if (!sendCommand (0x30 , 0x00 , 0x0000 )) {
114
+ return 0 ;
115
+ }
130
116
131
- delay (2 );
117
+ delay (1 );
132
118
133
119
if (!receiveResponse (&version, sizeof (version))) {
134
120
return 0 ;
@@ -140,6 +126,26 @@ int ECC508Class::version()
140
126
return version;
141
127
}
142
128
129
+ int ECC508Class::sendCommand (uint8_t opcode, uint8_t param1, uint16_t param2)
130
+ {
131
+ byte command[8 ]; // 1 for type, 1 for length, 1 for opcode, 1 for param1, 2 for param2, 2 for crc
132
+
133
+ command[0 ] = 0x03 ;
134
+ command[1 ] = sizeof (command) - 1 ;
135
+ command[2 ] = opcode;
136
+ command[3 ] = param1;
137
+ memcpy (&command[4 ], ¶m2, sizeof (param2));
138
+
139
+ uint16_t crc = crc16 (&command[1 ], sizeof (command) - 3 );
140
+ memcpy (&command[6 ], &crc, sizeof (crc));
141
+
142
+ if (_wire->sendTo (_address, command, sizeof (command)) != 0 ) {
143
+ return 0 ;
144
+ }
145
+
146
+ return 1 ;
147
+ }
148
+
143
149
int ECC508Class::receiveResponse (void * response, size_t length)
144
150
{
145
151
int retries = 20 ;
@@ -148,15 +154,49 @@ int ECC508Class::receiveResponse(void* response, size_t length)
148
154
149
155
while (_wire->requestFrom (_address, responseBuffer, responseSize) != responseSize && retries--);
150
156
157
+ // make sure length matches
151
158
if (responseBuffer[0 ] != responseSize) {
152
159
return 0 ;
153
160
}
154
161
155
- // TODO: verify CRC
162
+ // verify CRC
163
+ uint16_t responseCrc = responseBuffer[length + 1 ] | (responseBuffer[length + 2 ] << 8 );
164
+ if (responseCrc != crc16 (responseBuffer, responseSize - 2 )) {
165
+ return 0 ;
166
+ }
156
167
157
168
memcpy (response, &responseBuffer[1 ], length);
158
169
159
170
return 1 ;
160
171
}
161
172
173
+ uint16_t ECC508Class::crc16 (byte data[], size_t length)
174
+ {
175
+ if (data == NULL || length == 0 ) {
176
+ return 0 ;
177
+ }
178
+
179
+ uint16_t crc = 0 ;
180
+
181
+ while (length) {
182
+ byte b = *data;
183
+
184
+ for (uint8_t shift = 0x01 ; shift > 0x00 ; shift <<= 1 ) {
185
+ uint8_t dataBit = (b & shift) ? 1 : 0 ;
186
+ uint8_t crcBit = crc >> 15 ;
187
+
188
+ crc <<= 1 ;
189
+
190
+ if (dataBit != crcBit) {
191
+ crc ^= 0x8005 ;
192
+ }
193
+ }
194
+
195
+ length--;
196
+ data++;
197
+ }
198
+
199
+ return crc;
200
+ }
201
+
162
202
ECC508Class ECC508 (Wire, 0x60 );
0 commit comments