Skip to content

Commit

Permalink
Squashed 'panda/' changes from 769ade0..0696730
Browse files Browse the repository at this point in the history
0696730 Toyota: add missing offset from speed signal (#469)
5b1a8dc Filtering LKAS HUD messages (#468)
99050f4 test_spam_can_buses was missing from Nissan
0f21b19 Cleanup pedal nomenclature (#467)
ceff91d Standardize brake safety tests (#465)
04809e1 Hyundai brake check (#464)
74c8ee0 Subaru brake check (#463)
4ecc6b3 Cleanup: avoid unnecessary bus checks in rx hooks
c7d0d5f Volkswagen safety updates: Phase 3 (#462)
4368748 WIP: Toyota brake check.  (#459)
2ef996f fix addr frequencies
e063b26 Second test fix tentative
88e2593 This should fix the test replay
ebb8866 Added NISSAN replay test
b2dbb50 remove toyota ipas safety code and tests (#460)
a379faf White Panda's Wi-Fi setup instructions (#457)
11ef24b Improve tests (#456)
fb02390 Subaru checksum counter (#455)
9a44499 Fix Subaru Legacy Torque driver bug (#454)
dfa6b07 separating subary legacy safety mode from global (#452)
dad5858 Chrysler: add brakepress cancellation (#451)
db94a5b Added Nissan safety (#244)
d7f1195 Chrysler Checksum/counter (#450)
96e535e abstract crc function (#448)
1b49d3e Hyundai: add gas disengage and tests (#447)
598074c Volkswagen safety updates: Phase 2 (#445)
b2ffaae Chrysler: disengage on gas press  (#442)
2ebbe36 Subaru: disengage on gas press (#446)
ccf75c4 Volkswagen safety updates: Phase 1 (#444)

git-subtree-dir: panda
git-subtree-split: 0696730
  • Loading branch information
Vehicle Researcher committed Mar 13, 2020
1 parent 6b8726e commit 291dda0
Show file tree
Hide file tree
Showing 37 changed files with 1,878 additions and 1,140 deletions.
4 changes: 4 additions & 0 deletions board/config.h
Expand Up @@ -36,6 +36,10 @@
__typeof__ (b) _b = (b); \
(_a > _b) ? _a : _b; })

#define ABS(a) \
({ __typeof__ (a) _a = (a); \
(_a > 0) ? _a : (-_a); })

#define MAX_RESP_LEN 0x40U

// Around (1Mbps / 8 bits/byte / 12 bytes per message)
Expand Down
16 changes: 16 additions & 0 deletions board/crc.h
@@ -0,0 +1,16 @@
uint8_t crc_checksum(uint8_t *dat, int len, const uint8_t poly) {
uint8_t crc = 0xFF;
int i, j;
for (i = len - 1; i >= 0; i--) {
crc ^= dat[i];
for (j = 0; j < 8; j++) {
if ((crc & 0x80U) != 0U) {
crc = (uint8_t)((crc << 1) ^ poly);
}
else {
crc <<= 1;
}
}
}
return crc;
}
2 changes: 1 addition & 1 deletion board/drivers/llcan.h
Expand Up @@ -52,7 +52,7 @@ bool llcan_set_speed(CAN_TypeDef *CAN_obj, uint32_t speed, bool loopback, bool s
void llcan_init(CAN_TypeDef *CAN_obj) {
// Enter init mode
register_set_bits(&(CAN_obj->FMR), CAN_FMR_FINIT);

// Wait for INAK bit to be set
while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)) {}

Expand Down
27 changes: 5 additions & 22 deletions board/pedal/main.c
Expand Up @@ -19,6 +19,7 @@
#include "drivers/timer.h"

#include "gpio.h"
#include "crc.h"

#define CAN CAN1

Expand Down Expand Up @@ -105,26 +106,6 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)

#endif

// ***************************** pedal can checksum *****************************

uint8_t pedal_checksum(uint8_t *dat, int len) {
uint8_t crc = 0xFF;
uint8_t poly = 0xD5; // standard crc8
int i, j;
for (i = len - 1; i >= 0; i--) {
crc ^= dat[i];
for (j = 0; j < 8; j++) {
if ((crc & 0x80U) != 0U) {
crc = (uint8_t)((crc << 1) ^ poly);
}
else {
crc <<= 1;
}
}
}
return crc;
}

// ***************************** can port *****************************

// addresses to be used on CAN
Expand Down Expand Up @@ -155,6 +136,8 @@ uint32_t current_index = 0;
#define FAULT_INVALID 6U
uint8_t state = FAULT_STARTUP;

const uint8_t crc_poly = 0xD5; // standard crc8

void CAN1_RX0_IRQ_Handler(void) {
while ((CAN->RF0R & CAN_RF0R_FMP0) != 0) {
#ifdef DEBUG
Expand Down Expand Up @@ -184,7 +167,7 @@ void CAN1_RX0_IRQ_Handler(void) {
uint16_t value_1 = (dat[2] << 8) | dat[3];
bool enable = ((dat[4] >> 7) & 1U) != 0U;
uint8_t index = dat[4] & COUNTER_CYCLE;
if (pedal_checksum(dat, CAN_GAS_SIZE - 1) == dat[5]) {
if (crc_checksum(dat, CAN_GAS_SIZE - 1, crc_poly) == dat[5]) {
if (((current_index + 1U) & COUNTER_CYCLE) == index) {
#ifdef DEBUG
puts("setting gas ");
Expand Down Expand Up @@ -247,7 +230,7 @@ void TIM3_IRQ_Handler(void) {
dat[2] = (pdl1 >> 8) & 0xFFU;
dat[3] = (pdl1 >> 0) & 0xFFU;
dat[4] = ((state & 0xFU) << 4) | pkt_idx;
dat[5] = pedal_checksum(dat, CAN_GAS_SIZE - 1);
dat[5] = crc_checksum(dat, CAN_GAS_SIZE - 1, crc_poly);
CAN->sTxMailBox[0].TDLR = dat[0] | (dat[1] << 8) | (dat[2] << 16) | (dat[3] << 24);
CAN->sTxMailBox[0].TDHR = dat[4] | (dat[5] << 8);
CAN->sTxMailBox[0].TDTR = 6; // len of packet is 5
Expand Down
27 changes: 22 additions & 5 deletions board/safety.h
Expand Up @@ -4,7 +4,6 @@
#include "safety/safety_defaults.h"
#include "safety/safety_honda.h"
#include "safety/safety_toyota.h"
#include "safety/safety_toyota_ipas.h"
#include "safety/safety_tesla.h"
#include "safety/safety_gm_ascm.h"
#include "safety/safety_gm.h"
Expand All @@ -14,6 +13,7 @@
#include "safety/safety_chrysler.h"
#include "safety/safety_subaru.h"
#include "safety/safety_mazda.h"
#include "safety/safety_nissan.h"
#include "safety/safety_volkswagen.h"
#include "safety/safety_elm327.h"

Expand All @@ -31,12 +31,13 @@
#define SAFETY_TESLA 10U
#define SAFETY_SUBARU 11U
#define SAFETY_MAZDA 13U
#define SAFETY_VOLKSWAGEN 15U
#define SAFETY_TOYOTA_IPAS 16U
#define SAFETY_NISSAN 14U
#define SAFETY_VOLKSWAGEN_MQB 15U
#define SAFETY_ALLOUTPUT 17U
#define SAFETY_GM_ASCM 18U
#define SAFETY_NOOUTPUT 19U
#define SAFETY_HONDA_BOSCH_HARNESS 20U
#define SAFETY_SUBARU_LEGACY 22U

uint16_t current_safety_mode = SAFETY_SILENT;
const safety_hooks *current_hooks = &nooutput_hooks;
Expand All @@ -57,6 +58,21 @@ int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
return current_hooks->fwd(bus_num, to_fwd);
}

// Given a CRC-8 poly, generate a static lookup table to use with a fast CRC-8
// algorithm. Called at init time for safety modes using CRC-8.
void gen_crc_lookup_table(uint8_t poly, uint8_t crc_lut[]) {
for (int i = 0; i < 256; i++) {
uint8_t crc = i;
for (int j = 0; j < 8; j++) {
if ((crc & 0x80U) != 0U)
crc = (uint8_t)((crc << 1) ^ poly);
else
crc <<= 1;
}
crc_lut[i] = crc;
}
}

bool msg_allowed(int addr, int bus, const AddrBus addr_list[], int len) {
bool allowed = false;
for (int i = 0; i < len; i++) {
Expand Down Expand Up @@ -184,13 +200,14 @@ const safety_hook_config safety_hook_registry[] = {
{SAFETY_HYUNDAI, &hyundai_hooks},
{SAFETY_CHRYSLER, &chrysler_hooks},
{SAFETY_SUBARU, &subaru_hooks},
{SAFETY_SUBARU_LEGACY, &subaru_legacy_hooks},
{SAFETY_MAZDA, &mazda_hooks},
{SAFETY_VOLKSWAGEN, &volkswagen_hooks},
{SAFETY_VOLKSWAGEN_MQB, &volkswagen_mqb_hooks},
{SAFETY_NOOUTPUT, &nooutput_hooks},
#ifdef ALLOW_DEBUG
{SAFETY_CADILLAC, &cadillac_hooks},
{SAFETY_TOYOTA_IPAS, &toyota_ipas_hooks},
{SAFETY_TESLA, &tesla_hooks},
{SAFETY_NISSAN, &nissan_hooks},
{SAFETY_ALLOUTPUT, &alloutput_hooks},
{SAFETY_GM_ASCM, &gm_ascm_hooks},
{SAFETY_FORD, &ford_hooks},
Expand Down
88 changes: 80 additions & 8 deletions board/safety/safety_chrysler.h
Expand Up @@ -4,28 +4,77 @@ const uint32_t CHRYSLER_RT_INTERVAL = 250000; // 250ms between real time checks
const int CHRYSLER_MAX_RATE_UP = 3;
const int CHRYSLER_MAX_RATE_DOWN = 3;
const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor
const int CHRYSLER_GAS_THRSLD = 30; // 7% more than 2m/s
const int CHRYSLER_STANDSTILL_THRSLD = 10; // about 1m/s
const AddrBus CHRYSLER_TX_MSGS[] = {{571, 0}, {658, 0}, {678, 0}};

// TODO: do checksum and counter checks
AddrCheckStruct chrysler_rx_checks[] = {
{.addr = {544}, .bus = 0, .expected_timestep = 10000U},
{.addr = {500}, .bus = 0, .expected_timestep = 20000U},
{.addr = {544}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U},
{.addr = {514}, .bus = 0, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U},
{.addr = {500}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
{.addr = {308}, .bus = 0, .check_checksum = false, .max_counter = 15U, .expected_timestep = 20000U},
{.addr = {320}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
};
const int CHRYSLER_RX_CHECK_LEN = sizeof(chrysler_rx_checks) / sizeof(chrysler_rx_checks[0]);

int chrysler_rt_torque_last = 0;
int chrysler_desired_torque_last = 0;
int chrysler_cruise_engaged_last = 0;
int chrysler_speed = 0;
uint32_t chrysler_ts_last = 0;
struct sample_t chrysler_torque_meas; // last few torques measured

static uint8_t chrysler_get_checksum(CAN_FIFOMailBox_TypeDef *to_push) {
int checksum_byte = GET_LEN(to_push) - 1;
return (uint8_t)(GET_BYTE(to_push, checksum_byte));
}

static uint8_t chrysler_compute_checksum(CAN_FIFOMailBox_TypeDef *to_push) {
/* This function does not want the checksum byte in the input data.
jeep chrysler canbus checksum from http://illmatics.com/Remote%20Car%20Hacking.pdf */
uint8_t checksum = 0xFF;
int len = GET_LEN(to_push);
for (int j = 0; j < (len - 1); j++) {
uint8_t shift = 0x80;
uint8_t curr = (uint8_t)GET_BYTE(to_push, j);
for (int i=0; i<8; i++) {
uint8_t bit_sum = curr & shift;
uint8_t temp_chk = checksum & 0x80U;
if (bit_sum != 0U) {
bit_sum = 0x1C;
if (temp_chk != 0U) {
bit_sum = 1;
}
checksum = checksum << 1;
temp_chk = checksum | 1U;
bit_sum ^= temp_chk;
} else {
if (temp_chk != 0U) {
bit_sum = 0x1D;
}
checksum = checksum << 1;
bit_sum ^= checksum;
}
checksum = bit_sum;
shift = shift >> 1;
}
}
return ~checksum;
}

static uint8_t chrysler_get_counter(CAN_FIFOMailBox_TypeDef *to_push) {
// Well defined counter only for 8 bytes messages
return (uint8_t)(GET_BYTE(to_push, 6) >> 4);
}

static int chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {

bool valid = addr_safety_check(to_push, chrysler_rx_checks, CHRYSLER_RX_CHECK_LEN,
NULL, NULL, NULL);
chrysler_get_checksum, chrysler_compute_checksum,
chrysler_get_counter);

if (valid) {
int bus = GET_BUS(to_push);
if (valid && (GET_BUS(to_push) == 0)) {
int addr = GET_ADDR(to_push);

// Measured eps torque
Expand All @@ -37,7 +86,7 @@ static int chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
}

// enter controls on rising edge of ACC, exit controls on ACC off
if (addr == 0x1F4) {
if (addr == 500) {
int cruise_engaged = ((GET_BYTE(to_push, 2) & 0x38) >> 3) == 7;
if (cruise_engaged && !chrysler_cruise_engaged_last) {
controls_allowed = 1;
Expand All @@ -48,10 +97,33 @@ static int chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
chrysler_cruise_engaged_last = cruise_engaged;
}

// TODO: add gas pressed check
// update speed
if (addr == 514) {
int speed_l = (GET_BYTE(to_push, 0) << 4) + (GET_BYTE(to_push, 1) >> 4);
int speed_r = (GET_BYTE(to_push, 2) << 4) + (GET_BYTE(to_push, 3) >> 4);
chrysler_speed = (speed_l + speed_r) / 2;
}

// exit controls on rising edge of gas press
if (addr == 308) {
bool gas_pressed = (GET_BYTE(to_push, 5) & 0x7F) != 0;
if (gas_pressed && !gas_pressed_prev && (chrysler_speed > CHRYSLER_GAS_THRSLD)) {
controls_allowed = 0;
}
gas_pressed_prev = gas_pressed;
}

// exit controls on rising edge of brake press
if (addr == 320) {
bool brake_pressed = (GET_BYTE(to_push, 0) & 0x7) == 5;
if (brake_pressed && (!brake_pressed_prev || (chrysler_speed > CHRYSLER_STANDSTILL_THRSLD))) {
controls_allowed = 0;
}
brake_pressed_prev = brake_pressed;
}

// check if stock camera ECU is on bus 0
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 0x292)) {
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (addr == 0x292)) {
relay_malfunction = true;
}
}
Expand Down
16 changes: 7 additions & 9 deletions board/safety/safety_ford.h
Expand Up @@ -7,8 +7,6 @@
// brake rising edge
// brake > 0mph

int ford_brake_prev = 0;
int ford_gas_prev = 0;
bool ford_moving = false;

static int ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
Expand Down Expand Up @@ -39,20 +37,20 @@ static int ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
// exit controls on rising edge of brake press or on brake press when
// speed > 0
if (addr == 0x165) {
int brake = GET_BYTE(to_push, 0) & 0x20;
if (brake && (!(ford_brake_prev) || ford_moving)) {
int brake_pressed = GET_BYTE(to_push, 0) & 0x20;
if (brake_pressed && (!brake_pressed_prev || ford_moving)) {
controls_allowed = 0;
}
ford_brake_prev = brake;
brake_pressed_prev = brake_pressed;
}

// exit controls on rising edge of gas press
if (addr == 0x204) {
int gas = (GET_BYTE(to_push, 0) & 0x03) | GET_BYTE(to_push, 1);
if (gas && !(ford_gas_prev)) {
bool gas_pressed = ((GET_BYTE(to_push, 0) & 0x03) | GET_BYTE(to_push, 1)) != 0;
if (gas_pressed && !gas_pressed_prev) {
controls_allowed = 0;
}
ford_gas_prev = gas;
gas_pressed_prev = gas_pressed;
}

if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 0x3CA)) {
Expand All @@ -74,7 +72,7 @@ static int ford_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

// disallow actuator commands if gas or brake (with vehicle moving) are pressed
// and the the latching controls_allowed flag is True
int pedal_pressed = ford_gas_prev || (ford_brake_prev && ford_moving);
int pedal_pressed = gas_pressed_prev || (brake_pressed_prev && ford_moving);
bool current_controls_allowed = controls_allowed && !(pedal_pressed);

if (relay_malfunction) {
Expand Down

0 comments on commit 291dda0

Please sign in to comment.