|
|
|
@ -25,6 +25,8 @@ |
|
|
|
|
#include "common/swaglog.h" |
|
|
|
|
#include "common/timing.h" |
|
|
|
|
|
|
|
|
|
#include <algorithm> |
|
|
|
|
|
|
|
|
|
// double the FIFO size
|
|
|
|
|
#define RECV_SIZE (0x1000) |
|
|
|
|
#define TIMEOUT 0 |
|
|
|
@ -45,6 +47,7 @@ pthread_mutex_t usb_lock; |
|
|
|
|
bool spoofing_started = false; |
|
|
|
|
bool fake_send = false; |
|
|
|
|
bool loopback_can = false; |
|
|
|
|
bool has_pigeon = false; |
|
|
|
|
|
|
|
|
|
pthread_t safety_setter_thread_handle = -1; |
|
|
|
|
|
|
|
|
@ -102,6 +105,8 @@ void *safety_setter_thread(void *s) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void pigeon_init(); |
|
|
|
|
|
|
|
|
|
// must be called before threads or with mutex
|
|
|
|
|
bool usb_connect() { |
|
|
|
|
int err; |
|
|
|
@ -140,6 +145,8 @@ bool usb_connect() { |
|
|
|
|
err = pthread_create(&safety_setter_thread_handle, NULL, safety_setter_thread, NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (has_pigeon) pigeon_init(); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
fail: |
|
|
|
|
return false; |
|
|
|
@ -409,6 +416,100 @@ void *can_health_thread(void *crap) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define pigeon_send(x) _pigeon_send(x, sizeof(x)-1) |
|
|
|
|
|
|
|
|
|
void _pigeon_send(const char *dat, int len) { |
|
|
|
|
int sent; |
|
|
|
|
unsigned char a[0x20]; |
|
|
|
|
int err; |
|
|
|
|
a[0] = 1; |
|
|
|
|
for (int i=0; i<len; i+=0x1f) { |
|
|
|
|
int ll = std::max(0x1f, len-i); |
|
|
|
|
memcpy(&a[1], &dat[i], ll); |
|
|
|
|
err = libusb_bulk_transfer(dev_handle, 2, a, ll+1, &sent, TIMEOUT); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void pigeon_set_baud(int baud) { |
|
|
|
|
libusb_control_transfer(dev_handle, 0xc0, 0xe4, 1, baud/300, NULL, 0, TIMEOUT); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void pigeon_init() { |
|
|
|
|
// power on pigeon
|
|
|
|
|
libusb_control_transfer(dev_handle, 0xc0, 0xd9, 0, 0, NULL, 0, TIMEOUT); |
|
|
|
|
usleep(100*1000); |
|
|
|
|
libusb_control_transfer(dev_handle, 0xc0, 0xd9, 1, 0, NULL, 0, TIMEOUT); |
|
|
|
|
usleep(500*1000); |
|
|
|
|
|
|
|
|
|
// baud rate upping
|
|
|
|
|
pigeon_set_baud(9600); |
|
|
|
|
pigeon_send("$PUBX,41,1,0007,0003,230400,0*1A\r\n"); |
|
|
|
|
usleep(200*1000); |
|
|
|
|
|
|
|
|
|
// set baud rate to 230400
|
|
|
|
|
pigeon_set_baud(230400); |
|
|
|
|
|
|
|
|
|
// init from ubloxd
|
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x14\x00\x03\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x1E\x7F"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x3E\x00\x00\x44\xD2"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x14\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x35"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xC0\x08\x00\x00\x00\x08\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF2\x72"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x14\x00\x04\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x85"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x00\x00\x06\x18"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x01\x00\x01\x08\x22"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x01\x00\x02\x09\x23"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x00\x01\x00\x03\x0A\x24"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x08\x06\x00\x64\x00\x01\x00\x00\x00\x79\x10"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x24\x24\x00\x05\x00\x04\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5A\x63"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x1E\x14\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3C\x37"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x24\x00\x00\x2A\x84"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x23\x00\x00\x29\x81"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x1E\x00\x00\x24\x72"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x01\x03\x00\x01\x07\x01\x13\x51"); |
|
|
|
|
pigeon_send("\xB5\x62\x06\x01\x03\x00\x02\x15\x01\x22\x70"); |
|
|
|
|
|
|
|
|
|
LOGW("pigeon is ready to fly"); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void *pigeon_thread(void *crap) { |
|
|
|
|
// ubloxRaw = 8042
|
|
|
|
|
void *context = zmq_ctx_new(); |
|
|
|
|
void *publisher = zmq_socket(context, ZMQ_PUB); |
|
|
|
|
zmq_bind(publisher, "tcp://*:8042"); |
|
|
|
|
|
|
|
|
|
// run at ~200hz
|
|
|
|
|
unsigned char dat[0x40]; |
|
|
|
|
while (!do_exit) { |
|
|
|
|
while (1) { |
|
|
|
|
pthread_mutex_lock(&usb_lock); |
|
|
|
|
int len = libusb_control_transfer(dev_handle, 0xc0, 0xe0, 1, 0, dat, 0x40, TIMEOUT); |
|
|
|
|
pthread_mutex_unlock(&usb_lock); |
|
|
|
|
|
|
|
|
|
if (len <= 0) break; |
|
|
|
|
|
|
|
|
|
// create message
|
|
|
|
|
capnp::MallocMessageBuilder msg; |
|
|
|
|
cereal::Event::Builder event = msg.initRoot<cereal::Event>(); |
|
|
|
|
event.setLogMonoTime(nanos_since_boot()); |
|
|
|
|
auto ublox_raw = event.initUbloxRaw(len); |
|
|
|
|
memcpy(ublox_raw.begin(), dat, len); |
|
|
|
|
|
|
|
|
|
// send to ubloxRaw
|
|
|
|
|
auto words = capnp::messageToFlatArray(msg); |
|
|
|
|
auto bytes = words.asBytes(); |
|
|
|
|
zmq_send(publisher, bytes.begin(), bytes.size(), 0); |
|
|
|
|
|
|
|
|
|
if (len < 0x40) break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 10ms
|
|
|
|
|
usleep(10*1000); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int set_realtime_priority(int level) { |
|
|
|
|
// should match python using chrt
|
|
|
|
|
struct sched_param sa; |
|
|
|
@ -440,6 +541,10 @@ int main() { |
|
|
|
|
loopback_can = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (getenv("PIGEON")) { |
|
|
|
|
has_pigeon = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// init libusb
|
|
|
|
|
err = libusb_init(&ctx); |
|
|
|
|
assert(err == 0); |
|
|
|
@ -470,6 +575,15 @@ int main() { |
|
|
|
|
thermal_thread, NULL); |
|
|
|
|
assert(err == 0); |
|
|
|
|
|
|
|
|
|
if (has_pigeon) { |
|
|
|
|
pthread_t pigeon_thread_handle; |
|
|
|
|
err = pthread_create(&pigeon_thread_handle, NULL, |
|
|
|
|
pigeon_thread, NULL); |
|
|
|
|
assert(err == 0); |
|
|
|
|
err = pthread_join(pigeon_thread_handle, NULL); |
|
|
|
|
assert(err == 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// join threads
|
|
|
|
|
|
|
|
|
|
err = pthread_join(thermal_thread_handle, NULL); |
|
|
|
|