fix: data PEC calculation

This commit is contained in:
Kilian Bracher 2025-03-25 19:28:44 +01:00
parent e4566b0cee
commit 2ace1dd04c

View File

@ -81,37 +81,32 @@ static uint8_t checkCommandPEC(uint8_t* data, uint8_t datalen) {
//x^10 + x^7 + x^3 + x^2 + x + 1
static uint16_t computeCRC10(const uint8_t* data, size_t length, bool rx_cmd) {
uint16_t remainder = INITIAL_DATA_PEC;
const uint16_t poly = 0x8F;
size_t limit = length;
uint16_t remainder = INITIAL_DATA_PEC;
const uint16_t poly = 0x8F;
if (rx_cmd && (length > 0)) {
limit = length - 1;
}
for (size_t i = 0; i < length; i++) {
remainder ^= (uint16_t)(data[i] << 2);
for (int b = 0; b < 8; b++) {
if (remainder & 0x200) {
remainder = (uint16_t)((remainder << 1) ^ poly);
} else {
remainder <<= 1;
}
}
}
for (size_t i = 0; i < limit; i++) {
remainder ^= (uint16_t)(data[i] << 2);
for (int b = 0; b < 8; b++) {
if (remainder & 0x200) {
remainder = (uint16_t)((remainder << 1) ^ poly);
} else {
remainder <<= 1;
}
}
}
// If receiving a command, handle leftover bits
if (rx_cmd && (length > 0)) {
remainder ^= (uint16_t)((data[length - 1] & 0xFC) << 2);
for (int b = 0; b < 6; b++) {
if (remainder & 0x200) {
remainder = (uint16_t)((remainder << 1) ^ poly);
} else {
remainder <<= 1;
}
}
}
return (uint16_t)(remainder & 0x3FF);
// Handle last bits of the last byte if rx_cmd is true
if (rx_cmd) {
remainder ^= (uint16_t)((data[length] & 0xFC) << 2);
for (int b = 0; b < 6; b++) {
if (remainder & 0x200) {
remainder = (uint16_t)((remainder << 1) ^ poly);
} else {
remainder <<= 1;
}
}
}
return (uint16_t)(remainder & 0x3FF);
}
static uint8_t calculateDataPEC(uint8_t* data, uint8_t datalen) {
@ -188,6 +183,8 @@ HAL_StatusTypeDef ___writeCMD(uint16_t command, uint8_t * args, size_t arglen) {
calculateCommandPEC(args, 4);
for (size_t i = 0; i < N_BMS; i++) {
args[BUFFER_BMS_OFFSET(i, arglen) + arglen] = 0; // zero out the PEC
args[BUFFER_BMS_OFFSET(i, arglen) + arglen + 1] = 0;
calculateDataPEC(&args[4 + (i * (arglen + 2))], arglen + 2); //DPEC is calculated over the data, not the command, and placed at the end of the data
}