From 27ca61c112c2f06474340504820c1968d410c0e2 Mon Sep 17 00:00:00 2001 From: Adam Durham Date: Thu, 19 Sep 2024 21:28:06 -0400 Subject: [PATCH] Squashed commit of the following: commit 93aedd987bda7e267210689b877eb87f288fc6ab Author: Maxime Desroches Date: Mon Sep 16 14:07:21 2024 -0700 misra8.4: board/boards (#2021) * boards * revert * includes commit 2526d1ee4b7b740b5f5786c25638ee1528d425be Author: Willem Melching Date: Mon Sep 16 15:56:28 2024 +0200 UDS: Fix Write Data by Address (#2023) commit 8545c68e4d51eab55803c9c28cdf8bb7bfaa261e Author: Radek Date: Fri Sep 13 15:12:35 2024 -0700 Fix USB errors (#2011) Fix LIBUSB_ERROR_PIPE [-9] when resetting over USB hubs or jungle V2 commit b8a2a8678fc201d7c02453a4fb819389d0fbf53b Author: Maxime Desroches Date: Tue Sep 10 21:49:03 2024 -0700 fix python setup (#2018) * fix * comment commit fcccbb3a131cc8f60025fc7da9b9fdb7a4e3acf7 Author: dzid26 Date: Sat Sep 7 19:57:19 2024 -0700 revert shorter MISRA mutation CI timeout - test_misra.sh only got faster locally commit 2aaab401177bd16828d3d8f64d0777a7d8c3addc Author: Radek Date: Fri Sep 6 13:30:05 2024 -0700 fix test_mutation.py performace (#2012) stop pytest from executing test_misra.sh in test collections - in each test_mutation.py worker commit 6f0d1efbd9d9d4624dbbe1f839b0607e3fb7b091 Author: dzid26 Date: Thu Sep 5 21:49:30 2024 -0700 stricter misra config check - prevent quiet bail out commit 93776fd5bf5beb6e5a4cecfec8367c957143372c Author: Greg Hogan Date: Tue Sep 3 20:42:12 2024 -0700 CCP: fix upload response size and getting seed (#2009) commit aac60b8a7938d4d32c0c02608058022e4d876156 Author: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Sun Sep 1 09:51:30 2024 -0700 pre-commit: autoupdate hooks (#2010) Update pre-commit hook versions Co-authored-by: adeebshihadeh commit 9ec02e74f53a0a76d54e33142c045492a3acfc04 Author: Adeeb Shihadeh Date: Sat Aug 31 13:17:55 2024 -0700 socketcan: skip install in CI for now commit 160ea08e8f791954e7323c21ca3880600e357506 Author: Adeeb Shihadeh Date: Sat Aug 31 13:09:58 2024 -0700 misra: bump to cppcheck 2.15.0 (#2008) * misra: bump to latest cppcheck * update checkers commit a36ca220fa0d5e12b7d65a6c31c97a8982b6f25a Author: MarinkoMagla <159032106+MarinkoMagla@users.noreply.github.com> Date: Sat Aug 31 22:01:28 2024 +0200 Defining types in return dictionaries (#1923) * Defining types in return dictionaries * Correcting indent * Returning the class instead of dict * Fixing failing linter * Fixing whitespace error commit bd6cec3b2972fda7435c6030a88f0f97cab4c4b9 Author: Robbe Derks Date: Fri Aug 30 15:35:50 2024 +0200 cuatro LED (#2005) * Revert "cuatro: disable LED for now" This reverts commit 866bd9c3bc44a362a64f0104b5e555a064335009. * re-enable and make sure to use open-drain * use gpio function --------- Co-authored-by: Comma Device commit 8587ae3fc00d561c5d5d0c9def0a4de69cff7224 Author: Shane Smiskol Date: Mon Aug 26 17:56:46 2024 -0700 drivers: log can core reset when switching multiplexing (#1972) fdcan: log lost tx messages when resetting can core for multiplexing commit 0a0912234e4d3c67682109eb54c1d673770fc783 Author: Andrei Radulescu Date: Tue Aug 27 03:25:15 2024 +0300 update bash scripts to #!/usr/bin/env bash (#1987) * update bash shebang for better compatibility including macOS * can't have anything after #bash commit 2b94e4fef710a22313b99d8c5b723d8db5e9c8bd Author: dzid26 Date: Tue Aug 27 00:15:29 2024 +0000 Enable CAN3 printer (#1991) * panda has 3 can peripherals * enable printing CAN3 commit 866bd9c3bc44a362a64f0104b5e555a064335009 Author: Adeeb Shihadeh Date: Fri Aug 23 20:41:53 2024 -0700 cuatro: disable LED for now commit 30d0434380d314f72fe84a767622dde585d44eb3 Author: Comma Device Date: Fri Aug 23 04:57:34 2024 +0000 cuatro: disable SOM reset commit e53c8025a0204d4ff3a6937c642b1497256c86e1 Author: Adeeb Shihadeh Date: Thu Aug 22 21:55:02 2024 -0700 tres: fix SOM reset line blinking (#2003) Co-authored-by: Comma Device commit 080e53f04d45d5ca9348591e676c80a7149510f5 Author: Robbe Derks Date: Sun Aug 18 17:43:27 2024 -0700 Cuatro fan (#1999) * cuatro fan debugging * fix * faster fan, faster interrupts * fix comment --------- Co-authored-by: Comma Device commit cfa8b796f7fff01963b02fe51c6f7a0022cb8897 Author: Adeeb Shihadeh Date: Sun Aug 18 12:01:17 2024 -0700 cleanup dependencies (#2001) * cleanup dependencies * in the real spot * fix jenkins commit c4e75ee89cdd18e181fd78f8b8e1ed5af3fe8fc0 Author: Adeeb Shihadeh Date: Sun Aug 18 11:40:54 2024 -0700 remove cereal dependence (#2000) * remove cereal * rm more shit * add back make * python3 * python3 * fix that * put that back * rename * fix that * can't move it commit e7a04b54b039307c33f542efd21ce936c45756be Author: Shane Smiskol Date: Fri Aug 16 23:01:54 2024 -0700 make uds and isotp general imports (#1998) commit 0234e756e3fe1fdf222260ae6b782b8ce66377ef Author: Robbe Derks Date: Thu Aug 15 21:33:07 2024 -0700 STM32H7: add missing interrupt handlers (#1997) add missing interrupts Co-authored-by: Comma Device commit 87572e0b7592051c11536b57333d08e228712d93 Author: geeth345 <92386308+geeth345@users.noreply.github.com> Date: Tue Aug 13 18:34:46 2024 +0100 Update README.md to fix dead link (#1996) Changed C++ library link to reflect boardd -> pandad change commit 1cbcc13c35429b06e9d36c55b9ab46df73a8b51a Author: Shane Smiskol Date: Mon Aug 5 14:51:56 2024 -0700 use and configure custom logger (#1994) * prepare to log logs * utils * discoverability * forgot commit 3c1def1cc57f3fb37399a25d0e8088c70985c5ec Author: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Fri Aug 2 15:51:37 2024 -0700 pre-commit: autoupdate hooks (#1979) Update pre-commit hook versions Co-authored-by: adeebshihadeh commit 5d815231ea3858c958ecdd96ac3080169b407452 Author: Adeeb Shihadeh Date: Fri Aug 2 13:52:28 2024 -0700 1min is all you need commit b70ba5ecde9c734ba3880804c0488ef4b120d11b Author: Robbe Derks Date: Fri Aug 2 20:26:16 2024 +0200 Detect H723 in firmware (#1988) * determine H723 based on package type * wrong way round * misra... * enable SYSCFG clock before reading * whitelist certain package types commit ee7b385be7cef3bc1de4f9dd17017dddefb4cbb5 Author: Adeeb Shihadeh Date: Fri Aug 2 11:02:38 2024 -0700 CI: add jenkins-trigger --- .github/workflows/drivers.yaml | 6 +- .github/workflows/jenkins-pr-trigger.yaml | 45 +++++ .github/workflows/test.yaml | 8 +- .gitignore | 1 + .pre-commit-config.yaml | 4 +- Dockerfile | 54 ++---- Jenkinsfile | 4 +- README.md | 4 +- __init__.py | 3 +- board/SConscript | 3 - board/boards/black.h | 23 ++- board/boards/board_declarations.h | 15 ++ board/boards/cuatro.h | 44 +++-- board/boards/dos.h | 29 +-- board/boards/grey.h | 5 + board/boards/red.h | 21 ++- board/boards/red_chiplet.h | 16 +- board/boards/tres.h | 24 ++- board/boards/uno.h | 29 +-- board/boards/unused_funcs.h | 4 +- board/boards/white.h | 27 +-- board/debug/debug_h7.sh | 3 +- board/drivers/bxcan.h | 8 +- board/drivers/fan.h | 2 +- board/drivers/fdcan.h | 10 +- board/gdb.sh | 2 +- board/main.c | 2 +- board/stm32h7/board.h | 37 ++-- board/stm32h7/clock.h | 44 ++++- board/stm32h7/interrupt_handlers.h | 83 ++++++++- board/stm32h7/llfan.h | 4 +- drivers/spi/load.sh | 2 +- drivers/spi/pull-src.sh | 2 +- pyproject.toml | 2 +- python/__init__.py | 56 +++--- python/ccp.py | 73 ++++---- python/spi.py | 26 +-- python/uds.py | 2 +- python/utils.py | 11 ++ release/make_release.sh | 2 +- requirements.txt | 18 -- setup.py | 25 ++- tests/can_printer.py | 5 + tests/ci_shell.sh | 3 +- tests/hitl/run_parallel_tests.sh | 2 +- tests/hitl/run_serial_tests.sh | 2 +- tests/misra/checkers.txt | 204 +++++++++++++--------- tests/misra/install.sh | 4 +- tests/misra/test_misra.sh | 8 +- tests/read_st_flash.sh | 2 +- tests/setup_device_ci.sh | 4 +- tests/som_debug.sh | 2 +- tests/usbprotocol/test.sh | 2 +- 53 files changed, 648 insertions(+), 373 deletions(-) create mode 100644 .github/workflows/jenkins-pr-trigger.yaml create mode 100644 python/utils.py delete mode 100644 requirements.txt diff --git a/.github/workflows/drivers.yaml b/.github/workflows/drivers.yaml index 78efcdeab2a..1af13d91960 100644 --- a/.github/workflows/drivers.yaml +++ b/.github/workflows/drivers.yaml @@ -5,7 +5,7 @@ jobs: build_socketcan: name: socketcan build runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 1 steps: - uses: actions/checkout@v2 - name: Install dependencies @@ -16,7 +16,9 @@ jobs: cd drivers/linux make link make build - make install + + # FIXME: install doesn't work sometimes in GH Actions + #make install - name: Print make log if: always() continue-on-error: true diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml new file mode 100644 index 00000000000..db1d5240188 --- /dev/null +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -0,0 +1,45 @@ +name: jenkins scan + +on: + issue_comment: + types: [created, edited] + +jobs: + # TODO: gc old branches in a separate job in this workflow + scan-comments: + runs-on: ubuntu-latest + if: ${{ github.event.issue.pull_request }} + steps: + - name: Check for trigger phrase + id: check_comment + uses: actions/github-script@v7 + with: + script: | + const triggerPhrase = "trigger-jenkins"; + const comment = context.payload.comment.body; + const commenter = context.payload.comment.user.login; + + const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: commenter + }); + + const hasWriteAccess = permissions.permission === 'write' || permissions.permission === 'admin'; + + return (hasWriteAccess && comment.includes(triggerPhrase)); + result-encoding: json + + - name: Checkout repository + if: steps.check_comment.outputs.result == 'true' + uses: actions/checkout@v4 + with: + ref: refs/pull/${{ github.event.issue.number }}/head + + - name: Push to tmp-jenkins branch + if: steps.check_comment.outputs.result == 'true' + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b tmp-jenkins-${{ github.event.issue.number }} + GIT_LFS_SKIP_PUSH=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 97c9e07f0ed..5b62bf18fd1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,7 +11,7 @@ concurrency: cancel-in-progress: true env: - RUN: docker run -v ${{ github.workspace }}:/tmp/openpilot/panda -w /tmp/openpilot/panda --rm panda /bin/bash -c + RUN: docker run -v ${{ github.workspace }}:/tmp/pythonpath/panda -w /tmp/pythonpath/panda --rm panda /bin/bash -c BUILD: | export DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from ghcr.io/commaai/panda:latest -t panda -f Dockerfile . @@ -45,7 +45,7 @@ jobs: - name: Build Docker image run: eval "$BUILD" - name: Test python package installer - run: ${{ env.RUN }} "python setup.py install" + run: ${{ env.RUN }} "python3 setup.py install" - name: Build panda images and bootstub run: ${{ env.RUN }} "scons -j4" - name: Build panda with SPI support @@ -103,8 +103,8 @@ jobs: timeout-minutes: 5 run: ${{ env.RUN }} "cd tests/misra && pytest -n8 test_mutation.py" - python_linter: - name: python linter + static_analysis: + name: static analysis runs-on: ubuntu-latest timeout-minutes: 20 steps: diff --git a/.gitignore b/.gitignore index 2dfa0947686..640f25f8e0a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ a.out *~ .#* dist/ +build/ pandacan.egg-info/ obj/ examples/output.csv diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 04154b75ca7..c2759df9c39 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,12 +9,12 @@ repos: - id: check-executables-have-shebangs - id: check-shebang-scripts-are-executable - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.0 + rev: v1.11.2 hooks: - id: mypy additional_dependencies: ['numpy', 'types-requests', 'types-atomicwrites', 'types-pycurl'] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.7 + rev: v0.6.3 hooks: - id: ruff diff --git a/Dockerfile b/Dockerfile index 1a6122ee050..5d3c1ffc1d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,67 +1,45 @@ FROM ubuntu:24.04 -ENV PYTHONUNBUFFERED 1 -ENV PYTHONPATH /tmp/openpilot:$PYTHONPATH +ENV PYTHONUNBUFFERED=1 +ENV PYTHONPATH=/tmp/pythonpath ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ make \ - bzip2 \ - ca-certificates \ - capnproto \ - clang \ g++ \ gcc-arm-none-eabi libnewlib-arm-none-eabi \ git \ - libarchive-dev \ - libbz2-dev \ - libcapnp-dev \ libffi-dev \ - libtool \ libusb-1.0-0 \ - libzmq3-dev \ - locales \ - opencl-headers \ - ocl-icd-opencl-dev \ python3 \ python3-dev \ python3-pip \ - python-is-python3 \ - zlib1g-dev \ && rm -rf /var/lib/apt/lists/* && \ 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 -RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 - -COPY requirements.txt /tmp/ -RUN pip3 install --break-system-packages --no-cache-dir -r /tmp/requirements.txt - ENV CPPCHECK_DIR=/tmp/cppcheck COPY tests/misra/install.sh /tmp/ RUN /tmp/install.sh && rm -rf $CPPCHECK_DIR/.git/ ENV SKIP_CPPCHECK_INSTALL=1 -ENV CEREAL_REF="861144c136c91f70dcbc652c2ffe99f57440ad47" -ENV OPENDBC_REF="8e9d3688412405154a8189c421cfdc9d5feea715" +COPY setup.py __init__.py $PYTHONPATH/panda/ +COPY python/__init__.py $PYTHONPATH/panda/python/ +RUN pip3 install --break-system-packages --no-cache-dir $PYTHONPATH/panda/[dev] -RUN git config --global --add safe.directory /tmp/openpilot/panda -RUN mkdir -p /tmp/openpilot/ && \ - cd /tmp/openpilot/ && \ - git clone --depth 1 https://github.com/commaai/cereal && \ - git clone --depth 1 https://github.com/commaai/opendbc && \ - cd cereal && git fetch origin $CEREAL_REF && git checkout FETCH_HEAD && rm -rf .git/ && cd .. && \ - cd opendbc && git fetch origin $OPENDBC_REF && git checkout FETCH_HEAD && rm -rf .git/ && cd .. && \ - cp -pR opendbc/SConstruct opendbc/site_scons/ . && \ - pip3 install --break-system-packages --no-cache-dir -r opendbc/requirements.txt && \ - scons -j8 --minimal opendbc/ cereal/ +# TODO: this should be a "pip install" or not even in this repo at all +RUN git config --global --add safe.directory $PYTHONPATH/panda +ENV OPENDBC_REF="5ed7a834a4e0e24c3968dd1e98ceb4b9d5f9791a" +RUN cd /tmp/ && \ + git clone --depth 1 https://github.com/commaai/opendbc opendbc_repo && \ + cd opendbc_repo && git fetch origin $OPENDBC_REF && git checkout FETCH_HEAD && rm -rf .git/ && \ + pip3 install --break-system-packages --no-cache-dir Cython numpy && \ + scons -j8 --minimal opendbc/ && \ + ln -s $PWD/opendbc $PYTHONPATH/opendbc # for Jenkins COPY README.md panda.tar.* /tmp/ -RUN mkdir /tmp/openpilot/panda && \ - tar -xvf /tmp/panda.tar.gz -C /tmp/openpilot/panda/ || true +RUN mkdir -p /tmp/pythonpath/panda && \ + tar -xvf /tmp/panda.tar.gz -C /tmp/pythonpath/panda/ || true diff --git a/Jenkinsfile b/Jenkinsfile index b3b2690861b..2ccf6be116d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -4,7 +4,7 @@ def docker_run(String step_label, int timeout_mins, String cmd) { --env PYTHONWARNINGS=error \ --volume /dev/bus/usb:/dev/bus/usb \ --volume /var/run/dbus:/var/run/dbus \ - --workdir /tmp/openpilot/panda \ + --workdir /tmp/pythonpath/panda \ --net host \ ${env.DOCKER_IMAGE_TAG} \ bash -c 'scons -j8 && ${cmd}'", \ @@ -92,7 +92,7 @@ pipeline { steps { script { retry (3) { - docker_run("reset hardware", 3, "python ./tests/hitl/reset_jungles.py") + docker_run("reset hardware", 3, "python3 ./tests/hitl/reset_jungles.py") } } } diff --git a/README.md b/README.md index b9853e59087..618a5b70d6b 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ git clone https://github.com/commaai/panda.git cd panda # install dependencies -pip install -r requirements.txt +pip install -e .[dev] # install panda python setup.py install @@ -97,7 +97,7 @@ The panda jungle uses different udev rules. See [the repo](https://github.com/co As a universal car interface, it should support every reasonable software interface. - [Python library](https://github.com/commaai/panda/tree/master/python) -- [C++ library](https://github.com/commaai/openpilot/tree/master/selfdrive/boardd) +- [C++ library](https://github.com/commaai/openpilot/tree/master/selfdrive/pandad) - [socketcan in kernel](https://github.com/commaai/panda/tree/master/drivers/linux) (alpha) ## Licensing diff --git a/__init__.py b/__init__.py index bf487fddccd..665682521fa 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,8 @@ from .python.spi import PandaSpiException, PandaProtocolMismatch, STBootloaderSPIHandle # noqa: F401 from .python.serial import PandaSerial # noqa: F401 from .python.canhandle import CanHandle # noqa: F401 -from .python import (Panda, PandaDFU, # noqa: F401 +from .python.utils import logger # noqa: F401 +from .python import (Panda, PandaDFU, uds, isotp, # noqa: F401 pack_can_buffer, unpack_can_buffer, calculate_checksum, DLC_TO_LEN, LEN_TO_DLC, ALTERNATIVE_EXPERIENCE, CANPACKET_HEAD_SIZE) diff --git a/board/SConscript b/board/SConscript index 93fd47b07ed..3ff77648ba9 100644 --- a/board/SConscript +++ b/board/SConscript @@ -15,7 +15,4 @@ for project_name, project in build_projects.items(): if ("ENABLE_SPI" in os.environ or "h7" in project_name): flags.append('-DENABLE_SPI') - if "H723" in os.environ: - flags.append('-DSTM32H723') - build_project(project_name, project, flags) diff --git a/board/boards/black.h b/board/boards/black.h index c860d1401d4..45e0126cc47 100644 --- a/board/boards/black.h +++ b/board/boards/black.h @@ -1,8 +1,12 @@ +#pragma once + +#include "board_declarations.h" + // /////////////////////////////// // // Black Panda (STM32F4) + Harness // // /////////////////////////////// // -void black_enable_can_transceiver(uint8_t transceiver, bool enabled) { +static void black_enable_can_transceiver(uint8_t transceiver, bool enabled) { switch (transceiver){ case 1U: set_gpio_output(GPIOC, 1, !enabled); @@ -22,7 +26,7 @@ void black_enable_can_transceiver(uint8_t transceiver, bool enabled) { } } -void black_enable_can_transceivers(bool enabled) { +static void black_enable_can_transceivers(bool enabled) { for(uint8_t i=1U; i<=4U; i++){ // Leave main CAN always on for CAN-based ignition detection if((harness.status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){ @@ -33,7 +37,7 @@ void black_enable_can_transceivers(bool enabled) { } } -void black_set_led(uint8_t color, bool enabled) { +static void black_set_led(uint8_t color, bool enabled) { switch (color){ case LED_RED: set_gpio_output(GPIOC, 9, !enabled); @@ -49,11 +53,11 @@ void black_set_led(uint8_t color, bool enabled) { } } -void black_set_usb_load_switch(bool enabled) { +static void black_set_usb_load_switch(bool enabled) { set_gpio_output(GPIOB, 1, !enabled); } -void black_set_can_mode(uint8_t mode) { +static void black_set_can_mode(uint8_t mode) { black_enable_can_transceiver(2U, false); black_enable_can_transceiver(4U, false); switch (mode) { @@ -86,12 +90,12 @@ void black_set_can_mode(uint8_t mode) { } } -bool black_check_ignition(void){ +static bool black_check_ignition(void){ // ignition is checked through harness return harness_check_ignition(); } -void black_init(void) { +static void black_init(void) { common_init_gpio(); // A8,A15: normal CAN3 mode @@ -135,13 +139,13 @@ void black_init(void) { black_set_can_mode(CAN_MODE_NORMAL); } -void black_init_bootloader(void) { +static void black_init_bootloader(void) { // GPS OFF set_gpio_output(GPIOC, 5, 0); set_gpio_output(GPIOC, 12, 0); } -harness_configuration black_harness_config = { +static harness_configuration black_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOC, @@ -162,6 +166,7 @@ board board_black = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/board_declarations.h b/board/boards/board_declarations.h index a9ff9297bae..dbb29ffb79c 100644 --- a/board/boards/board_declarations.h +++ b/board/boards/board_declarations.h @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + // ******************** Prototypes ******************** typedef enum { BOOT_STANDBY, @@ -29,6 +34,7 @@ struct board { const uint16_t avdd_mV; const bool fan_stall_recovery; const uint8_t fan_enable_cooldown_time; + const uint8_t fan_max_pwm; board_init init; board_init_bootloader init_bootloader; board_enable_can_transceiver enable_can_transceiver; @@ -73,3 +79,12 @@ struct board { // CAN modes #define CAN_MODE_NORMAL 0U #define CAN_MODE_OBD_CAN2 1U + +extern struct board board_black; +extern struct board board_dos; +extern struct board board_uno; +extern struct board board_tres; +extern struct board board_grey; +extern struct board board_white; +extern struct board board_cuatro; +extern struct board board_red; diff --git a/board/boards/cuatro.h b/board/boards/cuatro.h index 43a5dfc5052..00c2cf2285c 100644 --- a/board/boards/cuatro.h +++ b/board/boards/cuatro.h @@ -1,13 +1,17 @@ +#pragma once + +#include "board_declarations.h" + // ////////////////////////// // // Cuatro (STM32H7) + Harness // // ////////////////////////// // -void cuatro_set_led(uint8_t color, bool enabled) { +static void cuatro_set_led(uint8_t color, bool enabled) { switch (color) { case LED_RED: set_gpio_output(GPIOD, 15, !enabled); break; - case LED_GREEN: + case LED_GREEN: set_gpio_output(GPIOD, 14, !enabled); break; case LED_BLUE: @@ -18,7 +22,7 @@ void cuatro_set_led(uint8_t color, bool enabled) { } } -void cuatro_enable_can_transceiver(uint8_t transceiver, bool enabled) { +static void cuatro_enable_can_transceiver(uint8_t transceiver, bool enabled) { switch (transceiver) { case 1U: set_gpio_output(GPIOB, 7, !enabled); @@ -37,7 +41,7 @@ void cuatro_enable_can_transceiver(uint8_t transceiver, bool enabled) { } } -void cuatro_enable_can_transceivers(bool enabled) { +static void cuatro_enable_can_transceivers(bool enabled) { uint8_t main_bus = (harness.status == HARNESS_STATUS_FLIPPED) ? 3U : 1U; for (uint8_t i=1U; i<=4U; i++) { // Leave main CAN always on for CAN-based ignition detection @@ -49,17 +53,32 @@ void cuatro_enable_can_transceivers(bool enabled) { } } -uint32_t cuatro_read_voltage_mV(void) { +static uint32_t cuatro_read_voltage_mV(void) { return adc_get_mV(8) * 11U; } -uint32_t cuatro_read_current_mA(void) { +static uint32_t cuatro_read_current_mA(void) { return adc_get_mV(3) * 2U; } -void cuatro_init(void) { +static void cuatro_set_fan_enabled(bool enabled) { + set_gpio_output(GPIOD, 3, !enabled); +} + +static void cuatro_set_bootkick(BootState state) { + set_gpio_output(GPIOA, 0, state != BOOT_BOOTKICK); + // only use if we have to + //set_gpio_output(GPIOC, 12, state != BOOT_RESET); +} + +static void cuatro_init(void) { red_chiplet_init(); + // init LEDs as open drain + set_gpio_output_type(GPIOE, 2, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOD, 14, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOD, 15, OUTPUT_TYPE_OPEN_DRAIN); + // Power readout set_gpio_mode(GPIOC, 5, MODE_ANALOG); set_gpio_mode(GPIOA, 6, MODE_ANALOG); @@ -81,8 +100,7 @@ void cuatro_init(void) { set_gpio_pullup(GPIOC, 2, PULL_DOWN); // SOM bootkick + reset lines - set_gpio_mode(GPIOC, 12, MODE_OUTPUT); - tres_set_bootkick(BOOT_BOOTKICK); + cuatro_set_bootkick(BOOT_BOOTKICK); // SOM debugging UART gpio_uart7_init(); @@ -93,6 +111,7 @@ void cuatro_init(void) { // fan setup set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3); + register_set_bits(&(GPIOC->OTYPER), GPIO_OTYPER_OT8); // open drain // Initialize IR PWM and set to 0% set_gpio_alternate(GPIOC, 9, GPIO_AF2_TIM3); @@ -108,7 +127,8 @@ board board_cuatro = { .has_obd = true, .has_spi = true, .has_canfd = true, - .fan_max_rpm = 6600U, + .fan_max_rpm = 12500U, + .fan_max_pwm = 99U, // it can go up to 14k RPM, but 99% -> 100% is very non-linear .avdd_mV = 1800U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 3U, @@ -121,9 +141,9 @@ board board_cuatro = { .check_ignition = red_check_ignition, .read_voltage_mV = cuatro_read_voltage_mV, .read_current_mA = cuatro_read_current_mA, - .set_fan_enabled = tres_set_fan_enabled, + .set_fan_enabled = cuatro_set_fan_enabled, .set_ir_power = tres_set_ir_power, .set_siren = unused_set_siren, - .set_bootkick = tres_set_bootkick, + .set_bootkick = cuatro_set_bootkick, .read_som_gpio = tres_read_som_gpio }; diff --git a/board/boards/dos.h b/board/boards/dos.h index 0164f2b262d..2c2fd5d4d61 100644 --- a/board/boards/dos.h +++ b/board/boards/dos.h @@ -1,8 +1,12 @@ +#pragma once + +#include "board_declarations.h" + // /////////////////////// // // Dos (STM32F4) + Harness // // /////////////////////// // -void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) { +static void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) { switch (transceiver){ case 1U: set_gpio_output(GPIOC, 1, !enabled); @@ -22,7 +26,7 @@ void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) { } } -void dos_enable_can_transceivers(bool enabled) { +static void dos_enable_can_transceivers(bool enabled) { for(uint8_t i=1U; i<=4U; i++){ // Leave main CAN always on for CAN-based ignition detection if((harness.status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){ @@ -33,7 +37,7 @@ void dos_enable_can_transceivers(bool enabled) { } } -void dos_set_led(uint8_t color, bool enabled) { +static void dos_set_led(uint8_t color, bool enabled) { switch (color){ case LED_RED: set_gpio_output(GPIOC, 9, !enabled); @@ -49,11 +53,11 @@ void dos_set_led(uint8_t color, bool enabled) { } } -void dos_set_bootkick(BootState state) { +static void dos_set_bootkick(BootState state) { set_gpio_output(GPIOC, 4, state != BOOT_BOOTKICK); } -void dos_set_can_mode(uint8_t mode) { +static void dos_set_can_mode(uint8_t mode) { dos_enable_can_transceiver(2U, false); dos_enable_can_transceiver(4U, false); switch (mode) { @@ -85,28 +89,28 @@ void dos_set_can_mode(uint8_t mode) { } } -bool dos_check_ignition(void){ +static bool dos_check_ignition(void){ // ignition is checked through harness return harness_check_ignition(); } -void dos_set_ir_power(uint8_t percentage){ +static void dos_set_ir_power(uint8_t percentage){ pwm_set(TIM4, 2, percentage); } -void dos_set_fan_enabled(bool enabled){ +static void dos_set_fan_enabled(bool enabled){ set_gpio_output(GPIOA, 1, enabled); } -void dos_set_siren(bool enabled){ +static void dos_set_siren(bool enabled){ set_gpio_output(GPIOC, 12, enabled); } -bool dos_read_som_gpio (void){ +static bool dos_read_som_gpio (void){ return (get_gpio_input(GPIOC, 2) != 0); } -void dos_init(void) { +static void dos_init(void) { common_init_gpio(); // A8,A15: normal CAN3 mode @@ -166,7 +170,7 @@ void dos_init(void) { clock_source_init(); } -harness_configuration dos_harness_config = { +static harness_configuration dos_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOC, @@ -190,6 +194,7 @@ board board_dos = { #endif .has_canfd = false, .fan_max_rpm = 6500U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = true, .fan_enable_cooldown_time = 3U, diff --git a/board/boards/grey.h b/board/boards/grey.h index 516d0fa70fe..c5c5321f6e6 100644 --- a/board/boards/grey.h +++ b/board/boards/grey.h @@ -1,3 +1,7 @@ +#pragma once + +#include "board_declarations.h" + // //////////////////// // // Grey Panda (STM32F4) // // //////////////////// // @@ -11,6 +15,7 @@ board board_grey = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/red.h b/board/boards/red.h index 746c54b622b..ac062772f05 100644 --- a/board/boards/red.h +++ b/board/boards/red.h @@ -1,8 +1,12 @@ +#pragma once + +#include "board_declarations.h" + // ///////////////////////////// // // Red Panda (STM32H7) + Harness // // ///////////////////////////// // -void red_enable_can_transceiver(uint8_t transceiver, bool enabled) { +static void red_enable_can_transceiver(uint8_t transceiver, bool enabled) { switch (transceiver) { case 1U: set_gpio_output(GPIOG, 11, !enabled); @@ -21,7 +25,7 @@ void red_enable_can_transceiver(uint8_t transceiver, bool enabled) { } } -void red_enable_can_transceivers(bool enabled) { +static void red_enable_can_transceivers(bool enabled) { uint8_t main_bus = (harness.status == HARNESS_STATUS_FLIPPED) ? 3U : 1U; for (uint8_t i=1U; i<=4U; i++) { // Leave main CAN always on for CAN-based ignition detection @@ -33,7 +37,7 @@ void red_enable_can_transceivers(bool enabled) { } } -void red_set_led(uint8_t color, bool enabled) { +static void red_set_led(uint8_t color, bool enabled) { switch (color) { case LED_RED: set_gpio_output(GPIOE, 4, !enabled); @@ -49,7 +53,7 @@ void red_set_led(uint8_t color, bool enabled) { } } -void red_set_can_mode(uint8_t mode) { +static void red_set_can_mode(uint8_t mode) { red_enable_can_transceiver(2U, false); red_enable_can_transceiver(4U, false); switch (mode) { @@ -91,16 +95,16 @@ void red_set_can_mode(uint8_t mode) { } } -bool red_check_ignition(void) { +static bool red_check_ignition(void) { // ignition is checked through harness return harness_check_ignition(); } -uint32_t red_read_voltage_mV(void){ +static uint32_t red_read_voltage_mV(void){ return adc_get_mV(2) * 11U; // TODO: is this correct? } -void red_init(void) { +static void red_init(void) { common_init_gpio(); //C10,C11 : OBD_SBU1_RELAY, OBD_SBU2_RELAY @@ -153,7 +157,7 @@ void red_init(void) { red_set_can_mode(CAN_MODE_NORMAL); } -harness_configuration red_harness_config = { +static harness_configuration red_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOA, @@ -174,6 +178,7 @@ board board_red = { .has_spi = false, .has_canfd = true, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/red_chiplet.h b/board/boards/red_chiplet.h index d79f8f83a64..e5d1aa097f6 100644 --- a/board/boards/red_chiplet.h +++ b/board/boards/red_chiplet.h @@ -1,10 +1,14 @@ +#pragma once + +#include "board_declarations.h" + // ///////////////////////////////////// // // Red Panda chiplet (STM32H7) + Harness // // ///////////////////////////////////// // // Most hardware functionality is similar to red panda -void red_chiplet_enable_can_transceiver(uint8_t transceiver, bool enabled) { +static void red_chiplet_enable_can_transceiver(uint8_t transceiver, bool enabled) { switch (transceiver) { case 1U: set_gpio_output(GPIOG, 11, !enabled); @@ -23,7 +27,7 @@ void red_chiplet_enable_can_transceiver(uint8_t transceiver, bool enabled) { } } -void red_chiplet_enable_can_transceivers(bool enabled) { +static void red_chiplet_enable_can_transceivers(bool enabled) { uint8_t main_bus = (harness.status == HARNESS_STATUS_FLIPPED) ? 3U : 1U; for (uint8_t i=1U; i<=4U; i++) { // Leave main CAN always on for CAN-based ignition detection @@ -35,7 +39,7 @@ void red_chiplet_enable_can_transceivers(bool enabled) { } } -void red_chiplet_set_can_mode(uint8_t mode) { +static void red_chiplet_set_can_mode(uint8_t mode) { red_chiplet_enable_can_transceiver(2U, false); red_chiplet_enable_can_transceiver(4U, false); switch (mode) { @@ -77,11 +81,11 @@ void red_chiplet_set_can_mode(uint8_t mode) { } } -void red_chiplet_set_fan_or_usb_load_switch(bool enabled) { +static void red_chiplet_set_fan_or_usb_load_switch(bool enabled) { set_gpio_output(GPIOD, 3, enabled); } -void red_chiplet_init(void) { +static void red_chiplet_init(void) { common_init_gpio(); // A8, A3: OBD_SBU1_RELAY, OBD_SBU2_RELAY @@ -132,7 +136,7 @@ void red_chiplet_init(void) { red_chiplet_set_can_mode(CAN_MODE_NORMAL); } -harness_configuration red_chiplet_harness_config = { +static harness_configuration red_chiplet_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOA, diff --git a/board/boards/tres.h b/board/boards/tres.h index 91b94f68e22..2ec0650dec7 100644 --- a/board/boards/tres.h +++ b/board/boards/tres.h @@ -1,35 +1,39 @@ +#pragma once + +#include "board_declarations.h" + // /////////////////////////// // Tres (STM32H7) + Harness // // /////////////////////////// -bool tres_ir_enabled; -bool tres_fan_enabled; -void tres_update_fan_ir_power(void) { +static bool tres_ir_enabled; +static bool tres_fan_enabled; +static void tres_update_fan_ir_power(void) { red_chiplet_set_fan_or_usb_load_switch(tres_ir_enabled || tres_fan_enabled); } -void tres_set_ir_power(uint8_t percentage){ +static void tres_set_ir_power(uint8_t percentage){ tres_ir_enabled = (percentage > 0U); tres_update_fan_ir_power(); pwm_set(TIM3, 4, percentage); } -void tres_set_bootkick(BootState state) { +static void tres_set_bootkick(BootState state) { set_gpio_output(GPIOA, 0, state != BOOT_BOOTKICK); set_gpio_output(GPIOC, 12, state != BOOT_RESET); } -void tres_set_fan_enabled(bool enabled) { +static void tres_set_fan_enabled(bool enabled) { // NOTE: fan controller reset doesn't work on a tres if IR is enabled tres_fan_enabled = enabled; tres_update_fan_ir_power(); } -bool tres_read_som_gpio (void) { +static bool tres_read_som_gpio (void) { return (get_gpio_input(GPIOC, 2) != 0); } -void tres_init(void) { +static void tres_init(void) { // Enable USB 3.3V LDO for USB block register_set_bits(&(PWR->CR3), PWR_CR3_USBREGEN); register_set_bits(&(PWR->CR3), PWR_CR3_USB33DEN); @@ -42,8 +46,9 @@ void tres_init(void) { set_gpio_pullup(GPIOC, 2, PULL_DOWN); // SOM bootkick + reset lines - set_gpio_mode(GPIOC, 12, MODE_OUTPUT); + // WARNING: make sure output state is set before configuring as output tres_set_bootkick(BOOT_BOOTKICK); + set_gpio_mode(GPIOC, 12, MODE_OUTPUT); // SOM debugging UART gpio_uart7_init(); @@ -76,6 +81,7 @@ board board_tres = { .has_spi = true, .has_canfd = true, .fan_max_rpm = 6600U, + .fan_max_pwm = 100U, .avdd_mV = 1800U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 3U, diff --git a/board/boards/uno.h b/board/boards/uno.h index a2e1e983542..2e74c249dc0 100644 --- a/board/boards/uno.h +++ b/board/boards/uno.h @@ -1,8 +1,12 @@ +#pragma once + +#include "board_declarations.h" + // /////////////////////// // // Uno (STM32F4) + Harness // // /////////////////////// // -void uno_enable_can_transceiver(uint8_t transceiver, bool enabled) { +static void uno_enable_can_transceiver(uint8_t transceiver, bool enabled) { switch (transceiver){ case 1U: set_gpio_output(GPIOC, 1, !enabled); @@ -22,7 +26,7 @@ void uno_enable_can_transceiver(uint8_t transceiver, bool enabled) { } } -void uno_enable_can_transceivers(bool enabled) { +static void uno_enable_can_transceivers(bool enabled) { for(uint8_t i=1U; i<=4U; i++){ // Leave main CAN always on for CAN-based ignition detection if((harness.status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){ @@ -33,7 +37,7 @@ void uno_enable_can_transceivers(bool enabled) { } } -void uno_set_led(uint8_t color, bool enabled) { +static void uno_set_led(uint8_t color, bool enabled) { switch (color){ case LED_RED: set_gpio_output(GPIOC, 9, !enabled); @@ -49,7 +53,7 @@ void uno_set_led(uint8_t color, bool enabled) { } } -void uno_set_bootkick(BootState state) { +static void uno_set_bootkick(BootState state) { if (state == BOOT_BOOTKICK) { set_gpio_output(GPIOB, 14, false); } else { @@ -58,7 +62,7 @@ void uno_set_bootkick(BootState state) { } } -void uno_set_can_mode(uint8_t mode) { +static void uno_set_can_mode(uint8_t mode) { uno_enable_can_transceiver(2U, false); uno_enable_can_transceiver(4U, false); switch (mode) { @@ -90,24 +94,24 @@ void uno_set_can_mode(uint8_t mode) { } } -bool uno_check_ignition(void){ +static bool uno_check_ignition(void){ // ignition is checked through harness return harness_check_ignition(); } -void uno_set_usb_switch(bool phone){ +static void uno_set_usb_switch(bool phone){ set_gpio_output(GPIOB, 3, phone); } -void uno_set_ir_power(uint8_t percentage){ +static void uno_set_ir_power(uint8_t percentage){ pwm_set(TIM4, 2, percentage); } -void uno_set_fan_enabled(bool enabled){ +static void uno_set_fan_enabled(bool enabled){ set_gpio_output(GPIOA, 1, enabled); } -void uno_init(void) { +static void uno_init(void) { common_init_gpio(); // A8,A15: normal CAN3 mode @@ -170,14 +174,14 @@ void uno_init(void) { uno_set_bootkick(BOOT_BOOTKICK); } -void uno_init_bootloader(void) { +static void uno_init_bootloader(void) { // GPS off set_gpio_output(GPIOB, 1, 0); set_gpio_output(GPIOC, 5, 0); set_gpio_output(GPIOC, 12, 0); } -harness_configuration uno_harness_config = { +static harness_configuration uno_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOC, @@ -197,6 +201,7 @@ board board_uno = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 5100U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/boards/unused_funcs.h b/board/boards/unused_funcs.h index 7bfde01391e..e9c18c76a3c 100644 --- a/board/boards/unused_funcs.h +++ b/board/boards/unused_funcs.h @@ -1,3 +1,5 @@ +#pragma once + void unused_init_bootloader(void) { } @@ -23,4 +25,4 @@ void unused_set_bootkick(BootState state) { bool unused_read_som_gpio(void) { return false; -} \ No newline at end of file +} diff --git a/board/boards/white.h b/board/boards/white.h index 8d22afbc9b4..2ef8de27a43 100644 --- a/board/boards/white.h +++ b/board/boards/white.h @@ -1,8 +1,12 @@ +#pragma once + +#include "board_declarations.h" + // ///////////////////// // // White Panda (STM32F4) // // ///////////////////// // -void white_enable_can_transceiver(uint8_t transceiver, bool enabled) { +static void white_enable_can_transceiver(uint8_t transceiver, bool enabled) { switch (transceiver){ case 1U: set_gpio_output(GPIOC, 1, !enabled); @@ -19,14 +23,14 @@ void white_enable_can_transceiver(uint8_t transceiver, bool enabled) { } } -void white_enable_can_transceivers(bool enabled) { +static void white_enable_can_transceivers(bool enabled) { uint8_t t1 = enabled ? 1U : 2U; // leave transceiver 1 enabled to detect CAN ignition for(uint8_t i=t1; i<=3U; i++) { white_enable_can_transceiver(i, enabled); } } -void white_set_led(uint8_t color, bool enabled) { +static void white_set_led(uint8_t color, bool enabled) { switch (color){ case LED_RED: set_gpio_output(GPIOC, 9, !enabled); @@ -42,7 +46,7 @@ void white_set_led(uint8_t color, bool enabled) { } } -void white_set_usb_power_mode(uint8_t mode){ +static void white_set_usb_power_mode(uint8_t mode){ switch (mode) { case USB_POWER_CLIENT: // B2,A13: set client mode @@ -65,7 +69,7 @@ void white_set_usb_power_mode(uint8_t mode){ } } -void white_set_can_mode(uint8_t mode){ +static void white_set_can_mode(uint8_t mode){ if (mode == CAN_MODE_NORMAL) { // B12,B13: disable GMLAN mode set_gpio_mode(GPIOB, 12, MODE_INPUT); @@ -85,21 +89,21 @@ void white_set_can_mode(uint8_t mode){ } } -uint32_t white_read_voltage_mV(void){ +static uint32_t white_read_voltage_mV(void){ return adc_get_mV(12) * 11U; } -uint32_t white_read_current_mA(void){ +static uint32_t white_read_current_mA(void){ // This isn't in mA, but we're keeping it for backwards compatibility return adc_get_raw(13); } -bool white_check_ignition(void){ +static bool white_check_ignition(void){ // ignition is on PA1 return !get_gpio_input(GPIOA, 1); } -void white_grey_init(void) { +static void white_grey_init(void) { common_init_gpio(); // C3: current sense @@ -174,13 +178,13 @@ void white_grey_init(void) { set_gpio_output(GPIOC, 14, 0); } -void white_grey_init_bootloader(void) { +static void white_grey_init_bootloader(void) { // ESP/GPS off set_gpio_output(GPIOC, 5, 0); set_gpio_output(GPIOC, 14, 0); } -harness_configuration white_harness_config = { +static harness_configuration white_harness_config = { .has_harness = false }; @@ -191,6 +195,7 @@ board board_white = { .has_spi = false, .has_canfd = false, .fan_max_rpm = 0U, + .fan_max_pwm = 100U, .avdd_mV = 3300U, .fan_stall_recovery = false, .fan_enable_cooldown_time = 0U, diff --git a/board/debug/debug_h7.sh b/board/debug/debug_h7.sh index a2bd88434e2..126a9c378c9 100755 --- a/board/debug/debug_h7.sh +++ b/board/debug/debug_h7.sh @@ -1,3 +1,4 @@ -#!/bin/bash -e +#!/usr/bin/env bash +set -e sudo openocd -f "interface/stlink.cfg" -c "transport select hla_swd" -f "target/stm32h7x.cfg" -c "init" diff --git a/board/drivers/bxcan.h b/board/drivers/bxcan.h index 27ffcee525c..89fdd960570 100644 --- a/board/drivers/bxcan.h +++ b/board/drivers/bxcan.h @@ -23,6 +23,11 @@ bool can_set_speed(uint8_t can_number) { return ret; } +void can_clear_send(CAN_TypeDef *CANx, uint8_t can_number) { + can_health[can_number].can_core_reset_cnt += 1U; + llcan_clear_send(CANx); +} + void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number); uint32_t esr_reg = CANx->ESR; @@ -52,8 +57,7 @@ void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { can_health[can_number].total_rx_lost_cnt += 1U; CANx->RF0R &= ~(CAN_RF0R_FOVR0); } - can_health[can_number].can_core_reset_cnt += 1U; - llcan_clear_send(CANx); + can_clear_send(CANx, can_number); } } diff --git a/board/drivers/fan.h b/board/drivers/fan.h index 15296079aef..e0946aac346 100644 --- a/board/drivers/fan.h +++ b/board/drivers/fan.h @@ -86,7 +86,7 @@ void fan_tick(void) { float error = fan_state.target_rpm - fan_rpm_fast; fan_state.error_integral += FAN_I * error; } - fan_state.power = CLAMP(fan_state.error_integral, 0U, 100U); + fan_state.power = CLAMP(fan_state.error_integral, 0U, current_board->fan_max_pwm); // Set PWM and enable line pwm_set(TIM3, 3, fan_state.power); diff --git a/board/drivers/fdcan.h b/board/drivers/fdcan.h index 0ba228a9e66..00bc1a34895 100644 --- a/board/drivers/fdcan.h +++ b/board/drivers/fdcan.h @@ -35,6 +35,12 @@ bool can_set_speed(uint8_t can_number) { return ret; } +void can_clear_send(FDCAN_GlobalTypeDef *FDCANx, uint8_t can_number) { + can_health[can_number].can_core_reset_cnt += 1U; + can_health[can_number].total_tx_lost_cnt += (FDCAN_TX_FIFO_EL_CNT - (FDCANx->TXFQS & FDCAN_TXFQS_TFFL)); // TX FIFO msgs will be lost after reset + llcan_clear_send(FDCANx); +} + void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { FDCAN_GlobalTypeDef *FDCANx = CANIF_FROM_CAN_NUM(can_number); uint32_t psr_reg = FDCANx->PSR; @@ -75,9 +81,7 @@ void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { // 2. H7 gets stuck in bus off recovery state indefinitely if ((((can_health[can_number].last_error == CAN_ACK_ERROR) || (can_health[can_number].last_data_error == CAN_ACK_ERROR)) && (can_health[can_number].transmit_error_cnt > 127U)) || ((ir_reg & FDCAN_IR_BO) != 0U)) { - can_health[can_number].can_core_reset_cnt += 1U; - can_health[can_number].total_tx_lost_cnt += (FDCAN_TX_FIFO_EL_CNT - (FDCANx->TXFQS & FDCAN_TXFQS_TFFL)); // TX FIFO msgs will be lost after reset - llcan_clear_send(FDCANx); + can_clear_send(FDCANx, can_number); } } } diff --git a/board/gdb.sh b/board/gdb.sh index 3dfe994cdcd..aa695d6ab70 100755 --- a/board/gdb.sh +++ b/board/gdb.sh @@ -1,3 +1,3 @@ -#!/bin/bash +#!/usr/bin/env bash gdb-multiarch --eval-command="target extended-remote localhost:3333" diff --git a/board/main.c b/board/main.c index e7954910cd3..0f4a66fb60e 100644 --- a/board/main.c +++ b/board/main.c @@ -95,7 +95,7 @@ void set_safety_mode(uint16_t mode, uint16_t param) { if (current_board->has_obd) { // Clear any pending messages in the can core (i.e. sending while comma power is unplugged) // TODO: rewrite using hardware queues rather than fifo to cancel specific messages - llcan_clear_send(CANIF_FROM_CAN_NUM(1)); + can_clear_send(CANIF_FROM_CAN_NUM(1), 1); if (param == 0U) { current_board->set_can_mode(CAN_MODE_OBD_CAN2); } else { diff --git a/board/stm32h7/board.h b/board/stm32h7/board.h index f5a8e55aa80..e8ea23b252d 100644 --- a/board/stm32h7/board.h +++ b/board/stm32h7/board.h @@ -18,36 +18,33 @@ #include "boards/cuatro.h" -uint8_t get_board_id(void) { - return detect_with_pull(GPIOF, 7, PULL_UP) | - (detect_with_pull(GPIOF, 8, PULL_UP) << 1U) | - (detect_with_pull(GPIOF, 9, PULL_UP) << 2U) | - (detect_with_pull(GPIOF, 10, PULL_UP) << 3U); -} - void detect_board_type(void) { - const uint8_t board_id = get_board_id(); + // On STM32H7 pandas, we use two different sets of pins. + const uint8_t id1 = detect_with_pull(GPIOF, 7, PULL_UP) | + (detect_with_pull(GPIOF, 8, PULL_UP) << 1U) | + (detect_with_pull(GPIOF, 9, PULL_UP) << 2U) | + (detect_with_pull(GPIOF, 10, PULL_UP) << 3U); - if (board_id == 0U) { + const uint8_t id2 = detect_with_pull(GPIOD, 4, PULL_UP) | + (detect_with_pull(GPIOD, 5, PULL_UP) << 1U) | + (detect_with_pull(GPIOD, 6, PULL_UP) << 2U) | + (detect_with_pull(GPIOD, 7, PULL_UP) << 3U); + + if (id2 == 3U) { + hw_type = HW_TYPE_CUATRO; + current_board = &board_cuatro; + } else if (id1 == 0U) { hw_type = HW_TYPE_RED_PANDA; current_board = &board_red; - } else if (board_id == 1U) { + } else if (id1 == 1U) { // deprecated //hw_type = HW_TYPE_RED_PANDA_V2; - } else if (board_id == 2U) { + hw_type = HW_TYPE_UNKNOWN; + } else if (id1 == 2U) { hw_type = HW_TYPE_TRES; current_board = &board_tres; - } else if (board_id == 3U) { - hw_type = HW_TYPE_CUATRO; - current_board = &board_tres; } else { hw_type = HW_TYPE_UNKNOWN; print("Hardware type is UNKNOWN!\n"); } - - // TODO: detect this live -#ifdef STM32H723 - hw_type = HW_TYPE_CUATRO; - current_board = &board_cuatro; -#endif } diff --git a/board/stm32h7/clock.h b/board/stm32h7/clock.h index 1ff94219810..b68fcc1c262 100644 --- a/board/stm32h7/clock.h +++ b/board/stm32h7/clock.h @@ -17,6 +17,34 @@ APB4 per: 60MHz PCLK1: 60MHz (for USART2,3,4,5,7,8) */ +typedef enum { + PACKAGE_UNKNOWN = 0, + PACKAGE_WITH_SMPS = 1, + PACKAGE_WITHOUT_SMPS = 2, +} PackageSMPSType; + +// TODO: find a better way to distinguish between H725 (using SMPS) and H723 (lacking SMPS) +// The package will do for now, since we have only used TFBGA100 for H723 +PackageSMPSType get_package_smps_type(void) { + PackageSMPSType ret; + RCC->APB4ENR |= RCC_APB4ENR_SYSCFGEN; // make sure SYSCFG clock is enabled. does seem to read fine without too though + + switch(SYSCFG->PKGR & 0xFU) { + case 0b0001U: // TFBGA100 Legacy + case 0b0011U: // TFBGA100 + ret = PACKAGE_WITHOUT_SMPS; + break; + case 0b0101U: // LQFP144 Legacy + case 0b0111U: // LQFP144 Industrial + case 0b1000U: // UFBGA169 + ret = PACKAGE_WITH_SMPS; + break; + default: + ret = PACKAGE_UNKNOWN; + } + return ret; +} + void clock_init(void) { /* WARNING: PWR->CR3's lower byte can only be written once @@ -28,12 +56,16 @@ void clock_init(void) { In a normal bootup, the bootstub will be the first to write this. The app section calls clock_init again, but the CR3 write will silently fail. This is fine for most cases, but caution should be taken that the bootstub and app always write the same config. */ - // Set power mode to direct SMPS power supply(depends on the board layout) -#ifndef STM32H723 - register_set(&(PWR->CR3), PWR_CR3_SMPSEN, 0xFU); // powered only by SMPS -#else - register_set(&(PWR->CR3), PWR_CR3_LDOEN, 0xFU); -#endif + // Set power mode to direct SMPS power supply (depends on the board layout) + PackageSMPSType package_smps = get_package_smps_type(); + if (package_smps == PACKAGE_WITHOUT_SMPS) { + register_set(&(PWR->CR3), PWR_CR3_LDOEN, 0xFU); // no SMPS, so powered by LDO + } else if (package_smps == PACKAGE_WITH_SMPS) { + register_set(&(PWR->CR3), PWR_CR3_SMPSEN, 0xFU); // powered only by SMPS + } else { + while(true); // unknown package, let's hang here + } + // Set VOS level (VOS3 to 170Mhz, VOS2 to 300Mhz, VOS1 to 400Mhz, VOS0 to 550Mhz) register_set(&(PWR->D3CR), PWR_D3CR_VOS_1 | PWR_D3CR_VOS_0, 0xC000U); //VOS1, needed for 80Mhz CAN FD while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U); diff --git a/board/stm32h7/interrupt_handlers.h b/board/stm32h7/interrupt_handlers.h index fb1298d77bd..8148021d697 100644 --- a/board/stm32h7/interrupt_handlers.h +++ b/board/stm32h7/interrupt_handlers.h @@ -20,6 +20,10 @@ void DMA1_Stream4_IRQHandler(void) {handle_interrupt(DMA1_Stream4_IRQn);} void DMA1_Stream5_IRQHandler(void) {handle_interrupt(DMA1_Stream5_IRQn);} void DMA1_Stream6_IRQHandler(void) {handle_interrupt(DMA1_Stream6_IRQn);} void ADC_IRQHandler(void) {handle_interrupt(ADC_IRQn);} +void FDCAN1_IT0_IRQHandler(void) {handle_interrupt(FDCAN1_IT0_IRQn);} +void FDCAN2_IT0_IRQHandler(void) {handle_interrupt(FDCAN2_IT0_IRQn);} +void FDCAN1_IT1_IRQHandler(void) {handle_interrupt(FDCAN1_IT1_IRQn);} +void FDCAN2_IT1_IRQHandler(void) {handle_interrupt(FDCAN2_IT1_IRQn);} void EXTI9_5_IRQHandler(void) {handle_interrupt(EXTI9_5_IRQn);} void TIM1_BRK_IRQHandler(void) {handle_interrupt(TIM1_BRK_IRQn);} void TIM1_UP_TIM10_IRQHandler(void) {handle_interrupt(TIM1_UP_TIM10_IRQn);} @@ -44,9 +48,10 @@ void TIM8_UP_TIM13_IRQHandler(void) {handle_interrupt(TIM8_UP_TIM13_IRQn);} void TIM8_TRG_COM_TIM14_IRQHandler(void) {handle_interrupt(TIM8_TRG_COM_TIM14_IRQn);} void TIM8_CC_IRQHandler(void) {handle_interrupt(TIM8_CC_IRQn);} void DMA1_Stream7_IRQHandler(void) {handle_interrupt(DMA1_Stream7_IRQn);} +void FMC_IRQHandler(void) {handle_interrupt(FMC_IRQn);} +void SDMMC1_IRQHandler(void) {handle_interrupt(SDMMC1_IRQn);} void TIM5_IRQHandler(void) {handle_interrupt(TIM5_IRQn);} void SPI3_IRQHandler(void) {handle_interrupt(SPI3_IRQn);} -void SPI4_IRQHandler(void) {handle_interrupt(SPI4_IRQn);} void UART4_IRQHandler(void) {handle_interrupt(UART4_IRQn);} void UART5_IRQHandler(void) {handle_interrupt(UART5_IRQn);} void TIM6_DAC_IRQHandler(void) {handle_interrupt(TIM6_DAC_IRQn);} @@ -56,21 +61,83 @@ void DMA2_Stream1_IRQHandler(void) {handle_interrupt(DMA2_Stream1_IRQn);} void DMA2_Stream2_IRQHandler(void) {handle_interrupt(DMA2_Stream2_IRQn);} void DMA2_Stream3_IRQHandler(void) {handle_interrupt(DMA2_Stream3_IRQn);} void DMA2_Stream4_IRQHandler(void) {handle_interrupt(DMA2_Stream4_IRQn);} +void ETH_IRQHandler(void) {handle_interrupt(ETH_IRQn);} +void ETH_WKUP_IRQHandler(void) {handle_interrupt(ETH_WKUP_IRQn);} +void FDCAN_CAL_IRQHandler(void) {handle_interrupt(FDCAN_CAL_IRQn);} void DMA2_Stream5_IRQHandler(void) {handle_interrupt(DMA2_Stream5_IRQn);} void DMA2_Stream6_IRQHandler(void) {handle_interrupt(DMA2_Stream6_IRQn);} void DMA2_Stream7_IRQHandler(void) {handle_interrupt(DMA2_Stream7_IRQn);} void USART6_IRQHandler(void) {handle_interrupt(USART6_IRQn);} void I2C3_EV_IRQHandler(void) {handle_interrupt(I2C3_EV_IRQn);} void I2C3_ER_IRQHandler(void) {handle_interrupt(I2C3_ER_IRQn);} -void FDCAN1_IT0_IRQHandler(void) {handle_interrupt(FDCAN1_IT0_IRQn);} -void FDCAN1_IT1_IRQHandler(void) {handle_interrupt(FDCAN1_IT1_IRQn);} -void FDCAN2_IT0_IRQHandler(void) {handle_interrupt(FDCAN2_IT0_IRQn);} -void FDCAN2_IT1_IRQHandler(void) {handle_interrupt(FDCAN2_IT1_IRQn);} -void FDCAN3_IT0_IRQHandler(void) {handle_interrupt(FDCAN3_IT0_IRQn);} -void FDCAN3_IT1_IRQHandler(void) {handle_interrupt(FDCAN3_IT1_IRQn);} -void FDCAN_CAL_IRQHandler(void) {handle_interrupt(FDCAN_CAL_IRQn);} void OTG_HS_EP1_OUT_IRQHandler(void) {handle_interrupt(OTG_HS_EP1_OUT_IRQn);} void OTG_HS_EP1_IN_IRQHandler(void) {handle_interrupt(OTG_HS_EP1_IN_IRQn);} void OTG_HS_WKUP_IRQHandler(void) {handle_interrupt(OTG_HS_WKUP_IRQn);} void OTG_HS_IRQHandler(void) {handle_interrupt(OTG_HS_IRQn);} +void DCMI_PSSI_IRQHandler(void) {handle_interrupt(DCMI_PSSI_IRQn);} +void CRYP_IRQHandler(void) {handle_interrupt(CRYP_IRQn);} +void HASH_RNG_IRQHandler(void) {handle_interrupt(HASH_RNG_IRQn);} +void FPU_IRQHandler(void) {handle_interrupt(FPU_IRQn);} void UART7_IRQHandler(void) {handle_interrupt(UART7_IRQn);} +void UART8_IRQHandler(void) {handle_interrupt(UART8_IRQn);} +void SPI4_IRQHandler(void) {handle_interrupt(SPI4_IRQn);} +void SPI5_IRQHandler(void) {handle_interrupt(SPI5_IRQn);} +void SPI6_IRQHandler(void) {handle_interrupt(SPI6_IRQn);} +void SAI1_IRQHandler(void) {handle_interrupt(SAI1_IRQn);} +void LTDC_IRQHandler(void) {handle_interrupt(LTDC_IRQn);} +void LTDC_ER_IRQHandler(void) {handle_interrupt(LTDC_ER_IRQn);} +void DMA2D_IRQHandler(void) {handle_interrupt(DMA2D_IRQn);} +void OCTOSPI1_IRQHandler(void) {handle_interrupt(OCTOSPI1_IRQn);} +void LPTIM1_IRQHandler(void) {handle_interrupt(LPTIM1_IRQn);} +void CEC_IRQHandler(void) {handle_interrupt(CEC_IRQn);} +void I2C4_EV_IRQHandler(void) {handle_interrupt(I2C4_EV_IRQn);} +void I2C4_ER_IRQHandler(void) {handle_interrupt(I2C4_ER_IRQn);} +void SPDIF_RX_IRQHandler(void) {handle_interrupt(SPDIF_RX_IRQn);} +void DMAMUX1_OVR_IRQHandler(void) {handle_interrupt(DMAMUX1_OVR_IRQn);} +void DFSDM1_FLT0_IRQHandler(void) {handle_interrupt(DFSDM1_FLT0_IRQn);} +void DFSDM1_FLT1_IRQHandler(void) {handle_interrupt(DFSDM1_FLT1_IRQn);} +void DFSDM1_FLT2_IRQHandler(void) {handle_interrupt(DFSDM1_FLT2_IRQn);} +void DFSDM1_FLT3_IRQHandler(void) {handle_interrupt(DFSDM1_FLT3_IRQn);} +void SWPMI1_IRQHandler(void) {handle_interrupt(SWPMI1_IRQn);} +void TIM15_IRQHandler(void) {handle_interrupt(TIM15_IRQn);} +void TIM16_IRQHandler(void) {handle_interrupt(TIM16_IRQn);} +void TIM17_IRQHandler(void) {handle_interrupt(TIM17_IRQn);} +void MDIOS_WKUP_IRQHandler(void) {handle_interrupt(MDIOS_WKUP_IRQn);} +void MDIOS_IRQHandler(void) {handle_interrupt(MDIOS_IRQn);} +void MDMA_IRQHandler(void) {handle_interrupt(MDMA_IRQn);} +void SDMMC2_IRQHandler(void) {handle_interrupt(SDMMC2_IRQn);} +void HSEM1_IRQHandler(void) {handle_interrupt(HSEM1_IRQn);} +void ADC3_IRQHandler(void) {handle_interrupt(ADC3_IRQn);} +void DMAMUX2_OVR_IRQHandler(void) {handle_interrupt(DMAMUX2_OVR_IRQn);} +void BDMA_Channel0_IRQHandler(void) {handle_interrupt(BDMA_Channel0_IRQn);} +void BDMA_Channel1_IRQHandler(void) {handle_interrupt(BDMA_Channel1_IRQn);} +void BDMA_Channel2_IRQHandler(void) {handle_interrupt(BDMA_Channel2_IRQn);} +void BDMA_Channel3_IRQHandler(void) {handle_interrupt(BDMA_Channel3_IRQn);} +void BDMA_Channel4_IRQHandler(void) {handle_interrupt(BDMA_Channel4_IRQn);} +void BDMA_Channel5_IRQHandler(void) {handle_interrupt(BDMA_Channel5_IRQn);} +void BDMA_Channel6_IRQHandler(void) {handle_interrupt(BDMA_Channel6_IRQn);} +void BDMA_Channel7_IRQHandler(void) {handle_interrupt(BDMA_Channel7_IRQn);} +void COMP_IRQHandler(void) {handle_interrupt(COMP_IRQn);} +void LPTIM2_IRQHandler(void) {handle_interrupt(LPTIM2_IRQn);} +void LPTIM3_IRQHandler(void) {handle_interrupt(LPTIM3_IRQn);} +void LPTIM4_IRQHandler(void) {handle_interrupt(LPTIM4_IRQn);} +void LPTIM5_IRQHandler(void) {handle_interrupt(LPTIM5_IRQn);} +void LPUART1_IRQHandler(void) {handle_interrupt(LPUART1_IRQn);} +void CRS_IRQHandler(void) {handle_interrupt(CRS_IRQn);} +void ECC_IRQHandler(void) {handle_interrupt(ECC_IRQn);} +void SAI4_IRQHandler(void) {handle_interrupt(SAI4_IRQn);} +void DTS_IRQHandler(void) {handle_interrupt(DTS_IRQn);} +void WAKEUP_PIN_IRQHandler(void) {handle_interrupt(WAKEUP_PIN_IRQn);} +void OCTOSPI2_IRQHandler(void) {handle_interrupt(OCTOSPI2_IRQn);} +void OTFDEC1_IRQHandler(void) {handle_interrupt(OTFDEC1_IRQn);} +void OTFDEC2_IRQHandler(void) {handle_interrupt(OTFDEC2_IRQn);} +void FMAC_IRQHandler(void) {handle_interrupt(FMAC_IRQn);} +void CORDIC_IRQHandler(void) {handle_interrupt(CORDIC_IRQn);} +void UART9_IRQHandler(void) {handle_interrupt(UART9_IRQn);} +void USART10_IRQHandler(void) {handle_interrupt(USART10_IRQn);} +void I2C5_EV_IRQHandler(void) {handle_interrupt(I2C5_EV_IRQn);} +void I2C5_ER_IRQHandler(void) {handle_interrupt(I2C5_ER_IRQn);} +void FDCAN3_IT0_IRQHandler(void) {handle_interrupt(FDCAN3_IT0_IRQn);} +void FDCAN3_IT1_IRQHandler(void) {handle_interrupt(FDCAN3_IT1_IRQn);} +void TIM23_IRQHandler(void) {handle_interrupt(TIM23_IRQn);} +void TIM24_IRQHandler(void) {handle_interrupt(TIM24_IRQn);} diff --git a/board/stm32h7/llfan.h b/board/stm32h7/llfan.h index dce622503ab..04f0fc11c87 100644 --- a/board/stm32h7/llfan.h +++ b/board/stm32h7/llfan.h @@ -8,8 +8,8 @@ void EXTI2_IRQ_Handler(void) { } void llfan_init(void) { - // 5000RPM * 4 tach edges / 60 seconds - REGISTER_INTERRUPT(EXTI2_IRQn, EXTI2_IRQ_Handler, 700U, FAULT_INTERRUPT_RATE_TACH) + // 12000RPM * 4 tach edges / 60 seconds + REGISTER_INTERRUPT(EXTI2_IRQn, EXTI2_IRQ_Handler, 1000U, FAULT_INTERRUPT_RATE_TACH) // Init PWM speed control pwm_init(TIM3, 3); diff --git a/drivers/spi/load.sh b/drivers/spi/load.sh index b8efdbf708f..910ac87282a 100755 --- a/drivers/spi/load.sh +++ b/drivers/spi/load.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/drivers/spi/pull-src.sh b/drivers/spi/pull-src.sh index f74b94b9e79..64dac9bca04 100755 --- a/drivers/spi/pull-src.sh +++ b/drivers/spi/pull-src.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/pyproject.toml b/pyproject.toml index 375885e54d1..5b0697d67b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,4 +12,4 @@ flake8-implicit-str-concat.allow-multiline=false "pytest.main".msg = "pytest.main requires special handling that is easy to mess up!" [tool.pytest.ini_options] -addopts = "-n auto" +addopts = "-n auto --ignore-glob='*.sh'" diff --git a/python/__init__.py b/python/__init__.py index 9238451dbbd..b3b6ace85a3 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -6,7 +6,6 @@ import struct import hashlib import binascii -import logging from functools import wraps, partial from itertools import accumulate @@ -16,17 +15,14 @@ from .isotp import isotp_send, isotp_recv from .spi import PandaSpiHandle, PandaSpiException, PandaProtocolMismatch from .usb import PandaUsbHandle +from .utils import logger __version__ = '0.0.10' -# setup logging -LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() -logging.basicConfig(level=LOGLEVEL, format='%(message)s') - CANPACKET_HEAD_SIZE = 0x6 DLC_TO_LEN = [0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64] LEN_TO_DLC = {length: dlc for (dlc, length) in enumerate(DLC_TO_LEN)} -PANDA_BUS_CNT = 4 +PANDA_BUS_CNT = 3 def calculate_checksum(data): @@ -39,7 +35,7 @@ def pack_can_buffer(arr): snds = [b''] for address, dat, bus in arr: assert len(dat) in LEN_TO_DLC - #logging.debug(" W 0x%x: 0x%s", address, dat.hex()) + #logger.debug(" W 0x%x: 0x%s", address, dat.hex()) extended = 1 if address >= 0x800 else 0 data_len_code = LEN_TO_DLC[len(dat)] @@ -276,7 +272,7 @@ def connect(self, claim=True, wait=False): self._handle = None while self._handle is None: # try USB first, then SPI - self._context, self._handle, serial, self.bootstub, bcd = self.usb_connect(self._connect_serial, claim=claim) + self._context, self._handle, serial, self.bootstub, bcd = self.usb_connect(self._connect_serial, claim=claim, no_error=wait) if self._handle is None: self._context, self._handle, serial, self.bootstub, bcd = self.spi_connect(self._connect_serial) if not wait: @@ -307,7 +303,7 @@ def connect(self, claim=True, wait=False): self._handle_open = True self._mcu_type = self.get_mcu_type() self.health_version, self.can_version, self.can_health_version = self.get_packets_versions() - logging.debug("connected") + logger.debug("connected") # disable openpilot's heartbeat checks if self._disable_checks: @@ -368,7 +364,7 @@ def spi_connect(cls, serial, ignore_version=False): return None, handle, spi_serial, bootstub, None @classmethod - def usb_connect(cls, serial, claim=True): + def usb_connect(cls, serial, claim=True, no_error=False): handle, usb_serial, bootstub, bcd = None, None, None, None context = usb1.USBContext() context.open() @@ -378,11 +374,13 @@ def usb_connect(cls, serial, claim=True): try: this_serial = device.getSerialNumber() except Exception: - logging.exception("failed to get serial number of panda") + # Allow to ignore errors on reconnect. USB hubs need some time to initialize after panda reset + if not no_error: + logger.exception("failed to get serial number of panda") continue if serial is None or this_serial == serial: - logging.debug("opening device %s %s", this_serial, hex(device.getProductID())) + logger.debug("opening device %s %s", this_serial, hex(device.getProductID())) usb_serial = this_serial bootstub = (device.getProductID() & 0xF0) == 0xe0 @@ -400,7 +398,7 @@ def usb_connect(cls, serial, claim=True): break except Exception: - logging.exception("USB connect error") + logger.exception("USB connect error") usb_handle = None if handle is not None: @@ -428,11 +426,11 @@ def usb_list(cls): if len(serial) == 24: ret.append(serial) else: - logging.warning(f"found device with panda descriptors but invalid serial: {serial}", RuntimeWarning) + logger.warning(f"found device with panda descriptors but invalid serial: {serial}", RuntimeWarning) except Exception: - logging.exception("error connecting to panda") + logger.exception("error connecting to panda") except Exception: - logging.exception("exception while listing pandas") + logger.exception("exception while listing pandas") return ret @classmethod @@ -472,7 +470,7 @@ def reconnect(self): # wait up to 15 seconds for _ in range(15*10): try: - self.connect() + self.connect(claim=False, wait=True) success = True break except Exception: @@ -500,22 +498,22 @@ def flash_static(handle, code, mcu_type): assert last_sector < 7, "Binary too large! Risk of overwriting provisioning chunk." # unlock flash - logging.warning("flash: unlocking") + logger.warning("flash: unlocking") handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'') # erase sectors - logging.warning(f"flash: erasing sectors 1 - {last_sector}") + logger.warning(f"flash: erasing sectors 1 - {last_sector}") for i in range(1, last_sector + 1): handle.controlWrite(Panda.REQUEST_IN, 0xb2, i, 0, b'') # flash over EP2 STEP = 0x10 - logging.warning("flash: flashing") + logger.warning("flash: flashing") for i in range(0, len(code), STEP): handle.bulkWrite(2, code[i:i + STEP]) # reset - logging.warning("flash: resetting") + logger.warning("flash: resetting") try: handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'', expect_disconnect=True) except Exception: @@ -523,13 +521,13 @@ def flash_static(handle, code, mcu_type): def flash(self, fn=None, code=None, reconnect=True): if self.up_to_date(fn=fn): - logging.debug("flash: already up to date") + logger.debug("flash: already up to date") return if not fn: fn = os.path.join(FW_PATH, self._mcu_type.config.app_fn) assert os.path.isfile(fn) - logging.debug("flash: main version is %s", self.get_version()) + logger.debug("flash: main version is %s", self.get_version()) if not self.bootstub: self.reset(enter_bootstub=True) assert(self.bootstub) @@ -539,7 +537,7 @@ def flash(self, fn=None, code=None, reconnect=True): code = f.read() # get version - logging.debug("flash: bootstub version is %s", self.get_version()) + logger.debug("flash: bootstub version is %s", self.get_version()) # do flash Panda.flash_static(self._handle, code, mcu_type=self._mcu_type) @@ -571,7 +569,7 @@ def wait_for_dfu(dfu_serial: str | None, timeout: int | None = None) -> bool: t_start = time.monotonic() dfu_list = PandaDFU.list() while (dfu_serial is None and len(dfu_list) == 0) or (dfu_serial is not None and dfu_serial not in dfu_list): - logging.debug("waiting for DFU...") + logger.debug("waiting for DFU...") time.sleep(0.1) if timeout is not None and (time.monotonic() - t_start) > timeout: return False @@ -583,7 +581,7 @@ def wait_for_panda(serial: str | None, timeout: int) -> bool: t_start = time.monotonic() serials = Panda.list() while (serial is None and len(serials) == 0) or (serial is not None and serial not in serials): - logging.debug("waiting for panda...") + logger.debug("waiting for panda...") time.sleep(0.1) if timeout is not None and (time.monotonic() - t_start) > timeout: return False @@ -823,10 +821,10 @@ def can_send_many(self, arr, timeout=CAN_SEND_TIMEOUT_MS): tx = tx[bs:] if len(tx) == 0: break - logging.error("CAN: PARTIAL SEND MANY, RETRYING") + logger.error("CAN: PARTIAL SEND MANY, RETRYING") break except (usb1.USBErrorIO, usb1.USBErrorOverflow): - logging.error("CAN: BAD SEND MANY, RETRYING") + logger.error("CAN: BAD SEND MANY, RETRYING") def can_send(self, addr, dat, bus, timeout=CAN_SEND_TIMEOUT_MS): self.can_send_many([[addr, dat, bus]], timeout=timeout) @@ -839,7 +837,7 @@ def can_recv(self): dat = self._handle.bulkRead(1, 16384) # Max receive batch size + 2 extra reserve frames break except (usb1.USBErrorIO, usb1.USBErrorOverflow): - logging.error("CAN: BAD RECV, RETRYING") + logger.error("CAN: BAD RECV, RETRYING") time.sleep(0.1) msgs, self.can_rx_overflow_buffer = unpack_can_buffer(self.can_rx_overflow_buffer + dat) return msgs diff --git a/python/ccp.py b/python/ccp.py index 3ba1ef3588e..20ca3c62da1 100644 --- a/python/ccp.py +++ b/python/ccp.py @@ -2,6 +2,35 @@ import time import struct from enum import IntEnum, Enum +from dataclasses import dataclass +from typing import Optional + +@dataclass +class ExchangeStationIdsReturn: + id_length: int + data_type: int + available: int + protected: int + +@dataclass +class GetDaqListSizeReturn: + list_size: int + first_pid: int + +@dataclass +class GetSessionStatusReturn: + status: int + info: Optional[int] + +@dataclass +class DiagnosticServiceReturn: + length: int + type: int + +@dataclass +class ActionServiceReturn: + length: int + type: int class COMMAND_CODE(IntEnum): CONNECT = 0x01 @@ -140,20 +169,15 @@ def connect(self, station_addr: int) -> None: self._send_cro(COMMAND_CODE.CONNECT, struct.pack(" dict: + def exchange_station_ids(self, device_id_info: bytes = b"") -> ExchangeStationIdsReturn: self._send_cro(COMMAND_CODE.EXCHANGE_ID, device_id_info) resp = self._recv_dto(0.025) - return { # TODO: define a type - "id_length": resp[0], - "data_type": resp[1], - "available": resp[2], - "protected": resp[3], - } + return ExchangeStationIdsReturn(id_length=resp[0], data_type=resp[1], available=resp[2], protected=resp[3]) def get_seed(self, resource_mask: int) -> bytes: if resource_mask > 255: raise ValueError("resource mask must be less than 256") - self._send_cro(COMMAND_CODE.GET_SEED) + self._send_cro(COMMAND_CODE.GET_SEED, bytes([resource_mask])) resp = self._recv_dto(0.025) # protected = resp[0] == 0 seed = resp[1:] @@ -197,7 +221,7 @@ def upload(self, size: int) -> bytes: if size > 5: raise ValueError("size must be less than 6") self._send_cro(COMMAND_CODE.UPLOAD, bytes([size])) - return self._recv_dto(0.025) + return self._recv_dto(0.025)[:size] def short_upload(self, size: int, addr_ext: int, addr: int) -> bytes: if size > 5: @@ -205,21 +229,18 @@ def short_upload(self, size: int, addr_ext: int, addr: int) -> bytes: if addr_ext > 255: raise ValueError("address extension must be less than 256") self._send_cro(COMMAND_CODE.SHORT_UP, bytes([size, addr_ext]) + struct.pack(f"{self.byte_order.value}I", addr)) - return self._recv_dto(0.025) + return self._recv_dto(0.025)[:size] def select_calibration_page(self) -> None: self._send_cro(COMMAND_CODE.SELECT_CAL_PAGE) self._recv_dto(0.025) - def get_daq_list_size(self, list_num: int, can_id: int = 0) -> dict: + def get_daq_list_size(self, list_num: int, can_id: int = 0) -> GetDaqListSizeReturn: if list_num > 255: raise ValueError("list number must be less than 256") self._send_cro(COMMAND_CODE.GET_DAQ_SIZE, bytes([list_num, 0]) + struct.pack(f"{self.byte_order.value}I", can_id)) resp = self._recv_dto(0.025) - return { # TODO: define a type - "list_size": resp[0], - "first_pid": resp[1], - } + return GetDaqListSizeReturn(list_size=resp[0], first_pid=resp[1]) def set_daq_list_pointer(self, list_num: int, odt_num: int, element_num: int) -> None: if list_num > 255: @@ -266,13 +287,11 @@ def set_session_status(self, status: int) -> None: self._send_cro(COMMAND_CODE.SET_S_STATUS, bytes([status])) self._recv_dto(0.025) - def get_session_status(self) -> dict: + def get_session_status(self) -> GetSessionStatusReturn: self._send_cro(COMMAND_CODE.GET_S_STATUS) resp = self._recv_dto(0.025) - return { # TODO: define a type - "status": resp[0], - "info": resp[2] if resp[1] else None, - } + info = resp[2] if resp[1] else None + return GetSessionStatusReturn(status=resp[0], info=info) def build_checksum(self, size: int) -> bytes: self._send_cro(COMMAND_CODE.BUILD_CHKSUM, struct.pack(f"{self.byte_order.value}I", size)) @@ -310,29 +329,23 @@ def move_memory_block(self, size: int) -> None: self._send_cro(COMMAND_CODE.MOVE, struct.pack(f"{self.byte_order.value}I", size)) self._recv_dto(0.025) - def diagnostic_service(self, service_num: int, data: bytes = b"") -> dict: + def diagnostic_service(self, service_num: int, data: bytes = b"") -> DiagnosticServiceReturn: if service_num > 65535: raise ValueError("service number must be less than 65536") if len(data) > 4: raise ValueError("max data size is 4 bytes") self._send_cro(COMMAND_CODE.DIAG_SERVICE, struct.pack(f"{self.byte_order.value}H", service_num) + data) resp = self._recv_dto(0.025) - return { # TODO: define a type - "length": resp[0], - "type": resp[1], - } + return DiagnosticServiceReturn(length=resp[0], type=resp[1]) - def action_service(self, service_num: int, data: bytes = b"") -> dict: + def action_service(self, service_num: int, data: bytes = b"") -> ActionServiceReturn: if service_num > 65535: raise ValueError("service number must be less than 65536") if len(data) > 4: raise ValueError("max data size is 4 bytes") self._send_cro(COMMAND_CODE.ACTION_SERVICE, struct.pack(f"{self.byte_order.value}H", service_num) + data) resp = self._recv_dto(0.025) - return { # TODO: define a type - "length": resp[0], - "type": resp[1], - } + return ActionServiceReturn(length=resp[0], type=resp[1]) def test_availability(self, station_addr: int) -> None: if station_addr > 65535: diff --git a/python/spi.py b/python/spi.py index be4f7dcf46e..59e9018159d 100644 --- a/python/spi.py +++ b/python/spi.py @@ -5,7 +5,6 @@ import math import time import struct -import logging import threading from contextlib import contextmanager from functools import reduce @@ -13,6 +12,7 @@ from .base import BaseHandle, BaseSTBootloaderHandle, TIMEOUT from .constants import McuType, MCU_TYPE_BY_IDCODE, USBPACKET_MAX_SIZE +from .utils import logger try: import spidev @@ -167,23 +167,23 @@ def _wait_for_ack(self, spi, ack_val: int, timeout: int, tx: int, length: int = def _transfer_spidev(self, spi, endpoint: int, data, timeout: int, max_rx_len: int = 1000, expect_disconnect: bool = False) -> bytes: max_rx_len = max(USBPACKET_MAX_SIZE, max_rx_len) - logging.debug("- send header") + logger.debug("- send header") packet = struct.pack(" bytes: - logging.debug("starting transfer: endpoint=%d, max_rx_len=%d", endpoint, max_rx_len) - logging.debug("==============================================") + logger.debug("starting transfer: endpoint=%d, max_rx_len=%d", endpoint, max_rx_len) + logger.debug("==============================================") n = 0 start_time = time.monotonic() exc = PandaSpiException() while (timeout == 0) or (time.monotonic() - start_time) < timeout*1e-3: n += 1 - logging.debug("\ntry #%d", n) + logger.debug("\ntry #%d", n) with self.dev.acquire() as spi: try: return self._transfer_raw(spi, endpoint, data, timeout, max_rx_len, expect_disconnect) except PandaSpiException as e: exc = e - logging.debug("SPI transfer failed, retrying", exc_info=True) + logger.debug("SPI transfer failed, retrying", exc_info=True) raise exc @@ -245,7 +245,7 @@ def get_protocol_version(self) -> bytes: def _get_version(spi) -> bytes: spi.writebytes(vers_str) - logging.debug("- waiting for echo") + logger.debug("- waiting for echo") start = time.monotonic() while True: version_bytes = spi.readbytes(len(vers_str) + 2) @@ -273,7 +273,7 @@ def _get_version(spi) -> bytes: return _get_version(spi) except PandaSpiException as e: exc = e - logging.debug("SPI get protocol version failed, retrying", exc_info=True) + logger.debug("SPI get protocol version failed, retrying", exc_info=True) raise exc # libusb1 functions @@ -378,7 +378,7 @@ def _cmd(self, cmd: int, data: list[bytes] | None = None, read_bytes: int = 0, p return self._cmd_no_retry(cmd, data, read_bytes, predata) except PandaSpiException as e: exc = e - logging.debug("SPI transfer failed, %d retries left", MAX_XFER_RETRY_COUNT - n - 1, exc_info=True) + logger.debug("SPI transfer failed, %d retries left", MAX_XFER_RETRY_COUNT - n - 1, exc_info=True) raise exc def _checksum(self, data: bytes) -> bytes: diff --git a/python/uds.py b/python/uds.py index 22e5129bd98..7ce7d24a298 100644 --- a/python/uds.py +++ b/python/uds.py @@ -826,7 +826,7 @@ def write_memory_by_address(self, memory_address: int, memory_size: int, data_re data += struct.pack('!I', memory_size)[4 - memory_size_bytes:] data += data_record - self._uds_request(SERVICE_TYPE.WRITE_MEMORY_BY_ADDRESS, subfunction=0x00, data=data) + self._uds_request(SERVICE_TYPE.WRITE_MEMORY_BY_ADDRESS, subfunction=None, data=data) def clear_diagnostic_information(self, dtc_group_type: DTC_GROUP_TYPE): data = struct.pack('!I', dtc_group_type)[1:] # 3 bytes diff --git a/python/utils.py b/python/utils.py new file mode 100644 index 00000000000..55181e08b11 --- /dev/null +++ b/python/utils.py @@ -0,0 +1,11 @@ +import os +import logging + +# set up logging +LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() +logger = logging.getLogger('panda') +logger.setLevel(LOGLEVEL) + +handler = logging.StreamHandler() +handler.setFormatter(logging.Formatter('%(message)s')) +logger.addHandler(handler) diff --git a/release/make_release.sh b/release/make_release.sh index 5628c4998db..cfecac3a165 100755 --- a/release/make_release.sh +++ b/release/make_release.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 5ee8636fd59..00000000000 --- a/requirements.txt +++ /dev/null @@ -1,18 +0,0 @@ -ruff -libusb1 -numpy -hexdump -pycryptodome -tqdm>=4.14.0 -pytest -pytest-mock -pytest-xdist -pytest-timeout -pytest-randomly -parameterized -cffi -pre-commit -scons>=4.4.0 -flaky -spidev -termcolor \ No newline at end of file diff --git a/setup.py b/setup.py index 25ee6692362..a7729cc6f89 100644 --- a/setup.py +++ b/setup.py @@ -44,12 +44,27 @@ def find_version(*file_paths): platforms='any', license='MIT', install_requires=[ - 'libusb1 == 2.0.1', - 'hexdump >= 3.3', - 'pycryptodome >= 3.9.8', - 'tqdm >= 4.14.0', - 'requests' + 'libusb1', ], + extras_require = { + 'dev': [ + "scons", + "pycryptodome >= 3.9.8", + "cffi", + "flaky", + "pytest", + "pytest-mock", + "pytest-xdist", + "pytest-timeout", + "pytest-randomly", + "parameterized", + "pre-commit", + "numpy", + "ruff", + "spidev", + "setuptools", # for setup.py + ], + }, ext_modules=[], description="Code powering the comma.ai panda", long_description='See https://github.com/commaai/panda', diff --git a/tests/can_printer.py b/tests/can_printer.py index 08315560edf..70a18a61bd2 100755 --- a/tests/can_printer.py +++ b/tests/can_printer.py @@ -17,7 +17,12 @@ def can_printer(): start = sec_since_boot() lp = sec_since_boot() msgs = defaultdict(list) + canbus = int(os.getenv("CAN", "0")) + if canbus == 3: + canbus = 1 + p.set_obd(True) + while True: can_recv = p.can_recv() for address, dat, src in can_recv: diff --git a/tests/ci_shell.sh b/tests/ci_shell.sh index 92c0f96e8ab..ab87f36cae0 100755 --- a/tests/ci_shell.sh +++ b/tests/ci_shell.sh @@ -1,4 +1,5 @@ -#!/bin/bash -e +#!/usr/bin/env bash +set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" OP_ROOT="$DIR/../../" diff --git a/tests/hitl/run_parallel_tests.sh b/tests/hitl/run_parallel_tests.sh index b6b79d99f6c..f60d838c5b7 100755 --- a/tests/hitl/run_parallel_tests.sh +++ b/tests/hitl/run_parallel_tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/tests/hitl/run_serial_tests.sh b/tests/hitl/run_serial_tests.sh index 31270f044c3..4feae5e30c2 100755 --- a/tests/hitl/run_serial_tests.sh +++ b/tests/hitl/run_serial_tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/tests/misra/checkers.txt b/tests/misra/checkers.txt index a9cc72173c9..00160a5baff 100644 --- a/tests/misra/checkers.txt +++ b/tests/misra/checkers.txt @@ -146,6 +146,7 @@ Yes CheckOther::clarifyCalculation Yes CheckOther::clarifyStatement Yes CheckOther::invalidPointerCast Yes CheckOther::redundantBitwiseOperationInSwitch +Yes CheckOther::suspiciousFloatingPointCast No CheckOther::warningOldStylePointerCast require:style,c++ No CheckPostfixOperator::postfixOperator require:performance Yes CheckSizeof::checkSizeofForArrayParameter @@ -222,11 +223,32 @@ Not available, Cppcheck Premium is not used Misra C 2012 ------------ +No Misra C 2012: Dir 1.1 +No Misra C 2012: Dir 2.1 +No Misra C 2012: Dir 3.1 +No Misra C 2012: Dir 4.1 +No Misra C 2012: Dir 4.2 +No Misra C 2012: Dir 4.3 +No Misra C 2012: Dir 4.4 +No Misra C 2012: Dir 4.5 +No Misra C 2012: Dir 4.6 amendment:3 +No Misra C 2012: Dir 4.7 +No Misra C 2012: Dir 4.8 +No Misra C 2012: Dir 4.9 amendment:3 +No Misra C 2012: Dir 4.10 +No Misra C 2012: Dir 4.11 amendment:3 +No Misra C 2012: Dir 4.12 +No Misra C 2012: Dir 4.13 +No Misra C 2012: Dir 4.14 amendment:2 +No Misra C 2012: Dir 4.15 amendment:3 +No Misra C 2012: Dir 5.1 amendment:4 +No Misra C 2012: Dir 5.2 amendment:4 +No Misra C 2012: Dir 5.3 amendment:4 Yes Misra C 2012: 1.1 Yes Misra C 2012: 1.2 Yes Misra C 2012: 1.3 -Yes Misra C 2012: 1.4 amendment:2 -No Misra C 2012: 1.5 amendment:3 require:premium +Yes Misra C 2012: 1.4 amendment:2 +No Misra C 2012: 1.5 amendment:3 require:premium Yes Misra C 2012: 2.1 Yes Misra C 2012: 2.2 Yes Misra C 2012: 2.3 @@ -303,8 +325,8 @@ Yes Misra C 2012: 12.1 Yes Misra C 2012: 12.2 Yes Misra C 2012: 12.3 Yes Misra C 2012: 12.4 -Yes Misra C 2012: 12.5 amendment:1 -No Misra C 2012: 12.6 amendment:4 require:premium +Yes Misra C 2012: 12.5 amendment:1 +No Misra C 2012: 12.6 amendment:4 require:premium Yes Misra C 2012: 13.1 No Misra C 2012: 13.2 Yes Misra C 2012: 13.3 @@ -380,48 +402,48 @@ Yes Misra C 2012: 21.9 Yes Misra C 2012: 21.10 Yes Misra C 2012: 21.11 Yes Misra C 2012: 21.12 -Yes Misra C 2012: 21.13 amendment:1 -Yes Misra C 2012: 21.14 amendment:1 -Yes Misra C 2012: 21.15 amendment:1 -Yes Misra C 2012: 21.16 amendment:1 -Yes Misra C 2012: 21.17 amendment:1 -Yes Misra C 2012: 21.18 amendment:1 -Yes Misra C 2012: 21.19 amendment:1 -Yes Misra C 2012: 21.20 amendment:1 -Yes Misra C 2012: 21.21 amendment:3 -No Misra C 2012: 21.22 amendment:3 require:premium -No Misra C 2012: 21.23 amendment:3 require:premium -No Misra C 2012: 21.24 amendment:3 require:premium -No Misra C 2012: 21.25 amendment:4 require:premium -No Misra C 2012: 21.26 amendment:4 require:premium +Yes Misra C 2012: 21.13 amendment:1 +Yes Misra C 2012: 21.14 amendment:1 +Yes Misra C 2012: 21.15 amendment:1 +Yes Misra C 2012: 21.16 amendment:1 +Yes Misra C 2012: 21.17 amendment:1 +Yes Misra C 2012: 21.18 amendment:1 +Yes Misra C 2012: 21.19 amendment:1 +Yes Misra C 2012: 21.20 amendment:1 +Yes Misra C 2012: 21.21 amendment:3 +No Misra C 2012: 21.22 amendment:3 require:premium +No Misra C 2012: 21.23 amendment:3 require:premium +No Misra C 2012: 21.24 amendment:3 require:premium +No Misra C 2012: 21.25 amendment:4 require:premium +No Misra C 2012: 21.26 amendment:4 require:premium Yes Misra C 2012: 22.1 Yes Misra C 2012: 22.2 Yes Misra C 2012: 22.3 Yes Misra C 2012: 22.4 Yes Misra C 2012: 22.5 Yes Misra C 2012: 22.6 -Yes Misra C 2012: 22.7 amendment:1 -Yes Misra C 2012: 22.8 amendment:1 -Yes Misra C 2012: 22.9 amendment:1 -Yes Misra C 2012: 22.10 amendment:1 -No Misra C 2012: 22.11 amendment:4 require:premium -No Misra C 2012: 22.12 amendment:4 require:premium -No Misra C 2012: 22.13 amendment:4 require:premium -No Misra C 2012: 22.14 amendment:4 require:premium -No Misra C 2012: 22.15 amendment:4 require:premium -No Misra C 2012: 22.16 amendment:4 require:premium -No Misra C 2012: 22.17 amendment:4 require:premium -No Misra C 2012: 22.18 amendment:4 require:premium -No Misra C 2012: 22.19 amendment:4 require:premium -No Misra C 2012: 22.20 amendment:4 require:premium -No Misra C 2012: 23.1 amendment:3 require:premium -No Misra C 2012: 23.2 amendment:3 require:premium -No Misra C 2012: 23.3 amendment:3 require:premium -No Misra C 2012: 23.4 amendment:3 require:premium -No Misra C 2012: 23.5 amendment:3 require:premium -No Misra C 2012: 23.6 amendment:3 require:premium -No Misra C 2012: 23.7 amendment:3 require:premium -No Misra C 2012: 23.8 amendment:3 require:premium +Yes Misra C 2012: 22.7 amendment:1 +Yes Misra C 2012: 22.8 amendment:1 +Yes Misra C 2012: 22.9 amendment:1 +Yes Misra C 2012: 22.10 amendment:1 +No Misra C 2012: 22.11 amendment:4 require:premium +No Misra C 2012: 22.12 amendment:4 require:premium +No Misra C 2012: 22.13 amendment:4 require:premium +No Misra C 2012: 22.14 amendment:4 require:premium +No Misra C 2012: 22.15 amendment:4 require:premium +No Misra C 2012: 22.16 amendment:4 require:premium +No Misra C 2012: 22.17 amendment:4 require:premium +No Misra C 2012: 22.18 amendment:4 require:premium +No Misra C 2012: 22.19 amendment:4 require:premium +No Misra C 2012: 22.20 amendment:4 require:premium +No Misra C 2012: 23.1 amendment:3 require:premium +No Misra C 2012: 23.2 amendment:3 require:premium +No Misra C 2012: 23.3 amendment:3 require:premium +No Misra C 2012: 23.4 amendment:3 require:premium +No Misra C 2012: 23.5 amendment:3 require:premium +No Misra C 2012: 23.6 amendment:3 require:premium +No Misra C 2012: 23.7 amendment:3 require:premium +No Misra C 2012: 23.8 amendment:3 require:premium Misra C++ 2008 @@ -579,6 +601,7 @@ Yes CheckOther::clarifyCalculation Yes CheckOther::clarifyStatement Yes CheckOther::invalidPointerCast Yes CheckOther::redundantBitwiseOperationInSwitch +Yes CheckOther::suspiciousFloatingPointCast No CheckOther::warningOldStylePointerCast require:style,c++ No CheckPostfixOperator::postfixOperator require:performance Yes CheckSizeof::checkSizeofForArrayParameter @@ -655,11 +678,32 @@ Not available, Cppcheck Premium is not used Misra C 2012 ------------ +No Misra C 2012: Dir 1.1 +No Misra C 2012: Dir 2.1 +No Misra C 2012: Dir 3.1 +No Misra C 2012: Dir 4.1 +No Misra C 2012: Dir 4.2 +No Misra C 2012: Dir 4.3 +No Misra C 2012: Dir 4.4 +No Misra C 2012: Dir 4.5 +No Misra C 2012: Dir 4.6 amendment:3 +No Misra C 2012: Dir 4.7 +No Misra C 2012: Dir 4.8 +No Misra C 2012: Dir 4.9 amendment:3 +No Misra C 2012: Dir 4.10 +No Misra C 2012: Dir 4.11 amendment:3 +No Misra C 2012: Dir 4.12 +No Misra C 2012: Dir 4.13 +No Misra C 2012: Dir 4.14 amendment:2 +No Misra C 2012: Dir 4.15 amendment:3 +No Misra C 2012: Dir 5.1 amendment:4 +No Misra C 2012: Dir 5.2 amendment:4 +No Misra C 2012: Dir 5.3 amendment:4 Yes Misra C 2012: 1.1 Yes Misra C 2012: 1.2 Yes Misra C 2012: 1.3 -Yes Misra C 2012: 1.4 amendment:2 -No Misra C 2012: 1.5 amendment:3 require:premium +Yes Misra C 2012: 1.4 amendment:2 +No Misra C 2012: 1.5 amendment:3 require:premium Yes Misra C 2012: 2.1 Yes Misra C 2012: 2.2 Yes Misra C 2012: 2.3 @@ -736,8 +780,8 @@ Yes Misra C 2012: 12.1 Yes Misra C 2012: 12.2 Yes Misra C 2012: 12.3 Yes Misra C 2012: 12.4 -Yes Misra C 2012: 12.5 amendment:1 -No Misra C 2012: 12.6 amendment:4 require:premium +Yes Misra C 2012: 12.5 amendment:1 +No Misra C 2012: 12.6 amendment:4 require:premium Yes Misra C 2012: 13.1 No Misra C 2012: 13.2 Yes Misra C 2012: 13.3 @@ -813,48 +857,48 @@ Yes Misra C 2012: 21.9 Yes Misra C 2012: 21.10 Yes Misra C 2012: 21.11 Yes Misra C 2012: 21.12 -Yes Misra C 2012: 21.13 amendment:1 -Yes Misra C 2012: 21.14 amendment:1 -Yes Misra C 2012: 21.15 amendment:1 -Yes Misra C 2012: 21.16 amendment:1 -Yes Misra C 2012: 21.17 amendment:1 -Yes Misra C 2012: 21.18 amendment:1 -Yes Misra C 2012: 21.19 amendment:1 -Yes Misra C 2012: 21.20 amendment:1 -Yes Misra C 2012: 21.21 amendment:3 -No Misra C 2012: 21.22 amendment:3 require:premium -No Misra C 2012: 21.23 amendment:3 require:premium -No Misra C 2012: 21.24 amendment:3 require:premium -No Misra C 2012: 21.25 amendment:4 require:premium -No Misra C 2012: 21.26 amendment:4 require:premium +Yes Misra C 2012: 21.13 amendment:1 +Yes Misra C 2012: 21.14 amendment:1 +Yes Misra C 2012: 21.15 amendment:1 +Yes Misra C 2012: 21.16 amendment:1 +Yes Misra C 2012: 21.17 amendment:1 +Yes Misra C 2012: 21.18 amendment:1 +Yes Misra C 2012: 21.19 amendment:1 +Yes Misra C 2012: 21.20 amendment:1 +Yes Misra C 2012: 21.21 amendment:3 +No Misra C 2012: 21.22 amendment:3 require:premium +No Misra C 2012: 21.23 amendment:3 require:premium +No Misra C 2012: 21.24 amendment:3 require:premium +No Misra C 2012: 21.25 amendment:4 require:premium +No Misra C 2012: 21.26 amendment:4 require:premium Yes Misra C 2012: 22.1 Yes Misra C 2012: 22.2 Yes Misra C 2012: 22.3 Yes Misra C 2012: 22.4 Yes Misra C 2012: 22.5 Yes Misra C 2012: 22.6 -Yes Misra C 2012: 22.7 amendment:1 -Yes Misra C 2012: 22.8 amendment:1 -Yes Misra C 2012: 22.9 amendment:1 -Yes Misra C 2012: 22.10 amendment:1 -No Misra C 2012: 22.11 amendment:4 require:premium -No Misra C 2012: 22.12 amendment:4 require:premium -No Misra C 2012: 22.13 amendment:4 require:premium -No Misra C 2012: 22.14 amendment:4 require:premium -No Misra C 2012: 22.15 amendment:4 require:premium -No Misra C 2012: 22.16 amendment:4 require:premium -No Misra C 2012: 22.17 amendment:4 require:premium -No Misra C 2012: 22.18 amendment:4 require:premium -No Misra C 2012: 22.19 amendment:4 require:premium -No Misra C 2012: 22.20 amendment:4 require:premium -No Misra C 2012: 23.1 amendment:3 require:premium -No Misra C 2012: 23.2 amendment:3 require:premium -No Misra C 2012: 23.3 amendment:3 require:premium -No Misra C 2012: 23.4 amendment:3 require:premium -No Misra C 2012: 23.5 amendment:3 require:premium -No Misra C 2012: 23.6 amendment:3 require:premium -No Misra C 2012: 23.7 amendment:3 require:premium -No Misra C 2012: 23.8 amendment:3 require:premium +Yes Misra C 2012: 22.7 amendment:1 +Yes Misra C 2012: 22.8 amendment:1 +Yes Misra C 2012: 22.9 amendment:1 +Yes Misra C 2012: 22.10 amendment:1 +No Misra C 2012: 22.11 amendment:4 require:premium +No Misra C 2012: 22.12 amendment:4 require:premium +No Misra C 2012: 22.13 amendment:4 require:premium +No Misra C 2012: 22.14 amendment:4 require:premium +No Misra C 2012: 22.15 amendment:4 require:premium +No Misra C 2012: 22.16 amendment:4 require:premium +No Misra C 2012: 22.17 amendment:4 require:premium +No Misra C 2012: 22.18 amendment:4 require:premium +No Misra C 2012: 22.19 amendment:4 require:premium +No Misra C 2012: 22.20 amendment:4 require:premium +No Misra C 2012: 23.1 amendment:3 require:premium +No Misra C 2012: 23.2 amendment:3 require:premium +No Misra C 2012: 23.3 amendment:3 require:premium +No Misra C 2012: 23.4 amendment:3 require:premium +No Misra C 2012: 23.5 amendment:3 require:premium +No Misra C 2012: 23.6 amendment:3 require:premium +No Misra C 2012: 23.7 amendment:3 require:premium +No Misra C 2012: 23.8 amendment:3 require:premium Misra C++ 2008 diff --git a/tests/misra/install.sh b/tests/misra/install.sh index e0a743b72e4..c1fdbe83834 100755 --- a/tests/misra/install.sh +++ b/tests/misra/install.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" @@ -10,7 +10,7 @@ fi cd $CPPCHECK_DIR -VERS="2.14.1" +VERS="2.15.0" git fetch --all --tags --force git checkout $VERS diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index e65f6a5e5ab..c35ed02a131 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" @@ -19,7 +19,7 @@ fi # ensure checked in coverage table is up to date cd $DIR if [ -z "$SKIP_TABLES_DIFF" ]; then - python $CPPCHECK_DIR/addons/misra.py -generate-table > coverage_table + python3 $CPPCHECK_DIR/addons/misra.py -generate-table > coverage_table if ! git diff --quiet coverage_table; then echo -e "${YELLOW}MISRA coverage table doesn't match. Update and commit:${NC}" exit 3 @@ -48,10 +48,10 @@ cppcheck() { -I "$(arm-none-eabi-gcc -print-file-name=include)" \ -I $PANDA_DIR/board/stm32f4/inc/ -I $PANDA_DIR/board/stm32h7/inc/ \ --suppressions-list=$DIR/suppressions.txt --suppress=*:*inc/* \ - --suppress=*:*include/* --error-exitcode=2 --check-level=exhaustive \ + --suppress=*:*include/* --error-exitcode=2 --check-level=exhaustive --safety \ --platform=arm32-wchar_t4 $COMMON_DEFINES --checkers-report=$CHECKLIST.tmp \ --std=c11 "$@" |& tee $OUTPUT - + cat $CHECKLIST.tmp >> $CHECKLIST rm $CHECKLIST.tmp # cppcheck bug: some MISRA errors won't result in the error exit code, diff --git a/tests/read_st_flash.sh b/tests/read_st_flash.sh index ffcfd7bbfe7..65b0709f6cd 100755 --- a/tests/read_st_flash.sh +++ b/tests/read_st_flash.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash rm -f /tmp/dump_bootstub rm -f /tmp/dump_main dfu-util -a 0 -s 0x08000000 -U /tmp/dump_bootstub diff --git a/tests/setup_device_ci.sh b/tests/setup_device_ci.sh index b45c6b466b2..a74ce7a2c99 100755 --- a/tests/setup_device_ci.sh +++ b/tests/setup_device_ci.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash set -e @@ -19,7 +19,7 @@ fi CONTINUE_PATH="/data/continue.sh" tee $CONTINUE_PATH << EOF -#!/usr/bin/bash +#!/usr/bin/env bash sudo abctl --set_success diff --git a/tests/som_debug.sh b/tests/som_debug.sh index 9bb4219713e..6f0a86537c4 100755 --- a/tests/som_debug.sh +++ b/tests/som_debug.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/tests/usbprotocol/test.sh b/tests/usbprotocol/test.sh index 8e3886da7d5..b4c32166b98 100755 --- a/tests/usbprotocol/test.sh +++ b/tests/usbprotocol/test.sh @@ -4,5 +4,5 @@ set -e # Loops over all HW_TYPEs, see board/boards/board_declarations.h for hw_type in {0..7}; do echo "Testing HW_TYPE: $hw_type" - HW_TYPE=$hw_type python -m unittest discover . + HW_TYPE=$hw_type python3 -m unittest discover . done