mirror of https://github.com/commaai/panda.git
Communication refactor (#997)
* cleanup is_enumerated, rename comms and init spi * big comms refactor, building now * misra fixes * more fixes * misra try 3 * cleanup * this belongs in a separate PR * remove unneccesary file * revert llspi changes * this needs packing * fix pedal usb Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
parent
89989abca5
commit
d24971ef8a
|
@ -0,0 +1,11 @@
|
|||
typedef struct {
|
||||
uint8_t request;
|
||||
uint16_t param1;
|
||||
uint16_t param2;
|
||||
uint16_t length;
|
||||
} __attribute__((packed)) ControlPacket_t;
|
||||
|
||||
int comms_control_handler(ControlPacket_t *req, uint8_t *resp);
|
||||
void comms_endpoint2_write(uint8_t *data, uint32_t len);
|
||||
void comms_can_write(uint8_t *data, uint32_t len);
|
||||
int comms_can_read(uint8_t *data, uint32_t max_len);
|
|
@ -26,12 +26,7 @@ USB_Setup_TypeDef;
|
|||
bool usb_enumerated = false;
|
||||
|
||||
void usb_init(void);
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp);
|
||||
int usb_cb_ep1_in(void *usbdata, int len);
|
||||
void usb_cb_ep2_out(void *usbdata, int len);
|
||||
void usb_cb_ep3_out(void *usbdata, int len);
|
||||
void usb_cb_ep3_out_complete(void);
|
||||
void usb_cb_enumeration_complete(void);
|
||||
void usb_outep3_resume_if_paused(void);
|
||||
|
||||
// **** supporting defines ****
|
||||
|
@ -478,6 +473,8 @@ char to_hex_char(int a) {
|
|||
|
||||
void usb_setup(void) {
|
||||
int resp_len;
|
||||
ControlPacket_t control_req;
|
||||
|
||||
// setup packet is ready
|
||||
switch (setup.b.bRequest) {
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
|
@ -511,10 +508,6 @@ void usb_setup(void) {
|
|||
puts(" set address\n");
|
||||
#endif
|
||||
|
||||
// TODO: this isn't enumeration complete
|
||||
// moved here to work better on OS X
|
||||
usb_cb_enumeration_complete();
|
||||
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
|
||||
|
@ -639,7 +632,12 @@ void usb_setup(void) {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
resp_len = usb_cb_control_msg(&setup, resp);
|
||||
control_req.request = setup.b.bRequest;
|
||||
control_req.param1 = setup.b.wValue.w;
|
||||
control_req.param2 = setup.b.wIndex.w;
|
||||
control_req.length = setup.b.wLength.w;
|
||||
|
||||
resp_len = comms_control_handler(&control_req, resp);
|
||||
// response pending if -1 was returned
|
||||
if (resp_len != -1) {
|
||||
USB_WritePacket(resp, MIN(resp_len, setup.b.wLength.w), 0);
|
||||
|
@ -737,12 +735,12 @@ void usb_irqhandler(void) {
|
|||
#endif
|
||||
|
||||
if (endpoint == 2) {
|
||||
usb_cb_ep2_out(usbdata, len);
|
||||
comms_endpoint2_write((uint8_t *) usbdata, len);
|
||||
}
|
||||
|
||||
if (endpoint == 3) {
|
||||
outep3_processing = true;
|
||||
usb_cb_ep3_out(usbdata, len);
|
||||
comms_can_write(usbdata, len);
|
||||
}
|
||||
} else if (status == STS_SETUP_UPDT) {
|
||||
(void)USB_ReadPacket(&setup, 8);
|
||||
|
@ -881,7 +879,7 @@ void usb_irqhandler(void) {
|
|||
puts(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
// TODO: always assuming max len, can we get the length?
|
||||
USB_WritePacket((void *)resp, usb_cb_ep1_in(resp, 0x40), 1);
|
||||
USB_WritePacket((void *)resp, comms_can_read(resp, 0x40), 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -892,7 +890,7 @@ void usb_irqhandler(void) {
|
|||
puts(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
// TODO: always assuming max len, can we get the length?
|
||||
int len = usb_cb_ep1_in(resp, 0x40);
|
||||
int len = comms_can_read(resp, 0x40);
|
||||
if (len > 0) {
|
||||
USB_WritePacket((void *)resp, len, 1);
|
||||
}
|
||||
|
|
|
@ -6,20 +6,20 @@ bool unlocked = false;
|
|||
void debug_ring_callback(uart_ring *ring) {}
|
||||
#endif
|
||||
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
||||
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
int resp_len = 0;
|
||||
|
||||
// flasher machine
|
||||
memset(resp, 0, 4);
|
||||
memcpy(resp+4, "\xde\xad\xd0\x0d", 4);
|
||||
resp[0] = 0xff;
|
||||
resp[2] = setup->b.bRequest;
|
||||
resp[3] = ~setup->b.bRequest;
|
||||
resp[2] = req->request;
|
||||
resp[3] = ~req->request;
|
||||
*((uint32_t **)&resp[8]) = prog_ptr;
|
||||
resp_len = 0xc;
|
||||
|
||||
int sec;
|
||||
switch (setup->b.bRequest) {
|
||||
switch (req->request) {
|
||||
// **** 0xb0: flasher echo
|
||||
case 0xb0:
|
||||
resp[1] = 0xff;
|
||||
|
@ -36,7 +36,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xb2: erase sector
|
||||
case 0xb2:
|
||||
sec = setup->b.wValue.w;
|
||||
sec = req->param1;
|
||||
if (flash_erase_sector(sec, unlocked)) {
|
||||
resp[1] = 0xff;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
case 0xd0:
|
||||
#ifndef STM32F2
|
||||
// addresses are OTP
|
||||
if (setup->b.wValue.w == 1) {
|
||||
if (req->param1 == 1) {
|
||||
memcpy(resp, (void *)DEVICE_SERIAL_NUMBER_ADDRESS, 0x10);
|
||||
resp_len = 0x10;
|
||||
} else {
|
||||
|
@ -57,7 +57,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
// **** 0xd1: enter bootloader mode
|
||||
case 0xd1:
|
||||
// this allows reflashing of the bootstub
|
||||
switch (setup->b.wValue.w) {
|
||||
switch (req->param1) {
|
||||
case 0:
|
||||
puts("-> entering bootloader\n");
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
|
@ -85,27 +85,23 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
return resp_len;
|
||||
}
|
||||
|
||||
int usb_cb_ep1_in(void *usbdata, int len) {
|
||||
UNUSED(usbdata);
|
||||
void comms_can_write(uint8_t *data, uint32_t len) {
|
||||
UNUSED(data);
|
||||
UNUSED(len);
|
||||
}
|
||||
|
||||
int comms_can_read(uint8_t *data, uint32_t max_len) {
|
||||
UNUSED(data);
|
||||
UNUSED(max_len);
|
||||
return 0;
|
||||
}
|
||||
void usb_cb_ep3_out(void *usbdata, int len) {
|
||||
UNUSED(usbdata);
|
||||
UNUSED(len);
|
||||
}
|
||||
|
||||
void usb_cb_ep3_out_complete(void) {}
|
||||
|
||||
int is_enumerated = 0;
|
||||
void usb_cb_enumeration_complete(void) {
|
||||
puts("USB enumeration complete\n");
|
||||
is_enumerated = 1;
|
||||
}
|
||||
|
||||
void usb_cb_ep2_out(void *usbdata, int len) {
|
||||
void comms_endpoint2_write(uint8_t *data, uint32_t len) {
|
||||
current_board->set_led(LED_RED, 0);
|
||||
for (int i = 0; i < len/4; i++) {
|
||||
flash_write_word(prog_ptr, *(uint32_t*)(usbdata+(i*4)));
|
||||
for (uint32_t i = 0; i < len/4; i++) {
|
||||
flash_write_word(prog_ptr, *(uint32_t*)(data+(i*4)));
|
||||
|
||||
//*(uint64_t*)(&spi_tx_buf[0x30+(i*4)]) = *prog_ptr;
|
||||
prog_ptr++;
|
||||
|
@ -116,15 +112,22 @@ void usb_cb_ep2_out(void *usbdata, int len) {
|
|||
|
||||
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) {
|
||||
UNUSED(len);
|
||||
ControlPacket_t control_req;
|
||||
|
||||
int resp_len = 0;
|
||||
switch (data[0]) {
|
||||
case 0:
|
||||
// control transfer
|
||||
resp_len = usb_cb_control_msg((USB_Setup_TypeDef *)(data+4), data_out);
|
||||
// control transfer
|
||||
control_req.request = ((USB_Setup_TypeDef *)(data+4))->b.bRequest;
|
||||
control_req.param1 = ((USB_Setup_TypeDef *)(data+4))->b.wValue.w;
|
||||
control_req.param2 = ((USB_Setup_TypeDef *)(data+4))->b.wIndex.w;
|
||||
control_req.length = ((USB_Setup_TypeDef *)(data+4))->b.wLength.w;
|
||||
|
||||
resp_len = comms_control_handler(&control_req, data_out);
|
||||
break;
|
||||
case 2:
|
||||
// ep 2, flash!
|
||||
usb_cb_ep2_out(data+4, data[2]);
|
||||
comms_endpoint2_write(data+4, data[2]);
|
||||
break;
|
||||
}
|
||||
return resp_len;
|
||||
|
@ -284,16 +287,7 @@ void soft_flasher_start(void) {
|
|||
|
||||
enable_interrupts();
|
||||
|
||||
uint64_t cnt = 0;
|
||||
|
||||
for (cnt=0;;cnt++) {
|
||||
if (cnt == 35 && !is_enumerated && usb_power_mode == USB_POWER_CLIENT) {
|
||||
// if you are connected through a hub to the phone
|
||||
// you need power to be able to see the device
|
||||
puts("USBP: didn't enumerate, switching to CDP mode\n");
|
||||
current_board->set_usb_power_mode(USB_POWER_CDP);
|
||||
current_board->set_led(LED_BLUE, 1);
|
||||
}
|
||||
for (;;) {
|
||||
// blink the green LED fast
|
||||
current_board->set_led(LED_GREEN, 0);
|
||||
delay(500000);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "obj/gitversion.h"
|
||||
|
||||
#include "usb_comms.h"
|
||||
#include "main_comms.h"
|
||||
|
||||
|
||||
// ********************* Serial debugging *********************
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "usb_protocol.h"
|
||||
#include "health.h"
|
||||
|
||||
extern int _app_start[0xc000]; // Only first 3 sectors of size 0x4000 are used
|
||||
|
@ -48,16 +47,117 @@ int get_rtc_pkt(void *dat) {
|
|||
return sizeof(t);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t ptr;
|
||||
uint32_t tail_size;
|
||||
uint8_t data[72];
|
||||
uint8_t counter;
|
||||
} asm_buffer;
|
||||
|
||||
asm_buffer can_read_buffer = {.ptr = 0U, .tail_size = 0U, .counter = 0U};
|
||||
uint32_t total_rx_size = 0U;
|
||||
|
||||
int comms_can_read(uint8_t *data, uint32_t max_len) {
|
||||
uint32_t pos = 1;
|
||||
data[0] = can_read_buffer.counter;
|
||||
// Send tail of previous message if it is in buffer
|
||||
if (can_read_buffer.ptr > 0U) {
|
||||
if (can_read_buffer.ptr <= 63U) {
|
||||
(void)memcpy(&data[pos], can_read_buffer.data, can_read_buffer.ptr);
|
||||
pos += can_read_buffer.ptr;
|
||||
can_read_buffer.ptr = 0U;
|
||||
} else {
|
||||
(void)memcpy(&data[pos], can_read_buffer.data, 63U);
|
||||
can_read_buffer.ptr = can_read_buffer.ptr - 63U;
|
||||
(void)memcpy(can_read_buffer.data, &can_read_buffer.data[63], can_read_buffer.ptr);
|
||||
pos += 63U;
|
||||
}
|
||||
}
|
||||
|
||||
if (total_rx_size > MAX_EP1_CHUNK_PER_BULK_TRANSFER) {
|
||||
total_rx_size = 0U;
|
||||
can_read_buffer.counter = 0U;
|
||||
} else {
|
||||
CANPacket_t can_packet;
|
||||
while ((pos < max_len) && can_pop(&can_rx_q, &can_packet)) {
|
||||
uint32_t pckt_len = CANPACKET_HEAD_SIZE + dlc_to_len[can_packet.data_len_code];
|
||||
if ((pos + pckt_len) <= max_len) {
|
||||
(void)memcpy(&data[pos], &can_packet, pckt_len);
|
||||
pos += pckt_len;
|
||||
} else {
|
||||
(void)memcpy(&data[pos], &can_packet, max_len - pos);
|
||||
can_read_buffer.ptr = pckt_len - (max_len - pos);
|
||||
// cppcheck-suppress objectIndex
|
||||
(void)memcpy(can_read_buffer.data, &((uint8_t*)&can_packet)[(max_len - pos)], can_read_buffer.ptr);
|
||||
pos = max_len;
|
||||
}
|
||||
}
|
||||
can_read_buffer.counter++;
|
||||
total_rx_size += pos;
|
||||
}
|
||||
if (pos != max_len) {
|
||||
can_read_buffer.counter = 0U;
|
||||
total_rx_size = 0U;
|
||||
}
|
||||
if (pos <= 1U) { pos = 0U; }
|
||||
return pos;
|
||||
}
|
||||
|
||||
asm_buffer can_write_buffer = {.ptr = 0U, .tail_size = 0U, .counter = 0U};
|
||||
|
||||
// send on CAN
|
||||
void comms_can_write(uint8_t *data, uint32_t len) {
|
||||
// Got first packet from a stream, resetting buffer and counter
|
||||
if (data[0] == 0U) {
|
||||
can_write_buffer.counter = 0U;
|
||||
can_write_buffer.ptr = 0U;
|
||||
can_write_buffer.tail_size = 0U;
|
||||
}
|
||||
// Assembling can message with data from buffer
|
||||
if (data[0] == can_write_buffer.counter) {
|
||||
uint32_t pos = 1U;
|
||||
can_write_buffer.counter++;
|
||||
if (can_write_buffer.ptr != 0U) {
|
||||
if (can_write_buffer.tail_size <= 63U) {
|
||||
CANPacket_t to_push;
|
||||
(void)memcpy(&can_write_buffer.data[can_write_buffer.ptr], &data[pos], can_write_buffer.tail_size);
|
||||
(void)memcpy(&to_push, can_write_buffer.data, can_write_buffer.ptr + can_write_buffer.tail_size);
|
||||
can_send(&to_push, to_push.bus, false);
|
||||
pos += can_write_buffer.tail_size;
|
||||
can_write_buffer.ptr = 0U;
|
||||
can_write_buffer.tail_size = 0U;
|
||||
} else {
|
||||
(void)memcpy(&can_write_buffer.data[can_write_buffer.ptr], &data[pos], len - pos);
|
||||
can_write_buffer.tail_size -= 63U;
|
||||
can_write_buffer.ptr += 63U;
|
||||
pos += 63U;
|
||||
}
|
||||
}
|
||||
|
||||
while (pos < len) {
|
||||
uint32_t pckt_len = CANPACKET_HEAD_SIZE + dlc_to_len[(data[pos] >> 4U)];
|
||||
if ((pos + pckt_len) <= len) {
|
||||
CANPacket_t to_push;
|
||||
(void)memcpy(&to_push, &data[pos], pckt_len);
|
||||
can_send(&to_push, to_push.bus, false);
|
||||
pos += pckt_len;
|
||||
} else {
|
||||
(void)memcpy(can_write_buffer.data, &data[pos], len - pos);
|
||||
can_write_buffer.ptr = len - pos;
|
||||
can_write_buffer.tail_size = pckt_len - can_write_buffer.ptr;
|
||||
pos += can_write_buffer.ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send on serial, first byte to select the ring
|
||||
void usb_cb_ep2_out(void *usbdata, int len) {
|
||||
uint8_t *usbdata8 = (uint8_t *)usbdata;
|
||||
uart_ring *ur = get_ring_by_number(usbdata8[0]);
|
||||
if ((len != 0) && (ur != NULL)) {
|
||||
if ((usbdata8[0] < 2U) || safety_tx_lin_hook(usbdata8[0] - 2U, &usbdata8[1], len - 1)) {
|
||||
for (int i = 1; i < len; i++) {
|
||||
while (!putc(ur, usbdata8[i])) {
|
||||
void comms_endpoint2_write(uint8_t *data, uint32_t len) {
|
||||
uart_ring *ur = get_ring_by_number(data[0]);
|
||||
if ((len != 0U) && (ur != NULL)) {
|
||||
if ((data[0] < 2U) || safety_tx_lin_hook(data[0] - 2U, &data[1], len - 1U)) {
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
while (!putc(ur, data[i])) {
|
||||
// wait
|
||||
}
|
||||
}
|
||||
|
@ -65,22 +165,18 @@ void usb_cb_ep2_out(void *usbdata, int len) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: make this more general!
|
||||
void usb_cb_ep3_out_complete(void) {
|
||||
if (can_tx_check_min_slots_free(MAX_CAN_MSGS_PER_BULK_TRANSFER)) {
|
||||
usb_outep3_resume_if_paused();
|
||||
}
|
||||
}
|
||||
|
||||
void usb_cb_enumeration_complete(void) {
|
||||
puts("USB enumeration complete\n");
|
||||
is_enumerated = 1;
|
||||
}
|
||||
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
||||
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
unsigned int resp_len = 0;
|
||||
uart_ring *ur = NULL;
|
||||
timestamp_t t;
|
||||
switch (setup->b.bRequest) {
|
||||
switch (req->request) {
|
||||
// **** 0xa0: get rtc time
|
||||
case 0xa0:
|
||||
resp_len = get_rtc_pkt(resp);
|
||||
|
@ -88,52 +184,52 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
// **** 0xa1: set rtc year
|
||||
case 0xa1:
|
||||
t = rtc_get_time();
|
||||
t.year = setup->b.wValue.w;
|
||||
t.year = req->param1;
|
||||
rtc_set_time(t);
|
||||
break;
|
||||
// **** 0xa2: set rtc month
|
||||
case 0xa2:
|
||||
t = rtc_get_time();
|
||||
t.month = setup->b.wValue.w;
|
||||
t.month = req->param1;
|
||||
rtc_set_time(t);
|
||||
break;
|
||||
// **** 0xa3: set rtc day
|
||||
case 0xa3:
|
||||
t = rtc_get_time();
|
||||
t.day = setup->b.wValue.w;
|
||||
t.day = req->param1;
|
||||
rtc_set_time(t);
|
||||
break;
|
||||
// **** 0xa4: set rtc weekday
|
||||
case 0xa4:
|
||||
t = rtc_get_time();
|
||||
t.weekday = setup->b.wValue.w;
|
||||
t.weekday = req->param1;
|
||||
rtc_set_time(t);
|
||||
break;
|
||||
// **** 0xa5: set rtc hour
|
||||
case 0xa5:
|
||||
t = rtc_get_time();
|
||||
t.hour = setup->b.wValue.w;
|
||||
t.hour = req->param1;
|
||||
rtc_set_time(t);
|
||||
break;
|
||||
// **** 0xa6: set rtc minute
|
||||
case 0xa6:
|
||||
t = rtc_get_time();
|
||||
t.minute = setup->b.wValue.w;
|
||||
t.minute = req->param1;
|
||||
rtc_set_time(t);
|
||||
break;
|
||||
// **** 0xa7: set rtc second
|
||||
case 0xa7:
|
||||
t = rtc_get_time();
|
||||
t.second = setup->b.wValue.w;
|
||||
t.second = req->param1;
|
||||
rtc_set_time(t);
|
||||
break;
|
||||
// **** 0xb0: set IR power
|
||||
case 0xb0:
|
||||
current_board->set_ir_power(setup->b.wValue.w);
|
||||
current_board->set_ir_power(req->param1);
|
||||
break;
|
||||
// **** 0xb1: set fan power
|
||||
case 0xb1:
|
||||
current_board->set_fan_power(setup->b.wValue.w);
|
||||
current_board->set_fan_power(req->param1);
|
||||
break;
|
||||
// **** 0xb2: get fan rpm
|
||||
case 0xb2:
|
||||
|
@ -143,7 +239,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xb3: set phone power
|
||||
case 0xb3:
|
||||
current_board->set_phone_power(setup->b.wValue.w > 0U);
|
||||
current_board->set_phone_power(req->param1 > 0U);
|
||||
break;
|
||||
// **** 0xc0: get CAN debug info
|
||||
case 0xc0:
|
||||
|
@ -161,7 +257,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
// **** 0xd0: fetch serial number
|
||||
case 0xd0:
|
||||
// addresses are OTP
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
if (req->param1 == 1U) {
|
||||
(void)memcpy(resp, (uint8_t *)DEVICE_SERIAL_NUMBER_ADDRESS, 0x10);
|
||||
resp_len = 0x10;
|
||||
} else {
|
||||
|
@ -172,7 +268,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
// **** 0xd1: enter bootloader mode
|
||||
case 0xd1:
|
||||
// this allows reflashing of the bootstub
|
||||
switch (setup->b.wValue.w) {
|
||||
switch (req->param1) {
|
||||
case 0:
|
||||
// only allow bootloader entry on debug builds
|
||||
#ifdef ALLOW_DEBUG
|
||||
|
@ -225,9 +321,9 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xd9: set ESP power
|
||||
case 0xd9:
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
if (req->param1 == 1U) {
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
} else if (setup->b.wValue.w == 2U) {
|
||||
} else if (req->param1 == 2U) {
|
||||
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||
} else {
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
|
@ -237,7 +333,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
case 0xda:
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
delay(1000000);
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
if (req->param1 == 1U) {
|
||||
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||
} else {
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
|
@ -248,7 +344,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
// **** 0xdb: set GMLAN (white/grey) or OBD CAN (black) multiplexing mode
|
||||
case 0xdb:
|
||||
if(current_board->has_obd){
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
if (req->param1 == 1U) {
|
||||
// Enable OBD CAN
|
||||
current_board->set_can_mode(CAN_MODE_OBD_CAN2);
|
||||
} else {
|
||||
|
@ -256,11 +352,11 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
current_board->set_can_mode(CAN_MODE_NORMAL);
|
||||
}
|
||||
} else {
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
if (req->param1 == 1U) {
|
||||
// GMLAN ON
|
||||
if (setup->b.wIndex.w == 1U) {
|
||||
if (req->param2 == 1U) {
|
||||
can_set_gmlan(1);
|
||||
} else if (setup->b.wIndex.w == 2U) {
|
||||
} else if (req->param2 == 2U) {
|
||||
can_set_gmlan(2);
|
||||
} else {
|
||||
puts("Invalid bus num for GMLAN CAN set\n");
|
||||
|
@ -273,7 +369,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
|
||||
// **** 0xdc: set safety mode
|
||||
case 0xdc:
|
||||
set_safety_mode(setup->b.wValue.w, (uint16_t)setup->b.wIndex.w);
|
||||
set_safety_mode(req->param1, (uint16_t)req->param2);
|
||||
break;
|
||||
// **** 0xdd: get healthpacket and CANPacket versions
|
||||
case 0xdd:
|
||||
|
@ -283,10 +379,10 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xde: set can bitrate
|
||||
case 0xde:
|
||||
if (setup->b.wValue.w < BUS_CNT) {
|
||||
if (req->param1 < BUS_CNT) {
|
||||
// TODO: add sanity check, ideally check if value is correct(from array of correct values)
|
||||
bus_config[setup->b.wValue.w].can_speed = setup->b.wIndex.w;
|
||||
bool ret = can_init(CAN_NUM_FROM_BUS_NUM(setup->b.wValue.w));
|
||||
bus_config[req->param1].can_speed = req->param2;
|
||||
bool ret = can_init(CAN_NUM_FROM_BUS_NUM(req->param1));
|
||||
UNUSED(ret);
|
||||
}
|
||||
break;
|
||||
|
@ -294,12 +390,12 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
case 0xdf:
|
||||
// you can only set this if you are in a non car safety mode
|
||||
if (!is_car_safety_mode(current_safety_mode)) {
|
||||
alternative_experience = setup->b.wValue.w;
|
||||
alternative_experience = req->param1;
|
||||
}
|
||||
break;
|
||||
// **** 0xe0: uart read
|
||||
case 0xe0:
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
ur = get_ring_by_number(req->param1);
|
||||
if (!ur) {
|
||||
break;
|
||||
}
|
||||
|
@ -310,26 +406,26 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
}
|
||||
|
||||
// read
|
||||
while ((resp_len < MIN(setup->b.wLength.w, USBPACKET_MAX_SIZE)) &&
|
||||
while ((resp_len < MIN(req->length, USBPACKET_MAX_SIZE)) &&
|
||||
getc(ur, (char*)&resp[resp_len])) {
|
||||
++resp_len;
|
||||
}
|
||||
break;
|
||||
// **** 0xe1: uart set baud rate
|
||||
case 0xe1:
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
ur = get_ring_by_number(req->param1);
|
||||
if (!ur) {
|
||||
break;
|
||||
}
|
||||
uart_set_baud(ur->uart, setup->b.wIndex.w);
|
||||
uart_set_baud(ur->uart, req->param2);
|
||||
break;
|
||||
// **** 0xe2: uart set parity
|
||||
case 0xe2:
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
ur = get_ring_by_number(req->param1);
|
||||
if (!ur) {
|
||||
break;
|
||||
}
|
||||
switch (setup->b.wIndex.w) {
|
||||
switch (req->param2) {
|
||||
case 0:
|
||||
// disable parity, 8-bit
|
||||
ur->uart->CR1 &= ~(USART_CR1_PCE | USART_CR1_M);
|
||||
|
@ -350,30 +446,30 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xe4: uart set baud rate extended
|
||||
case 0xe4:
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
ur = get_ring_by_number(req->param1);
|
||||
if (!ur) {
|
||||
break;
|
||||
}
|
||||
uart_set_baud(ur->uart, (int)setup->b.wIndex.w*300);
|
||||
uart_set_baud(ur->uart, (int)req->param2*300);
|
||||
break;
|
||||
// **** 0xe5: set CAN loopback (for testing)
|
||||
case 0xe5:
|
||||
can_loopback = (setup->b.wValue.w > 0U);
|
||||
can_loopback = (req->param1 > 0U);
|
||||
can_init_all();
|
||||
break;
|
||||
// **** 0xe6: set USB power
|
||||
case 0xe6:
|
||||
current_board->set_usb_power_mode(setup->b.wValue.w);
|
||||
current_board->set_usb_power_mode(req->param1);
|
||||
break;
|
||||
// **** 0xe7: set power save state
|
||||
case 0xe7:
|
||||
set_power_save_state(setup->b.wValue.w);
|
||||
set_power_save_state(req->param1);
|
||||
break;
|
||||
// **** 0xf0: k-line/l-line wake-up pulse for KWP2000 fast initialization
|
||||
case 0xf0:
|
||||
if(current_board->has_lin) {
|
||||
bool k = (setup->b.wValue.w == 0U) || (setup->b.wValue.w == 2U);
|
||||
bool l = (setup->b.wValue.w == 1U) || (setup->b.wValue.w == 2U);
|
||||
bool k = (req->param1 == 0U) || (req->param1 == 2U);
|
||||
bool l = (req->param1 == 1U) || (req->param1 == 2U);
|
||||
if (bitbang_wakeup(k, l)) {
|
||||
resp_len = -1; // do not clear NAK yet (wait for bit banging to finish)
|
||||
}
|
||||
|
@ -381,12 +477,12 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xf1: Clear CAN ring buffer.
|
||||
case 0xf1:
|
||||
if (setup->b.wValue.w == 0xFFFFU) {
|
||||
if (req->param1 == 0xFFFFU) {
|
||||
puts("Clearing CAN Rx queue\n");
|
||||
can_clear(&can_rx_q);
|
||||
} else if (setup->b.wValue.w < BUS_CNT) {
|
||||
} else if (req->param1 < BUS_CNT) {
|
||||
puts("Clearing CAN Tx queue\n");
|
||||
can_clear(can_queues[setup->b.wValue.w]);
|
||||
can_clear(can_queues[req->param1]);
|
||||
} else {
|
||||
puts("Clearing CAN CAN ring buffer failed: wrong bus number\n");
|
||||
}
|
||||
|
@ -394,7 +490,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
// **** 0xf2: Clear UART ring buffer.
|
||||
case 0xf2:
|
||||
{
|
||||
uart_ring * rb = get_ring_by_number(setup->b.wValue.w);
|
||||
uart_ring * rb = get_ring_by_number(req->param1);
|
||||
if (rb != NULL) {
|
||||
puts("Clearing UART queue.\n");
|
||||
clear_uart_buff(rb);
|
||||
|
@ -407,15 +503,15 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
heartbeat_counter = 0U;
|
||||
heartbeat_lost = false;
|
||||
heartbeat_disabled = false;
|
||||
heartbeat_engaged = (setup->b.wValue.w == 1U);
|
||||
heartbeat_engaged = (req->param1 == 1U);
|
||||
break;
|
||||
}
|
||||
// **** 0xf4: k-line/l-line 5 baud initialization
|
||||
case 0xf4:
|
||||
if(current_board->has_lin) {
|
||||
bool k = (setup->b.wValue.w == 0U) || (setup->b.wValue.w == 2U);
|
||||
bool l = (setup->b.wValue.w == 1U) || (setup->b.wValue.w == 2U);
|
||||
uint8_t five_baud_addr = (setup->b.wIndex.w & 0xFFU);
|
||||
bool k = (req->param1 == 0U) || (req->param1 == 2U);
|
||||
bool l = (req->param1 == 1U) || (req->param1 == 2U);
|
||||
uint8_t five_baud_addr = (req->param2 & 0xFFU);
|
||||
if (bitbang_five_baud_addr(k, l, five_baud_addr)) {
|
||||
resp_len = -1; // do not clear NAK yet (wait for bit banging to finish)
|
||||
}
|
||||
|
@ -423,15 +519,15 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xf5: set clock source mode
|
||||
case 0xf5:
|
||||
current_board->set_clock_source_mode(setup->b.wValue.w);
|
||||
current_board->set_clock_source_mode(req->param1);
|
||||
break;
|
||||
// **** 0xf6: set siren enabled
|
||||
case 0xf6:
|
||||
siren_enabled = (setup->b.wValue.w != 0U);
|
||||
siren_enabled = (req->param1 != 0U);
|
||||
break;
|
||||
// **** 0xf7: set green led enabled
|
||||
case 0xf7:
|
||||
green_led_enabled = (setup->b.wValue.w != 0U);
|
||||
green_led_enabled = (req->param1 != 0U);
|
||||
break;
|
||||
#ifdef ALLOW_DEBUG
|
||||
// **** 0xf8: disable heartbeat checks
|
||||
|
@ -441,20 +537,20 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
#endif
|
||||
// **** 0xde: set CAN FD data bitrate
|
||||
case 0xf9:
|
||||
if (setup->b.wValue.w < CAN_CNT) {
|
||||
if (req->param1 < CAN_CNT) {
|
||||
// TODO: add sanity check, ideally check if value is correct (from array of correct values)
|
||||
bus_config[setup->b.wValue.w].can_data_speed = setup->b.wIndex.w;
|
||||
bus_config[setup->b.wValue.w].canfd_enabled = (setup->b.wIndex.w >= bus_config[setup->b.wValue.w].can_speed);
|
||||
bus_config[setup->b.wValue.w].brs_enabled = (setup->b.wIndex.w > bus_config[setup->b.wValue.w].can_speed);
|
||||
bool ret = can_init(CAN_NUM_FROM_BUS_NUM(setup->b.wValue.w));
|
||||
bus_config[req->param1].can_data_speed = req->param2;
|
||||
bus_config[req->param1].canfd_enabled = (req->param2 >= bus_config[req->param1].can_speed);
|
||||
bus_config[req->param1].brs_enabled = (req->param2 > bus_config[req->param1].can_speed);
|
||||
bool ret = can_init(CAN_NUM_FROM_BUS_NUM(req->param1));
|
||||
UNUSED(ret);
|
||||
}
|
||||
break;
|
||||
// **** 0xfa: check if CAN FD and BRS are enabled
|
||||
case 0xfa:
|
||||
if (setup->b.wValue.w < CAN_CNT) {
|
||||
resp[0] = bus_config[setup->b.wValue.w].canfd_enabled;
|
||||
resp[1] = bus_config[setup->b.wValue.w].brs_enabled;
|
||||
if (req->param1 < CAN_CNT) {
|
||||
resp[0] = bus_config[req->param1].canfd_enabled;
|
||||
resp[1] = bus_config[req->param1].brs_enabled;
|
||||
resp_len = 2;
|
||||
}
|
||||
break;
|
||||
|
@ -464,7 +560,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
default:
|
||||
puts("NO HANDLER ");
|
||||
puth(setup->b.bRequest);
|
||||
puth(req->request);
|
||||
puts("\n");
|
||||
break;
|
||||
}
|
|
@ -12,7 +12,6 @@ void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage);
|
|||
// ********************* Globals **********************
|
||||
uint8_t hw_type = 0;
|
||||
const board *current_board;
|
||||
bool is_enumerated = 0;
|
||||
uint32_t uptime_cnt = 0;
|
||||
bool green_led_enabled = false;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#define USBPACKET_MAX_SIZE 0x40U
|
||||
|
||||
#define MAX_CAN_MSGS_PER_BULK_TRANSFER 51U
|
||||
#define MAX_EP1_CHUNK_PER_BULK_TRANSFER 16256 // max data stream chunk in bytes, shouldn't be higher than 16320 or counter will overflow
|
||||
#define MAX_EP1_CHUNK_PER_BULK_TRANSFER 16256U // max data stream chunk in bytes, shouldn't be higher than 16320 or counter will overflow
|
||||
|
||||
// CAN definitions
|
||||
#define CANPACKET_HEAD_SIZE 5U
|
||||
|
|
|
@ -41,26 +41,25 @@ void debug_ring_callback(uart_ring *ring) {
|
|||
}
|
||||
}
|
||||
|
||||
int usb_cb_ep1_in(void *usbdata, int len) {
|
||||
UNUSED(usbdata);
|
||||
UNUSED(len);
|
||||
int comms_can_read(uint8_t *data, uint32_t max_len) {
|
||||
UNUSED(data);
|
||||
UNUSED(max_len);
|
||||
return 0;
|
||||
}
|
||||
void usb_cb_ep2_out(void *usbdata, int len) {
|
||||
UNUSED(usbdata);
|
||||
void comms_can_write(uint8_t *data, uint32_t len) {
|
||||
UNUSED(data);
|
||||
UNUSED(len);
|
||||
}
|
||||
void usb_cb_ep3_out(void *usbdata, int len) {
|
||||
UNUSED(usbdata);
|
||||
void comms_endpoint2_write(uint8_t *data, uint32_t len) {
|
||||
UNUSED(data);
|
||||
UNUSED(len);
|
||||
}
|
||||
void usb_cb_ep3_out_complete(void) {}
|
||||
void usb_cb_enumeration_complete(void) {}
|
||||
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
||||
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
unsigned int resp_len = 0;
|
||||
uart_ring *ur = NULL;
|
||||
switch (setup->b.bRequest) {
|
||||
switch (req->request) {
|
||||
// **** 0xc1: get hardware type
|
||||
case 0xc1:
|
||||
resp[0] = hw_type;
|
||||
|
@ -68,19 +67,19 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
|||
break;
|
||||
// **** 0xe0: uart read
|
||||
case 0xe0:
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
ur = get_ring_by_number(req->param1);
|
||||
if (!ur) {
|
||||
break;
|
||||
}
|
||||
// read
|
||||
while ((resp_len < MIN(setup->b.wLength.w, USBPACKET_MAX_SIZE)) &&
|
||||
while ((resp_len < MIN(req->length, USBPACKET_MAX_SIZE)) &&
|
||||
getc(ur, (char*)&resp[resp_len])) {
|
||||
++resp_len;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
puts("NO HANDLER ");
|
||||
puth(setup->b.bRequest);
|
||||
puth(req->request);
|
||||
puts("\n");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -9,4 +9,3 @@ typedef struct harness_configuration harness_configuration;
|
|||
// ********************* Globals **********************
|
||||
uint8_t hw_type = 0;
|
||||
const board *current_board;
|
||||
bool is_enumerated = 0;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define DEVICE_SERIAL_NUMBER_ADDRESS 0x1FFF79C0U
|
||||
|
||||
#include "can_definitions.h"
|
||||
#include "comms_definitions.h"
|
||||
|
||||
#ifndef BOOTSTUB
|
||||
#ifdef PANDA
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define DEVICE_SERIAL_NUMBER_ADDRESS 0x080FFFC0U
|
||||
|
||||
#include "can_definitions.h"
|
||||
#include "comms_definitions.h"
|
||||
|
||||
#ifndef BOOTSTUB
|
||||
#include "main_declarations.h"
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
typedef struct {
|
||||
int ptr;
|
||||
int tail_size;
|
||||
uint8_t data[72];
|
||||
uint8_t counter;
|
||||
} usb_asm_buffer;
|
||||
|
||||
usb_asm_buffer ep1_buffer = {.ptr = 0, .tail_size = 0, .counter = 0};
|
||||
int total_rx_size = 0;
|
||||
|
||||
int usb_cb_ep1_in(void *usbdata, int len) {
|
||||
int pos = 1;
|
||||
uint8_t *usbdata8 = (uint8_t *)usbdata;
|
||||
usbdata8[0] = ep1_buffer.counter;
|
||||
// Send tail of previous message if it is in buffer
|
||||
if (ep1_buffer.ptr > 0) {
|
||||
if (ep1_buffer.ptr <= 63) {
|
||||
(void)memcpy(&usbdata8[pos], ep1_buffer.data, ep1_buffer.ptr);
|
||||
pos += ep1_buffer.ptr;
|
||||
ep1_buffer.ptr = 0;
|
||||
} else {
|
||||
(void)memcpy(&usbdata8[pos], ep1_buffer.data, 63);
|
||||
ep1_buffer.ptr = ep1_buffer.ptr - 63;
|
||||
(void)memcpy(ep1_buffer.data, &ep1_buffer.data[63], ep1_buffer.ptr);
|
||||
pos += 63;
|
||||
}
|
||||
}
|
||||
|
||||
if (total_rx_size > MAX_EP1_CHUNK_PER_BULK_TRANSFER) {
|
||||
total_rx_size = 0;
|
||||
ep1_buffer.counter = 0U;
|
||||
} else {
|
||||
CANPacket_t can_packet;
|
||||
while ((pos < len) && can_pop(&can_rx_q, &can_packet)) {
|
||||
int pckt_len = CANPACKET_HEAD_SIZE + dlc_to_len[can_packet.data_len_code];
|
||||
if ((pos + pckt_len) <= len) {
|
||||
(void)memcpy(&usbdata8[pos], &can_packet, pckt_len);
|
||||
pos += pckt_len;
|
||||
} else {
|
||||
(void)memcpy(&usbdata8[pos], &can_packet, len - pos);
|
||||
ep1_buffer.ptr = pckt_len - (len - pos);
|
||||
//(void)memcpy(ep1_buffer.data, ((uint8_t*)&can_packet + (len - pos)), ep1_buffer.ptr);
|
||||
// cppcheck-suppress objectIndex
|
||||
(void)memcpy(ep1_buffer.data, &((uint8_t*)&can_packet)[(len - pos)], ep1_buffer.ptr);
|
||||
pos = len;
|
||||
}
|
||||
}
|
||||
ep1_buffer.counter++;
|
||||
total_rx_size += pos;
|
||||
}
|
||||
if (pos != len) {
|
||||
ep1_buffer.counter = 0U;
|
||||
total_rx_size = 0;
|
||||
}
|
||||
if (pos <= 1) { pos = 0; }
|
||||
return pos;
|
||||
}
|
||||
|
||||
usb_asm_buffer ep3_buffer = {.ptr = 0, .tail_size = 0, .counter = 0};
|
||||
|
||||
// send on CAN
|
||||
void usb_cb_ep3_out(void *usbdata, int len) {
|
||||
uint8_t *usbdata8 = (uint8_t *)usbdata;
|
||||
// Got first packet from a stream, resetting buffer and counter
|
||||
if (usbdata8[0] == 0U) {
|
||||
ep3_buffer.counter = 0U;
|
||||
ep3_buffer.ptr = 0;
|
||||
ep3_buffer.tail_size = 0;
|
||||
}
|
||||
// Assembling can message with data from buffer
|
||||
if (usbdata8[0] == ep3_buffer.counter) {
|
||||
int pos = 1;
|
||||
ep3_buffer.counter++;
|
||||
if (ep3_buffer.ptr != 0) {
|
||||
if (ep3_buffer.tail_size <= 63) {
|
||||
CANPacket_t to_push;
|
||||
(void)memcpy(&ep3_buffer.data[ep3_buffer.ptr], &usbdata8[pos], ep3_buffer.tail_size);
|
||||
(void)memcpy(&to_push, ep3_buffer.data, ep3_buffer.ptr + ep3_buffer.tail_size);
|
||||
can_send(&to_push, to_push.bus, false);
|
||||
pos += ep3_buffer.tail_size;
|
||||
ep3_buffer.ptr = 0;
|
||||
ep3_buffer.tail_size = 0;
|
||||
} else {
|
||||
(void)memcpy(&ep3_buffer.data[ep3_buffer.ptr], &usbdata8[pos], len - pos);
|
||||
ep3_buffer.tail_size -= 63;
|
||||
ep3_buffer.ptr += 63;
|
||||
pos += 63;
|
||||
}
|
||||
}
|
||||
|
||||
while (pos < len) {
|
||||
int pckt_len = CANPACKET_HEAD_SIZE + dlc_to_len[(usbdata8[pos] >> 4U)];
|
||||
if ((pos + pckt_len) <= len) {
|
||||
CANPacket_t to_push;
|
||||
(void)memcpy(&to_push, &usbdata8[pos], pckt_len);
|
||||
can_send(&to_push, to_push.bus, false);
|
||||
pos += pckt_len;
|
||||
} else {
|
||||
(void)memcpy(ep3_buffer.data, &usbdata8[pos], len - pos);
|
||||
ep3_buffer.ptr = len - pos;
|
||||
ep3_buffer.tail_size = pckt_len - ep3_buffer.ptr;
|
||||
pos += ep3_buffer.ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_
|
||||
#define SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_
|
||||
|
||||
#include "stdint.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
#define uint8_t unsigned char
|
||||
#define uint32_t unsigned int
|
||||
#define int64_t long long
|
||||
#define uint64_t unsigned long long
|
Loading…
Reference in New Issue