Skip to content

Commit 4affafc

Browse files
author
Vehicle Researcher
committed
Squashed 'panda/' changes from 3b35621..73a60d5c
73a60d5c uds: clear rx buffer on drain 3b20804b uds: rx message buffering d034f3e Added the option to turn on IR in power savings mode (#431) 82cafd1 Allow fan control in power saving (#429) 186d9dc Fixed GMLAN interrupts when used in Tesla safety (#428) f67ec28 Fix msg checks for non Honda and Toyota (#426) git-subtree-dir: panda git-subtree-split: 73a60d5
1 parent b0b7a76 commit 4affafc

10 files changed

+240
-200
lines changed

board/drivers/gmlan_alt.h

+7-4
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,12 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) {
122122
return len;
123123
}
124124

125+
void TIM4_IRQ_Handler(void);
126+
125127
void setup_timer4(void) {
128+
// register interrupt
129+
REGISTER_INTERRUPT(TIM4_IRQn, TIM4_IRQ_Handler, 40000U, FAULT_INTERRUPT_RATE_GMLAN)
130+
126131
// setup
127132
register_set(&(TIM4->PSC), (48-1), 0xFFFFU); // Tick on 1 us
128133
register_set(&(TIM4->CR1), TIM_CR1_CEN, 0x3FU); // Enable
@@ -236,7 +241,6 @@ void TIM4_IRQ_Handler(void) {
236241
gmlan_sendmax = -1; // exit
237242
}
238243
}
239-
TIM4->SR = 0;
240244
} else if (gmlan_alt_mode == GPIO_SWITCH) {
241245
if ((TIM4->SR & TIM_SR_UIF) && (gmlan_switch_below_timeout != -1)) {
242246
if ((can_timeout_counter == 0) && gmlan_switch_timeout_enable) {
@@ -259,10 +263,10 @@ void TIM4_IRQ_Handler(void) {
259263
}
260264
}
261265
}
262-
TIM4->SR = 0;
263266
} else {
264-
puts("invalid gmlan_alt_mode\n");
267+
// Invalid GMLAN mode. Do not put a print statement here, way too fast to keep up with
265268
}
269+
TIM4->SR = 0;
266270
}
267271

268272
bool bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) {
@@ -280,7 +284,6 @@ bool bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) {
280284
set_gpio_mode(GPIOB, 13, MODE_OUTPUT);
281285

282286
// 33kbps
283-
REGISTER_INTERRUPT(TIM4_IRQn, TIM4_IRQ_Handler, 40000U, FAULT_INTERRUPT_RATE_GMLAN)
284287
setup_timer4();
285288
}
286289
return gmlan_send_ok;

board/main.c

+6-10
Original file line numberDiff line numberDiff line change
@@ -294,19 +294,11 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
294294
break;
295295
// **** 0xb0: set IR power
296296
case 0xb0:
297-
if(power_save_status == POWER_SAVE_STATUS_DISABLED){
298-
current_board->set_ir_power(setup->b.wValue.w);
299-
} else {
300-
puts("Setting IR power not allowed in power saving mode\n");
301-
}
297+
current_board->set_ir_power(setup->b.wValue.w);
302298
break;
303299
// **** 0xb1: set fan power
304300
case 0xb1:
305-
if(power_save_status == POWER_SAVE_STATUS_DISABLED){
306-
current_board->set_fan_power(setup->b.wValue.w);
307-
} else {
308-
puts("Setting fan power not allowed in power saving mode\n");
309-
}
301+
current_board->set_fan_power(setup->b.wValue.w);
310302
break;
311303
// **** 0xb2: get fan rpm
312304
case 0xb2:
@@ -716,6 +708,10 @@ void TIM1_BRK_TIM9_IRQ_Handler(void) {
716708
if (power_save_status != POWER_SAVE_STATUS_ENABLED) {
717709
set_power_save_state(POWER_SAVE_STATUS_ENABLED);
718710
}
711+
712+
// Also disable fan and IR when the heartbeat goes missing
713+
current_board->set_fan_power(0U);
714+
current_board->set_ir_power(0U);
719715
}
720716

721717
// enter CDP mode when car starts to ensure we are charging a turned off EON

board/power_saving.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ void set_power_save_state(int state) {
4949
set_gpio_output(GPIOA, 14, enable);
5050
}
5151

52-
// Switch off IR and fan when in power saving
52+
// Switch off IR when in power saving
5353
if(!enable){
5454
current_board->set_ir_power(0U);
55-
current_board->set_fan_power(0U);
5655
}
5756

5857
power_save_status = state;

board/safety.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -148,20 +148,20 @@ bool addr_safety_check(CAN_FIFOMailBox_TypeDef *to_push,
148148

149149
if (index != -1) {
150150
// checksum check
151-
if ((get_checksum != NULL) && (compute_checksum != NULL)) {
152-
if (rx_checks[index].check_checksum) {
153-
uint8_t checksum = get_checksum(to_push);
154-
uint8_t checksum_comp = compute_checksum(to_push);
155-
rx_checks[index].valid_checksum = checksum_comp == checksum;
156-
}
151+
if ((get_checksum != NULL) && (compute_checksum != NULL) && rx_checks[index].check_checksum) {
152+
uint8_t checksum = get_checksum(to_push);
153+
uint8_t checksum_comp = compute_checksum(to_push);
154+
rx_checks[index].valid_checksum = checksum_comp == checksum;
155+
} else {
156+
rx_checks[index].valid_checksum = true;
157157
}
158158

159-
// counter check
160-
if (get_counter != NULL) {
161-
if (rx_checks[index].max_counter > 0U) {
162-
uint8_t counter = get_counter(to_push);
163-
update_counter(rx_checks, index, counter);
164-
}
159+
// counter check (max_counter == 0 means skip check)
160+
if ((get_counter != NULL) && (rx_checks[index].max_counter > 0U)) {
161+
uint8_t counter = get_counter(to_push);
162+
update_counter(rx_checks, index, counter);
163+
} else {
164+
rx_checks[index].wrong_counters = 0U;
165165
}
166166
}
167167
return is_msg_valid(rx_checks, index);

board/safety/safety_chrysler.h

+28-22
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,42 @@ uint32_t chrysler_ts_last = 0;
2020
struct sample_t chrysler_torque_meas; // last few torques measured
2121

2222
static int chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
23-
int bus = GET_BUS(to_push);
24-
int addr = GET_ADDR(to_push);
2523

26-
// Measured eps torque
27-
if (addr == 544) {
28-
int torque_meas_new = ((GET_BYTE(to_push, 4) & 0x7U) << 8) + GET_BYTE(to_push, 5) - 1024U;
24+
bool valid = addr_safety_check(to_push, chrysler_rx_checks, CHRYSLER_RX_CHECK_LEN,
25+
NULL, NULL, NULL);
2926

30-
// update array of samples
31-
update_sample(&chrysler_torque_meas, torque_meas_new);
32-
}
27+
if (valid) {
28+
int bus = GET_BUS(to_push);
29+
int addr = GET_ADDR(to_push);
30+
31+
// Measured eps torque
32+
if (addr == 544) {
33+
int torque_meas_new = ((GET_BYTE(to_push, 4) & 0x7U) << 8) + GET_BYTE(to_push, 5) - 1024U;
3334

34-
// enter controls on rising edge of ACC, exit controls on ACC off
35-
if (addr == 0x1F4) {
36-
int cruise_engaged = ((GET_BYTE(to_push, 2) & 0x38) >> 3) == 7;
37-
if (cruise_engaged && !chrysler_cruise_engaged_last) {
38-
controls_allowed = 1;
35+
// update array of samples
36+
update_sample(&chrysler_torque_meas, torque_meas_new);
3937
}
40-
if (!cruise_engaged) {
41-
controls_allowed = 0;
38+
39+
// enter controls on rising edge of ACC, exit controls on ACC off
40+
if (addr == 0x1F4) {
41+
int cruise_engaged = ((GET_BYTE(to_push, 2) & 0x38) >> 3) == 7;
42+
if (cruise_engaged && !chrysler_cruise_engaged_last) {
43+
controls_allowed = 1;
44+
}
45+
if (!cruise_engaged) {
46+
controls_allowed = 0;
47+
}
48+
chrysler_cruise_engaged_last = cruise_engaged;
4249
}
43-
chrysler_cruise_engaged_last = cruise_engaged;
44-
}
4550

46-
// TODO: add gas pressed check
51+
// TODO: add gas pressed check
4752

48-
// check if stock camera ECU is on bus 0
49-
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 0x292)) {
50-
relay_malfunction = true;
53+
// check if stock camera ECU is on bus 0
54+
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 0x292)) {
55+
relay_malfunction = true;
56+
}
5157
}
52-
return 1;
58+
return valid;
5359
}
5460

5561
static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

board/safety/safety_gm.h

+66-60
Original file line numberDiff line numberDiff line change
@@ -42,78 +42,84 @@ uint32_t gm_ts_last = 0;
4242
struct sample_t gm_torque_driver; // last few driver torques measured
4343

4444
static int gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
45-
int bus = GET_BUS(to_push);
46-
int addr = GET_ADDR(to_push);
47-
48-
if (addr == 388) {
49-
int torque_driver_new = ((GET_BYTE(to_push, 6) & 0x7) << 8) | GET_BYTE(to_push, 7);
50-
torque_driver_new = to_signed(torque_driver_new, 11);
51-
// update array of samples
52-
update_sample(&gm_torque_driver, torque_driver_new);
53-
}
5445

55-
// sample speed, really only care if car is moving or not
56-
// rear left wheel speed
57-
if (addr == 842) {
58-
gm_moving = GET_BYTE(to_push, 0) | GET_BYTE(to_push, 1);
59-
}
46+
bool valid = addr_safety_check(to_push, gm_rx_checks, GM_RX_CHECK_LEN,
47+
NULL, NULL, NULL);
6048

61-
// ACC steering wheel buttons
62-
if (addr == 481) {
63-
int button = (GET_BYTE(to_push, 5) & 0x70) >> 4;
64-
switch (button) {
65-
case 2: // resume
66-
case 3: // set
67-
controls_allowed = 1;
68-
break;
69-
case 6: // cancel
70-
controls_allowed = 0;
71-
break;
72-
default:
73-
break; // any other button is irrelevant
49+
if (valid) {
50+
int bus = GET_BUS(to_push);
51+
int addr = GET_ADDR(to_push);
52+
53+
if (addr == 388) {
54+
int torque_driver_new = ((GET_BYTE(to_push, 6) & 0x7) << 8) | GET_BYTE(to_push, 7);
55+
torque_driver_new = to_signed(torque_driver_new, 11);
56+
// update array of samples
57+
update_sample(&gm_torque_driver, torque_driver_new);
7458
}
75-
}
7659

77-
// exit controls on rising edge of brake press or on brake press when
78-
// speed > 0
79-
if (addr == 241) {
80-
int brake = GET_BYTE(to_push, 1);
81-
// Brake pedal's potentiometer returns near-zero reading
82-
// even when pedal is not pressed
83-
if (brake < 10) {
84-
brake = 0;
60+
// sample speed, really only care if car is moving or not
61+
// rear left wheel speed
62+
if (addr == 842) {
63+
gm_moving = GET_BYTE(to_push, 0) | GET_BYTE(to_push, 1);
8564
}
86-
if (brake && (!gm_brake_prev || gm_moving)) {
87-
controls_allowed = 0;
65+
66+
// ACC steering wheel buttons
67+
if (addr == 481) {
68+
int button = (GET_BYTE(to_push, 5) & 0x70) >> 4;
69+
switch (button) {
70+
case 2: // resume
71+
case 3: // set
72+
controls_allowed = 1;
73+
break;
74+
case 6: // cancel
75+
controls_allowed = 0;
76+
break;
77+
default:
78+
break; // any other button is irrelevant
79+
}
8880
}
89-
gm_brake_prev = brake;
90-
}
9181

92-
// exit controls on rising edge of gas press
93-
if (addr == 417) {
94-
int gas = GET_BYTE(to_push, 6);
95-
if (gas && !gm_gas_prev) {
96-
controls_allowed = 0;
82+
// exit controls on rising edge of brake press or on brake press when
83+
// speed > 0
84+
if (addr == 241) {
85+
int brake = GET_BYTE(to_push, 1);
86+
// Brake pedal's potentiometer returns near-zero reading
87+
// even when pedal is not pressed
88+
if (brake < 10) {
89+
brake = 0;
90+
}
91+
if (brake && (!gm_brake_prev || gm_moving)) {
92+
controls_allowed = 0;
93+
}
94+
gm_brake_prev = brake;
9795
}
98-
gm_gas_prev = gas;
99-
}
10096

101-
// exit controls on regen paddle
102-
if (addr == 189) {
103-
bool regen = GET_BYTE(to_push, 0) & 0x20;
104-
if (regen) {
105-
controls_allowed = 0;
97+
// exit controls on rising edge of gas press
98+
if (addr == 417) {
99+
int gas = GET_BYTE(to_push, 6);
100+
if (gas && !gm_gas_prev) {
101+
controls_allowed = 0;
102+
}
103+
gm_gas_prev = gas;
106104
}
107-
}
108105

109-
// Check if ASCM or LKA camera are online
110-
// on powertrain bus.
111-
// 384 = ASCMLKASteeringCmd
112-
// 715 = ASCMGasRegenCmd
113-
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && ((addr == 384) || (addr == 715))) {
114-
relay_malfunction = true;
106+
// exit controls on regen paddle
107+
if (addr == 189) {
108+
bool regen = GET_BYTE(to_push, 0) & 0x20;
109+
if (regen) {
110+
controls_allowed = 0;
111+
}
112+
}
113+
114+
// Check if ASCM or LKA camera are online
115+
// on powertrain bus.
116+
// 384 = ASCMLKASteeringCmd
117+
// 715 = ASCMGasRegenCmd
118+
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && ((addr == 384) || (addr == 715))) {
119+
relay_malfunction = true;
120+
}
115121
}
116-
return 1;
122+
return valid;
117123
}
118124

119125
// all commands: gas/regen, friction brake and steering

board/safety/safety_hyundai.h

+28-22
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,41 @@ uint32_t hyundai_ts_last = 0;
2121
struct sample_t hyundai_torque_driver; // last few driver torques measured
2222

2323
static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
24-
int bus = GET_BUS(to_push);
25-
int addr = GET_ADDR(to_push);
2624

27-
if (addr == 897) {
28-
int torque_driver_new = ((GET_BYTES_04(to_push) >> 11) & 0xfff) - 2048;
29-
// update array of samples
30-
update_sample(&hyundai_torque_driver, torque_driver_new);
31-
}
25+
bool valid = addr_safety_check(to_push, hyundai_rx_checks, HYUNDAI_RX_CHECK_LEN,
26+
NULL, NULL, NULL);
27+
28+
if (valid) {
29+
int bus = GET_BUS(to_push);
30+
int addr = GET_ADDR(to_push);
3231

33-
// enter controls on rising edge of ACC, exit controls on ACC off
34-
if (addr == 1057) {
35-
// 2 bits: 13-14
36-
int cruise_engaged = (GET_BYTES_04(to_push) >> 13) & 0x3;
37-
if (cruise_engaged && !hyundai_cruise_engaged_last) {
38-
controls_allowed = 1;
32+
if (addr == 897) {
33+
int torque_driver_new = ((GET_BYTES_04(to_push) >> 11) & 0xfff) - 2048;
34+
// update array of samples
35+
update_sample(&hyundai_torque_driver, torque_driver_new);
3936
}
40-
if (!cruise_engaged) {
41-
controls_allowed = 0;
37+
38+
// enter controls on rising edge of ACC, exit controls on ACC off
39+
if (addr == 1057) {
40+
// 2 bits: 13-14
41+
int cruise_engaged = (GET_BYTES_04(to_push) >> 13) & 0x3;
42+
if (cruise_engaged && !hyundai_cruise_engaged_last) {
43+
controls_allowed = 1;
44+
}
45+
if (!cruise_engaged) {
46+
controls_allowed = 0;
47+
}
48+
hyundai_cruise_engaged_last = cruise_engaged;
4249
}
43-
hyundai_cruise_engaged_last = cruise_engaged;
44-
}
4550

46-
// TODO: check gas pressed
51+
// TODO: check gas pressed
4752

48-
// check if stock camera ECU is on bus 0
49-
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 832)) {
50-
relay_malfunction = true;
53+
// check if stock camera ECU is on bus 0
54+
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == 0) && (addr == 832)) {
55+
relay_malfunction = true;
56+
}
5157
}
52-
return 1;
58+
return valid;
5359
}
5460

5561
static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

0 commit comments

Comments
 (0)