|
|
|
@ -363,23 +363,26 @@ static uint8_t len_to_dlc(uint8_t len) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Panda::pack_can_buffer(const capnp::List<cereal::CanData>::Reader &can_data_list, |
|
|
|
|
std::function<void(uint8_t *, size_t)> write_func) { |
|
|
|
|
if (send.size() < (can_data_list.size() * CANPACKET_MAX_SIZE)) { |
|
|
|
|
send.resize(can_data_list.size() * CANPACKET_MAX_SIZE); |
|
|
|
|
static void write_packet(uint8_t *dest, int *write_pos, const uint8_t *src, size_t size) { |
|
|
|
|
for (int i = 0, &pos = *write_pos; i < size; ++i, ++pos) { |
|
|
|
|
// Insert counter every 64 bytes (first byte of 64 bytes USB packet)
|
|
|
|
|
if (pos % USBPACKET_MAX_SIZE == 0) { |
|
|
|
|
dest[pos] = pos / USBPACKET_MAX_SIZE; |
|
|
|
|
pos++; |
|
|
|
|
} |
|
|
|
|
dest[pos] = src[i]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int msg_count = 0; |
|
|
|
|
while (msg_count < can_data_list.size()) { |
|
|
|
|
uint32_t pos = 0; |
|
|
|
|
while (pos < USB_TX_SOFT_LIMIT) { |
|
|
|
|
if (msg_count == can_data_list.size()) { break; } |
|
|
|
|
auto cmsg = can_data_list[msg_count]; |
|
|
|
|
void Panda::pack_can_buffer(const capnp::List<cereal::CanData>::Reader &can_data_list, |
|
|
|
|
std::function<void(uint8_t *, size_t)> write_func) { |
|
|
|
|
int32_t pos = 0; |
|
|
|
|
uint8_t send_buf[2 * USB_TX_SOFT_LIMIT]; |
|
|
|
|
|
|
|
|
|
for (auto cmsg : can_data_list) { |
|
|
|
|
// check if the message is intended for this panda
|
|
|
|
|
uint8_t bus = cmsg.getSrc(); |
|
|
|
|
if (bus < bus_offset || bus >= (bus_offset + PANDA_BUS_CNT)) { |
|
|
|
|
msg_count++; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
auto can_data = cmsg.getDat(); |
|
|
|
@ -392,28 +395,17 @@ void Panda::pack_can_buffer(const capnp::List<cereal::CanData>::Reader &can_data |
|
|
|
|
header.extended = (cmsg.getAddress() >= 0x800) ? 1 : 0; |
|
|
|
|
header.data_len_code = data_len_code; |
|
|
|
|
header.bus = bus - bus_offset; |
|
|
|
|
memcpy(&send[pos], &header, CANPACKET_HEAD_SIZE); |
|
|
|
|
memcpy(&send[pos+CANPACKET_HEAD_SIZE], can_data.begin(), can_data.size()); |
|
|
|
|
|
|
|
|
|
pos += CANPACKET_HEAD_SIZE + dlc_to_len[data_len_code]; |
|
|
|
|
msg_count++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pos > 0) { // Helps not to spam with ZLP
|
|
|
|
|
// Counter needs to be inserted every 64 bytes (first byte of 64 bytes USB packet)
|
|
|
|
|
uint8_t counter = 0; |
|
|
|
|
uint8_t to_write[USB_TX_SOFT_LIMIT+128]; |
|
|
|
|
int ptr = 0; |
|
|
|
|
for (int i = 0; i < pos; i += 63) { |
|
|
|
|
to_write[ptr] = counter; |
|
|
|
|
int copy_size = ((pos - i) < 63) ? (pos - i) : 63; |
|
|
|
|
memcpy(&to_write[ptr+1], &(send.data()[i]) , copy_size); |
|
|
|
|
ptr += copy_size + 1; |
|
|
|
|
counter++; |
|
|
|
|
} |
|
|
|
|
write_func(to_write, ptr); |
|
|
|
|
write_packet(send_buf, &pos, (uint8_t *)&header, sizeof(can_header)); |
|
|
|
|
write_packet(send_buf, &pos, (uint8_t *)can_data.begin(), can_data.size()); |
|
|
|
|
if (pos >= USB_TX_SOFT_LIMIT) { |
|
|
|
|
write_func(send_buf, pos); |
|
|
|
|
pos = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// send remaining packets
|
|
|
|
|
if (pos > 0) write_func(send_buf, pos); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Panda::can_send(capnp::List<cereal::CanData>::Reader can_data_list) { |
|
|
|
|