openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

267 lines
9.1 KiB

extern int _app_start[0xc000]; // Only first 3 sectors of size 0x4000 are used
bool generated_can_traffic = false;
int get_jungle_health_pkt(void *dat) {
COMPILE_TIME_ASSERT(sizeof(struct jungle_health_t) <= USBPACKET_MAX_SIZE);
struct jungle_health_t * health = (struct jungle_health_t*)dat;
health->uptime_pkt = uptime_cnt;
health->ch1_power = current_board->get_channel_power(1U);
health->ch2_power = current_board->get_channel_power(2U);
health->ch3_power = current_board->get_channel_power(3U);
health->ch4_power = current_board->get_channel_power(4U);
health->ch5_power = current_board->get_channel_power(5U);
health->ch6_power = current_board->get_channel_power(6U);
health->ch1_sbu1_mV = current_board->get_sbu_mV(1U, SBU1);
health->ch1_sbu2_mV = current_board->get_sbu_mV(1U, SBU2);
health->ch2_sbu1_mV = current_board->get_sbu_mV(2U, SBU1);
health->ch2_sbu2_mV = current_board->get_sbu_mV(2U, SBU2);
health->ch3_sbu1_mV = current_board->get_sbu_mV(3U, SBU1);
health->ch3_sbu2_mV = current_board->get_sbu_mV(3U, SBU2);
health->ch4_sbu1_mV = current_board->get_sbu_mV(4U, SBU1);
health->ch4_sbu2_mV = current_board->get_sbu_mV(4U, SBU2);
health->ch5_sbu1_mV = current_board->get_sbu_mV(5U, SBU1);
health->ch5_sbu2_mV = current_board->get_sbu_mV(5U, SBU2);
health->ch6_sbu1_mV = current_board->get_sbu_mV(6U, SBU1);
health->ch6_sbu2_mV = current_board->get_sbu_mV(6U, SBU2);
return sizeof(*health);
}
// send on serial, first byte to select the ring
void comms_endpoint2_write(const uint8_t *data, uint32_t len) {
UNUSED(data);
UNUSED(len);
}
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
unsigned int resp_len = 0;
uint32_t time;
#ifdef DEBUG_COMMS
print("raw control request: "); hexdump(req, sizeof(ControlPacket_t)); print("\n");
print("- request "); puth(req->request); print("\n");
print("- param1 "); puth(req->param1); print("\n");
print("- param2 "); puth(req->param2); print("\n");
#endif
switch (req->request) {
// **** 0xa0: Set panda power.
case 0xa0:
current_board->set_panda_power((req->param1 == 1U));
break;
// **** 0xa1: Set harness orientation.
case 0xa1:
current_board->set_harness_orientation(req->param1);
break;
// **** 0xa2: Set ignition.
case 0xa2:
current_board->set_ignition((req->param1 == 1U));
break;
// **** 0xa3: Set panda power per channel by bitmask.
case 0xa3:
current_board->set_panda_individual_power(req->param1, (req->param2 > 0U));
break;
// **** 0xa4: Enable generated CAN traffic.
case 0xa4:
generated_can_traffic = (req->param1 > 0U);
break;
// **** 0xa8: get microsecond timer
case 0xa8:
time = microsecond_timer_get();
resp[0] = (time & 0x000000FFU);
resp[1] = ((time & 0x0000FF00U) >> 8U);
resp[2] = ((time & 0x00FF0000U) >> 16U);
resp[3] = ((time & 0xFF000000U) >> 24U);
resp_len = 4U;
break;
// **** 0xc0: reset communications
case 0xc0:
comms_can_reset();
break;
// **** 0xc1: get hardware type
case 0xc1:
resp[0] = hw_type;
resp_len = 1;
break;
// **** 0xc2: CAN health stats
case 0xc2:
COMPILE_TIME_ASSERT(sizeof(can_health_t) <= USBPACKET_MAX_SIZE);
if (req->param1 < 3U) {
update_can_health_pkt(req->param1, 0U);
can_health[req->param1].can_speed = (bus_config[req->param1].can_speed / 10U);
can_health[req->param1].can_data_speed = (bus_config[req->param1].can_data_speed / 10U);
can_health[req->param1].canfd_enabled = bus_config[req->param1].canfd_enabled;
can_health[req->param1].brs_enabled = bus_config[req->param1].brs_enabled;
can_health[req->param1].canfd_non_iso = bus_config[req->param1].canfd_non_iso;
resp_len = sizeof(can_health[req->param1]);
(void)memcpy(resp, &can_health[req->param1], resp_len);
}
break;
// **** 0xc3: fetch MCU UID
case 0xc3:
(void)memcpy(resp, ((uint8_t *)UID_BASE), 12);
resp_len = 12;
break;
// **** 0xd0: fetch serial (aka the provisioned dongle ID)
case 0xd0:
// addresses are OTP
if (req->param1 == 1U) {
(void)memcpy(resp, (uint8_t *)DEVICE_SERIAL_NUMBER_ADDRESS, 0x10);
resp_len = 0x10;
} else {
get_provision_chunk(resp);
resp_len = PROVISION_CHUNK_LEN;
}
break;
// **** 0xd1: enter bootloader mode
case 0xd1:
// this allows reflashing of the bootstub
switch (req->param1) {
case 0:
// only allow bootloader entry on debug builds
#ifdef ALLOW_DEBUG
print("-> entering bootloader\n");
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
NVIC_SystemReset();
#endif
break;
case 1:
print("-> entering softloader\n");
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
NVIC_SystemReset();
break;
default:
print("Bootloader mode invalid\n");
break;
}
break;
// **** 0xd2: get health packet
case 0xd2:
resp_len = get_jungle_health_pkt(resp);
break;
// **** 0xd3: get first 64 bytes of signature
case 0xd3:
{
resp_len = 64;
char * code = (char*)_app_start;
int code_len = _app_start[0];
(void)memcpy(resp, &code[code_len], resp_len);
}
break;
// **** 0xd4: get second 64 bytes of signature
case 0xd4:
{
resp_len = 64;
char * code = (char*)_app_start;
int code_len = _app_start[0];
(void)memcpy(resp, &code[code_len + 64], resp_len);
}
break;
// **** 0xd6: get version
case 0xd6:
COMPILE_TIME_ASSERT(sizeof(gitversion) <= USBPACKET_MAX_SIZE);
(void)memcpy(resp, gitversion, sizeof(gitversion));
resp_len = sizeof(gitversion) - 1U;
break;
// **** 0xd8: reset ST
case 0xd8:
NVIC_SystemReset();
break;
// **** 0xdb: set OBD CAN multiplexing mode
case 0xdb:
if (req->param1 == 1U) {
// Enable OBD CAN
current_board->set_can_mode(CAN_MODE_OBD_CAN2);
} else {
// Disable OBD CAN
current_board->set_can_mode(CAN_MODE_NORMAL);
}
break;
// **** 0xdd: get healthpacket and CANPacket versions
case 0xdd:
resp[0] = JUNGLE_HEALTH_PACKET_VERSION;
resp[1] = CAN_PACKET_VERSION;
resp[2] = CAN_HEALTH_PACKET_VERSION;
resp_len = 3;
break;
// **** 0xde: set can bitrate
case 0xde:
if ((req->param1 < PANDA_BUS_CNT) && is_speed_valid(req->param2, speeds, sizeof(speeds)/sizeof(speeds[0]))) {
bus_config[req->param1].can_speed = req->param2;
bool ret = can_init(CAN_NUM_FROM_BUS_NUM(req->param1));
UNUSED(ret);
}
break;
// **** 0xe0: debug read
case 0xe0:
// read
while ((resp_len < MIN(req->length, USBPACKET_MAX_SIZE)) && get_char(get_ring_by_number(0), (char*)&resp[resp_len])) {
++resp_len;
}
break;
// **** 0xe5: set CAN loopback (for testing)
case 0xe5:
can_loopback = (req->param1 > 0U);
can_init_all();
break;
// **** 0xf1: Clear CAN ring buffer.
case 0xf1:
if (req->param1 == 0xFFFFU) {
print("Clearing CAN Rx queue\n");
can_clear(&can_rx_q);
} else if (req->param1 < PANDA_BUS_CNT) {
print("Clearing CAN Tx queue\n");
can_clear(can_queues[req->param1]);
} else {
print("Clearing CAN CAN ring buffer failed: wrong bus number\n");
}
break;
// **** 0xf2: Clear debug ring buffer.
case 0xf2:
print("Clearing debug queue.\n");
clear_uart_buff(get_ring_by_number(0));
break;
// **** 0xf4: Set CAN transceiver enable pin
case 0xf4:
current_board->enable_can_transceiver(req->param1, req->param2 > 0U);
break;
// **** 0xf5: Set CAN silent mode
case 0xf5:
can_silent = (req->param1 > 0U) ? ALL_CAN_SILENT : ALL_CAN_LIVE;
can_init_all();
break;
// **** 0xf7: enable/disable header pin by number
case 0xf7:
current_board->enable_header_pin(req->param1, req->param2 > 0U);
break;
// **** 0xf9: set CAN FD data bitrate
case 0xf9:
if ((req->param1 < PANDA_CAN_CNT) &&
current_board->has_canfd &&
is_speed_valid(req->param2, data_speeds, sizeof(data_speeds)/sizeof(data_speeds[0]))) {
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;
// **** 0xfc: set CAN FD non-ISO mode
case 0xfc:
if ((req->param1 < PANDA_CAN_CNT) && current_board->has_canfd) {
bus_config[req->param1].canfd_non_iso = (req->param2 != 0U);
bool ret = can_init(CAN_NUM_FROM_BUS_NUM(req->param1));
UNUSED(ret);
}
break;
default:
print("NO HANDLER ");
puth(req->request);
print("\n");
break;
}
return resp_len;
}