| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "safety_declarations.h" | ||
| 4 | |||
| 5 | // Stock longitudinal | ||
| 6 | #define TOYOTA_BASE_TX_MSGS \ | ||
| 7 | {0x191, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, /* LKAS + LTA + ACC & PCM cancel cmds */ \ | ||
| 8 | |||
| 9 | #define TOYOTA_COMMON_TX_MSGS \ | ||
| 10 | TOYOTA_BASE_TX_MSGS \ | ||
| 11 | {0x2E4, 0, 5}, \ | ||
| 12 | |||
| 13 | #define TOYOTA_COMMON_SECOC_TX_MSGS \ | ||
| 14 | TOYOTA_BASE_TX_MSGS \ | ||
| 15 | {0x2E4, 0, 8}, {0x131, 0, 8}, \ | ||
| 16 | |||
| 17 | #define TOYOTA_COMMON_LONG_TX_MSGS \ | ||
| 18 | TOYOTA_COMMON_TX_MSGS \ | ||
| 19 | {0x283, 0, 7}, {0x2E6, 0, 8}, {0x2E7, 0, 8}, {0x33E, 0, 7}, {0x344, 0, 8}, {0x365, 0, 7}, {0x366, 0, 7}, {0x4CB, 0, 8}, /* DSU bus 0 */ \ | ||
| 20 | {0x128, 1, 6}, {0x141, 1, 4}, {0x160, 1, 8}, {0x161, 1, 7}, {0x470, 1, 4}, /* DSU bus 1 */ \ | ||
| 21 | {0x411, 0, 8}, /* PCS_HUD */ \ | ||
| 22 | {0x750, 0, 8}, /* radar diagnostic address */ \ | ||
| 23 | |||
| 24 | #define TOYOTA_COMMON_RX_CHECKS(lta) \ | ||
| 25 | {.msg = {{ 0xaa, 0, 8, .check_checksum = false, .frequency = 83U}, { 0 }, { 0 }}}, \ | ||
| 26 | {.msg = {{0x260, 0, 8, .check_checksum = true, .quality_flag = (lta), .frequency = 50U}, { 0 }, { 0 }}}, \ | ||
| 27 | {.msg = {{0x1D2, 0, 8, .check_checksum = true, .frequency = 33U}, \ | ||
| 28 | {0x176, 0, 8, .check_checksum = true, .frequency = 32U}, { 0 }}}, \ | ||
| 29 | {.msg = {{0x101, 0, 8, .check_checksum = false, .frequency = 50U}, \ | ||
| 30 | {0x224, 0, 8, .check_checksum = false, .frequency = 40U}, \ | ||
| 31 | {0x226, 0, 8, .check_checksum = false, .frequency = 40U}}}, \ | ||
| 32 | |||
| 33 | static bool toyota_secoc = false; | ||
| 34 | static bool toyota_alt_brake = false; | ||
| 35 | static bool toyota_stock_longitudinal = false; | ||
| 36 | static bool toyota_lta = false; | ||
| 37 | static int toyota_dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file | ||
| 38 | |||
| 39 | 126826 | static uint32_t toyota_compute_checksum(const CANPacket_t *to_push) { | |
| 40 | 126826 | int addr = GET_ADDR(to_push); | |
| 41 | 126826 | int len = GET_LEN(to_push); | |
| 42 | 126826 | uint8_t checksum = (uint8_t)(addr) + (uint8_t)((unsigned int)(addr) >> 8U) + (uint8_t)(len); | |
| 43 |
2/2✓ Branch 0 taken 887782 times.
✓ Branch 1 taken 126826 times.
|
1014608 | for (int i = 0; i < (len - 1); i++) { |
| 44 | 887782 | checksum += (uint8_t)GET_BYTE(to_push, i); | |
| 45 | } | ||
| 46 | 126826 | return checksum; | |
| 47 | } | ||
| 48 | |||
| 49 | 126826 | static uint32_t toyota_get_checksum(const CANPacket_t *to_push) { | |
| 50 | 126826 | int checksum_byte = GET_LEN(to_push) - 1U; | |
| 51 | 126826 | return (uint8_t)(GET_BYTE(to_push, checksum_byte)); | |
| 52 | } | ||
| 53 | |||
| 54 | 126662 | static bool toyota_get_quality_flag_valid(const CANPacket_t *to_push) { | |
| 55 | 126662 | int addr = GET_ADDR(to_push); | |
| 56 | |||
| 57 | 126662 | bool valid = false; | |
| 58 |
1/2✓ Branch 0 taken 126662 times.
✗ Branch 1 not taken.
|
126662 | if (addr == 0x260) { |
| 59 | 126662 | valid = !GET_BIT(to_push, 3U); // STEER_ANGLE_INITIALIZING | |
| 60 | } | ||
| 61 | 126662 | return valid; | |
| 62 | } | ||
| 63 | |||
| 64 | 180050 | static void toyota_rx_hook(const CANPacket_t *to_push) { | |
| 65 | 180050 | const int TOYOTA_LTA_MAX_ANGLE = 1657; // EPS only accepts up to 94.9461 | |
| 66 | |||
| 67 |
2/2✓ Branch 0 taken 146258 times.
✓ Branch 1 taken 33792 times.
|
180050 | if (GET_BUS(to_push) == 0U) { |
| 68 | 146258 | int addr = GET_ADDR(to_push); | |
| 69 | |||
| 70 | // get eps motor torque (0.66 factor in dbc) | ||
| 71 |
2/2✓ Branch 0 taken 124424 times.
✓ Branch 1 taken 21834 times.
|
146258 | if (addr == 0x260) { |
| 72 | 124424 | int torque_meas_new = (GET_BYTE(to_push, 5) << 8) | GET_BYTE(to_push, 6); | |
| 73 | 124424 | torque_meas_new = to_signed(torque_meas_new, 16); | |
| 74 | |||
| 75 | // scale by dbc_factor | ||
| 76 | 124424 | torque_meas_new = (torque_meas_new * toyota_dbc_eps_torque_factor) / 100; | |
| 77 | |||
| 78 | // update array of sample | ||
| 79 | 124424 | update_sample(&torque_meas, torque_meas_new); | |
| 80 | |||
| 81 | // increase torque_meas by 1 to be conservative on rounding | ||
| 82 | 124424 | torque_meas.min--; | |
| 83 | 124424 | torque_meas.max++; | |
| 84 | |||
| 85 | // driver torque for angle limiting | ||
| 86 | 124424 | int torque_driver_new = (GET_BYTE(to_push, 1) << 8) | GET_BYTE(to_push, 2); | |
| 87 | 124424 | torque_driver_new = to_signed(torque_driver_new, 16); | |
| 88 | 124424 | update_sample(&torque_driver, torque_driver_new); | |
| 89 | |||
| 90 | // LTA request angle should match current angle while inactive, clipped to max accepted angle. | ||
| 91 | // note that angle can be relative to init angle on some TSS2 platforms, LTA has the same offset | ||
| 92 | 124424 | bool steer_angle_initializing = GET_BIT(to_push, 3U); | |
| 93 |
1/2✓ Branch 0 taken 124424 times.
✗ Branch 1 not taken.
|
124424 | if (!steer_angle_initializing) { |
| 94 | 124424 | int angle_meas_new = (GET_BYTE(to_push, 3) << 8U) | GET_BYTE(to_push, 4); | |
| 95 |
2/2✓ Branch 1 taken 124234 times.
✓ Branch 2 taken 190 times.
|
124424 | angle_meas_new = CLAMP(to_signed(angle_meas_new, 16), -TOYOTA_LTA_MAX_ANGLE, TOYOTA_LTA_MAX_ANGLE); |
| 96 | 124424 | update_sample(&angle_meas, angle_meas_new); | |
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | // enter controls on rising edge of ACC, exit controls on ACC off | ||
| 101 | // exit controls on rising edge of gas press, if not alternative experience | ||
| 102 | // exit controls on rising edge of brake press | ||
| 103 |
2/2✓ Branch 0 taken 2852 times.
✓ Branch 1 taken 143406 times.
|
146258 | if (toyota_secoc) { |
| 104 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2844 times.
|
2852 | if (addr == 0x176) { |
| 105 | 8 | bool cruise_engaged = GET_BIT(to_push, 5U); // PCM_CRUISE.CRUISE_ACTIVE | |
| 106 | 8 | pcm_cruise_check(cruise_engaged); | |
| 107 | } | ||
| 108 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2841 times.
|
2852 | if (addr == 0x116) { |
| 109 | 11 | gas_pressed = GET_BYTE(to_push, 1) != 0U; // GAS_PEDAL.GAS_PEDAL_USER | |
| 110 | } | ||
| 111 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2839 times.
|
2852 | if (addr == 0x101) { |
| 112 | 13 | brake_pressed = GET_BIT(to_push, 3U); // BRAKE_MODULE.BRAKE_PRESSED (toyota_rav4_prime_generated.dbc) | |
| 113 | } | ||
| 114 | } else { | ||
| 115 |
2/2✓ Branch 0 taken 95 times.
✓ Branch 1 taken 143311 times.
|
143406 | if (addr == 0x1D2) { |
| 116 | 95 | bool cruise_engaged = GET_BIT(to_push, 5U); // PCM_CRUISE.CRUISE_ACTIVE | |
| 117 | 95 | pcm_cruise_check(cruise_engaged); | |
| 118 | 95 | gas_pressed = !GET_BIT(to_push, 4U); // PCM_CRUISE.GAS_RELEASED | |
| 119 | } | ||
| 120 |
4/4✓ Branch 0 taken 140540 times.
✓ Branch 1 taken 2866 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 140488 times.
|
143406 | if (!toyota_alt_brake && (addr == 0x226)) { |
| 121 | 52 | brake_pressed = GET_BIT(to_push, 37U); // BRAKE_MODULE.BRAKE_PRESSED (toyota_nodsu_pt_generated.dbc) | |
| 122 | } | ||
| 123 |
4/4✓ Branch 0 taken 2866 times.
✓ Branch 1 taken 140540 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 2853 times.
|
143406 | if (toyota_alt_brake && (addr == 0x224)) { |
| 124 | 13 | brake_pressed = GET_BIT(to_push, 5U); // BRAKE_MODULE.BRAKE_PRESSED (toyota_new_mc_pt_generated.dbc) | |
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | // sample speed | ||
| 129 |
2/2✓ Branch 0 taken 4776 times.
✓ Branch 1 taken 141482 times.
|
146258 | if (addr == 0xaa) { |
| 130 | 4776 | int speed = 0; | |
| 131 | // sum 4 wheel speeds. conversion: raw * 0.01 - 67.67 | ||
| 132 |
2/2✓ Branch 0 taken 19104 times.
✓ Branch 1 taken 4776 times.
|
23880 | for (uint8_t i = 0U; i < 8U; i += 2U) { |
| 133 | 19104 | int wheel_speed = (GET_BYTE(to_push, i) << 8U) | GET_BYTE(to_push, (i + 1U)); | |
| 134 | 19104 | speed += wheel_speed - 6767; | |
| 135 | } | ||
| 136 | // check that all wheel speeds are at zero value | ||
| 137 | 4776 | vehicle_moving = speed != 0; | |
| 138 | |||
| 139 | 4776 | UPDATE_VEHICLE_SPEED(speed / 4.0 * 0.01 / 3.6); | |
| 140 | } | ||
| 141 | |||
| 142 | 146258 | bool stock_ecu_detected = addr == 0x2E4; // STEERING_LKA | |
| 143 |
4/4✓ Branch 0 taken 73136 times.
✓ Branch 1 taken 73122 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 73133 times.
|
146258 | if (!toyota_stock_longitudinal && (addr == 0x343)) { |
| 144 | 3 | stock_ecu_detected = true; // ACC_CONTROL | |
| 145 | } | ||
| 146 | 146258 | generic_rx_checks(stock_ecu_detected); | |
| 147 | } | ||
| 148 | 180050 | } | |
| 149 | |||
| 150 | 109153 | static bool toyota_tx_hook(const CANPacket_t *to_send) { | |
| 151 | const SteeringLimits TOYOTA_STEERING_LIMITS = { | ||
| 152 | .max_steer = 1500, | ||
| 153 | .max_rate_up = 15, // ramp up slow | ||
| 154 | .max_rate_down = 25, // ramp down fast | ||
| 155 | .max_torque_error = 350, // max torque cmd in excess of motor torque | ||
| 156 | .max_rt_delta = 450, // the real time limit is 1800/sec, a 20% buffer | ||
| 157 | .max_rt_interval = 250000, | ||
| 158 | .type = TorqueMotorLimited, | ||
| 159 | |||
| 160 | // the EPS faults when the steering angle rate is above a certain threshold for too long. to prevent this, | ||
| 161 | // we allow setting STEER_REQUEST bit to 0 while maintaining the requested torque value for a single frame | ||
| 162 | .min_valid_request_frames = 18, | ||
| 163 | .max_invalid_request_frames = 1, | ||
| 164 | .min_valid_request_rt_interval = 170000, // 170ms; a ~10% buffer on cutting every 19 frames | ||
| 165 | .has_steer_req_tolerance = true, | ||
| 166 | |||
| 167 | // LTA angle limits | ||
| 168 | // factor for STEER_TORQUE_SENSOR->STEER_ANGLE and STEERING_LTA->STEER_ANGLE_CMD (1 / 0.0573) | ||
| 169 | .angle_deg_to_can = 17.452007, | ||
| 170 | .angle_rate_up_lookup = { | ||
| 171 | {5., 25., 25.}, | ||
| 172 | {0.3, 0.15, 0.15} | ||
| 173 | }, | ||
| 174 | .angle_rate_down_lookup = { | ||
| 175 | {5., 25., 25.}, | ||
| 176 | {0.36, 0.26, 0.26} | ||
| 177 | }, | ||
| 178 | }; | ||
| 179 | |||
| 180 | 109153 | const int TOYOTA_LTA_MAX_MEAS_TORQUE = 1500; | |
| 181 | 109153 | const int TOYOTA_LTA_MAX_DRIVER_TORQUE = 150; | |
| 182 | |||
| 183 | // longitudinal limits | ||
| 184 | const LongitudinalLimits TOYOTA_LONG_LIMITS = { | ||
| 185 | .max_accel = 2000, // 2.0 m/s2 | ||
| 186 | .min_accel = -3500, // -3.5 m/s2 | ||
| 187 | }; | ||
| 188 | |||
| 189 | 109153 | bool tx = true; | |
| 190 | 109153 | int addr = GET_ADDR(to_send); | |
| 191 | 109153 | int bus = GET_BUS(to_send); | |
| 192 | |||
| 193 | // Check if msg is sent on BUS 0 | ||
| 194 |
2/2✓ Branch 0 taken 109150 times.
✓ Branch 1 taken 3 times.
|
109153 | if (bus == 0) { |
| 195 | // ACCEL: safety check on byte 1-2 | ||
| 196 |
2/2✓ Branch 0 taken 4554 times.
✓ Branch 1 taken 104596 times.
|
109150 | if (addr == 0x343) { |
| 197 | 4554 | int desired_accel = (GET_BYTE(to_send, 0) << 8) | GET_BYTE(to_send, 1); | |
| 198 | 4554 | desired_accel = to_signed(desired_accel, 16); | |
| 199 | |||
| 200 | 4554 | bool violation = false; | |
| 201 | 4554 | violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS); | |
| 202 | |||
| 203 | // only ACC messages that cancel are allowed when openpilot is not controlling longitudinal | ||
| 204 |
2/2✓ Branch 0 taken 2727 times.
✓ Branch 1 taken 1827 times.
|
4554 | if (toyota_stock_longitudinal) { |
| 205 | 2727 | bool cancel_req = GET_BIT(to_send, 24U); | |
| 206 |
2/2✓ Branch 0 taken 2277 times.
✓ Branch 1 taken 450 times.
|
2727 | if (!cancel_req) { |
| 207 | 2277 | violation = true; | |
| 208 | } | ||
| 209 |
2/2✓ Branch 0 taken 2676 times.
✓ Branch 1 taken 51 times.
|
2727 | if (desired_accel != TOYOTA_LONG_LIMITS.inactive_accel) { |
| 210 | 2676 | violation = true; | |
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 |
2/2✓ Branch 0 taken 3849 times.
✓ Branch 1 taken 705 times.
|
4554 | if (violation) { |
| 215 | 3849 | tx = false; | |
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | // AEB: block all actuation. only used when DSU is unplugged | ||
| 220 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 109030 times.
|
109150 | if (addr == 0x283) { |
| 221 | // only allow the checksum, which is the last byte | ||
| 222 |
4/6✓ Branch 1 taken 60 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 60 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 60 times.
|
120 | bool block = (GET_BYTES(to_send, 0, 4) != 0U) || (GET_BYTE(to_send, 4) != 0U) || (GET_BYTE(to_send, 5) != 0U); |
| 223 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 60 times.
|
120 | if (block) { |
| 224 | 60 | tx = false; | |
| 225 | } | ||
| 226 | } | ||
| 227 | |||
| 228 | // STEERING_LTA angle steering check | ||
| 229 |
2/2✓ Branch 0 taken 51890 times.
✓ Branch 1 taken 57260 times.
|
109150 | if (addr == 0x191) { |
| 230 | // check the STEER_REQUEST, STEER_REQUEST_2, TORQUE_WIND_DOWN, STEER_ANGLE_CMD signals | ||
| 231 | 51890 | bool lta_request = GET_BIT(to_send, 0U); | |
| 232 | 51890 | bool lta_request2 = GET_BIT(to_send, 25U); | |
| 233 | 51890 | int torque_wind_down = GET_BYTE(to_send, 5); | |
| 234 | 51890 | int lta_angle = (GET_BYTE(to_send, 1) << 8) | GET_BYTE(to_send, 2); | |
| 235 | 51890 | lta_angle = to_signed(lta_angle, 16); | |
| 236 | |||
| 237 |
4/4✓ Branch 0 taken 7138 times.
✓ Branch 1 taken 44752 times.
✓ Branch 2 taken 2250 times.
✓ Branch 3 taken 4888 times.
|
51890 | bool steer_control_enabled = lta_request || lta_request2; |
| 238 |
2/2✓ Branch 0 taken 364 times.
✓ Branch 1 taken 51526 times.
|
51890 | if (!toyota_lta) { |
| 239 | // using torque (LKA), block LTA msgs with actuation requests | ||
| 240 |
6/6✓ Branch 0 taken 94 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 10 times.
|
364 | if (steer_control_enabled || (lta_angle != 0) || (torque_wind_down != 0)) { |
| 241 | 354 | tx = false; | |
| 242 | } | ||
| 243 | } else { | ||
| 244 | // check angle rate limits and inactive angle | ||
| 245 |
2/2✓ Branch 1 taken 6266 times.
✓ Branch 2 taken 45260 times.
|
51526 | if (steer_angle_cmd_checks(lta_angle, steer_control_enabled, TOYOTA_STEERING_LIMITS)) { |
| 246 | 6266 | tx = false; | |
| 247 | } | ||
| 248 | |||
| 249 |
2/2✓ Branch 0 taken 4320 times.
✓ Branch 1 taken 47206 times.
|
51526 | if (lta_request != lta_request2) { |
| 250 | 4320 | tx = false; | |
| 251 | } | ||
| 252 | |||
| 253 | // TORQUE_WIND_DOWN is gated on steer request | ||
| 254 |
4/4✓ Branch 0 taken 4794 times.
✓ Branch 1 taken 46732 times.
✓ Branch 2 taken 1440 times.
✓ Branch 3 taken 3354 times.
|
51526 | if (!steer_control_enabled && (torque_wind_down != 0)) { |
| 255 | 1440 | tx = false; | |
| 256 | } | ||
| 257 | |||
| 258 | // TORQUE_WIND_DOWN can only be no or full torque | ||
| 259 |
4/4✓ Branch 0 taken 28012 times.
✓ Branch 1 taken 23514 times.
✓ Branch 2 taken 2880 times.
✓ Branch 3 taken 25132 times.
|
51526 | if ((torque_wind_down != 0) && (torque_wind_down != 100)) { |
| 260 | 2880 | tx = false; | |
| 261 | } | ||
| 262 | |||
| 263 | // check if we should wind down torque | ||
| 264 | 51526 | int driver_torque = MIN(ABS(torque_driver.min), ABS(torque_driver.max)); | |
| 265 |
4/4✓ Branch 0 taken 14400 times.
✓ Branch 1 taken 37126 times.
✓ Branch 2 taken 7200 times.
✓ Branch 3 taken 7200 times.
|
51526 | if ((driver_torque > TOYOTA_LTA_MAX_DRIVER_TORQUE) && (torque_wind_down != 0)) { |
| 266 | 7200 | tx = false; | |
| 267 | } | ||
| 268 | |||
| 269 | 51526 | int eps_torque = MIN(ABS(torque_meas.min), ABS(torque_meas.max)); | |
| 270 |
4/4✓ Branch 0 taken 7200 times.
✓ Branch 1 taken 44326 times.
✓ Branch 2 taken 3600 times.
✓ Branch 3 taken 3600 times.
|
51526 | if ((eps_torque > TOYOTA_LTA_MAX_MEAS_TORQUE) && (torque_wind_down != 0)) { |
| 271 | 3600 | tx = false; | |
| 272 | } | ||
| 273 | } | ||
| 274 | } | ||
| 275 | |||
| 276 | // STEERING_LTA_2 angle steering check (SecOC) | ||
| 277 |
4/4✓ Branch 0 taken 1074 times.
✓ Branch 1 taken 108076 times.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 1033 times.
|
109150 | if (toyota_secoc && (addr == 0x131)) { |
| 278 | // SecOC cars block any form of LTA actuation for now | ||
| 279 | 41 | bool lta_request = GET_BIT(to_send, 3U); // STEERING_LTA_2.STEER_REQUEST | |
| 280 | 41 | bool lta_request2 = GET_BIT(to_send, 0U); // STEERING_LTA_2.STEER_REQUEST_2 | |
| 281 | 41 | int lta_angle_msb = GET_BYTE(to_send, 2); // STEERING_LTA_2.STEER_ANGLE_CMD (MSB) | |
| 282 | 41 | int lta_angle_lsb = GET_BYTE(to_send, 3); // STEERING_LTA_2.STEER_ANGLE_CMD (LSB) | |
| 283 | |||
| 284 |
8/8✓ Branch 0 taken 21 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 3 times.
|
41 | bool actuation = lta_request || lta_request2 || (lta_angle_msb != 0) || (lta_angle_lsb != 0); |
| 285 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 3 times.
|
41 | if (actuation) { |
| 286 | 38 | tx = false; | |
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | // STEER: safety check on bytes 2-3 | ||
| 291 |
2/2✓ Branch 0 taken 52503 times.
✓ Branch 1 taken 56647 times.
|
109150 | if (addr == 0x2E4) { |
| 292 | 52503 | int desired_torque = (GET_BYTE(to_send, 1) << 8) | GET_BYTE(to_send, 2); | |
| 293 | 52503 | desired_torque = to_signed(desired_torque, 16); | |
| 294 | 52503 | bool steer_req = GET_BIT(to_send, 0U); | |
| 295 | // When using LTA (angle control), assert no actuation on LKA message | ||
| 296 |
2/2✓ Branch 0 taken 52447 times.
✓ Branch 1 taken 56 times.
|
52503 | if (!toyota_lta) { |
| 297 |
2/2✓ Branch 1 taken 33486 times.
✓ Branch 2 taken 18961 times.
|
52447 | if (steer_torque_cmd_checks(desired_torque, steer_req, TOYOTA_STEERING_LIMITS)) { |
| 298 | 33486 | tx = false; | |
| 299 | } | ||
| 300 | } else { | ||
| 301 |
4/4✓ Branch 0 taken 8 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
|
56 | if ((desired_torque != 0) || steer_req) { |
| 302 | 52 | tx = false; | |
| 303 | } | ||
| 304 | } | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | // UDS: Only tester present ("\x0F\x02\x3E\x00\x00\x00\x00\x00") allowed on diagnostics address | ||
| 309 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 109138 times.
|
109153 | if (addr == 0x750) { |
| 310 | // this address is sub-addressed. only allow tester present to radar (0xF) | ||
| 311 |
3/4✓ Branch 1 taken 3 times.
✓ Branch 2 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
|
15 | bool invalid_uds_msg = (GET_BYTES(to_send, 0, 4) != 0x003E020FU) || (GET_BYTES(to_send, 4, 4) != 0x0U); |
| 312 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
|
15 | if (invalid_uds_msg) { |
| 313 | 12 | tx = 0; | |
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | 109153 | return tx; | |
| 318 | } | ||
| 319 | |||
| 320 | 1299 | static safety_config toyota_init(uint16_t param) { | |
| 321 | static const CanMsg TOYOTA_TX_MSGS[] = { | ||
| 322 | TOYOTA_COMMON_TX_MSGS | ||
| 323 | }; | ||
| 324 | |||
| 325 | static const CanMsg TOYOTA_SECOC_TX_MSGS[] = { | ||
| 326 | TOYOTA_COMMON_SECOC_TX_MSGS | ||
| 327 | }; | ||
| 328 | |||
| 329 | static const CanMsg TOYOTA_LONG_TX_MSGS[] = { | ||
| 330 | TOYOTA_COMMON_LONG_TX_MSGS | ||
| 331 | }; | ||
| 332 | |||
| 333 | // safety param flags | ||
| 334 | // first byte is for EPS factor, second is for flags | ||
| 335 | 1299 | const uint32_t TOYOTA_PARAM_OFFSET = 8U; | |
| 336 | 1299 | const uint32_t TOYOTA_EPS_FACTOR = (1UL << TOYOTA_PARAM_OFFSET) - 1U; | |
| 337 | 1299 | const uint32_t TOYOTA_PARAM_ALT_BRAKE = 1UL << TOYOTA_PARAM_OFFSET; | |
| 338 | 1299 | const uint32_t TOYOTA_PARAM_STOCK_LONGITUDINAL = 2UL << TOYOTA_PARAM_OFFSET; | |
| 339 | 1299 | const uint32_t TOYOTA_PARAM_LTA = 4UL << TOYOTA_PARAM_OFFSET; | |
| 340 | |||
| 341 | #ifdef ALLOW_DEBUG | ||
| 342 | 1299 | const uint32_t TOYOTA_PARAM_SECOC = 8UL << TOYOTA_PARAM_OFFSET; | |
| 343 | 1299 | toyota_secoc = GET_FLAG(param, TOYOTA_PARAM_SECOC); | |
| 344 | #endif | ||
| 345 | |||
| 346 | 1299 | toyota_alt_brake = GET_FLAG(param, TOYOTA_PARAM_ALT_BRAKE); | |
| 347 | 1299 | toyota_stock_longitudinal = GET_FLAG(param, TOYOTA_PARAM_STOCK_LONGITUDINAL); | |
| 348 | 1299 | toyota_lta = GET_FLAG(param, TOYOTA_PARAM_LTA); | |
| 349 | 1299 | toyota_dbc_eps_torque_factor = param & TOYOTA_EPS_FACTOR; | |
| 350 | |||
| 351 | safety_config ret; | ||
| 352 |
2/2✓ Branch 0 taken 645 times.
✓ Branch 1 taken 654 times.
|
1299 | if (toyota_stock_longitudinal) { |
| 353 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 615 times.
|
645 | if (toyota_secoc) { |
| 354 | 30 | SET_TX_MSGS(TOYOTA_SECOC_TX_MSGS, ret); | |
| 355 | } else { | ||
| 356 | 615 | SET_TX_MSGS(TOYOTA_TX_MSGS, ret); | |
| 357 | } | ||
| 358 | } else { | ||
| 359 | 654 | SET_TX_MSGS(TOYOTA_LONG_TX_MSGS, ret); | |
| 360 | } | ||
| 361 | |||
| 362 |
2/2✓ Branch 0 taken 1145 times.
✓ Branch 1 taken 154 times.
|
1299 | if (toyota_lta) { |
| 363 | // Check the quality flag for angle measurement when using LTA, since it's not set on TSS-P cars | ||
| 364 | static RxCheck toyota_lta_rx_checks[] = { | ||
| 365 | TOYOTA_COMMON_RX_CHECKS(true) | ||
| 366 | }; | ||
| 367 | |||
| 368 | 1145 | SET_RX_CHECKS(toyota_lta_rx_checks, ret); | |
| 369 | } else { | ||
| 370 | static RxCheck toyota_lka_rx_checks[] = { | ||
| 371 | TOYOTA_COMMON_RX_CHECKS(false) | ||
| 372 | }; | ||
| 373 | |||
| 374 | 154 | SET_RX_CHECKS(toyota_lka_rx_checks, ret); | |
| 375 | } | ||
| 376 | |||
| 377 | 1299 | return ret; | |
| 378 | } | ||
| 379 | |||
| 380 | 50688 | static int toyota_fwd_hook(int bus_num, int addr) { | |
| 381 | |||
| 382 | 50688 | int bus_fwd = -1; | |
| 383 | |||
| 384 |
2/2✓ Branch 0 taken 16896 times.
✓ Branch 1 taken 33792 times.
|
50688 | if (bus_num == 0) { |
| 385 | 16896 | bus_fwd = 2; | |
| 386 | } | ||
| 387 | |||
| 388 |
2/2✓ Branch 0 taken 16896 times.
✓ Branch 1 taken 33792 times.
|
50688 | if (bus_num == 2) { |
| 389 | // block stock lkas messages and stock acc messages (if OP is doing ACC) | ||
| 390 | // in TSS2, 0x191 is LTA which we need to block to avoid controls collision | ||
| 391 |
6/6✓ Branch 0 taken 16890 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 16884 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 16878 times.
|
16896 | bool is_lkas_msg = ((addr == 0x2E4) || (addr == 0x412) || (addr == 0x191)); |
| 392 | // on SecOC cars 0x131 is also LTA | ||
| 393 |
4/4✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 14080 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2815 times.
|
16896 | is_lkas_msg |= toyota_secoc && (addr == 0x131); |
| 394 | // in TSS2 the camera does ACC as well, so filter 0x343 | ||
| 395 | 16896 | bool is_acc_msg = (addr == 0x343); | |
| 396 |
6/6✓ Branch 0 taken 16877 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 16871 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
|
16896 | bool block_msg = is_lkas_msg || (is_acc_msg && !toyota_stock_longitudinal); |
| 397 |
2/2✓ Branch 0 taken 16874 times.
✓ Branch 1 taken 22 times.
|
16896 | if (!block_msg) { |
| 398 | 16874 | bus_fwd = 0; | |
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | 50688 | return bus_fwd; | |
| 403 | } | ||
| 404 | |||
| 405 | const safety_hooks toyota_hooks = { | ||
| 406 | .init = toyota_init, | ||
| 407 | .rx = toyota_rx_hook, | ||
| 408 | .tx = toyota_tx_hook, | ||
| 409 | .fwd = toyota_fwd_hook, | ||
| 410 | .get_checksum = toyota_get_checksum, | ||
| 411 | .compute_checksum = toyota_compute_checksum, | ||
| 412 | .get_quality_flag_valid = toyota_get_quality_flag_valid, | ||
| 413 | }; | ||
| 414 |