Skip to content

Commit 12acbd3

Browse files
committed
Verify response CRC and dynamic CRC calculations for commands
1 parent c67e03d commit 12acbd3

File tree

2 files changed

+64
-22
lines changed

2 files changed

+64
-22
lines changed

src/utility/ECC508.cpp

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,9 @@ int ECC508Class::random(byte data[], size_t length)
3636
}
3737

3838
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+
}
4942

5043
delay(23);
5144

@@ -117,18 +110,11 @@ int ECC508Class::version()
117110
return 0;
118111
}
119112

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+
}
130116

131-
delay(2);
117+
delay(1);
132118

133119
if (!receiveResponse(&version, sizeof(version))) {
134120
return 0;
@@ -140,6 +126,26 @@ int ECC508Class::version()
140126
return version;
141127
}
142128

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], &param2, 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+
143149
int ECC508Class::receiveResponse(void* response, size_t length)
144150
{
145151
int retries = 20;
@@ -148,15 +154,49 @@ int ECC508Class::receiveResponse(void* response, size_t length)
148154

149155
while (_wire->requestFrom(_address, responseBuffer, responseSize) != responseSize && retries--);
150156

157+
// make sure length matches
151158
if (responseBuffer[0] != responseSize) {
152159
return 0;
153160
}
154161

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+
}
156167

157168
memcpy(response, &responseBuffer[1], length);
158169

159170
return 1;
160171
}
161172

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+
162202
ECC508Class ECC508(Wire, 0x60);

src/utility/ECC508.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ class ECC508Class
2121

2222
int version();
2323

24+
int sendCommand(uint8_t opcode, uint8_t param1, uint16_t param2);
2425
int receiveResponse(void* response, size_t length);
26+
uint16_t crc16(byte data[], size_t length);
2527

2628
private:
2729
TwoWire* _wire;

0 commit comments

Comments
 (0)