/**************************************************************************/
/* CAN latency tester */
-/* Copyright (C) 2010, 2011, 2012 Michal Sojka, DCE FEE CTU Prague */
+/* Copyright (C) 2010, 2011, 2012, 2013 Michal Sojka, DCE FEE CTU Prague */
/* License: GPLv2 */
/**************************************************************************/
return crc;
}
+uint32_t calc_bitmap_crc(uint32_t *bitmap, unsigned start, unsigned end)
+{
+ crc_t crc = 0;
+ crc = crc_update(crc, bitmap[0] << start, 32 - start);
+ crc = crc_update(crc, bitmap[1], 32);
+ crc = crc_update(crc, bitmap[2], end - 64 > 32 ? 32 : end - 64);
+ crc = crc_update(crc, bitmap[3], end > 96 ? end - 96 : 0);
+ return (uint32_t)htons(crc) << 17;
+}
+
+void write_crc_to_bitmap(uint32_t crc, uint32_t *bitmap, struct can_frame *frame)
+{
+ unsigned index = frame->can_id & CAN_EFF_FLAG ? 2 : 1;
+ if (frame->can_dlc < 4)
+ bitmap[index] |= crc >> (frame->can_dlc*8);
+ if (frame->can_dlc == 3)
+ bitmap[index + 1] |= crc << 8;
+ if (frame->can_dlc >= 4 && frame->can_dlc < 8)
+ {
+ bitmap[index + 1] |= crc >> (frame->can_dlc*8);
+ if (frame->can_dlc == 7)
+ bitmap[index + 2] = crc << 8;
+ }
+ else if (frame->can_dlc == 8)
+ bitmap[index + 2] = crc;
+}
+
unsigned calc_stuff_bits(struct can_frame *frame) {
uint32_t bitmap[4];
unsigned start = 0, end;
uint32_t mask, ones = 0, basemask = 0xf8000000;
unsigned stuffed = 0;
memset(bitmap, 0, sizeof(bitmap));
- crc_t crc = 0;
- uint32_t crcx;
+ uint32_t crc;
/* char received[64]; */
/* sprint_canframe(received, frame, true); */
/* printf("Frame: %s\n", received); */
if (frame->can_id & CAN_EFF_FLAG) {
+ // bit 31 0
+ // [0] |...........................sBBBB| s = SOF, B = Base ID (11 bits)
+ // [1] |BBBBBBBSIEEEEEEEEEEEEEEEEEER10DLC4| S = SRR, I = IDE, E = Extended ID (18 bits), DLC4 = DLC
+ // [2] |00000000111111112222222233333333| Data bytes, MSB first
+ // [3] |44444444555555556666666677777777|
bitmap[0] =
((frame->can_id & CAN_EFF_MASK) >> 25);
bitmap[1] =
bitmap[3] = htonl(((uint32_t*)frame->data)[1]);
start = 27;
end = 64 + 8*frame->can_dlc;
- crc = crc_update(crc, bitmap[0] << start, 32-start);
- crc = crc_update(crc, bitmap[1], 32);
- crc = crc_update(crc, bitmap[2], end - 64 > 32 ? 32 : end - 64);
- crc = crc_update(crc, bitmap[3], end > 96 ? end - 96 : 0);
- crcx = (uint32_t)htons(crc) << 17;
- if (frame->can_dlc < 4)
- bitmap[2] |= crcx >> (frame->can_dlc*8);
- if (frame->can_dlc = 3)
- bitmap[3] |= crcx << 8;
- if (frame->can_dlc >= 4)
- bitmap[3] |= crcx >> (frame->can_dlc*8);
} else {
+ // bit 31 0
+ // [0] |.............sIIIIIIIIIIIRE0DLC4| s = SOF, I = ID (11 bits), R = RTR, E = IDE, DLC4 = DLC
+ // [1] |00000000111111112222222233333333| Data bytes, MSB first
+ // [2] |44444444555555556666666677777777|
bitmap[0] =
(frame->can_id << 7) |
(!!(frame->can_id & CAN_RTR_FLAG)) << 6 |
start = 13;
end = 32 + 8*frame->can_dlc;
}
- /* TODO: Calc stuff bits in CRC */
+ crc = calc_bitmap_crc(bitmap, start, end);
+ write_crc_to_bitmap(crc, bitmap, frame);
+ end += 15;
+
while (start < end) {
mask = basemask >> (start & 0x1f);
while (1) {