Here is a C example off how to decode mileage from bytes:
Code: Select all
BYTE g_ubMileage[20];
// CRC Table. 16 Bytes found in 1MB Flash ("7M2T-14C026-AG") at 0x4B064
BYTE g_ubCrc8Bit[16] =
{
0x0, 0xD, 0x7, 0xA,
0xE, 0x3, 0x9, 0x4,
0x1, 0xC, 0x6, 0xB,
0xF, 0x2, 0x8, 0x5,
};
// return word from mileage data entry (five entries, four bytes each) in Big Endian
WORD get_mileage_entry(int idx, int iWord)
{
if(idx < 0 || idx > 4)
return 0xFFFF;
if(iWord != 0 && iWord != 1)
return 0xFFFF;
return (g_ubMileage[(idx * 4) + (iWord * 2) + 0] << 8) |
(g_ubMileage[(idx * 4) + (iWord * 2) + 1] << 0);
}
// calculate 4-bit CRC of a 16-bit word
BYTE calc_crc_4bit(WORD w)
{
BYTE ubCrc = 0xF;
int i;
for(i = 0; i < 4; i++)
{
ubCrc = g_ubCrc8Bit[ubCrc] ^ (w & 0xF);
w = (w >> 4);
}
return ubCrc;
}
// get parity bit of a byte (even/odd)
BYTE get_parity(BYTE ub)
{
BYTE ubParity = 0;
while(ub != 0)
{
ubParity++;
ub &= (ub - ubParity);
}
return ubParity & 0x01;
}
// get MSB mileage bits, check for valid CRC
WORD get_mileage_entry_and_check_crc(int idx)
{
if(idx < 0 || idx > 4)
return 0xFFFF;
WORD w1 = get_mileage_entry(idx, 0);
WORD w2 = get_mileage_entry(idx, 1);
BYTE ub = (w2 >> 8); // MSB of word
WORD w = (w1 >> 4) | (((~ub) & 0xF0) << 8);
BYTE ubCrc = calc_crc_4bit(w);
if(ubCrc == (w1 & 0x0F)) // CRC valid ?
return w;
else
return 0xFFFF;
}
// get LSB mileage bits, check for valid parity
WORD get_mileage_entry_and_check_parity(int idx)
{
if(idx < 0 || idx > 4)
return 0xFFFF;
WORD w1 = get_mileage_entry(idx, 0);
WORD w2 = get_mileage_entry(idx, 1);
BYTE ub = (w2 & 0xFF); // LSB of word
if(get_parity(ub)) // odd parity ?
return (ub & 0x7F) + 1;
else
return 0;
}
void calc_mileage(BYTE *ubMileage)
{
// copy data into buffer
memcpy(g_ubMileage, ubMileage, sizeof(g_ubMileage));
// calculate sum of each all five entries
DWORD dw1sum = 0;
WORD w2sum = 0;
int i;
for(i = 0; i < 5; i++)
{
WORD w1 = get_mileage_entry_and_check_crc(i); // MSB of mileage
WORD w2 = get_mileage_entry_and_check_parity(i); // LSB of mileage
dw1sum += w1;
w2sum += w2;
}
// combine MSB and LSB
DWORD dw = (dw1sum << 7) + w2sum;
// final calulation, 200 meter resolution
dw = (dw / 5) + 1;
return(dw);
}
// try it...
void main()
{
// Test data of 249.510 km (offset 0x774)
BYTE testdata[20] =
{
0x79, 0xD9, 0xFF, 0x26,
0x79, 0xD9, 0xFF, 0xA2,
0x79, 0xD9, 0xFF, 0x23,
0x79, 0xD9, 0xFF, 0xA4,
0x79, 0xD9, 0xFF, 0x25,
};
WORD km = calc_mileage(testdata);
printf("Mileage is %d km\n", km);
}