Skip to content

Commit

Permalink
Merge branch 'master' into safety_mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime-desroches committed Sep 26, 2024
2 parents f0f6a30 + fb67bda commit 00556ab
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 53 deletions.
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
apt clean && \
cd /usr/lib/gcc/arm-none-eabi/* && \
rm -rf arm/ && \
rm -rf thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp
rm -rf thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp && \
apt-get update && apt-get install -y clang-17 && \
ln -s $(which clang-17) /usr/bin/clang

RUN apt-get update && apt-get install -y curl clang-17 && \
curl -1sLf 'https://dl.cloudsmith.io/public/mull-project/mull-stable/setup.deb.sh' | bash && \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ In addition, we run the [ruff linter](https://github.com/astral-sh/ruff) and [my
Setup dependencies:
```bash
# Ubuntu
sudo apt-get install dfu-util gcc-arm-none-eabi python3-pip libffi-dev git
sudo apt-get install dfu-util gcc-arm-none-eabi python3-pip libffi-dev git clang-17

# macOS
brew install --cask gcc-arm-embedded
Expand Down
15 changes: 12 additions & 3 deletions board/flash.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
#!/usr/bin/env python3
import os
import subprocess
import argparse

from panda import Panda

board_path = os.path.dirname(os.path.realpath(__file__))

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--all", action="store_true", help="Recover all Panda devices")
args = parser.parse_args()

subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)

serials = Panda.list()
print(f"found {len(serials)} panda(s) - {serials}")
if args.all:
serials = Panda.list()
print(f"found {len(serials)} panda(s) - {serials}")
else:
serials = [None]

for s in serials:
print("flashing", s)
with Panda(serial=s) as p:
print("flashing", p.get_usb_serial())
p.flash()
exit(1 if len(serials) == 0 else 0)
16 changes: 12 additions & 4 deletions board/jungle/flash.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
#!/usr/bin/env python3
import os
import subprocess
import argparse

from panda import PandaJungle

board_path = os.path.dirname(os.path.realpath(__file__))

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--all", action="store_true", help="Recover all panda jungle devices")
args = parser.parse_args()

subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) {board_path}", shell=True)

serials = PandaJungle.list()
print(f"found {len(serials)} panda jungle(s) - {serials}")
if args.all:
serials = PandaJungle.list()
print(f"found {len(serials)} panda jungles(s) - {serials}")
else:
serials = [None]

for s in serials:
print("flashing", s)
with PandaJungle(serial=s) as p:
print("flashing", p.get_usb_serial())
p.flash()

exit(1 if len(serials) == 0 else 0)
10 changes: 8 additions & 2 deletions board/jungle/recover.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@
import os
import time
import subprocess
import argparse

from panda import PandaJungle, PandaJungleDFU

board_path = os.path.dirname(os.path.realpath(__file__))

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--all", action="store_true", help="Recover all panda jungle devices")
args = parser.parse_args()

subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) {board_path}", shell=True)

for s in PandaJungle.list():
print("putting", s, "in DFU mode")
serials = PandaJungle.list() if args.all else [None]
for s in serials:
with PandaJungle(serial=s) as p:
print(f"putting {p.get_usb_serial()} in DFU mode")
p.reset(enter_bootstub=True)
p.reset(enter_bootloader=True)

Expand Down
10 changes: 8 additions & 2 deletions board/recover.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@
import os
import time
import subprocess
import argparse

from panda import Panda, PandaDFU

board_path = os.path.dirname(os.path.realpath(__file__))

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--all", action="store_true", help="Recover all Panda devices")
args = parser.parse_args()

subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)

for s in Panda.list():
print("putting", s, "in DFU mode")
serials = Panda.list() if args.all else [None]
for s in serials:
with Panda(serial=s) as p:
print(f"putting {p.get_usb_serial()} in DFU mode")
p.reset(enter_bootstub=True)
p.reset(enter_bootloader=True)

Expand Down
28 changes: 13 additions & 15 deletions board/safety/safety_ford.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ static uint8_t ford_get_counter(const CANPacket_t *to_push) {
if (addr == FORD_BrakeSysFeatures) {
// Signal: VehVActlBrk_No_Cnt
cnt = (GET_BYTE(to_push, 2) >> 2) & 0xFU;
} else if (addr == FORD_Yaw_Data_FD1) {
}
if (addr == FORD_Yaw_Data_FD1) {
// Signal: VehRollYaw_No_Cnt
cnt = GET_BYTE(to_push, 5);
} else {
}
return cnt;
}
Expand All @@ -43,10 +43,10 @@ static uint32_t ford_get_checksum(const CANPacket_t *to_push) {
if (addr == FORD_BrakeSysFeatures) {
// Signal: VehVActlBrk_No_Cs
chksum = GET_BYTE(to_push, 3);
} else if (addr == FORD_Yaw_Data_FD1) {
}
if (addr == FORD_Yaw_Data_FD1) {
// Signal: VehRollYawW_No_Cs
chksum = GET_BYTE(to_push, 4);
} else {
}
return chksum;
}
Expand All @@ -60,14 +60,14 @@ static uint32_t ford_compute_checksum(const CANPacket_t *to_push) {
chksum += GET_BYTE(to_push, 2) >> 6; // VehVActlBrk_D_Qf
chksum += (GET_BYTE(to_push, 2) >> 2) & 0xFU; // VehVActlBrk_No_Cnt
chksum = 0xFFU - chksum;
} else if (addr == FORD_Yaw_Data_FD1) {
}
if (addr == FORD_Yaw_Data_FD1) {
chksum += GET_BYTE(to_push, 0) + GET_BYTE(to_push, 1); // VehRol_W_Actl
chksum += GET_BYTE(to_push, 2) + GET_BYTE(to_push, 3); // VehYaw_W_Actl
chksum += GET_BYTE(to_push, 5); // VehRollYaw_No_Cnt
chksum += GET_BYTE(to_push, 6) >> 6; // VehRolWActl_D_Qf
chksum += (GET_BYTE(to_push, 6) >> 4) & 0x3U; // VehYawWActl_D_Qf
chksum = 0xFFU - chksum;
} else {
}

return chksum;
Expand All @@ -79,11 +79,12 @@ static bool ford_get_quality_flag_valid(const CANPacket_t *to_push) {
bool valid = false;
if (addr == FORD_BrakeSysFeatures) {
valid = (GET_BYTE(to_push, 2) >> 6) == 0x3U; // VehVActlBrk_D_Qf
} else if (addr == FORD_EngVehicleSpThrottle2) {
}
if (addr == FORD_EngVehicleSpThrottle2) {
valid = ((GET_BYTE(to_push, 4) >> 5) & 0x3U) == 0x3U; // VehVActlEng_D_Qf
} else if (addr == FORD_Yaw_Data_FD1) {
}
if (addr == FORD_Yaw_Data_FD1) {
valid = ((GET_BYTE(to_push, 6) >> 4) & 0x3U) == 0x3U; // VehYawWActl_D_Qf
} else {
}
return valid;
}
Expand Down Expand Up @@ -316,8 +317,7 @@ static int ford_fwd_hook(int bus_num, int addr) {
// Forward all traffic from bus 0 onward
bus_fwd = FORD_CAM_BUS;
break;
}
case FORD_CAM_BUS: {
} case FORD_CAM_BUS: {
if (ford_lkas_msg_check(addr)) {
// Block stock LKAS and UI messages
bus_fwd = -1;
Expand All @@ -329,12 +329,10 @@ static int ford_fwd_hook(int bus_num, int addr) {
bus_fwd = FORD_MAIN_BUS;
}
break;
}
default: {
} default: {
// No other buses should be in use; fallback to do-not-forward
bus_fwd = -1;
break;
}
break;}
}

return bus_fwd;
Expand Down
5 changes: 2 additions & 3 deletions board/safety/safety_gm.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,11 @@ static safety_config gm_init(uint16_t param) {
{0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus

gm_hw = GET_FLAG(param, GM_PARAM_HW_CAM) ? GM_CAM : GM_ASCM;

if (gm_hw == GM_ASCM) {
gm_long_limits = &GM_ASCM_LONG_LIMITS;
} else if (gm_hw == GM_CAM) {
}
if (gm_hw == GM_CAM) {
gm_long_limits = &GM_CAM_LONG_LIMITS;
} else {
}

#ifdef ALLOW_DEBUG
Expand Down
25 changes: 15 additions & 10 deletions board/safety/safety_hyundai.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,19 @@ static uint8_t hyundai_get_counter(const CANPacket_t *to_push) {
uint8_t cnt = 0;
if (addr == 0x260) {
cnt = (GET_BYTE(to_push, 7) >> 4) & 0x3U;
} else if (addr == 0x386) {
}
if (addr == 0x386) {
cnt = ((GET_BYTE(to_push, 3) >> 6) << 2) | (GET_BYTE(to_push, 1) >> 6);
} else if (addr == 0x394) {
}
if (addr == 0x394) {
cnt = (GET_BYTE(to_push, 1) >> 5) & 0x7U;
} else if (addr == 0x421) {
}
if (addr == 0x421) {
cnt = GET_BYTE(to_push, 7) & 0xFU;
} else if (addr == 0x4F1) {
cnt = (GET_BYTE(to_push, 3) >> 4) & 0xFU;
} else {
}
if (addr == 0x4F1) {
cnt = (GET_BYTE(to_push, 3) >> 4) & 0xFU;
}
return cnt;
}

Expand All @@ -68,13 +71,15 @@ static uint32_t hyundai_get_checksum(const CANPacket_t *to_push) {
uint8_t chksum = 0;
if (addr == 0x260) {
chksum = GET_BYTE(to_push, 7) & 0xFU;
} else if (addr == 0x386) {
}
if (addr == 0x386) {
chksum = ((GET_BYTE(to_push, 7) >> 6) << 2) | (GET_BYTE(to_push, 5) >> 6);
} else if (addr == 0x394) {
}
if (addr == 0x394) {
chksum = GET_BYTE(to_push, 6) & 0xFU;
} else if (addr == 0x421) {
}
if (addr == 0x421) {
chksum = GET_BYTE(to_push, 7) >> 4;
} else {
}
return chksum;
}
Expand Down
5 changes: 2 additions & 3 deletions board/safety/safety_hyundai_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,9 @@ uint32_t hyundai_common_canfd_compute_checksum(const CANPacket_t *to_push) {

if (len == 24) {
crc ^= 0x819dU;
} else if (len == 32) {
}
if (len == 32) {
crc ^= 0x9f5bU;
} else {

}

return crc;
Expand Down
16 changes: 9 additions & 7 deletions board/safety/safety_volkswagen_mqb.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,19 @@ static uint32_t volkswagen_mqb_compute_crc(const CANPacket_t *to_push) {
uint8_t counter = volkswagen_mqb_get_counter(to_push);
if (addr == MSG_LH_EPS_03) {
crc ^= (uint8_t[]){0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5}[counter];
} else if (addr == MSG_ESP_05) {
}
if (addr == MSG_ESP_05) {
crc ^= (uint8_t[]){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}[counter];
} else if (addr == MSG_TSK_06) {
}
if (addr == MSG_TSK_06) {
crc ^= (uint8_t[]){0xC4,0xE2,0x4F,0xE4,0xF8,0x2F,0x56,0x81,0x9F,0xE5,0x83,0x44,0x05,0x3F,0x97,0xDF}[counter];
} else if (addr == MSG_MOTOR_20) {
}
if (addr == MSG_MOTOR_20) {
crc ^= (uint8_t[]){0xE9,0x65,0xAE,0x6B,0x7B,0x35,0xE5,0x5F,0x4E,0xC7,0x86,0xA2,0xBB,0xDD,0xEB,0xB4}[counter];
} else if (addr == MSG_GRA_ACC_01) {
}
if (addr == MSG_GRA_ACC_01) {
crc ^= (uint8_t[]){0x6A,0x38,0xB4,0x27,0x22,0xEF,0xE1,0xBB,0xF8,0x80,0x84,0x49,0xC7,0x9E,0x1E,0x2B}[counter];
} else {
// Undefined CAN message, CRC check expected to fail
}
}
crc = volkswagen_crc8_lut_8h2f[crc];

return (uint8_t)(crc ^ 0xFFU);
Expand Down
38 changes: 36 additions & 2 deletions python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,18 +224,46 @@ class Panda:
FLAG_FORD_LONG_CONTROL = 1
FLAG_FORD_CANFD = 2

def __init__(self, serial: str | None = None, claim: bool = True, disable_checks: bool = True, can_speed_kbps: int = 500):
self._connect_serial = serial
def __init__(self, serial: str | None = None, claim: bool = True, disable_checks: bool = True, can_speed_kbps: int = 500, cli: bool = True):
self._disable_checks = disable_checks

self._handle: BaseHandle
self._handle_open = False
self.can_rx_overflow_buffer = b''
self._can_speed_kbps = can_speed_kbps

if cli and serial is None:
self._connect_serial = self._cli_select_panda()
else:
self._connect_serial = serial

# connect and set mcu type
self.connect(claim)

def _cli_select_panda(self):
dfu_pandas = PandaDFU.list()
if len(dfu_pandas) > 0:
print("INFO: some attached pandas are in DFU mode.")

pandas = self.list()
if len(pandas) == 0:
print("INFO: panda not available")
return None
if len(pandas) == 1:
print(f"INFO: connecting to panda {pandas[0]}")
time.sleep(1)
return pandas[0]
while True:
print("Multiple pandas available:")
pandas.sort()
for idx, serial in enumerate(pandas):
print(f"{[idx]}: {serial}")
try:
choice = int(input("Choose serial [0]:") or "0")
return pandas[choice]
except (ValueError, IndexError):
print("Enter a valid index.")

def __enter__(self):
return self

Expand Down Expand Up @@ -391,6 +419,12 @@ def usb_connect(cls, serial, claim=True, no_error=False):

return context, usb_handle, usb_serial, bootstub, bcd

def is_connected_spi(self):
return isinstance(self._handle, PandaSpiHandle)

def is_connected_usb(self):
return isinstance(self._handle, PandaUsbHandle)

@classmethod
def list(cls):
ret = cls.usb_list()
Expand Down

0 comments on commit 00556ab

Please sign in to comment.