Line | Branch | Exec | Source |
---|---|---|---|
1 | #pragma once | ||
2 | |||
3 | #include "safety_declarations.h" | ||
4 | |||
5 | static bool nissan_alt_eps = false; | ||
6 | |||
7 | 77436 | static void nissan_rx_hook(const CANPacket_t *to_push) { | |
8 | 77436 | int bus = GET_BUS(to_push); | |
9 | 77436 | int addr = GET_ADDR(to_push); | |
10 | |||
11 |
2/2✓ Branch 0 taken 60526 times.
✓ Branch 1 taken 16910 times.
|
77436 | if (bus == (nissan_alt_eps ? 1 : 0)) { |
12 |
2/2✓ Branch 0 taken 36039 times.
✓ Branch 1 taken 24487 times.
|
60526 | if (addr == 0x2) { |
13 | // Current steering angle | ||
14 | // Factor -0.1, little endian | ||
15 | 36039 | int angle_meas_new = (GET_BYTES(to_push, 0, 4) & 0xFFFFU); | |
16 | // Multiply by -10 to match scale of LKAS angle | ||
17 | 36039 | angle_meas_new = to_signed(angle_meas_new, 16) * -10; | |
18 | |||
19 | // update array of samples | ||
20 | 36039 | update_sample(&angle_meas, angle_meas_new); | |
21 | } | ||
22 | |||
23 |
2/2✓ Branch 0 taken 15972 times.
✓ Branch 1 taken 44554 times.
|
60526 | if (addr == 0x285) { |
24 | // Get current speed and standstill | ||
25 | 15972 | uint16_t right_rear = (GET_BYTE(to_push, 0) << 8) | (GET_BYTE(to_push, 1)); | |
26 | 15972 | uint16_t left_rear = (GET_BYTE(to_push, 2) << 8) | (GET_BYTE(to_push, 3)); | |
27 | 15972 | vehicle_moving = (right_rear | left_rear) != 0U; | |
28 | 15972 | UPDATE_VEHICLE_SPEED((right_rear + left_rear) / 2.0 * 0.005 / 3.6); | |
29 | } | ||
30 | |||
31 | // X-Trail 0x15c, Leaf 0x239 | ||
32 |
4/4✓ Branch 0 taken 60503 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 60478 times.
|
60526 | if ((addr == 0x15c) || (addr == 0x239)) { |
33 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 25 times.
|
48 | if (addr == 0x15c){ |
34 | 23 | gas_pressed = ((GET_BYTE(to_push, 5) << 2) | ((GET_BYTE(to_push, 6) >> 6) & 0x3U)) > 3U; | |
35 | } else { | ||
36 | 25 | gas_pressed = GET_BYTE(to_push, 0) > 3U; | |
37 | } | ||
38 | } | ||
39 | |||
40 | // X-trail 0x454, Leaf 0x239 | ||
41 |
4/4✓ Branch 0 taken 60499 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 60474 times.
|
60526 | if ((addr == 0x454) || (addr == 0x239)) { |
42 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 25 times.
|
52 | if (addr == 0x454){ |
43 | 27 | brake_pressed = (GET_BYTE(to_push, 2) & 0x80U) != 0U; | |
44 | } else { | ||
45 | 25 | brake_pressed = ((GET_BYTE(to_push, 4) >> 5) & 1U) != 0U; | |
46 | } | ||
47 | } | ||
48 | } | ||
49 | |||
50 | // Handle cruise enabled | ||
51 |
6/6✓ Branch 0 taken 30 times.
✓ Branch 1 taken 77406 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 6 times.
|
77436 | if ((addr == 0x30f) && (bus == (nissan_alt_eps ? 1 : 2))) { |
52 | 24 | bool cruise_engaged = (GET_BYTE(to_push, 0) >> 3) & 1U; | |
53 | 24 | pcm_cruise_check(cruise_engaged); | |
54 | } | ||
55 | |||
56 |
4/4✓ Branch 0 taken 9 times.
✓ Branch 1 taken 77427 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 6 times.
|
77436 | generic_rx_checks((addr == 0x169) && (bus == 0)); |
57 | 77436 | } | |
58 | |||
59 | |||
60 | 19614 | static bool nissan_tx_hook(const CANPacket_t *to_send) { | |
61 | const SteeringLimits NISSAN_STEERING_LIMITS = { | ||
62 | .angle_deg_to_can = 100, | ||
63 | .angle_rate_up_lookup = { | ||
64 | {0., 5., 15.}, | ||
65 | {5., .8, .15} | ||
66 | }, | ||
67 | .angle_rate_down_lookup = { | ||
68 | {0., 5., 15.}, | ||
69 | {5., 3.5, .4} | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | 19614 | bool tx = true; | |
74 | 19614 | int addr = GET_ADDR(to_send); | |
75 | 19614 | bool violation = false; | |
76 | |||
77 | // steer cmd checks | ||
78 |
2/2✓ Branch 0 taken 19581 times.
✓ Branch 1 taken 33 times.
|
19614 | if (addr == 0x169) { |
79 | 19581 | int desired_angle = ((GET_BYTE(to_send, 0) << 10) | (GET_BYTE(to_send, 1) << 2) | ((GET_BYTE(to_send, 2) >> 6) & 0x3U)); | |
80 | 19581 | bool lka_active = (GET_BYTE(to_send, 6) >> 4) & 1U; | |
81 | |||
82 | // Factor is -0.01, offset is 1310. Flip to correct sign, but keep units in CAN scale | ||
83 | 19581 | desired_angle = -desired_angle + (1310.0f * NISSAN_STEERING_LIMITS.angle_deg_to_can); | |
84 | |||
85 |
2/2✓ Branch 1 taken 7494 times.
✓ Branch 2 taken 12087 times.
|
19581 | if (steer_angle_cmd_checks(desired_angle, lka_active, NISSAN_STEERING_LIMITS)) { |
86 | 7494 | violation = true; | |
87 | } | ||
88 | } | ||
89 | |||
90 | // acc button check, only allow cancel button to be sent | ||
91 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 19590 times.
|
19614 | if (addr == 0x20b) { |
92 | // Violation of any button other than cancel is pressed | ||
93 | 24 | violation |= ((GET_BYTE(to_send, 1) & 0x3dU) > 0U); | |
94 | } | ||
95 | |||
96 |
2/2✓ Branch 0 taken 7514 times.
✓ Branch 1 taken 12100 times.
|
19614 | if (violation) { |
97 | 7514 | tx = false; | |
98 | } | ||
99 | |||
100 | 19614 | return tx; | |
101 | } | ||
102 | |||
103 | |||
104 | 25344 | static int nissan_fwd_hook(int bus_num, int addr) { | |
105 | 25344 | int bus_fwd = -1; | |
106 | |||
107 |
2/2✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 16896 times.
|
25344 | if (bus_num == 0) { |
108 | 8448 | bool block_msg = (addr == 0x280); // CANCEL_MSG | |
109 |
2/2✓ Branch 0 taken 8445 times.
✓ Branch 1 taken 3 times.
|
8448 | if (!block_msg) { |
110 | 8445 | bus_fwd = 2; // ADAS | |
111 | } | ||
112 | } | ||
113 | |||
114 |
2/2✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 16896 times.
|
25344 | if (bus_num == 2) { |
115 | // 0x169 is LKAS, 0x2b1 LKAS_HUD, 0x4cc LKAS_HUD_INFO_MSG | ||
116 |
6/6✓ Branch 0 taken 8445 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 8442 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 8439 times.
|
8448 | bool block_msg = ((addr == 0x169) || (addr == 0x2b1) || (addr == 0x4cc)); |
117 |
2/2✓ Branch 0 taken 8439 times.
✓ Branch 1 taken 9 times.
|
8448 | if (!block_msg) { |
118 | 8439 | bus_fwd = 0; // V-CAN | |
119 | } | ||
120 | } | ||
121 | |||
122 | 25344 | return bus_fwd; | |
123 | } | ||
124 | |||
125 | 4161 | static safety_config nissan_init(uint16_t param) { | |
126 | static const CanMsg NISSAN_TX_MSGS[] = { | ||
127 | {0x169, 0, 8}, // LKAS | ||
128 | {0x2b1, 0, 8}, // PROPILOT_HUD | ||
129 | {0x4cc, 0, 8}, // PROPILOT_HUD_INFO_MSG | ||
130 | {0x20b, 2, 6}, // CRUISE_THROTTLE (X-Trail) | ||
131 | {0x20b, 1, 6}, // CRUISE_THROTTLE (Altima) | ||
132 | {0x280, 2, 8} // CANCEL_MSG (Leaf) | ||
133 | }; | ||
134 | |||
135 | // Signals duplicated below due to the fact that these messages can come in on either CAN bus, depending on car model. | ||
136 | static RxCheck nissan_rx_checks[] = { | ||
137 | {.msg = {{0x2, 0, 5, .frequency = 100U}, | ||
138 | {0x2, 1, 5, .frequency = 100U}, { 0 }}}, // STEER_ANGLE_SENSOR | ||
139 | {.msg = {{0x285, 0, 8, .frequency = 50U}, | ||
140 | {0x285, 1, 8, .frequency = 50U}, { 0 }}}, // WHEEL_SPEEDS_REAR | ||
141 | {.msg = {{0x30f, 2, 3, .frequency = 10U}, | ||
142 | {0x30f, 1, 3, .frequency = 10U}, { 0 }}}, // CRUISE_STATE | ||
143 | {.msg = {{0x15c, 0, 8, .frequency = 50U}, | ||
144 | {0x15c, 1, 8, .frequency = 50U}, | ||
145 | {0x239, 0, 8, .frequency = 50U}}}, // GAS_PEDAL | ||
146 | {.msg = {{0x454, 0, 8, .frequency = 10U}, | ||
147 | {0x454, 1, 8, .frequency = 10U}, | ||
148 | {0x1cc, 0, 4, .frequency = 100U}}}, // DOORS_LIGHTS / BRAKE | ||
149 | }; | ||
150 | |||
151 | // EPS Location. false = V-CAN, true = C-CAN | ||
152 | 4161 | const int NISSAN_PARAM_ALT_EPS_BUS = 1; | |
153 | |||
154 | 4161 | nissan_alt_eps = GET_FLAG(param, NISSAN_PARAM_ALT_EPS_BUS); | |
155 | 4161 | return BUILD_SAFETY_CFG(nissan_rx_checks, NISSAN_TX_MSGS); | |
156 | } | ||
157 | |||
158 | const safety_hooks nissan_hooks = { | ||
159 | .init = nissan_init, | ||
160 | .rx = nissan_rx_hook, | ||
161 | .tx = nissan_tx_hook, | ||
162 | .fwd = nissan_fwd_hook, | ||
163 | }; | ||
164 |