|  |  |  | @ -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) { | 
			
		
	
	
		
			
				
					|  |  |  | 
 |