Skip to content

Commit

Permalink
Squashed 'panda/' changes from 769ade0..db94a5b
Browse files Browse the repository at this point in the history
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: db94a5b
  • Loading branch information
Vehicle Researcher committed Feb 27, 2020
1 parent 6b8726e commit d242099
Show file tree
Hide file tree
Showing 22 changed files with 1,304 additions and 383 deletions.
16 changes: 16 additions & 0 deletions board/crc.h
Original file line number Diff line number Diff line change
@@ -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;
}
27 changes: 5 additions & 22 deletions board/pedal/main.c
Original file line number Diff line number Diff line change
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
22 changes: 20 additions & 2 deletions board/safety.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,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,7 +32,8 @@
#define SAFETY_TESLA 10U
#define SAFETY_SUBARU 11U
#define SAFETY_MAZDA 13U
#define SAFETY_VOLKSWAGEN 15U
#define SAFETY_NISSAN 14U
#define SAFETY_VOLKSWAGEN_MQB 15U
#define SAFETY_TOYOTA_IPAS 16U
#define SAFETY_ALLOUTPUT 17U
#define SAFETY_GM_ASCM 18U
Expand All @@ -57,6 +59,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 @@ -185,12 +202,13 @@ const safety_hook_config safety_hook_registry[] = {
{SAFETY_CHRYSLER, &chrysler_hooks},
{SAFETY_SUBARU, &subaru_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
75 changes: 69 additions & 6 deletions board/safety/safety_chrysler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,89 @@ 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 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},
};
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;
bool chrysler_gas_prev = false;
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);
int addr = GET_ADDR(to_push);

// Measured eps torque
if (addr == 544) {
if ((addr == 544) && (bus == 0)) {
int torque_meas_new = ((GET_BYTE(to_push, 4) & 0x7U) << 8) + GET_BYTE(to_push, 5) - 1024U;

// update array of samples
update_sample(&chrysler_torque_meas, torque_meas_new);
}

// enter controls on rising edge of ACC, exit controls on ACC off
if (addr == 0x1F4) {
if ((addr == 500) && (bus == 0)) {
int cruise_engaged = ((GET_BYTE(to_push, 2) & 0x38) >> 3) == 7;
if (cruise_engaged && !chrysler_cruise_engaged_last) {
controls_allowed = 1;
Expand All @@ -48,7 +97,21 @@ 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) && (bus == 0)) {
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) && (bus == 0)) {
bool gas = (GET_BYTE(to_push, 5) & 0x7F) != 0;
if (gas && !chrysler_gas_prev && (chrysler_speed > CHRYSLER_GAS_THRSLD)) {
controls_allowed = 0;
}
chrysler_gas_prev = gas;
}

// check if stock camera ECU is on bus 0
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 0x292)) {
Expand Down
2 changes: 1 addition & 1 deletion board/safety/safety_honda.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static uint8_t honda_compute_checksum(CAN_FIFOMailBox_TypeDef *to_push) {
while (addr > 0U) {
checksum += (addr & 0xFU); addr >>= 4;
}
for (int j = 0; (j < len); j++) {
for (int j = 0; j < len; j++) {
uint8_t byte = GET_BYTE(to_push, j);
checksum += (byte & 0xFU) + (byte >> 4U);
if (j == (len - 1)) {
Expand Down
11 changes: 10 additions & 1 deletion board/safety/safety_hyundai.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const AddrBus HYUNDAI_TX_MSGS[] = {{832, 0}, {1265, 0}};

// TODO: do checksum and counter checks
AddrCheckStruct hyundai_rx_checks[] = {
{.addr = {608}, .bus = 0, .expected_timestep = 10000U},
{.addr = {897}, .bus = 0, .expected_timestep = 10000U},
{.addr = {1057}, .bus = 0, .expected_timestep = 20000U},
};
Expand All @@ -17,6 +18,7 @@ const int HYUNDAI_RX_CHECK_LEN = sizeof(hyundai_rx_checks) / sizeof(hyundai_rx_c
int hyundai_rt_torque_last = 0;
int hyundai_desired_torque_last = 0;
int hyundai_cruise_engaged_last = 0;
bool hyundai_gas_last = false;
uint32_t hyundai_ts_last = 0;
struct sample_t hyundai_torque_driver; // last few driver torques measured

Expand Down Expand Up @@ -48,7 +50,14 @@ static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
hyundai_cruise_engaged_last = cruise_engaged;
}

// TODO: check gas pressed
// exit controls on rising edge of gas press
if ((addr == 608) && (bus == 0)) {
bool gas = (GET_BYTE(to_push, 7) >> 6) != 0;
if (gas && ! hyundai_gas_last) {
controls_allowed = 0;
}
hyundai_gas_last = gas;
}

// check if stock camera ECU is on bus 0
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 832)) {
Expand Down
Loading

0 comments on commit d242099

Please sign in to comment.