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.
187 lines
4.4 KiB
187 lines
4.4 KiB
7 years ago
|
// board enforces
|
||
|
// in-state
|
||
|
// accel set/resume
|
||
|
// out-state
|
||
|
// cancel button
|
||
|
// regen paddle
|
||
|
// accel rising edge
|
||
|
// brake rising edge
|
||
|
// brake > 0mph
|
||
|
|
||
|
// gm_: poor man's namespacing
|
||
|
int gm_brake_prev = 0;
|
||
|
int gm_gas_prev = 0;
|
||
|
int gm_speed = 0;
|
||
|
|
||
|
// silence everything if stock ECUs are still online
|
||
|
int gm_ascm_detected = 0;
|
||
|
|
||
|
static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||
|
|
||
|
uint32_t addr;
|
||
|
if (to_push->RIR & 4) {
|
||
|
// Extended
|
||
|
// Not looked at, but have to be separated
|
||
|
// to avoid address collision
|
||
|
addr = to_push->RIR >> 3;
|
||
|
} else {
|
||
|
// Normal
|
||
|
addr = to_push->RIR >> 21;
|
||
|
}
|
||
|
|
||
|
// sample speed, really only care if car is moving or not
|
||
|
// rear left wheel speed
|
||
|
if (addr == 842) {
|
||
|
gm_speed = to_push->RDLR & 0xFFFF;
|
||
|
}
|
||
|
|
||
|
// check if stock ASCM ECU is still online
|
||
|
int bus_number = (to_push->RDTR >> 4) & 0xFF;
|
||
|
if (bus_number == 0 && addr == 715) {
|
||
|
gm_ascm_detected = 1;
|
||
|
controls_allowed = 0;
|
||
|
}
|
||
|
|
||
|
// ACC steering wheel buttons
|
||
|
if (addr == 481) {
|
||
|
int buttons = (to_push->RDHR >> 12) & 0x7;
|
||
|
// res/set - enable, cancel button - disable
|
||
|
if (buttons == 2 || buttons == 3) {
|
||
|
controls_allowed = 1;
|
||
|
} else if (buttons == 6) {
|
||
|
controls_allowed = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// exit controls on rising edge of brake press or on brake press when
|
||
|
// speed > 0
|
||
|
if (addr == 241) {
|
||
|
int brake = (to_push->RDLR & 0xFF00) >> 8;
|
||
|
// Brake pedal's potentiometer returns near-zero reading
|
||
|
// even when pedal is not pressed
|
||
|
if (brake < 10) {
|
||
|
brake = 0;
|
||
|
}
|
||
|
if (brake && (!gm_brake_prev || gm_speed)) {
|
||
|
controls_allowed = 0;
|
||
|
}
|
||
|
gm_brake_prev = brake;
|
||
|
}
|
||
|
|
||
|
// exit controls on rising edge of gas press
|
||
|
if (addr == 417) {
|
||
|
int gas = to_push->RDHR & 0xFF0000;
|
||
|
if (gas && !gm_gas_prev) {
|
||
|
controls_allowed = 0;
|
||
|
}
|
||
|
gm_gas_prev = gas;
|
||
|
}
|
||
|
|
||
|
// exit controls on regen paddle
|
||
|
if (addr == 189) {
|
||
|
int regen = to_push->RDLR & 0x20;
|
||
|
if (regen) {
|
||
|
controls_allowed = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// all commands: gas/regen, friction brake and steering
|
||
|
// if controls_allowed and no pedals pressed
|
||
|
// allow all commands up to limit
|
||
|
// else
|
||
|
// block all commands that produce actuation
|
||
|
|
||
|
static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||
|
|
||
|
// There can be only one! (ASCM)
|
||
|
if (gm_ascm_detected) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// disallow actuator commands if gas or brake (with vehicle moving) are pressed
|
||
|
// and the the latching controls_allowed flag is True
|
||
|
int pedal_pressed = gm_gas_prev || (gm_brake_prev && gm_speed);
|
||
|
int current_controls_allowed = controls_allowed && !pedal_pressed;
|
||
|
|
||
|
uint32_t addr;
|
||
|
if (to_send->RIR & 4) {
|
||
|
// Extended
|
||
|
addr = to_send->RIR >> 3;
|
||
|
} else {
|
||
|
// Normal
|
||
|
addr = to_send->RIR >> 21;
|
||
|
}
|
||
|
|
||
|
// BRAKE: safety check
|
||
|
if (addr == 789) {
|
||
|
int rdlr = to_send->RDLR;
|
||
|
int brake = ((rdlr & 0xF) << 8) + ((rdlr & 0xFF00) >> 8);
|
||
|
brake = (0x1000 - brake) & 0xFFF;
|
||
|
if (current_controls_allowed) {
|
||
|
if (brake > 255) return 0;
|
||
|
} else {
|
||
|
if (brake != 0) return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// LKA STEER: safety check
|
||
|
if (addr == 384) {
|
||
|
int rdlr = to_send->RDLR;
|
||
|
int steer = ((rdlr & 0x7) << 8) + ((rdlr & 0xFF00) >> 8);
|
||
|
int max_steer = 255;
|
||
|
if (current_controls_allowed) {
|
||
|
// Signed arithmetic
|
||
|
if (steer & 0x400) {
|
||
|
if (steer < (0x800 - max_steer)) return 0;
|
||
|
} else {
|
||
|
if (steer > max_steer) return 0;
|
||
|
}
|
||
|
} else {
|
||
|
if (steer != 0) return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// PARK ASSIST STEER: unlimited torque, no thanks
|
||
|
if (addr == 823) return 0;
|
||
|
|
||
|
// GAS/REGEN: safety check
|
||
|
if (addr == 715) {
|
||
|
int rdlr = to_send->RDLR;
|
||
|
int gas_regen = ((rdlr & 0x7F0000) >> 11) + ((rdlr & 0xF8000000) >> 27);
|
||
|
int apply = rdlr & 1;
|
||
|
if (current_controls_allowed) {
|
||
|
if (gas_regen > 3072) return 0;
|
||
|
} else {
|
||
|
// Disabled message is !engaed with gas
|
||
|
// value that corresponds to max regen.
|
||
|
if (apply || gas_regen != 1404) return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 1 allows the message through
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static int gm_tx_lin_hook(int lin_num, uint8_t *data, int len) {
|
||
|
// LIN is not used in Volt
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static void gm_init(int16_t param) {
|
||
|
controls_allowed = 0;
|
||
|
}
|
||
|
|
||
|
static int gm_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
const safety_hooks gm_hooks = {
|
||
|
.init = gm_init,
|
||
|
.rx = gm_rx_hook,
|
||
|
.tx = gm_tx_hook,
|
||
|
.tx_lin = gm_tx_lin_hook,
|
||
|
.fwd = gm_fwd_hook,
|
||
|
};
|
||
|
|