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:
Robbe Derks 2022-08-03 13:11:52 +02:00 committed by GitHub
parent 89989abca5
commit d24971ef8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 237 additions and 249 deletions

11
board/comms_definitions.h Normal file
View File

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

View File

@ -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);
}

View File

@ -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_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);

View File

@ -22,7 +22,7 @@
#include "obj/gitversion.h"
#include "usb_comms.h"
#include "main_comms.h"
// ********************* Serial debugging *********************

View File

@ -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;
}

View File

@ -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;

View File

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

View File

@ -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;
}

View File

@ -9,4 +9,3 @@ typedef struct harness_configuration harness_configuration;
// ********************* Globals **********************
uint8_t hw_type = 0;
const board *current_board;
bool is_enumerated = 0;

View File

@ -39,6 +39,7 @@
#define DEVICE_SERIAL_NUMBER_ADDRESS 0x1FFF79C0U
#include "can_definitions.h"
#include "comms_definitions.h"
#ifndef BOOTSTUB
#ifdef PANDA

View File

@ -35,6 +35,7 @@
#define DEVICE_SERIAL_NUMBER_ADDRESS 0x080FFFC0U
#include "can_definitions.h"
#include "comms_definitions.h"
#ifndef BOOTSTUB
#include "main_declarations.h"

View File

@ -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;
}
}
}
}

View File

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

View File

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