diff --git a/.github/workflows/drivers.yaml b/.github/workflows/drivers.yaml index c425d4c67c..78efcdeab2 100644 --- a/.github/workflows/drivers.yaml +++ b/.github/workflows/drivers.yaml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: build_socketcan: name: socketcan build - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/repo.yml b/.github/workflows/repo.yml index 1e3dcf9c0f..1191aaf9d1 100644 --- a/.github/workflows/repo.yml +++ b/.github/workflows/repo.yml @@ -8,7 +8,7 @@ on: jobs: pre-commit-autoupdate: name: pre-commit autoupdate - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest container: image: ghcr.io/commaai/panda:latest steps: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 968ee3ecf8..97c9e07f0e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -21,7 +21,7 @@ env: jobs: docker_push: name: docker push - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 20 if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/panda' steps: @@ -38,7 +38,7 @@ jobs: build: name: build - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v2 @@ -57,7 +57,7 @@ jobs: unit_tests: name: unit tests - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v2 @@ -70,7 +70,7 @@ jobs: safety: name: safety - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: flags: ['', '--ubsan'] @@ -82,16 +82,13 @@ jobs: - name: Run safety tests timeout-minutes: 5 run: | - ${{ env.RUN }} "cd .. && \ - scons -c && \ - scons -j$(nproc) opendbc/ cereal/ && \ - cd panda && \ + ${{ env.RUN }} "scons -c -j$(nproc) && \ scons -j$(nproc) ${{ matrix.flags }} && \ tests/safety/test.sh" misra: name: MISRA C:2012 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v2 @@ -103,12 +100,12 @@ jobs: timeout-minutes: 1 run: ${{ env.RUN }} "cd tests/misra && ./test_misra.sh" - name: MISRA mutation tests - timeout-minutes: 4 - run: ${{ env.RUN }} "cd tests/misra && ./test_mutation.py" + timeout-minutes: 5 + run: ${{ env.RUN }} "cd tests/misra && pytest -n8 test_mutation.py" python_linter: name: python linter - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1f978433e2..a9d1d81664 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-ast - id: check-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.8.0 + rev: v1.9.0 hooks: - id: mypy additional_dependencies: ['git+https://github.com/numpy/numpy-stubs', 'types-requests', 'types-atomicwrites', 'types-pycurl'] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.2 + rev: v0.4.1 hooks: - id: ruff diff --git a/Dockerfile b/Dockerfile index b2c2073297..74afcb6b5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,44 +1,36 @@ -FROM ubuntu:20.04 +FROM ubuntu:24.04 + ENV PYTHONUNBUFFERED 1 ENV PYTHONPATH /tmp/openpilot:$PYTHONPATH ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ - autoconf \ - automake \ + make \ bzip2 \ ca-certificates \ capnproto \ clang \ - curl \ g++ \ gcc-arm-none-eabi libnewlib-arm-none-eabi \ git \ libarchive-dev \ - libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libavresample-dev libavfilter-dev \ libbz2-dev \ libcapnp-dev \ - libcurl4-openssl-dev \ libffi-dev \ libtool \ - libssl-dev \ - libsqlite3-dev \ libusb-1.0-0 \ libzmq3-dev \ locales \ opencl-headers \ ocl-icd-opencl-dev \ - make \ - patch \ - pkg-config \ - python \ - python-dev \ - qt5-default \ - unzip \ - wget \ + python3 \ + python3-dev \ + python3-pip \ + python-is-python3 \ zlib1g-dev \ && rm -rf /var/lib/apt/lists/* && \ - cd /usr/lib/gcc/arm-none-eabi/9.2.1 && \ + 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 @@ -47,43 +39,27 @@ ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 -RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash -ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" - -ENV PANDA_PATH=/tmp/openpilot/panda -ENV OPENPILOT_REF="5690386d8d731c9bebda536a5c71c890f6dfe98c" -ENV OPENDBC_REF="40d9c723d48496229fecc436046538a53af19c11" - COPY requirements.txt /tmp/ -RUN pyenv install 3.11.4 && \ - pyenv global 3.11.4 && \ - pyenv rehash && \ - pip install --no-cache-dir -r /tmp/requirements.txt +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 - -RUN git config --global --add safe.directory /tmp/openpilot/panda -RUN cd /tmp && \ - git clone https://github.com/commaai/openpilot.git tmppilot || true && \ - cd /tmp/tmppilot && \ - git fetch origin $OPENPILOT_REF && \ - git checkout $OPENPILOT_REF && \ - git submodule update --init cereal opendbc rednose_repo body && \ - git -C opendbc fetch && \ - git -C opendbc checkout $OPENDBC_REF && \ - git -C opendbc reset --hard HEAD && \ - git -C opendbc clean -xfd && \ - mkdir /tmp/openpilot && \ - cp -pR SConstruct site_scons/ tools/ selfdrive/ system/ common/ cereal/ opendbc/ rednose/ third_party/ body/ /tmp/openpilot && \ - rm -rf /tmp/openpilot/panda && \ - rm -rf /tmp/tmppilot +RUN /tmp/install.sh && rm -rf $CPPCHECK_DIR/.git/ +ENV SKIP_CPPCHECK_INSTALL=1 -RUN cd /tmp/openpilot && \ - pip install --no-cache-dir -r opendbc/requirements.txt && \ - pip install --no-cache-dir --upgrade aenum lru-dict pycurl tenacity atomicwrites serial smbus2 +ENV CEREAL_REF="861144c136c91f70dcbc652c2ffe99f57440ad47" +ENV OPENDBC_REF="e0d4be4a6215d44809718dc84efe1b9f0299ad63" +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/ # for Jenkins COPY README.md panda.tar.* /tmp/ diff --git a/Jenkinsfile b/Jenkinsfile index 25b8490a00..2d4c615dfe 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -82,7 +82,7 @@ pipeline { ["build", "scons -j4"], ["flash", "cd tests/ && ./reflash_internal_panda.py"], ["flash jungle", "cd board/jungle && ./flash.py"], - ["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-7]*.py -k 'not test_send_recv'"], + ["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-9]*.py -k 'not test_send_recv'"], ]) } } @@ -130,24 +130,6 @@ pipeline { } } } - - /* - stage('HITL tests') { - steps { - script { - docker_run("parallel tests", 5, 'PANDAS_JUNGLE=23002d000851393038373731 PANDAS_EXCLUDE="1d0002000c51303136383232 2f002e000c51303136383232" ./tests/hitl/run_parallel_tests.sh') - docker_run("serial tests", 9, 'PANDAS_JUNGLE=23002d000851393038373731 PANDAS_EXCLUDE="1d0002000c51303136383232 2f002e000c51303136383232" ./tests/hitl/run_serial_tests.sh') - } - } - } - stage('CANFD tests') { - steps { - script { - docker_run("CANFD tets", 6, 'JUNGLE=058010800f51363038363036 H7_PANDAS_EXCLUDE="080021000c51303136383232 33000e001051393133353939" ./tests/canfd/test_canfd.py') - } - } - } - */ } } } diff --git a/SConscript b/SConscript index 357daba954..f44105fd26 100644 --- a/SConscript +++ b/SConscript @@ -84,7 +84,7 @@ def build_project(project_name, project, extra_flags): '..', panda_root, f"{panda_root}/board/", - f"{panda_root}/board/stm32fx/inc", + f"{panda_root}/board/stm32f4/inc", f"{panda_root}/board/stm32h7/inc", ] @@ -130,8 +130,8 @@ def build_project(project_name, project, extra_flags): base_project_f4 = { "MAIN": "main.c", - "STARTUP_FILE": File("./board/stm32fx/startup_stm32f413xx.s"), - "LINKER_SCRIPT": File("./board/stm32fx/stm32f4_flash.ld"), + "STARTUP_FILE": File("./board/stm32f4/startup_stm32f413xx.s"), + "LINKER_SCRIPT": File("./board/stm32f4/stm32f4_flash.ld"), "APP_START_ADDRESS": "0x8004000", "PROJECT_FLAGS": [ "-mcpu=cortex-m4", diff --git a/board/boards/black.h b/board/boards/black.h index ea636334d2..c860d1401d 100644 --- a/board/boards/black.h +++ b/board/boards/black.h @@ -122,8 +122,6 @@ void black_init(void) { // Initialize harness harness_init(); - // Initialize RTC - rtc_init(); // Enable CAN transceivers black_enable_can_transceivers(true); @@ -135,11 +133,6 @@ void black_init(void) { // Set normal CAN mode black_set_can_mode(CAN_MODE_NORMAL); - - // change CAN mapping when flipped - if (harness.status == HARNESS_STATUS_FLIPPED) { - can_flip_buses(0, 2); - } } void black_init_bootloader(void) { @@ -148,7 +141,7 @@ void black_init_bootloader(void) { set_gpio_output(GPIOC, 12, 0); } -const harness_configuration black_harness_config = { +harness_configuration black_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOC, @@ -162,13 +155,12 @@ const harness_configuration black_harness_config = { .adc_channel_SBU2 = 13 }; -const board board_black = { +board board_black = { .set_bootkick = unused_set_bootkick, .harness_config = &black_harness_config, .has_obd = true, .has_spi = false, .has_canfd = false, - .has_rtc_battery = false, .fan_max_rpm = 0U, .avdd_mV = 3300U, .fan_stall_recovery = false, diff --git a/board/boards/board_declarations.h b/board/boards/board_declarations.h index 600dc2884e..a9ff9297ba 100644 --- a/board/boards/board_declarations.h +++ b/board/boards/board_declarations.h @@ -21,11 +21,10 @@ typedef void (*board_set_bootkick)(BootState state); typedef bool (*board_read_som_gpio)(void); struct board { - const harness_configuration *harness_config; + harness_configuration *harness_config; const bool has_obd; const bool has_spi; const bool has_canfd; - const bool has_rtc_battery; const uint16_t fan_max_rpm; const uint16_t avdd_mV; const bool fan_stall_recovery; @@ -73,6 +72,4 @@ struct board { // CAN modes #define CAN_MODE_NORMAL 0U -#define CAN_MODE_GMLAN_CAN2 1U -#define CAN_MODE_GMLAN_CAN3 2U -#define CAN_MODE_OBD_CAN2 3U +#define CAN_MODE_OBD_CAN2 1U diff --git a/board/boards/cuatro.h b/board/boards/cuatro.h index b8cd3d035a..43a5dfc505 100644 --- a/board/boards/cuatro.h +++ b/board/boards/cuatro.h @@ -103,12 +103,11 @@ void cuatro_init(void) { clock_source_init(); } -const board board_cuatro = { +board board_cuatro = { .harness_config = &red_chiplet_harness_config, .has_obd = true, .has_spi = true, .has_canfd = true, - .has_rtc_battery = true, .fan_max_rpm = 6600U, .avdd_mV = 1800U, .fan_stall_recovery = false, diff --git a/board/boards/dos.h b/board/boards/dos.h index 428bbf2a5e..0164f2b262 100644 --- a/board/boards/dos.h +++ b/board/boards/dos.h @@ -147,8 +147,6 @@ void dos_init(void) { // Initialize harness harness_init(); - // Initialize RTC - rtc_init(); // Enable CAN transceivers dos_enable_can_transceivers(true); @@ -164,16 +162,11 @@ void dos_init(void) { // Set normal CAN mode dos_set_can_mode(CAN_MODE_NORMAL); - // change CAN mapping when flipped - if (harness.status == HARNESS_STATUS_FLIPPED) { - can_flip_buses(0, 2); - } - // Init clock source (camera strobe) using PWM clock_source_init(); } -const harness_configuration dos_harness_config = { +harness_configuration dos_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOC, @@ -187,7 +180,7 @@ const harness_configuration dos_harness_config = { .adc_channel_SBU2 = 13 }; -const board board_dos = { +board board_dos = { .harness_config = &dos_harness_config, .has_obd = true, #ifdef ENABLE_SPI @@ -196,7 +189,6 @@ const board board_dos = { .has_spi = false, #endif .has_canfd = false, - .has_rtc_battery = true, .fan_max_rpm = 6500U, .avdd_mV = 3300U, .fan_stall_recovery = true, diff --git a/board/boards/grey.h b/board/boards/grey.h index 8b3bd8aed5..516d0fa70f 100644 --- a/board/boards/grey.h +++ b/board/boards/grey.h @@ -4,13 +4,12 @@ // Most hardware functionality is similar to white panda -const board board_grey = { +board board_grey = { .set_bootkick = unused_set_bootkick, .harness_config = &white_harness_config, .has_obd = false, .has_spi = false, .has_canfd = false, - .has_rtc_battery = false, .fan_max_rpm = 0U, .avdd_mV = 3300U, .fan_stall_recovery = false, diff --git a/board/boards/red.h b/board/boards/red.h index aa8c91be79..746c54b622 100644 --- a/board/boards/red.h +++ b/board/boards/red.h @@ -140,8 +140,6 @@ void red_init(void) { // Initialize harness harness_init(); - // Initialize RTC - rtc_init(); // Enable CAN transceivers red_enable_can_transceivers(true); @@ -153,14 +151,9 @@ void red_init(void) { // Set normal CAN mode red_set_can_mode(CAN_MODE_NORMAL); - - // change CAN mapping when flipped - if (harness.status == HARNESS_STATUS_FLIPPED) { - can_flip_buses(0, 2); - } } -const harness_configuration red_harness_config = { +harness_configuration red_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOA, @@ -174,13 +167,12 @@ const harness_configuration red_harness_config = { .adc_channel_SBU2 = 17 //ADC1_INP17 }; -const board board_red = { +board board_red = { .set_bootkick = unused_set_bootkick, .harness_config = &red_harness_config, .has_obd = true, .has_spi = false, .has_canfd = true, - .has_rtc_battery = false, .fan_max_rpm = 0U, .avdd_mV = 3300U, .fan_stall_recovery = false, diff --git a/board/boards/red_chiplet.h b/board/boards/red_chiplet.h index eec3d95cdf..d79f8f83a6 100644 --- a/board/boards/red_chiplet.h +++ b/board/boards/red_chiplet.h @@ -119,8 +119,6 @@ void red_chiplet_init(void) { // Initialize harness harness_init(); - // Initialize RTC - rtc_init(); // Enable CAN transceivers red_chiplet_enable_can_transceivers(true); @@ -132,14 +130,9 @@ void red_chiplet_init(void) { // Set normal CAN mode red_chiplet_set_can_mode(CAN_MODE_NORMAL); - - // change CAN mapping when flipped - if (harness.status == HARNESS_STATUS_FLIPPED) { - can_flip_buses(0, 2); - } } -const harness_configuration red_chiplet_harness_config = { +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 959c93b5d2..91b94f68e2 100644 --- a/board/boards/tres.h +++ b/board/boards/tres.h @@ -33,7 +33,7 @@ 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); - while ((PWR->CR3 & PWR_CR3_USB33RDY) == 0); + while ((PWR->CR3 & PWR_CR3_USB33RDY) == 0U); red_chiplet_init(); @@ -70,12 +70,11 @@ void tres_init(void) { clock_source_init(); } -const board board_tres = { +board board_tres = { .harness_config = &red_chiplet_harness_config, .has_obd = true, .has_spi = true, .has_canfd = true, - .has_rtc_battery = true, .fan_max_rpm = 6600U, .avdd_mV = 1800U, .fan_stall_recovery = false, diff --git a/board/boards/uno.h b/board/boards/uno.h index f4e2016bd1..a2e1e98354 100644 --- a/board/boards/uno.h +++ b/board/boards/uno.h @@ -147,8 +147,6 @@ void uno_init(void) { // Initialize harness harness_init(); - // Initialize RTC - rtc_init(); // Enable CAN transceivers uno_enable_can_transceivers(true); @@ -161,11 +159,6 @@ void uno_init(void) { // Set normal CAN mode uno_set_can_mode(CAN_MODE_NORMAL); - // change CAN mapping when flipped - if (harness.status == HARNESS_STATUS_FLIPPED) { - can_flip_buses(0, 2); - } - // Switch to phone usb mode if harness connection is powered by less than 7V if(white_read_voltage_mV() < 7000U){ uno_set_usb_switch(true); @@ -184,7 +177,7 @@ void uno_init_bootloader(void) { set_gpio_output(GPIOC, 12, 0); } -const harness_configuration uno_harness_config = { +harness_configuration uno_harness_config = { .has_harness = true, .GPIO_SBU1 = GPIOC, .GPIO_SBU2 = GPIOC, @@ -198,12 +191,11 @@ const harness_configuration uno_harness_config = { .adc_channel_SBU2 = 13 }; -const board board_uno = { +board board_uno = { .harness_config = &uno_harness_config, .has_obd = true, .has_spi = false, .has_canfd = false, - .has_rtc_battery = true, .fan_max_rpm = 5100U, .avdd_mV = 3300U, .fan_stall_recovery = false, diff --git a/board/boards/white.h b/board/boards/white.h index 0de29a39be..8d22afbc9b 100644 --- a/board/boards/white.h +++ b/board/boards/white.h @@ -66,61 +66,22 @@ void white_set_usb_power_mode(uint8_t mode){ } void white_set_can_mode(uint8_t mode){ - switch (mode) { - case CAN_MODE_NORMAL: - // B12,B13: disable GMLAN mode - set_gpio_mode(GPIOB, 12, MODE_INPUT); - set_gpio_mode(GPIOB, 13, MODE_INPUT); - - // B3,B4: disable GMLAN mode - set_gpio_mode(GPIOB, 3, MODE_INPUT); - set_gpio_mode(GPIOB, 4, MODE_INPUT); - - // B5,B6: normal CAN2 mode - set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); - set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); - - // A8,A15: normal CAN3 mode - set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3); - set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3); - break; - case CAN_MODE_GMLAN_CAN2: - // B5,B6: disable CAN2 mode - set_gpio_mode(GPIOB, 5, MODE_INPUT); - set_gpio_mode(GPIOB, 6, MODE_INPUT); - - // B3,B4: disable GMLAN mode - set_gpio_mode(GPIOB, 3, MODE_INPUT); - set_gpio_mode(GPIOB, 4, MODE_INPUT); - - // B12,B13: GMLAN mode - set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); - set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); - - // A8,A15: normal CAN3 mode - set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3); - set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3); - break; - case CAN_MODE_GMLAN_CAN3: - // A8,A15: disable CAN3 mode - set_gpio_mode(GPIOA, 8, MODE_INPUT); - set_gpio_mode(GPIOA, 15, MODE_INPUT); - - // B12,B13: disable GMLAN mode - set_gpio_mode(GPIOB, 12, MODE_INPUT); - set_gpio_mode(GPIOB, 13, MODE_INPUT); - - // B3,B4: GMLAN mode - set_gpio_alternate(GPIOB, 3, GPIO_AF11_CAN3); - set_gpio_alternate(GPIOB, 4, GPIO_AF11_CAN3); - - // B5,B6: normal CAN2 mode - set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); - set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); - break; - default: - print("Tried to set unsupported CAN mode: "); puth(mode); print("\n"); - break; + if (mode == CAN_MODE_NORMAL) { + // B12,B13: disable GMLAN mode + set_gpio_mode(GPIOB, 12, MODE_INPUT); + set_gpio_mode(GPIOB, 13, MODE_INPUT); + + // B3,B4: disable GMLAN mode + set_gpio_mode(GPIOB, 3, MODE_INPUT); + set_gpio_mode(GPIOB, 4, MODE_INPUT); + + // B5,B6: normal CAN2 mode + set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); + set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); + + // A8,A15: normal CAN3 mode + set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3); + set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3); } } @@ -168,8 +129,8 @@ void white_grey_init(void) { 0 1 high voltage wakeup 1 1 33kbit (normal) */ - set_gpio_output(GPIOB, 14, 1); - set_gpio_output(GPIOB, 15, 1); + set_gpio_output(GPIOB, 14, 0); + set_gpio_output(GPIOB, 15, 0); // B7: K-line enable set_gpio_output(GPIOB, 7, 1); @@ -187,8 +148,6 @@ void white_grey_init(void) { set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3); set_gpio_pullup(GPIOC, 11, PULL_UP); - // Initialize RTC - rtc_init(); // Enable CAN transceivers white_enable_can_transceivers(true); @@ -221,17 +180,16 @@ void white_grey_init_bootloader(void) { set_gpio_output(GPIOC, 14, 0); } -const harness_configuration white_harness_config = { +harness_configuration white_harness_config = { .has_harness = false }; -const board board_white = { +board board_white = { .set_bootkick = unused_set_bootkick, .harness_config = &white_harness_config, .has_obd = false, .has_spi = false, .has_canfd = false, - .has_rtc_battery = false, .fan_max_rpm = 0U, .avdd_mV = 3300U, .fan_stall_recovery = false, diff --git a/board/bootstub_declarations.h b/board/bootstub_declarations.h index ae115d2eb3..5cdec508e7 100644 --- a/board/bootstub_declarations.h +++ b/board/bootstub_declarations.h @@ -6,8 +6,6 @@ void puth4(uint8_t i){ UNUSED(i); } void hexdump(const void *a, int l){ UNUSED(a); UNUSED(l); } typedef struct board board; typedef struct harness_configuration harness_configuration; -// No CAN support on bootloader -void can_flip_buses(uint8_t bus1, uint8_t bus2){UNUSED(bus1); UNUSED(bus2);} void pwm_init(TIM_TypeDef *TIM, uint8_t channel); void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage); // No UART support in bootloader @@ -17,4 +15,4 @@ void uart_init(uart_ring *q, int baud) { UNUSED(q); UNUSED(baud); } // ********************* Globals ********************** uint8_t hw_type = 0; -const board *current_board; +board *current_board; diff --git a/board/can_definitions.h b/board/can_definitions.h index b3631d8071..f3ce437827 100644 --- a/board/can_definitions.h +++ b/board/can_definitions.h @@ -1,7 +1,7 @@ #pragma once const uint8_t PANDA_CAN_CNT = 3U; -const uint8_t PANDA_BUS_CNT = 4U; +const uint8_t PANDA_BUS_CNT = 3U; // bump this when changing the CAN packet #define CAN_PACKET_VERSION 4 diff --git a/board/config.h b/board/config.h index 0adcc3e09a..ef9ffcb8dc 100644 --- a/board/config.h +++ b/board/config.h @@ -11,7 +11,6 @@ //#define DEBUG_FAN #define CAN_INIT_TIMEOUT_MS 500U -#define DEEPSLEEP_WAKEUP_DELAY 3U #define USBPACKET_MAX_SIZE 0x40U #define MAX_CAN_MSGS_PER_USB_BULK_TRANSFER 51U #define MAX_CAN_MSGS_PER_SPI_BULK_TRANSFER 170U @@ -37,7 +36,7 @@ #ifdef STM32H7 #include "stm32h7/stm32h7_config.h" #elif defined(STM32F4) - #include "stm32fx/stm32fx_config.h" + #include "stm32f4/stm32f4_config.h" #else // TODO: uncomment this, cppcheck complains // building for tests diff --git a/board/debug/README.md b/board/debug/README.md index d89eab818a..d475ce90b6 100644 --- a/board/debug/README.md +++ b/board/debug/README.md @@ -11,7 +11,7 @@ Connect an ST-Link V2 programmer to the SWD pins on the board. The pins that nee Make sure you're using a genuine one for boards that do not have a 3.3V panda power rail. For example, the tres runs at 1.8V, which is not supported by the clones. ## Openocd -Install openocd. For Ubuntu 20.04, the one in the package manager works fine: `sudo apt install openocd`. +Install openocd. For Ubuntu 24.04, the one in the package manager works fine: `sudo apt install openocd`. To run, use `./debug_f4.sh (TODO)` or `./debug_h7.sh` depending on the panda. diff --git a/board/drivers/bxcan.h b/board/drivers/bxcan.h index ea2705d9d0..27ffcee525 100644 --- a/board/drivers/bxcan.h +++ b/board/drivers/bxcan.h @@ -48,7 +48,7 @@ void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { can_health[can_number].total_error_cnt += 1U; // RX message lost due to FIFO overrun - if ((CANx->RF0R & (CAN_RF0R_FOVR0)) != 0) { + if ((CANx->RF0R & (CAN_RF0R_FOVR0)) != 0U) { can_health[can_number].total_rx_lost_cnt += 1U; CANx->RF0R &= ~(CAN_RF0R_FOVR0); } @@ -74,7 +74,7 @@ void process_can(uint8_t can_number) { // check for empty mailbox CANPacket_t to_send; - if ((CANx->TSR & (CAN_TSR_TERR0 | CAN_TSR_ALST0)) != 0) { // last TX failed due to error arbitration lost + if ((CANx->TSR & (CAN_TSR_TERR0 | CAN_TSR_ALST0)) != 0U) { // last TX failed due to error arbitration lost can_health[can_number].total_tx_lost_cnt += 1U; CANx->TSR |= (CAN_TSR_TERR0 | CAN_TSR_ALST0); } @@ -129,7 +129,7 @@ void can_rx(uint8_t can_number) { CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number); uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - while ((CANx->RF0R & CAN_RF0R_FMP0) != 0) { + while ((CANx->RF0R & CAN_RF0R_FMP0) != 0U) { can_health[can_number].total_rx_cnt += 1U; // can is live diff --git a/board/drivers/can_common.h b/board/drivers/can_common.h index bc9adde7ce..6b9b41fd9a 100644 --- a/board/drivers/can_common.h +++ b/board/drivers/can_common.h @@ -20,7 +20,6 @@ uint32_t safety_tx_blocked = 0; uint32_t safety_rx_invalid = 0; uint32_t tx_buffer_overflow = 0; uint32_t rx_buffer_overflow = 0; -uint32_t gmlan_send_errs = 0; can_health_t can_health[] = {{0}, {0}, {0}}; @@ -54,7 +53,6 @@ void process_can(uint8_t can_number); #define CAN_RX_BUFFER_SIZE 4096U #define CAN_TX_BUFFER_SIZE 416U -#define GMLAN_TX_BUFFER_SIZE 416U #ifdef STM32H7 // ITCM RAM and DTCM RAM are the fastest for Cortex-M7 core access @@ -67,10 +65,10 @@ can_buffer(tx1_q, CAN_TX_BUFFER_SIZE) can_buffer(tx2_q, CAN_TX_BUFFER_SIZE) #endif can_buffer(tx3_q, CAN_TX_BUFFER_SIZE) -can_buffer(txgmlan_q, GMLAN_TX_BUFFER_SIZE) + // FIXME: // cppcheck-suppress misra-c2012-9.3 -can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q}; +can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q}; // helpers #define WORD_TO_BYTE_ARRAY(dst8, src32) 0[dst8] = ((src32) & 0xFFU); 1[dst8] = (((src32) >> 8U) & 0xFFU); 2[dst8] = (((src32) >> 16U) & 0xFFU); 3[dst8] = (((src32) >> 24U) & 0xFFU) @@ -122,8 +120,6 @@ bool can_push(can_ring *q, const CANPacket_t *elem) { print("can_tx2_q"); } else if (q == &can_tx3_q) { print("can_tx3_q"); - } else if (q == &can_txgmlan_q) { - print("can_txgmlan_q"); } else { print("unknown"); } @@ -157,7 +153,7 @@ void can_clear(can_ring *q) { } // assign CAN numbering -// bus num: Can bus number on ODB connector. Sent to/from USB +// bus num: CAN Bus numbers in panda, sent to/from USB // Min: 0; Max: 127; Bit 7 marks message as receipt (bus 129 is receipt for but 1) // cans: Look up MCU can interface from bus number // can number: numeric lookup for MCU CAN interfaces (0 = CAN1, 1 = CAN2, etc); @@ -179,22 +175,20 @@ bus_config_t bus_config[] = { #define CAN_NUM_FROM_BUS_NUM(num) (bus_config[num].can_num_lookup) void can_init_all(void) { - bool ret = true; for (uint8_t i=0U; i < PANDA_CAN_CNT; i++) { if (!current_board->has_canfd) { bus_config[i].can_data_speed = 0U; } can_clear(can_queues[i]); - ret &= can_init(i); + (void)can_init(i); } - UNUSED(ret); } -void can_flip_buses(uint8_t bus1, uint8_t bus2){ - bus_config[bus1].bus_lookup = bus2; - bus_config[bus2].bus_lookup = bus1; - bus_config[bus1].can_num_lookup = bus2; - bus_config[bus2].can_num_lookup = bus1; +void can_set_orientation(bool flipped) { + bus_config[0].bus_lookup = flipped ? 2U : 0U; + bus_config[0].can_num_lookup = flipped ? 2U : 0U; + bus_config[2].bus_lookup = flipped ? 0U : 2U; + bus_config[2].can_num_lookup = flipped ? 0U : 2U; } void can_set_forwarding(uint8_t from, uint8_t to) { @@ -234,8 +228,7 @@ bool can_tx_check_min_slots_free(uint32_t min) { return (can_slots_empty(&can_tx1_q) >= min) && (can_slots_empty(&can_tx2_q) >= min) && - (can_slots_empty(&can_tx3_q) >= min) && - (can_slots_empty(&can_txgmlan_q) >= min); + (can_slots_empty(&can_tx3_q) >= min); } uint8_t calculate_checksum(const uint8_t *dat, uint32_t len) { @@ -259,12 +252,8 @@ void can_send(CANPacket_t *to_push, uint8_t bus_number, bool skip_tx_hook) { if (skip_tx_hook || safety_tx_hook(to_push) != 0) { if (bus_number < PANDA_BUS_CNT) { // add CAN packet to send queue - if ((bus_number == 3U) && (bus_config[3].can_num_lookup == 0xFFU)) { - gmlan_send_errs += bitbang_gmlan(to_push) ? 0U : 1U; - } else { - tx_buffer_overflow += can_push(can_queues[bus_number], to_push) ? 0U : 1U; - process_can(CAN_NUM_FROM_BUS_NUM(bus_number)); - } + tx_buffer_overflow += can_push(can_queues[bus_number], to_push) ? 0U : 1U; + process_can(CAN_NUM_FROM_BUS_NUM(bus_number)); } } else { safety_tx_blocked += 1U; diff --git a/board/drivers/clock_source.h b/board/drivers/clock_source.h index 11b2fa3247..5d6fdc8a77 100644 --- a/board/drivers/clock_source.h +++ b/board/drivers/clock_source.h @@ -26,8 +26,8 @@ void clock_source_init(void) { set_gpio_alternate(GPIOB, 15, GPIO_AF1_TIM1); // Set PWM mode - register_set(&(TIM1->CCMR1), (0b110 << TIM_CCMR1_OC2M_Pos), 0xFFFFU); - register_set(&(TIM1->CCMR2), (0b110 << TIM_CCMR2_OC3M_Pos), 0xFFFFU); + register_set(&(TIM1->CCMR1), (0b110UL << TIM_CCMR1_OC2M_Pos), 0xFFFFU); + register_set(&(TIM1->CCMR2), (0b110UL << TIM_CCMR2_OC3M_Pos), 0xFFFFU); // Enable output register_set(&(TIM1->BDTR), TIM_BDTR_MOE, 0xFFFFU); diff --git a/board/drivers/fake_siren.h b/board/drivers/fake_siren.h index 38c87deb0c..7c73be0b1c 100644 --- a/board/drivers/fake_siren.h +++ b/board/drivers/fake_siren.h @@ -59,13 +59,13 @@ void fake_siren_init(void) { register_set(&DMA1_Stream1->PAR, (uint32_t) &(DAC1->DHR8R1), 0xFFFFFFFFU); DMA1_Stream1->NDTR = sizeof(fake_siren_lut); register_set(&DMA1_Stream1->FCR, 0U, 0x00000083U); - DMA1_Stream1->CR = (0b11 << DMA_SxCR_PL_Pos); - DMA1_Stream1->CR |= DMA_SxCR_MINC | DMA_SxCR_CIRC | (1 << DMA_SxCR_DIR_Pos); + DMA1_Stream1->CR = (0b11UL << DMA_SxCR_PL_Pos); + DMA1_Stream1->CR |= DMA_SxCR_MINC | DMA_SxCR_CIRC | (1U << DMA_SxCR_DIR_Pos); // Init trigger timer (around 2.5kHz) register_set(&TIM7->PSC, 0U, 0xFFFFU); register_set(&TIM7->ARR, 133U, 0xFFFFU); - register_set(&TIM7->CR2, (0b10 << TIM_CR2_MMS_Pos), TIM_CR2_MMS_Msk); + register_set(&TIM7->CR2, (0b10U << TIM_CR2_MMS_Pos), TIM_CR2_MMS_Msk); register_set(&TIM7->CR1, TIM_CR1_ARPE | TIM_CR1_URS, 0x088EU); TIM7->SR = 0U; TIM7->CR1 |= TIM_CR1_CEN; diff --git a/board/drivers/fdcan.h b/board/drivers/fdcan.h index bc4c2a532e..0ba228a9e6 100644 --- a/board/drivers/fdcan.h +++ b/board/drivers/fdcan.h @@ -67,14 +67,14 @@ void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) { FDCANx->IR |= (FDCAN_IR_PED | FDCAN_IR_PEA | FDCAN_IR_EP | FDCAN_IR_BO | FDCAN_IR_RF0L); can_health[can_number].total_error_cnt += 1U; // Check for RX FIFO overflow - if ((ir_reg & (FDCAN_IR_RF0L)) != 0) { + if ((ir_reg & (FDCAN_IR_RF0L)) != 0U) { can_health[can_number].total_rx_lost_cnt += 1U; } // Cases: // 1. while multiplexing between buses 1 and 3 we are getting ACK errors that overwhelm CAN core, by resetting it recovers faster // 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) != 0)) { + ((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); @@ -93,7 +93,7 @@ void process_can(uint8_t can_number) { FDCANx->IR |= FDCAN_IR_TFE; // Clear Tx FIFO Empty flag - if ((FDCANx->TXFQS & FDCAN_TXFQS_TFQF) == 0) { + if ((FDCANx->TXFQS & FDCAN_TXFQS_TFQF) == 0U) { CANPacket_t to_send; if (can_pop(can_queues[bus_number], &to_send)) { if (can_check_checksum(&to_send)) { @@ -101,7 +101,7 @@ void process_can(uint8_t can_number) { uint32_t TxFIFOSA = FDCAN_START_ADDRESS + (can_number * FDCAN_OFFSET) + (FDCAN_RX_FIFO_0_EL_CNT * FDCAN_RX_FIFO_0_EL_SIZE); // get the index of the next TX FIFO element (0 to FDCAN_TX_FIFO_EL_CNT - 1) - uint32_t tx_index = (FDCANx->TXFQS >> FDCAN_TXFQS_TFQPI_Pos) & 0x1F; + uint32_t tx_index = (FDCANx->TXFQS >> FDCAN_TXFQS_TFQPI_Pos) & 0x1FU; // only send if we have received a packet canfd_fifo *fifo; fifo = (canfd_fifo *)(TxFIFOSA + (tx_index * FDCAN_TX_FIFO_EL_SIZE)); @@ -126,7 +126,7 @@ void process_can(uint8_t can_number) { to_push.rejected = 0U; to_push.extended = to_send.extended; to_push.addr = to_send.addr; - to_push.bus = to_send.bus; + to_push.bus = bus_number; to_push.data_len_code = to_send.data_len_code; (void)memcpy(to_push.data, to_send.data, dlc_to_len[to_push.data_len_code]); can_set_checksum(&to_push); @@ -153,14 +153,14 @@ void can_rx(uint8_t can_number) { // Clear all new messages from Rx FIFO 0 FDCANx->IR |= FDCAN_IR_RF0N; - while((FDCANx->RXF0S & FDCAN_RXF0S_F0FL) != 0) { + while((FDCANx->RXF0S & FDCAN_RXF0S_F0FL) != 0U) { can_health[can_number].total_rx_cnt += 1U; // can is live pending_can_live = 1; // get the index of the next RX FIFO element (0 to FDCAN_RX_FIFO_0_EL_CNT - 1) - uint32_t rx_fifo_idx = (uint8_t)((FDCANx->RXF0S >> FDCAN_RXF0S_F0GI_Pos) & 0x3F); + uint32_t rx_fifo_idx = (uint8_t)((FDCANx->RXF0S >> FDCAN_RXF0S_F0GI_Pos) & 0x3FU); // Recommended to offset get index by at least +1 if RX FIFO is in overwrite mode and full (datasheet) if((FDCANx->RXF0S & FDCAN_RXF0S_F0F) == FDCAN_RXF0S_F0F) { @@ -232,7 +232,7 @@ void can_rx(uint8_t can_number) { } // Error handling - if ((ir_reg & (FDCAN_IR_PED | FDCAN_IR_PEA | FDCAN_IR_EP | FDCAN_IR_BO | FDCAN_IR_RF0L)) != 0) { + if ((ir_reg & (FDCAN_IR_PED | FDCAN_IR_PEA | FDCAN_IR_EP | FDCAN_IR_BO | FDCAN_IR_RF0L)) != 0U) { update_can_health_pkt(can_number, ir_reg); } } diff --git a/board/drivers/gmlan_alt.h b/board/drivers/gmlan_alt.h deleted file mode 100644 index 2dbc381bd2..0000000000 --- a/board/drivers/gmlan_alt.h +++ /dev/null @@ -1,270 +0,0 @@ -#define GMLAN_TICKS_PER_SECOND 33300 //1sec @ 33.3kbps -#define GMLAN_TICKS_PER_TIMEOUT_TICKLE 500 //15ms @ 33.3kbps -#define GMLAN_HIGH 0 //0 is high on bus (dominant) -#define GMLAN_LOW 1 //1 is low on bus - -#define DISABLED -1 -#define BITBANG 0 -#define GPIO_SWITCH 1 - -#define MAX_BITS_CAN_PACKET (200) - -int gmlan_alt_mode = DISABLED; - -// returns out_len -int do_bitstuff(char *out, const char *in, int in_len) { - int last_bit = -1; - int bit_cnt = 0; - int j = 0; - for (int i = 0; i < in_len; i++) { - char bit = in[i]; - out[j] = bit; - j++; - - // do the stuffing - if (bit == (char)last_bit) { - bit_cnt++; - if (bit_cnt == 5) { - // 5 in a row the same, do stuff - last_bit = !bit ? 1 : 0; - out[j] = last_bit; - j++; - bit_cnt = 1; - } - } else { - // this is a new bit - last_bit = (int)bit; - bit_cnt = 1; - } - } - return j; -} - -int append_crc(char *in, int in_len) { - unsigned int crc = 0; - for (int i = 0; i < in_len; i++) { - crc <<= 1; - if (((unsigned int)(in[i]) ^ ((crc >> 15) & 1U)) != 0U) { - crc = crc ^ 0x4599U; - } - crc &= 0x7fffU; - } - int in_len_copy = in_len; - for (int i = 14; i >= 0; i--) { - in[in_len_copy] = (crc >> (unsigned int)(i)) & 1U; - in_len_copy++; - } - return in_len_copy; -} - -int append_bits(char *in, int in_len, const char *app, int app_len) { - int in_len_copy = in_len; - for (int i = 0; i < app_len; i++) { - in[in_len_copy] = app[i]; - in_len_copy++; - } - return in_len_copy; -} - -int append_int(char *in, int in_len, int val, int val_len) { - int in_len_copy = in_len; - for (int i = val_len - 1; i >= 0; i--) { - in[in_len_copy] = ((unsigned int)(val) & (1U << (unsigned int)(i))) != 0U; - in_len_copy++; - } - return in_len_copy; -} - -int get_bit_message(char *out, const CANPacket_t *to_bang) { - char pkt[MAX_BITS_CAN_PACKET]; - char footer[] = { - 1, // CRC delimiter - 1, // ACK - 1, // ACK delimiter - 1,1,1,1,1,1,1, // EOF - 1,1,1, // IFS - }; - - int len = 0; - - // test packet - int dlc_len = GET_LEN(to_bang); - len = append_int(pkt, len, 0, 1); // Start-of-frame - - if (to_bang->extended != 0U) { - // extended identifier - len = append_int(pkt, len, GET_ADDR(to_bang) >> 18, 11); // Identifier - len = append_int(pkt, len, 3, 2); // SRR+IDE - len = append_int(pkt, len, (GET_ADDR(to_bang)) & ((1UL << 18) - 1U), 18); // Identifier - len = append_int(pkt, len, 0, 3); // RTR+r1+r0 - } else { - // standard identifier - len = append_int(pkt, len, GET_ADDR(to_bang), 11); // Identifier - len = append_int(pkt, len, 0, 3); // RTR+IDE+reserved - } - - len = append_int(pkt, len, dlc_len, 4); // Data length code - - // append data - for (int i = 0; i < dlc_len; i++) { - len = append_int(pkt, len, to_bang->data[i], 8); - } - - // append crc - len = append_crc(pkt, len); - - // do bitstuffing - len = do_bitstuff(out, pkt, len); - - // append footer - len = append_bits(out, len, footer, sizeof(footer)); - return len; -} - -void TIM12_IRQ_Handler(void); - -void setup_timer(void) { - // register interrupt - REGISTER_INTERRUPT(TIM8_BRK_TIM12_IRQn, TIM12_IRQ_Handler, 40000U, FAULT_INTERRUPT_RATE_GMLAN) - - // setup - register_set(&(TIM12->PSC), (APB1_TIMER_FREQ-1U), 0xFFFFU); // Tick on 1 us - register_set(&(TIM12->CR1), TIM_CR1_CEN, 0x3FU); // Enable - register_set(&(TIM12->ARR), (30U-1U), 0xFFFFU); // 33.3 kbps - - // in case it's disabled - NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn); - - // run the interrupt - register_set(&(TIM12->DIER), TIM_DIER_UIE, 0x5F5FU); // Update interrupt - TIM12->SR = 0; -} - -int gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; //GMLAN transceiver times out every 17ms held high; tickle every 15ms -int can_timeout_counter = GMLAN_TICKS_PER_SECOND; //1 second - -int inverted_bit_to_send = GMLAN_HIGH; -int gmlan_switch_below_timeout = -1; -int gmlan_switch_timeout_enable = 0; - -void set_bitbanged_gmlan(int val) { - if (val != 0) { - register_set_bits(&(GPIOB->ODR), (1UL << 13)); - } else { - register_clear_bits(&(GPIOB->ODR), (1UL << 13)); - } -} - -char pkt_stuffed[MAX_BITS_CAN_PACKET]; -int gmlan_sending = -1; -int gmlan_sendmax = -1; -bool gmlan_send_ok = true; - -int gmlan_silent_count = 0; -int gmlan_fail_count = 0; -#define REQUIRED_SILENT_TIME 10 -#define MAX_FAIL_COUNT 10 - -void TIM12_IRQ_Handler(void) { - if (gmlan_alt_mode == BITBANG) { - if ((TIM12->SR & TIM_SR_UIF) && (gmlan_sendmax != -1)) { - int read = get_gpio_input(GPIOB, 12); - if (gmlan_silent_count < REQUIRED_SILENT_TIME) { - if (read == 0) { - gmlan_silent_count = 0; - } else { - gmlan_silent_count++; - } - } else { - bool retry = 0; - // in send loop - if ((gmlan_sending > 0) && // not first bit - ((read == 0) && (pkt_stuffed[gmlan_sending-1] == (char)1)) && // bus wrongly dominant - (gmlan_sending != (gmlan_sendmax - 11))) { //not ack bit - print("GMLAN ERR: bus driven at "); - puth(gmlan_sending); - print("\n"); - retry = 1; - } else if ((read == 1) && (gmlan_sending == (gmlan_sendmax - 11))) { // recessive during ACK - print("GMLAN ERR: didn't recv ACK\n"); - retry = 1; - } else { - // do not retry - } - if (retry) { - // reset sender (retry after 7 silent) - set_bitbanged_gmlan(1); // recessive - gmlan_silent_count = 0; - gmlan_sending = 0; - gmlan_fail_count++; - if (gmlan_fail_count == MAX_FAIL_COUNT) { - print("GMLAN ERR: giving up send\n"); - gmlan_send_ok = false; - } - } else { - set_bitbanged_gmlan(pkt_stuffed[gmlan_sending]); - gmlan_sending++; - } - } - if ((gmlan_sending == gmlan_sendmax) || (gmlan_fail_count == MAX_FAIL_COUNT)) { - set_bitbanged_gmlan(1); // recessive - set_gpio_mode(GPIOB, 13, MODE_INPUT); - register_clear_bits(&(TIM12->DIER), TIM_DIER_UIE); // No update interrupt - register_set(&(TIM12->CR1), 0U, 0x3FU); // Disable timer - gmlan_sendmax = -1; // exit - } - } - } else if (gmlan_alt_mode == GPIO_SWITCH) { - if ((TIM12->SR & TIM_SR_UIF) && (gmlan_switch_below_timeout != -1)) { - if ((can_timeout_counter == 0) && gmlan_switch_timeout_enable) { - //it has been more than 1 second since timeout was reset; disable timer and restore the GMLAN output - set_gpio_output(GPIOB, 13, GMLAN_LOW); - gmlan_switch_below_timeout = -1; - gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; - gmlan_alt_mode = DISABLED; - } - else { - can_timeout_counter--; - if (gmlan_timeout_counter == 0) { - //Send a 1 (bus low) every 15ms to reset the GMLAN transceivers timeout - gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; - set_gpio_output(GPIOB, 13, GMLAN_LOW); - } - else { - set_gpio_output(GPIOB, 13, inverted_bit_to_send); - gmlan_timeout_counter--; - } - } - } - } else { - // Invalid GMLAN mode. Do not put a print statement here, way too fast to keep up with - } - TIM12->SR = 0; -} - -bool bitbang_gmlan(const CANPacket_t *to_bang) { - gmlan_send_ok = true; - gmlan_alt_mode = BITBANG; - -#ifdef HW_TYPE_DOS - if (hw_type == HW_TYPE_DOS) { - if (gmlan_sendmax == -1) { - int len = get_bit_message(pkt_stuffed, to_bang); - gmlan_fail_count = 0; - gmlan_silent_count = 0; - gmlan_sending = 0; - gmlan_sendmax = len; - // setup for bitbang loop - set_bitbanged_gmlan(1); // recessive - set_gpio_mode(GPIOB, 13, MODE_OUTPUT); - - // 33kbps - setup_timer(); - } - } -#else - UNUSED(to_bang); -#endif - - return gmlan_send_ok; -} diff --git a/board/drivers/gpio.h b/board/drivers/gpio.h index bf96a0326e..0b8fc091b1 100644 --- a/board/drivers/gpio.h +++ b/board/drivers/gpio.h @@ -11,7 +11,7 @@ #define OUTPUT_TYPE_OPEN_DRAIN 1U typedef struct { - GPIO_TypeDef *bank; + GPIO_TypeDef * const bank; uint8_t pin; } gpio_t; @@ -68,13 +68,13 @@ int get_gpio_input(const GPIO_TypeDef *GPIO, unsigned int pin) { return (GPIO->IDR & (1UL << pin)) == (1UL << pin); } -void gpio_set_all_output(const gpio_t *pins, uint8_t num_pins, bool enabled) { +void gpio_set_all_output(gpio_t *pins, uint8_t num_pins, bool enabled) { for (uint8_t i = 0; i < num_pins; i++) { set_gpio_output(pins[i].bank, pins[i].pin, enabled); } } -void gpio_set_bitmask(const gpio_t *pins, uint8_t num_pins, uint32_t bitmask) { +void gpio_set_bitmask(gpio_t *pins, uint8_t num_pins, uint32_t bitmask) { for (uint8_t i = 0; i < num_pins; i++) { set_gpio_output(pins[i].bank, pins[i].pin, (bitmask >> i) & 1U); } diff --git a/board/drivers/harness.h b/board/drivers/harness.h index 60f99fc85c..f8f0ccb7d3 100644 --- a/board/drivers/harness.h +++ b/board/drivers/harness.h @@ -13,16 +13,16 @@ struct harness_t harness; struct harness_configuration { const bool has_harness; - GPIO_TypeDef *GPIO_SBU1; - GPIO_TypeDef *GPIO_SBU2; - GPIO_TypeDef *GPIO_relay_SBU1; - GPIO_TypeDef *GPIO_relay_SBU2; - uint8_t pin_SBU1; - uint8_t pin_SBU2; - uint8_t pin_relay_SBU1; - uint8_t pin_relay_SBU2; - uint8_t adc_channel_SBU1; - uint8_t adc_channel_SBU2; + GPIO_TypeDef * const GPIO_SBU1; + GPIO_TypeDef * const GPIO_SBU2; + GPIO_TypeDef * const GPIO_relay_SBU1; + GPIO_TypeDef * const GPIO_relay_SBU2; + const uint8_t pin_SBU1; + const uint8_t pin_SBU2; + const uint8_t pin_relay_SBU1; + const uint8_t pin_relay_SBU2; + const uint8_t adc_channel_SBU1; + const uint8_t adc_channel_SBU2; }; // The ignition relay is only used for testing purposes @@ -117,11 +117,6 @@ void harness_tick(void) { } void harness_init(void) { - // delay such that the connection is fully made before trying orientation detection - current_board->set_led(LED_BLUE, true); - delay(10000000); - current_board->set_led(LED_BLUE, false); - // try to detect orientation harness.status = harness_detect_orientation(); if (harness.status != HARNESS_STATUS_NC) { diff --git a/board/drivers/interrupts.h b/board/drivers/interrupts.h index d4c72be1df..77988f6e45 100644 --- a/board/drivers/interrupts.h +++ b/board/drivers/interrupts.h @@ -64,7 +64,7 @@ void handle_interrupt(IRQn_Type irq_type){ // Every second void interrupt_timer_handler(void) { - if (INTERRUPT_TIMER->SR != 0) { + if (INTERRUPT_TIMER->SR != 0U) { for (uint16_t i = 0U; i < NUM_INTERRUPTS; i++) { // Log IRQ call rate faults if (check_interrupt_rate && (interrupts[i].call_counter > interrupts[i].max_call_rate)) { diff --git a/board/drivers/rtc.h b/board/drivers/rtc.h deleted file mode 100644 index df121e3e89..0000000000 --- a/board/drivers/rtc.h +++ /dev/null @@ -1,79 +0,0 @@ -#define YEAR_OFFSET 2000U - -typedef struct __attribute__((packed)) timestamp_t { - uint16_t year; - uint8_t month; - uint8_t day; - uint8_t weekday; - uint8_t hour; - uint8_t minute; - uint8_t second; -} timestamp_t; - -uint8_t to_bcd(uint16_t value){ - return (((value / 10U) & 0x0FU) << 4U) | ((value % 10U) & 0x0FU); -} - -uint16_t from_bcd(uint8_t value){ - return (((value & 0xF0U) >> 4U) * 10U) + (value & 0x0FU); -} - -void rtc_set_time(timestamp_t time){ - print("Setting RTC time\n"); - - // Disable write protection - disable_bdomain_protection(); - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - // Enable initialization mode - register_set_bits(&(RTC->ISR), RTC_ISR_INIT); - while((RTC->ISR & RTC_ISR_INITF) == 0){} - - // Set time - RTC->TR = (to_bcd(time.hour) << RTC_TR_HU_Pos) | (to_bcd(time.minute) << RTC_TR_MNU_Pos) | (to_bcd(time.second) << RTC_TR_SU_Pos); - RTC->DR = (to_bcd(time.year - YEAR_OFFSET) << RTC_DR_YU_Pos) | (time.weekday << RTC_DR_WDU_Pos) | (to_bcd(time.month) << RTC_DR_MU_Pos) | (to_bcd(time.day) << RTC_DR_DU_Pos); - - // Set options - register_set(&(RTC->CR), 0U, 0xFCFFFFU); - - // Disable initalization mode - register_clear_bits(&(RTC->ISR), RTC_ISR_INIT); - - // Wait for synchronization - while((RTC->ISR & RTC_ISR_RSF) == 0){} - - // Re-enable write protection - RTC->WPR = 0x00; - enable_bdomain_protection(); -} - -timestamp_t rtc_get_time(void){ - timestamp_t result; - // Init with zero values in case there is no RTC running - result.year = 0U; - result.month = 0U; - result.day = 0U; - result.weekday = 0U; - result.hour = 0U; - result.minute = 0U; - result.second = 0U; - - // Wait until the register sync flag is set - while((RTC->ISR & RTC_ISR_RSF) == 0){} - - // Read time and date registers. Since our HSE > 7*LSE, this should be fine. - uint32_t time = RTC->TR; - uint32_t date = RTC->DR; - - // Parse values - result.year = from_bcd((date & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos) + YEAR_OFFSET; - result.month = from_bcd((date & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos); - result.day = from_bcd((date & (RTC_DR_DT | RTC_DR_DU)) >> RTC_DR_DU_Pos); - result.weekday = ((date & RTC_DR_WDU) >> RTC_DR_WDU_Pos); - result.hour = from_bcd((time & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TR_HU_Pos); - result.minute = from_bcd((time & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos); - result.second = from_bcd((time & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TR_SU_Pos); - - return result; -} diff --git a/board/drivers/spi.h b/board/drivers/spi.h index 1a7b9be590..e1ae010f73 100644 --- a/board/drivers/spi.h +++ b/board/drivers/spi.h @@ -73,10 +73,8 @@ uint16_t spi_version_packet(uint8_t *out) { uint16_t data_pos = 7U + 2U; // write serial - #ifdef UID_BASE (void)memcpy(&out[data_pos], ((uint8_t *)UID_BASE), 12); data_len += 12U; - #endif // HW type out[data_pos + data_len] = hw_type; @@ -232,7 +230,7 @@ void spi_rx_done(void) { llspi_miso_dma(spi_buf_tx, response_len); spi_state = next_rx_state; - if (!checksum_valid && (spi_checksum_error_count < __UINT16_MAX__)) { + if (!checksum_valid && (spi_checksum_error_count < UINT16_MAX)) { spi_checksum_error_count += 1U; } } diff --git a/board/drivers/usb.h b/board/drivers/usb.h index 1872dd5276..e006372216 100644 --- a/board/drivers/usb.h +++ b/board/drivers/usb.h @@ -304,13 +304,6 @@ uint8_t binary_object_store_desc[] = { MS_VENDOR_CODE, 0x00 // vendor code, no alternate enumeration }; -uint8_t webusb_url_descriptor[] = { - 0x14, /* bLength */ - WEBUSB_DESC_TYPE_URL, // bDescriptorType - WEBUSB_URL_SCHEME_HTTPS, // bScheme - 'u', 's', 'b', 'p', 'a', 'n', 'd', 'a', '.', 'c', 'o', 'm', 'm', 'a', '.', 'a', 'i' -}; - // WinUSB 2.0 descriptor. This is what modern systems use // https://github.com/sowbug/weblight/blob/192ad7a0e903542e2aa28c607d98254a12a6399d/firmware/webusb.c // http://janaxelson.com/files/ms_os_20_descriptors.c @@ -364,10 +357,10 @@ int current_int0_alt_setting = 0; void *USB_ReadPacket(void *dest, uint16_t len) { uint32_t *dest_copy = (uint32_t *)dest; - uint32_t count32b = (len + 3U) / 4U; + uint32_t count32b = ((uint32_t)len + 3U) / 4U; for (uint32_t i = 0; i < count32b; i++) { - *dest_copy = USBx_DFIFO(0); + *dest_copy = USBx_DFIFO(0U); dest_copy++; } return ((void *)dest_copy); @@ -379,9 +372,9 @@ void USB_WritePacket(const void *src, uint16_t len, uint32_t ep) { hexdump(src, len); #endif - uint32_t numpacket = (len + (USBPACKET_MAX_SIZE - 1U)) / USBPACKET_MAX_SIZE; + uint32_t numpacket = ((uint32_t)len + (USBPACKET_MAX_SIZE - 1U)) / USBPACKET_MAX_SIZE; uint32_t count32b = 0; - count32b = (len + 3U) / 4U; + count32b = ((uint32_t)len + 3U) / 4U; // TODO: revisit this USBx_INEP(ep)->DIEPTSIZ = ((numpacket << 19) & USB_OTG_DIEPTSIZ_PKTCNT) | @@ -414,7 +407,7 @@ void USB_WritePacket_EP0(uint8_t *src, uint16_t len) { ep0_txlen = len - wplen; USBx_DEVICE->DIEPEMPMSK |= 1; } else { - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; } } @@ -431,8 +424,8 @@ void usb_reset(void) { USBx_DEVICE->DOEPMSK = 0xFFFFFFFFU; // clear interrupts - USBx_INEP(0)->DIEPINT = 0xFF; - USBx_OUTEP(0)->DOEPINT = 0xFF; + USBx_INEP(0U)->DIEPINT = 0xFF; + USBx_OUTEP(0U)->DOEPINT = 0xFF; // unset the address USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; @@ -458,7 +451,7 @@ void usb_reset(void) { USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK; // ready to receive setup packets - USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1UL << 19)) | (3U << 3); + USBx_OUTEP(0U)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1UL << 19)) | (3U << 3); } char to_hex_char(uint8_t a) { @@ -485,26 +478,26 @@ void usb_setup(void) { switch (setup.b.bRequest) { case USB_REQ_SET_CONFIGURATION: // enable other endpoints, has to be here? - USBx_INEP(1)->DIEPCTL = (0x40U & USB_OTG_DIEPCTL_MPSIZ) | (2UL << 18) | (1UL << 22) | + USBx_INEP(1U)->DIEPCTL = (0x40U & USB_OTG_DIEPCTL_MPSIZ) | (2UL << 18) | (1UL << 22) | USB_OTG_DIEPCTL_SD0PID_SEVNFRM | USB_OTG_DIEPCTL_USBAEP; - USBx_INEP(1)->DIEPINT = 0xFF; + USBx_INEP(1U)->DIEPINT = 0xFF; - USBx_OUTEP(2)->DOEPTSIZ = (1UL << 19) | 0x40U; - USBx_OUTEP(2)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2UL << 18) | + USBx_OUTEP(2U)->DOEPTSIZ = (1UL << 19) | 0x40U; + USBx_OUTEP(2U)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2UL << 18) | USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP; - USBx_OUTEP(2)->DOEPINT = 0xFF; + USBx_OUTEP(2U)->DOEPINT = 0xFF; - USBx_OUTEP(3)->DOEPTSIZ = (32UL << 19) | 0x800U; - USBx_OUTEP(3)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2UL << 18) | + USBx_OUTEP(3U)->DOEPTSIZ = (32UL << 19) | 0x800U; + USBx_OUTEP(3U)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2UL << 18) | USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP; - USBx_OUTEP(3)->DOEPINT = 0xFF; + USBx_OUTEP(3U)->DOEPINT = 0xFF; // mark ready to receive - USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; - USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(2U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(3U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; USB_WritePacket(0, 0, 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_REQ_SET_ADDRESS: // set now? @@ -515,7 +508,7 @@ void usb_setup(void) { #endif USB_WritePacket(0, 0, 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_REQ_GET_DESCRIPTOR: @@ -527,17 +520,17 @@ void usb_setup(void) { device_desc[13] = hw_type; // setup transfer USB_WritePacket(device_desc, MIN(sizeof(device_desc), setup.b.wLength.w), 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; //print("D"); break; case USB_DESC_TYPE_CONFIGURATION: USB_WritePacket(configuration_desc, MIN(sizeof(configuration_desc), setup.b.wLength.w), 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_DESC_TYPE_DEVICE_QUALIFIER: USB_WritePacket(device_qualifier, MIN(sizeof(device_qualifier), setup.b.wLength.w), 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_DESC_TYPE_STRING: switch (setup.b.wValue.bw.msb) { @@ -551,23 +544,19 @@ void usb_setup(void) { USB_WritePacket((uint8_t*)string_product_desc, MIN(sizeof(string_product_desc), setup.b.wLength.w), 0); break; case STRING_OFFSET_ISERIAL: - #ifdef UID_BASE - response[0] = 0x02 + (12 * 4); - response[1] = 0x03; - - // 96 bits = 12 bytes - for (int i = 0; i < 12; i++){ - uint8_t cc = ((uint8_t *)UID_BASE)[i]; - response[2 + (i * 4)] = to_hex_char((cc >> 4) & 0xFU); - response[2 + (i * 4) + 1] = '\0'; - response[2 + (i * 4) + 2] = to_hex_char((cc >> 0) & 0xFU); - response[2 + (i * 4) + 3] = '\0'; - } - - USB_WritePacket(response, MIN(response[0], setup.b.wLength.w), 0); - #else - USB_WritePacket((const uint8_t *)string_serial_desc, MIN(sizeof(string_serial_desc), setup.b.wLength.w), 0); - #endif + response[0] = 0x02 + (12 * 4); + response[1] = 0x03; + + // 96 bits = 12 bytes + for (int i = 0; i < 12; i++){ + uint8_t cc = ((uint8_t *)UID_BASE)[i]; + response[2 + (i * 4)] = to_hex_char((cc >> 4) & 0xFU); + response[2 + (i * 4) + 1] = '\0'; + response[2 + (i * 4) + 2] = to_hex_char((cc >> 0) & 0xFU); + response[2 + (i * 4) + 3] = '\0'; + } + + USB_WritePacket(response, MIN(response[0], setup.b.wLength.w), 0); break; case STRING_OFFSET_ICONFIGURATION: USB_WritePacket((uint8_t*)string_configuration_desc, MIN(sizeof(string_configuration_desc), setup.b.wLength.w), 0); @@ -580,16 +569,16 @@ void usb_setup(void) { USB_WritePacket(0, 0, 0); break; } - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_DESC_TYPE_BINARY_OBJECT_STORE: USB_WritePacket(binary_object_store_desc, MIN(sizeof(binary_object_store_desc), setup.b.wLength.w), 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; default: // nothing here? USB_WritePacket(0, 0, 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; } break; @@ -598,26 +587,18 @@ void usb_setup(void) { response[0] = 0; response[1] = 0; USB_WritePacket((void*)&response, 2, 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_REQ_SET_INTERFACE: // Store the alt setting number for IN EP behavior. current_int0_alt_setting = setup.b.wValue.w; USB_WritePacket(0, 0, 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case WEBUSB_VENDOR_CODE: - switch (setup.b.wIndex.w) { - case WEBUSB_REQ_GET_URL: - USB_WritePacket(webusb_url_descriptor, MIN(sizeof(webusb_url_descriptor), setup.b.wLength.w), 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; - break; - default: - // probably asking for allowed origins, which was removed from the spec - USB_WritePacket(0, 0, 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; - break; - } + // probably asking for allowed origins, which was removed from the spec + USB_WritePacket(0, 0, 0); + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case MS_VENDOR_CODE: switch (setup.b.wIndex.w) { @@ -647,7 +628,7 @@ void usb_setup(void) { // response pending if -1 was returned if (resp_len != -1) { USB_WritePacket(response, MIN(resp_len, setup.b.wLength.w), 0); - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; } } } @@ -675,23 +656,23 @@ void usb_irqhandler(void) { print(" USB interrupt!\n"); #endif - if ((gintsts & USB_OTG_GINTSTS_CIDSCHG) != 0) { + if ((gintsts & USB_OTG_GINTSTS_CIDSCHG) != 0U) { print("connector ID status change\n"); } - if ((gintsts & USB_OTG_GINTSTS_USBRST) != 0) { + if ((gintsts & USB_OTG_GINTSTS_USBRST) != 0U) { print("USB reset\n"); usb_reset(); } - if ((gintsts & USB_OTG_GINTSTS_ENUMDNE) != 0) { + if ((gintsts & USB_OTG_GINTSTS_ENUMDNE) != 0U) { print("enumeration done"); // Full speed, ENUMSPD //puth(USBx_DEVICE->DSTS); print("\n"); } - if ((gintsts & USB_OTG_GINTSTS_OTGINT) != 0) { + if ((gintsts & USB_OTG_GINTSTS_OTGINT) != 0U) { print("OTG int:"); puth(USBx->GOTGINT); print("\n"); @@ -701,7 +682,7 @@ void usb_irqhandler(void) { } // RX FIFO first - if ((gintsts & USB_OTG_GINTSTS_RXFLVL) != 0) { + if ((gintsts & USB_OTG_GINTSTS_RXFLVL) != 0U) { // 1. Read the Receive status pop register volatile unsigned int rxst = USBx->GRXSTSP; int status = (rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17; @@ -767,7 +748,7 @@ void usb_irqhandler(void) { USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK | USB_OTG_DCTL_CGINAK; } - if ((gintsts & USB_OTG_GINTSTS_SRQINT) != 0) { + if ((gintsts & USB_OTG_GINTSTS_SRQINT) != 0U) { // we want to do "A-device host negotiation protocol" since we are the A-device /*print("start request\n"); puth(USBx->GOTGCTL); @@ -778,76 +759,76 @@ void usb_irqhandler(void) { } // out endpoint hit - if ((gintsts & USB_OTG_GINTSTS_OEPINT) != 0) { + if ((gintsts & USB_OTG_GINTSTS_OEPINT) != 0U) { #ifdef DEBUG_USB print(" 0:"); - puth(USBx_OUTEP(0)->DOEPINT); + puth(USBx_OUTEP(0U)->DOEPINT); print(" 2:"); - puth(USBx_OUTEP(2)->DOEPINT); + puth(USBx_OUTEP(2U)->DOEPINT); print(" 3:"); - puth(USBx_OUTEP(3)->DOEPINT); + puth(USBx_OUTEP(3U)->DOEPINT); print(" "); - puth(USBx_OUTEP(3)->DOEPCTL); + puth(USBx_OUTEP(3U)->DOEPCTL); print(" 4:"); puth(USBx_OUTEP(4)->DOEPINT); print(" OUT ENDPOINT\n"); #endif - if ((USBx_OUTEP(2)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0) { + if ((USBx_OUTEP(2U)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0U) { #ifdef DEBUG_USB print(" OUT2 PACKET XFRC\n"); #endif - USBx_OUTEP(2)->DOEPTSIZ = (1UL << 19) | 0x40U; - USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(2U)->DOEPTSIZ = (1UL << 19) | 0x40U; + USBx_OUTEP(2U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; } - if ((USBx_OUTEP(3)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0) { + if ((USBx_OUTEP(3U)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0U) { #ifdef DEBUG_USB print(" OUT3 PACKET XFRC\n"); #endif // NAK cleared by process_can (if tx buffers have room) outep3_processing = false; refresh_can_tx_slots_available(); - } else if ((USBx_OUTEP(3)->DOEPINT & 0x2000) != 0) { + } else if ((USBx_OUTEP(3U)->DOEPINT & 0x2000U) != 0U) { #ifdef DEBUG_USB print(" OUT3 PACKET WTF\n"); #endif // if NAK was set trigger this, unknown interrupt // TODO: why was this here? fires when TX buffers when we can't clear NAK - // USBx_OUTEP(3)->DOEPTSIZ = (1U << 19) | 0x40U; - // USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; - } else if ((USBx_OUTEP(3)->DOEPINT) != 0) { + // USBx_OUTEP(3U)->DOEPTSIZ = (1U << 19) | 0x40U; + // USBx_OUTEP(3U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + } else if ((USBx_OUTEP(3U)->DOEPINT) != 0U) { #ifdef DEBUG_USB print("OUTEP3 error "); - puth(USBx_OUTEP(3)->DOEPINT); + puth(USBx_OUTEP(3U)->DOEPINT); print("\n"); #endif } else { - // USBx_OUTEP(3)->DOEPINT is 0, ok to skip + // USBx_OUTEP(3U)->DOEPINT is 0, ok to skip } - if ((USBx_OUTEP(0)->DOEPINT & USB_OTG_DIEPINT_XFRC) != 0) { + if ((USBx_OUTEP(0U)->DOEPINT & USB_OTG_DIEPINT_XFRC) != 0U) { // ready for next packet - USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1UL << 19)) | (1U << 3); + USBx_OUTEP(0U)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1UL << 19)) | (1U << 3); } // respond to setup packets - if ((USBx_OUTEP(0)->DOEPINT & USB_OTG_DOEPINT_STUP) != 0) { + if ((USBx_OUTEP(0U)->DOEPINT & USB_OTG_DOEPINT_STUP) != 0U) { usb_setup(); } - USBx_OUTEP(0)->DOEPINT = USBx_OUTEP(0)->DOEPINT; - USBx_OUTEP(2)->DOEPINT = USBx_OUTEP(2)->DOEPINT; - USBx_OUTEP(3)->DOEPINT = USBx_OUTEP(3)->DOEPINT; + USBx_OUTEP(0U)->DOEPINT = USBx_OUTEP(0U)->DOEPINT; + USBx_OUTEP(2U)->DOEPINT = USBx_OUTEP(2U)->DOEPINT; + USBx_OUTEP(3U)->DOEPINT = USBx_OUTEP(3U)->DOEPINT; } // interrupt endpoint hit (Page 1221) - if ((gintsts & USB_OTG_GINTSTS_IEPINT) != 0) { + if ((gintsts & USB_OTG_GINTSTS_IEPINT) != 0U) { #ifdef DEBUG_USB print(" "); - puth(USBx_INEP(0)->DIEPINT); + puth(USBx_INEP(0U)->DIEPINT); print(" "); - puth(USBx_INEP(1)->DIEPINT); + puth(USBx_INEP(1U)->DIEPINT); print(" IN ENDPOINT\n"); #endif @@ -867,7 +848,7 @@ void usb_irqhandler(void) { switch (current_int0_alt_setting) { case 0: ////// Bulk config // *** IN token received when TxFIFO is empty - if ((USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) { + if ((USBx_INEP(1U)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0U) { #ifdef DEBUG_USB print(" IN PACKET QUEUE\n"); #endif @@ -878,7 +859,7 @@ void usb_irqhandler(void) { case 1: ////// Interrupt config // *** IN token received when TxFIFO is empty - if ((USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) { + if ((USBx_INEP(1U)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0U) { #ifdef DEBUG_USB print(" IN PACKET QUEUE\n"); #endif @@ -894,12 +875,12 @@ void usb_irqhandler(void) { break; } - if ((USBx_INEP(0)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) { + if ((USBx_INEP(0U)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0U) { #ifdef DEBUG_USB print(" IN PACKET QUEUE\n"); #endif - if ((ep0_txlen != 0U) && ((USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40U)) { + if ((ep0_txlen != 0U) && ((USBx_INEP(0U)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40U)) { uint16_t len = MIN(ep0_txlen, 0x40); USB_WritePacket(ep0_txdata, len, 0); ep0_txdata = &ep0_txdata[len]; @@ -907,14 +888,14 @@ void usb_irqhandler(void) { if (ep0_txlen == 0U) { ep0_txdata = NULL; USBx_DEVICE->DIEPEMPMSK &= ~1; - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; } } } // clear interrupts - USBx_INEP(0)->DIEPINT = USBx_INEP(0)->DIEPINT; // Why ep0? - USBx_INEP(1)->DIEPINT = USBx_INEP(1)->DIEPINT; + USBx_INEP(0U)->DIEPINT = USBx_INEP(0U)->DIEPINT; // Why ep0? + USBx_INEP(1U)->DIEPINT = USBx_INEP(1U)->DIEPINT; } // clear all interrupts we handled @@ -927,9 +908,9 @@ void usb_irqhandler(void) { void can_tx_comms_resume_usb(void) { ENTER_CRITICAL(); - if (!outep3_processing && (USBx_OUTEP(3)->DOEPCTL & USB_OTG_DOEPCTL_NAKSTS) != 0) { - USBx_OUTEP(3)->DOEPTSIZ = (32UL << 19) | 0x800U; - USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + if (!outep3_processing && (USBx_OUTEP(3U)->DOEPCTL & USB_OTG_DOEPCTL_NAKSTS) != 0U) { + USBx_OUTEP(3U)->DOEPTSIZ = (32UL << 19) | 0x800U; + USBx_OUTEP(3U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; } EXIT_CRITICAL(); } diff --git a/board/faults.h b/board/faults.h index a7f437dee5..dc6c1f2aa4 100644 --- a/board/faults.h +++ b/board/faults.h @@ -9,7 +9,7 @@ #define FAULT_INTERRUPT_RATE_CAN_2 (1UL << 3) #define FAULT_INTERRUPT_RATE_CAN_3 (1UL << 4) #define FAULT_INTERRUPT_RATE_TACH (1UL << 5) -#define FAULT_INTERRUPT_RATE_GMLAN (1UL << 6) +#define FAULT_INTERRUPT_RATE_GMLAN (1UL << 6) // deprecated #define FAULT_INTERRUPT_RATE_INTERRUPTS (1UL << 7) #define FAULT_INTERRUPT_RATE_SPI_DMA (1UL << 8) #define FAULT_INTERRUPT_RATE_SPI_CS (1UL << 9) diff --git a/board/flash.py b/board/flash.py index d1a78e2c51..903a6a645f 100755 --- a/board/flash.py +++ b/board/flash.py @@ -15,3 +15,4 @@ print("flashing", s) with Panda(serial=s) as p: p.flash() + exit(1 if len(serials) == 0 else 0) diff --git a/board/health.h b/board/health.h index fc7661ca9c..74d822dc6c 100644 --- a/board/health.h +++ b/board/health.h @@ -1,6 +1,6 @@ // When changing these structs, python/__init__.py needs to be kept up to date! -#define HEALTH_PACKET_VERSION 15 +#define HEALTH_PACKET_VERSION 16 struct __attribute__((packed)) health_t { uint32_t uptime_pkt; uint32_t voltage_pkt; @@ -9,7 +9,6 @@ struct __attribute__((packed)) health_t { uint32_t safety_rx_invalid_pkt; uint32_t tx_buffer_overflow_pkt; uint32_t rx_buffer_overflow_pkt; - uint32_t gmlan_send_errs_pkt; uint32_t faults_pkt; uint8_t ignition_line_pkt; uint8_t ignition_can_pkt; diff --git a/board/jungle/__init__.py b/board/jungle/__init__.py index 77a6e3c7cc..688a8f91f0 100644 --- a/board/jungle/__init__.py +++ b/board/jungle/__init__.py @@ -2,7 +2,6 @@ import os import struct from functools import wraps -from typing import Optional from panda import Panda, PandaDFU from panda.python.constants import McuType @@ -57,7 +56,7 @@ def flash(self, fn=None, code=None, reconnect=True): fn = os.path.join(FW_PATH, self._mcu_type.config.app_fn.replace("panda", "panda_jungle")) super().flash(fn=fn, code=code, reconnect=reconnect) - def recover(self, timeout: Optional[int] = 60, reset: bool = True) -> bool: + def recover(self, timeout: int | None = 60, reset: bool = True) -> bool: dfu_serial = self.get_dfu_serial() if reset: @@ -81,6 +80,12 @@ def get_mcu_type(self) -> McuType: return McuType.F4 elif hw_type in PandaJungle.H7_DEVICES: return McuType.H7 + else: + # have to assume F4, see comment in Panda.connect + # initially Jungle V1 has HW type: bytearray(b'') + if hw_type == b'' or self._assume_f4_mcu: + return McuType.F4 + raise ValueError(f"unknown HW type: {hw_type}") def up_to_date(self, fn=None) -> bool: diff --git a/board/jungle/boards/board_declarations.h b/board/jungle/boards/board_declarations.h index 925918921f..2f65ff4a80 100644 --- a/board/jungle/boards/board_declarations.h +++ b/board/jungle/boards/board_declarations.h @@ -49,8 +49,6 @@ struct board { // CAN modes #define CAN_MODE_NORMAL 0U -#define CAN_MODE_GMLAN_CAN2 1U -#define CAN_MODE_GMLAN_CAN3 2U #define CAN_MODE_OBD_CAN2 3U // Harness states diff --git a/board/jungle/boards/board_v1.h b/board/jungle/boards/board_v1.h index 9581686e2a..efaacf60ce 100644 --- a/board/jungle/boards/board_v1.h +++ b/board/jungle/boards/board_v1.h @@ -157,7 +157,7 @@ void board_v1_init(void) { void board_v1_tick(void) {} -const board board_v1 = { +board board_v1 = { .has_canfd = false, .has_sbu_sense = false, .avdd_mV = 3300U, diff --git a/board/jungle/boards/board_v2.h b/board/jungle/boards/board_v2.h index 095114825b..ae4b2fc8d1 100644 --- a/board/jungle/boards/board_v2.h +++ b/board/jungle/boards/board_v2.h @@ -2,7 +2,7 @@ // Jungle board v2 (STM32H7) // // ///////////////////////// // -const gpio_t power_pins[] = { +gpio_t power_pins[] = { {.bank = GPIOA, .pin = 0}, {.bank = GPIOA, .pin = 1}, {.bank = GPIOF, .pin = 12}, @@ -11,7 +11,7 @@ const gpio_t power_pins[] = { {.bank = GPIOB, .pin = 2}, }; -const gpio_t sbu1_ignition_pins[] = { +gpio_t sbu1_ignition_pins[] = { {.bank = GPIOD, .pin = 0}, {.bank = GPIOD, .pin = 5}, {.bank = GPIOD, .pin = 12}, @@ -20,7 +20,7 @@ const gpio_t sbu1_ignition_pins[] = { {.bank = GPIOE, .pin = 9}, }; -const gpio_t sbu1_relay_pins[] = { +gpio_t sbu1_relay_pins[] = { {.bank = GPIOD, .pin = 1}, {.bank = GPIOD, .pin = 6}, {.bank = GPIOD, .pin = 11}, @@ -29,7 +29,7 @@ const gpio_t sbu1_relay_pins[] = { {.bank = GPIOE, .pin = 10}, }; -const gpio_t sbu2_ignition_pins[] = { +gpio_t sbu2_ignition_pins[] = { {.bank = GPIOD, .pin = 3}, {.bank = GPIOD, .pin = 8}, {.bank = GPIOD, .pin = 9}, @@ -38,7 +38,7 @@ const gpio_t sbu2_ignition_pins[] = { {.bank = GPIOE, .pin = 11}, }; -const gpio_t sbu2_relay_pins[] = { +gpio_t sbu2_relay_pins[] = { {.bank = GPIOD, .pin = 4}, {.bank = GPIOD, .pin = 10}, {.bank = GPIOD, .pin = 13}, @@ -47,7 +47,7 @@ const gpio_t sbu2_relay_pins[] = { {.bank = GPIOE, .pin = 12}, }; -const adc_channel_t sbu1_channels[] = { +adc_channel_t sbu1_channels[] = { {.adc = ADC3, .channel = 12}, {.adc = ADC3, .channel = 2}, {.adc = ADC3, .channel = 4}, @@ -56,7 +56,7 @@ const adc_channel_t sbu1_channels[] = { {.adc = ADC3, .channel = 10}, }; -const adc_channel_t sbu2_channels[] = { +adc_channel_t sbu2_channels[] = { {.adc = ADC1, .channel = 13}, {.adc = ADC3, .channel = 3}, {.adc = ADC3, .channel = 5}, @@ -307,7 +307,7 @@ void board_v2_init(void) { void board_v2_tick(void) {} -const board board_v2 = { +board board_v2 = { .has_canfd = true, .has_sbu_sense = true, .avdd_mV = 3300U, diff --git a/board/jungle/flash.py b/board/jungle/flash.py index 75a7f0c8ee..5b6c6e9046 100755 --- a/board/jungle/flash.py +++ b/board/jungle/flash.py @@ -15,3 +15,5 @@ print("flashing", s) with PandaJungle(serial=s) as p: p.flash() + + exit(1 if len(serials) == 0 else 0) diff --git a/board/jungle/main.c b/board/jungle/main.c index f0a09dfbde..0359be9684 100644 --- a/board/jungle/main.c +++ b/board/jungle/main.c @@ -2,7 +2,6 @@ #include "board/config.h" #include "board/safety.h" -#include "board/drivers/gmlan_alt.h" #include "board/drivers/pwm.h" #include "board/drivers/usb.h" diff --git a/board/jungle/recover.py b/board/jungle/recover.py index 98afb06748..19666c3eda 100755 --- a/board/jungle/recover.py +++ b/board/jungle/recover.py @@ -24,3 +24,4 @@ for s in dfu_serials: print("flashing", s) PandaJungleDFU(s).recover() + exit(1 if len(dfu_serials) == 0 else 0) diff --git a/board/jungle/scripts/get_version.py b/board/jungle/scripts/get_version.py index ad4a1c4264..4fc9d30bef 100755 --- a/board/jungle/scripts/get_version.py +++ b/board/jungle/scripts/get_version.py @@ -4,6 +4,6 @@ if __name__ == "__main__": for p in PandaJungle.list(): pp = PandaJungle(p) - print("%s: %s" % (pp.get_serial()[0], pp.get_version())) + print(f"{pp.get_serial()[0]}: {pp.get_version()}") diff --git a/board/jungle/stm32fx/board.h b/board/jungle/stm32f4/board.h similarity index 100% rename from board/jungle/stm32fx/board.h rename to board/jungle/stm32f4/board.h diff --git a/board/main.c b/board/main.c index 061a913814..4bd784bf0a 100644 --- a/board/main.c +++ b/board/main.c @@ -3,7 +3,6 @@ #include "drivers/pwm.h" #include "drivers/usb.h" -#include "drivers/gmlan_alt.h" #include "drivers/simple_watchdog.h" #include "drivers/bootkick.h" @@ -34,7 +33,6 @@ bool check_started(void) { bool started = current_board->check_ignition() || ignition_can; - ignition_seen |= started; return started; } @@ -145,8 +143,10 @@ void __attribute__ ((noinline)) enable_fpu(void) { // called at 8Hz uint8_t loop_counter = 0U; +uint8_t prev_harness_status = HARNESS_STATUS_NC; void tick_handler(void) { - if (TICK_TIMER->SR != 0) { + if (TICK_TIMER->SR != 0U) { + // siren current_board->set_siren((loop_counter & 1U) && (siren_enabled || (siren_countdown > 0U))); @@ -156,6 +156,17 @@ void tick_handler(void) { harness_tick(); simple_watchdog_kick(); + // re-init everything that uses harness status + if (harness.status != prev_harness_status) { + prev_harness_status = harness.status; + can_set_orientation(harness.status == HARNESS_STATUS_FLIPPED); + + // re-init everything that uses harness status + can_init_all(); + set_safety_mode(current_safety_mode, current_safety_param); + set_power_save_state(power_save_status); + } + // decimated to 1Hz if (loop_counter == 0U) { can_live = pending_can_live; @@ -187,7 +198,7 @@ void tick_handler(void) { bootkick_tick(check_started(), recent_heartbeat); // increase heartbeat counter and cap it at the uint32 limit - if (heartbeat_counter < __UINT32_MAX__) { + if (heartbeat_counter < UINT32_MAX) { heartbeat_counter += 1U; } @@ -280,38 +291,6 @@ void tick_handler(void) { TICK_TIMER->SR = 0; } -void EXTI_IRQ_Handler(void) { - if (check_exti_irq()) { - exti_irq_clear(); - clock_init(); - - set_power_save_state(POWER_SAVE_STATUS_DISABLED); - deepsleep_allowed = false; - heartbeat_counter = 0U; - usb_soft_disconnect(false); - - NVIC_EnableIRQ(TICK_TIMER_IRQ); - } -} - -uint8_t rtc_counter = 0; -void RTC_WKUP_IRQ_Handler(void) { - exti_irq_clear(); - clock_init(); - - rtc_counter++; - if ((rtc_counter % 2U) == 0U) { - current_board->set_led(LED_BLUE, false); - } else { - current_board->set_led(LED_BLUE, true); - } - - if (rtc_counter == __UINT8_MAX__) { - rtc_counter = 1U; - } -} - - int main(void) { // Init interrupt table init_interrupts(true); @@ -413,22 +392,6 @@ int main(void) { } #endif } else { - if (deepsleep_allowed && !usb_enumerated && !check_started() && ignition_seen && (heartbeat_counter > 20U)) { - usb_soft_disconnect(true); - fan_set_power(0U); - NVIC_DisableIRQ(TICK_TIMER_IRQ); - delay(512000U); - - // Init IRQs for CAN transceiver and ignition line - exti_irq_init(); - - // Init RTC Wakeup event on EXTI22 - REGISTER_INTERRUPT(RTC_WKUP_IRQn, RTC_WKUP_IRQ_Handler, 10U, FAULT_INTERRUPT_RATE_EXTI) - rtc_wakeup_init(); - - // STOP mode - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - } __WFI(); SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; } diff --git a/board/main_comms.h b/board/main_comms.h index c0d5c516fb..4c5d509624 100644 --- a/board/main_comms.h +++ b/board/main_comms.h @@ -21,7 +21,6 @@ int get_health_pkt(void *dat) { health->safety_rx_invalid_pkt = safety_rx_invalid; health->tx_buffer_overflow_pkt = tx_buffer_overflow; health->rx_buffer_overflow_pkt = rx_buffer_overflow; - health->gmlan_send_errs_pkt = gmlan_send_errs; health->car_harness_status_pkt = harness.status; health->safety_mode_pkt = (uint8_t)(current_safety_mode); health->safety_param_pkt = current_safety_param; @@ -48,12 +47,6 @@ int get_health_pkt(void *dat) { return sizeof(*health); } -int get_rtc_pkt(void *dat) { - timestamp_t t = rtc_get_time(); - (void)memcpy(dat, &t, sizeof(t)); - return sizeof(t); -} - // send on serial, first byte to select the ring void comms_endpoint2_write(const uint8_t *data, uint32_t len) { uart_ring *ur = get_ring_by_number(data[0]); @@ -71,7 +64,6 @@ void comms_endpoint2_write(const uint8_t *data, uint32_t len) { int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { unsigned int resp_len = 0; uart_ring *ur = NULL; - timestamp_t t; uint32_t time; #ifdef DEBUG_COMMS @@ -82,52 +74,6 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { #endif switch (req->request) { - // **** 0xa0: get rtc time - case 0xa0: - resp_len = get_rtc_pkt(resp); - break; - // **** 0xa1: set rtc year - case 0xa1: - t = rtc_get_time(); - t.year = req->param1; - rtc_set_time(t); - break; - // **** 0xa2: set rtc month - case 0xa2: - t = rtc_get_time(); - t.month = req->param1; - rtc_set_time(t); - break; - // **** 0xa3: set rtc day - case 0xa3: - t = rtc_get_time(); - t.day = req->param1; - rtc_set_time(t); - break; - // **** 0xa4: set rtc weekday - case 0xa4: - t = rtc_get_time(); - t.weekday = req->param1; - rtc_set_time(t); - break; - // **** 0xa5: set rtc hour - case 0xa5: - t = rtc_get_time(); - t.hour = req->param1; - rtc_set_time(t); - break; - // **** 0xa6: set rtc minute - case 0xa6: - t = rtc_get_time(); - t.minute = req->param1; - rtc_set_time(t); - break; - // **** 0xa7: set rtc second - case 0xa7: - t = rtc_get_time(); - t.second = req->param1; - rtc_set_time(t); - break; // **** 0xa8: get microsecond timer case 0xa8: time = microsecond_timer_get(); @@ -264,9 +210,9 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { case 0xd8: NVIC_SystemReset(); break; - // **** 0xdb: set GMLAN (white/grey) or OBD CAN (black) multiplexing mode + // **** 0xdb: set OBD CAN multiplexing mode case 0xdb: - if(current_board->has_obd){ + if (current_board->has_obd) { if (req->param1 == 1U) { // Enable OBD CAN current_board->set_can_mode(CAN_MODE_OBD_CAN2); @@ -428,10 +374,6 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { UNUSED(ret); } break; - // **** 0xfb: allow highest power saving mode (stop) to be entered - case 0xfb: - deepsleep_allowed = true; - break; // **** 0xfc: set CAN FD non-ISO mode case 0xfc: if ((req->param1 < PANDA_CAN_CNT) && current_board->has_canfd) { diff --git a/board/main_declarations.h b/board/main_declarations.h index 4570c6e67d..a1496c0d0a 100644 --- a/board/main_declarations.h +++ b/board/main_declarations.h @@ -6,13 +6,12 @@ void puth4(unsigned int i); void hexdump(const void *a, int l); typedef struct board board; typedef struct harness_configuration harness_configuration; -void can_flip_buses(uint8_t bus1, uint8_t bus2); void pwm_init(TIM_TypeDef *TIM, uint8_t channel); void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage); // ********************* Globals ********************** uint8_t hw_type = 0; -const board *current_board; +board *current_board; uint32_t uptime_cnt = 0; bool green_led_enabled = false; @@ -21,10 +20,6 @@ uint32_t heartbeat_counter = 0; bool heartbeat_lost = false; bool heartbeat_disabled = false; // set over USB -// Enter deep sleep mode -bool deepsleep_allowed = false; -bool ignition_seen = false; - // siren state bool siren_enabled = false; uint32_t siren_countdown = 0; // siren plays while countdown > 0 diff --git a/board/recover.py b/board/recover.py index 5284a4e295..0a248525a8 100755 --- a/board/recover.py +++ b/board/recover.py @@ -24,3 +24,4 @@ for s in dfu_serials: print("flashing", s) PandaDFU(s).recover() + exit(1 if len(dfu_serials) == 0 else 0) diff --git a/board/safety.h b/board/safety.h index 1e95244099..048d7cca48 100644 --- a/board/safety.h +++ b/board/safety.h @@ -327,8 +327,6 @@ int set_safety_hooks(uint16_t mode, uint16_t param) { // reset state set by safety mode safety_mode_cnt = 0U; relay_malfunction = false; - enable_gas_interceptor = false; - gas_interceptor_prev = 0; gas_pressed = false; gas_pressed_prev = false; brake_pressed = false; @@ -543,10 +541,6 @@ bool longitudinal_brake_checks(int desired_brake, const LongitudinalLimits limit return violation; } -bool longitudinal_interceptor_checks(const CANPacket_t *to_send) { - return !get_longitudinal_allowed() && (GET_BYTE(to_send, 0) || GET_BYTE(to_send, 1)); -} - // Safety checks for torque-based steering commands bool steer_torque_cmd_checks(int desired_torque, int steer_req, const SteeringLimits limits) { bool violation = false; diff --git a/board/safety/safety_chrysler.h b/board/safety/safety_chrysler.h index fa0e1532d5..be27832c9d 100644 --- a/board/safety/safety_chrysler.h +++ b/board/safety/safety_chrysler.h @@ -123,11 +123,12 @@ RxCheck chrysler_ram_hd_rx_checks[] = { const uint32_t CHRYSLER_PARAM_RAM_DT = 1U; // set for Ram DT platform const uint32_t CHRYSLER_PARAM_RAM_HD = 2U; // set for Ram HD platform -enum { +typedef enum { CHRYSLER_RAM_DT, CHRYSLER_RAM_HD, CHRYSLER_PACIFICA, // plus Jeep -} chrysler_platform = CHRYSLER_PACIFICA; +} ChryslerPlatform; +ChryslerPlatform chrysler_platform = CHRYSLER_PACIFICA; const ChryslerAddrs *chrysler_addrs = &CHRYSLER_ADDRS; static uint32_t chrysler_get_checksum(const CANPacket_t *to_push) { diff --git a/board/safety/safety_ford.h b/board/safety/safety_ford.h index 2f11863b49..d6ee208036 100644 --- a/board/safety/safety_ford.h +++ b/board/safety/safety_ford.h @@ -59,8 +59,10 @@ const CanMsg FORD_CANFD_LONG_TX_MSGS[] = { // this may be the cause of blocked messages RxCheck ford_rx_checks[] = { {.msg = {{FORD_BrakeSysFeatures, 0, 8, .check_checksum = true, .max_counter = 15U, .quality_flag=true, .frequency = 50U}, { 0 }, { 0 }}}, - // TODO: FORD_EngVehicleSpThrottle2 has a counter that skips by 2, understand and enable counter check - {.msg = {{FORD_EngVehicleSpThrottle2, 0, 8, .check_checksum = true, .quality_flag=true, .frequency = 50U}, { 0 }, { 0 }}}, + // FORD_EngVehicleSpThrottle2 has a counter that either randomly skips or by 2, likely ECU bug + // Some hybrid models also experience a bug where this checksum mismatches for one or two frames under heavy acceleration with ACC + // It has been confirmed that the Bronco Sport's camera only disallows ACC for bad quality flags, not counters or checksums, so we match that + {.msg = {{FORD_EngVehicleSpThrottle2, 0, 8, .check_checksum = false, .quality_flag=true, .frequency = 50U}, { 0 }, { 0 }}}, {.msg = {{FORD_Yaw_Data_FD1, 0, 8, .check_checksum = true, .max_counter = 255U, .quality_flag=true, .frequency = 100U}, { 0 }, { 0 }}}, // These messages have no counter or checksum {.msg = {{FORD_EngBrakeData, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, @@ -90,9 +92,6 @@ 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_EngVehicleSpThrottle2) { - // Signal: VehVActlEng_No_Cs - chksum = GET_BYTE(to_push, 1); } else if (addr == FORD_Yaw_Data_FD1) { // Signal: VehRollYawW_No_Cs chksum = GET_BYTE(to_push, 4); @@ -110,11 +109,6 @@ 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_EngVehicleSpThrottle2) { - chksum += (GET_BYTE(to_push, 2) >> 3) & 0xFU; // VehVActlEng_No_Cnt - chksum += (GET_BYTE(to_push, 4) >> 5) & 0x3U; // VehVActlEng_D_Qf - chksum += GET_BYTE(to_push, 6) + GET_BYTE(to_push, 7); // Veh_V_ActlEng - chksum = 0xFFU - chksum; } else 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 diff --git a/board/safety/safety_gm.h b/board/safety/safety_gm.h index 82a5d9cd3e..09ac34ecbd 100644 --- a/board/safety/safety_gm.h +++ b/board/safety/safety_gm.h @@ -29,8 +29,7 @@ const int GM_STANDSTILL_THRSLD = 10; // 0.311kph const CanMsg GM_ASCM_TX_MSGS[] = {{0x180, 0, 4}, {0x409, 0, 7}, {0x40A, 0, 7}, {0x2CB, 0, 8}, {0x370, 0, 6}, // pt bus {0xA1, 1, 7}, {0x306, 1, 8}, {0x308, 1, 7}, {0x310, 1, 2}, // obs bus - {0x315, 2, 5}, // ch bus - {0x104c006c, 3, 3}, {0x10400060, 3, 5}}; // gmlan + {0x315, 2, 5}}; // ch bus const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, // pt bus {0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus @@ -60,7 +59,11 @@ enum { GM_BTN_CANCEL = 6, }; -enum {GM_ASCM, GM_CAM} gm_hw = GM_ASCM; +typedef enum { + GM_ASCM, + GM_CAM +} GmHardware; +GmHardware gm_hw = GM_ASCM; bool gm_cam_long = false; bool gm_pcm_cruise = false; diff --git a/board/safety/safety_honda.h b/board/safety/safety_honda.h index 4bcbd7745d..754d7e9dbf 100644 --- a/board/safety/safety_honda.h +++ b/board/safety/safety_honda.h @@ -1,16 +1,9 @@ const CanMsg HONDA_N_TX_MSGS[] = {{0xE4, 0, 5}, {0x194, 0, 4}, {0x1FA, 0, 8}, {0x30C, 0, 8}, {0x33D, 0, 5}}; -const CanMsg HONDA_N_INTERCEPTOR_TX_MSGS[] = {{0xE4, 0, 5}, {0x194, 0, 4}, {0x1FA, 0, 8}, {0x200, 0, 6}, {0x30C, 0, 8}, {0x33D, 0, 5}}; const CanMsg HONDA_BOSCH_TX_MSGS[] = {{0xE4, 0, 5}, {0xE5, 0, 8}, {0x296, 1, 4}, {0x33D, 0, 5}, {0x33DA, 0, 5}, {0x33DB, 0, 8}}; // Bosch const CanMsg HONDA_BOSCH_LONG_TX_MSGS[] = {{0xE4, 1, 5}, {0x1DF, 1, 8}, {0x1EF, 1, 8}, {0x1FA, 1, 8}, {0x30C, 1, 8}, {0x33D, 1, 5}, {0x33DA, 1, 5}, {0x33DB, 1, 8}, {0x39F, 1, 8}, {0x18DAB0F1, 1, 8}}; // Bosch w/ gas and brakes const CanMsg HONDA_RADARLESS_TX_MSGS[] = {{0xE4, 0, 5}, {0x296, 2, 4}, {0x33D, 0, 8}}; // Bosch radarless const CanMsg HONDA_RADARLESS_LONG_TX_MSGS[] = {{0xE4, 0, 5}, {0x33D, 0, 8}, {0x1C8, 0, 8}, {0x30C, 0, 8}}; // Bosch radarless w/ gas and brakes -// panda interceptor threshold needs to be equivalent to openpilot threshold to avoid controls mismatches -// If thresholds are mismatched then it is possible for panda to see the gas fall and rise while openpilot is in the pre-enabled state -// Threshold calculated from DBC gains: round(((83.3 / 0.253984064) + (83.3 / 0.126992032)) / 2) = 492 -const int HONDA_GAS_INTERCEPTOR_THRESHOLD = 492; -#define HONDA_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + (GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2U) // avg between 2 tracks - const LongitudinalLimits HONDA_BOSCH_LONG_LIMITS = { .max_accel = 200, // accel is used for brakes .min_accel = -350, @@ -47,11 +40,6 @@ RxCheck honda_common_rx_checks[] = { HONDA_COMMON_RX_CHECKS(0) }; -RxCheck honda_common_interceptor_rx_checks[] = { - HONDA_COMMON_RX_CHECKS(0) - {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, -}; - RxCheck honda_common_alt_brake_rx_checks[] = { HONDA_COMMON_RX_CHECKS(0) HONDA_ALT_BRAKE_ADDR_CHECK(0) @@ -62,11 +50,6 @@ RxCheck honda_nidec_alt_rx_checks[] = { HONDA_COMMON_NO_SCM_FEEDBACK_RX_CHECKS(0) }; -RxCheck honda_nidec_alt_interceptor_rx_checks[] = { - HONDA_COMMON_NO_SCM_FEEDBACK_RX_CHECKS(0) - {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, -}; - // Bosch has pt on bus 1, verified 0x1A6 does not exist RxCheck honda_bosch_rx_checks[] = { HONDA_COMMON_RX_CHECKS(1) @@ -81,7 +64,6 @@ const uint16_t HONDA_PARAM_ALT_BRAKE = 1; const uint16_t HONDA_PARAM_BOSCH_LONG = 2; const uint16_t HONDA_PARAM_NIDEC_ALT = 4; const uint16_t HONDA_PARAM_RADARLESS = 8; -const uint16_t HONDA_PARAM_GAS_INTERCEPTOR = 16; enum { HONDA_BTN_NONE = 0, @@ -97,7 +79,8 @@ bool honda_alt_brake_msg = false; bool honda_fwd_brake = false; bool honda_bosch_long = false; bool honda_bosch_radarless = false; -enum {HONDA_NIDEC, HONDA_BOSCH} honda_hw = HONDA_NIDEC; +typedef enum {HONDA_NIDEC, HONDA_BOSCH} HondaHw; +HondaHw honda_hw = HONDA_NIDEC; int honda_get_pt_bus(void) { @@ -127,26 +110,15 @@ static uint32_t honda_compute_checksum(const CANPacket_t *to_push) { } static uint8_t honda_get_counter(const CANPacket_t *to_push) { - int addr = GET_ADDR(to_push); - - uint8_t cnt = 0U; - if (addr == 0x201) { - // Signal: COUNTER_PEDAL - cnt = GET_BYTE(to_push, 4) & 0x0FU; - } else { - int counter_byte = GET_LEN(to_push) - 1U; - cnt = (GET_BYTE(to_push, counter_byte) >> 4U) & 0x3U; - } - return cnt; + int counter_byte = GET_LEN(to_push) - 1U; + return (GET_BYTE(to_push, counter_byte) >> 4U) & 0x3U; } static void honda_rx_hook(const CANPacket_t *to_push) { - const bool pcm_cruise = ((honda_hw == HONDA_BOSCH) && !honda_bosch_long) || \ - ((honda_hw == HONDA_NIDEC) && !enable_gas_interceptor); + const bool pcm_cruise = ((honda_hw == HONDA_BOSCH) && !honda_bosch_long) || (honda_hw == HONDA_NIDEC); int pt_bus = honda_get_pt_bus(); int addr = GET_ADDR(to_push); - int len = GET_LEN(to_push); int bus = GET_BUS(to_push); // sample speed @@ -218,17 +190,8 @@ static void honda_rx_hook(const CANPacket_t *to_push) { } } - // length check because bosch hardware also uses this id (0x201 w/ len = 8) - if ((addr == 0x201) && (len == 6) && enable_gas_interceptor) { - int gas_interceptor = HONDA_GET_INTERCEPTOR(to_push); - gas_pressed = gas_interceptor > HONDA_GAS_INTERCEPTOR_THRESHOLD; - gas_interceptor_prev = gas_interceptor; - } - - if (!enable_gas_interceptor) { - if (addr == 0x17C) { - gas_pressed = GET_BYTE(to_push, 0) != 0U; - } + if (addr == 0x17C) { + gas_pressed = GET_BYTE(to_push, 0) != 0U; } // disable stock Honda AEB in alternative experience @@ -346,13 +309,6 @@ static bool honda_tx_hook(const CANPacket_t *to_send) { } } - // GAS: safety check (interceptor) - if (addr == 0x200) { - if (longitudinal_interceptor_checks(to_send)) { - tx = false; - } - } - // FORCE CANCEL: safety check only relevant when spamming the cancel button in Bosch HW // ensuring that only the cancel button press is sent (VAL 2) when controls are off. // This avoids unintended engagements while still allowing resume spam and button passthrough. @@ -380,24 +336,18 @@ static safety_config honda_nidec_init(uint16_t param) { honda_alt_brake_msg = false; honda_bosch_long = false; honda_bosch_radarless = false; - enable_gas_interceptor = GET_FLAG(param, HONDA_PARAM_GAS_INTERCEPTOR); safety_config ret; bool enable_nidec_alt = GET_FLAG(param, HONDA_PARAM_NIDEC_ALT); + if (enable_nidec_alt) { - enable_gas_interceptor ? SET_RX_CHECKS(honda_nidec_alt_interceptor_rx_checks, ret) : \ - SET_RX_CHECKS(honda_nidec_alt_rx_checks, ret); + SET_RX_CHECKS(honda_nidec_alt_rx_checks, ret); } else { - enable_gas_interceptor ? SET_RX_CHECKS(honda_common_interceptor_rx_checks, ret) : \ - SET_RX_CHECKS(honda_common_rx_checks, ret); + SET_RX_CHECKS(honda_common_rx_checks, ret); } + SET_TX_MSGS(HONDA_N_TX_MSGS, ret); - if (enable_gas_interceptor) { - SET_TX_MSGS(HONDA_N_INTERCEPTOR_TX_MSGS, ret); - } else { - SET_TX_MSGS(HONDA_N_TX_MSGS, ret); - } return ret; } diff --git a/board/safety/safety_subaru.h b/board/safety/safety_subaru.h index c445bc435e..581dc50b7f 100644 --- a/board/safety/safety_subaru.h +++ b/board/safety/safety_subaru.h @@ -28,7 +28,7 @@ const LongitudinalLimits SUBARU_LONG_LIMITS = { .max_brake = 600, // approx -3.5 m/s^2 .min_transmission_rpm = 0, - .max_transmission_rpm = 2400, + .max_transmission_rpm = 3600, }; #define MSG_SUBARU_Brake_Status 0x13c diff --git a/board/safety/safety_tesla.h b/board/safety/safety_tesla.h index 4fa0df84aa..652161ff2c 100644 --- a/board/safety/safety_tesla.h +++ b/board/safety/safety_tesla.h @@ -19,6 +19,7 @@ const LongitudinalLimits TESLA_LONG_LIMITS = { const int TESLA_FLAG_POWERTRAIN = 1; const int TESLA_FLAG_LONGITUDINAL_CONTROL = 2; +const int TESLA_FLAG_RAVEN = 4; const CanMsg TESLA_TX_MSGS[] = { {0x488, 0, 4}, // DAS_steeringControl @@ -41,6 +42,16 @@ RxCheck tesla_rx_checks[] = { {.msg = {{0x318, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, // GTW_carState }; +RxCheck tesla_raven_rx_checks[] = { + {.msg = {{0x2b9, 2, 8, .frequency = 25U}, { 0 }, { 0 }}}, // DAS_control + {.msg = {{0x131, 2, 8, .frequency = 100U}, { 0 }, { 0 }}}, // EPAS3P_sysStatus + {.msg = {{0x108, 0, 8, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque1 + {.msg = {{0x118, 0, 6, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque2 + {.msg = {{0x20a, 0, 8, .frequency = 50U}, { 0 }, { 0 }}}, // BrakeMessage + {.msg = {{0x368, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, // DI_state + {.msg = {{0x318, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, // GTW_carState +}; + RxCheck tesla_pt_rx_checks[] = { {.msg = {{0x106, 0, 8, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque1 {.msg = {{0x116, 0, 6, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque2 @@ -51,6 +62,7 @@ RxCheck tesla_pt_rx_checks[] = { bool tesla_longitudinal = false; bool tesla_powertrain = false; // Are we the second panda intercepting the powertrain bus? +bool tesla_raven = false; bool tesla_stock_aeb = false; @@ -58,16 +70,16 @@ static void tesla_rx_hook(const CANPacket_t *to_push) { int bus = GET_BUS(to_push); int addr = GET_ADDR(to_push); - if(bus == 0) { - if (!tesla_powertrain) { - if(addr == 0x370) { - // Steering angle: (0.1 * val) - 819.2 in deg. - // Store it 1/10 deg to match steering request - int angle_meas_new = (((GET_BYTE(to_push, 4) & 0x3FU) << 8) | GET_BYTE(to_push, 5)) - 8192U; - update_sample(&angle_meas, angle_meas_new); - } + if (!tesla_powertrain) { + if((!tesla_raven && (addr == 0x370) && (bus == 0)) || (tesla_raven && (addr == 0x131) && (bus == 2))) { + // Steering angle: (0.1 * val) - 819.2 in deg. + // Store it 1/10 deg to match steering request + int angle_meas_new = (((GET_BYTE(to_push, 4) & 0x3FU) << 8) | GET_BYTE(to_push, 5)) - 8192U; + update_sample(&angle_meas, angle_meas_new); } + } + if(bus == 0) { if(addr == (tesla_powertrain ? 0x116 : 0x118)) { // Vehicle speed: ((0.05 * val) - 25) * MPH_TO_MPS float speed = (((((GET_BYTE(to_push, 3) & 0x0FU) << 8) | (GET_BYTE(to_push, 2))) * 0.05) - 25) * 0.447; @@ -206,12 +218,15 @@ static int tesla_fwd_hook(int bus_num, int addr) { static safety_config tesla_init(uint16_t param) { tesla_powertrain = GET_FLAG(param, TESLA_FLAG_POWERTRAIN); tesla_longitudinal = GET_FLAG(param, TESLA_FLAG_LONGITUDINAL_CONTROL); + tesla_raven = GET_FLAG(param, TESLA_FLAG_RAVEN); tesla_stock_aeb = false; safety_config ret; if (tesla_powertrain) { ret = BUILD_SAFETY_CFG(tesla_pt_rx_checks, TESLA_PT_TX_MSGS); + } else if (tesla_raven) { + ret = BUILD_SAFETY_CFG(tesla_raven_rx_checks, TESLA_TX_MSGS); } else { ret = BUILD_SAFETY_CFG(tesla_rx_checks, TESLA_TX_MSGS); } diff --git a/board/safety/safety_toyota.h b/board/safety/safety_toyota.h index 50c00b38a8..05f84e4604 100644 --- a/board/safety/safety_toyota.h +++ b/board/safety/safety_toyota.h @@ -37,12 +37,6 @@ const LongitudinalLimits TOYOTA_LONG_LIMITS = { .min_accel = -3500, // -3.5 m/s2 }; -// panda interceptor threshold needs to be equivalent to openpilot threshold to avoid controls mismatches -// If thresholds are mismatched then it is possible for panda to see the gas fall and rise while openpilot is in the pre-enabled state -// Threshold calculated from DBC gains: round((((15 + 75.555) / 0.159375) + ((15 + 151.111) / 0.159375)) / 2) = 805 -const int TOYOTA_GAS_INTERCEPTOR_THRSLD = 805; -#define TOYOTA_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + (GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2U) // avg between 2 tracks - // Stock longitudinal #define TOYOTA_COMMON_TX_MSGS \ {0x2E4, 0, 5}, {0x191, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, /* LKAS + LTA + ACC & PCM cancel cmds */ \ @@ -62,11 +56,6 @@ const CanMsg TOYOTA_LONG_TX_MSGS[] = { TOYOTA_COMMON_LONG_TX_MSGS }; -const CanMsg TOYOTA_INTERCEPTOR_TX_MSGS[] = { - TOYOTA_COMMON_LONG_TX_MSGS - {0x200, 0, 6}, // gas interceptor -}; - #define TOYOTA_COMMON_RX_CHECKS(lta) \ {.msg = {{ 0xaa, 0, 8, .check_checksum = false, .frequency = 83U}, { 0 }, { 0 }}}, \ {.msg = {{0x260, 0, 8, .check_checksum = true, .quality_flag = (lta), .frequency = 50U}, { 0 }, { 0 }}}, \ @@ -78,21 +67,11 @@ RxCheck toyota_lka_rx_checks[] = { TOYOTA_COMMON_RX_CHECKS(false) }; -RxCheck toyota_lka_interceptor_rx_checks[] = { - TOYOTA_COMMON_RX_CHECKS(false) - {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, -}; - // Check the quality flag for angle measurement when using LTA, since it's not set on TSS-P cars RxCheck toyota_lta_rx_checks[] = { TOYOTA_COMMON_RX_CHECKS(true) }; -RxCheck toyota_lta_interceptor_rx_checks[] = { - TOYOTA_COMMON_RX_CHECKS(true) - {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, -}; - // safety param flags // first byte is for EPS factor, second is for flags const uint32_t TOYOTA_PARAM_OFFSET = 8U; @@ -100,7 +79,6 @@ const uint32_t TOYOTA_EPS_FACTOR = (1UL << TOYOTA_PARAM_OFFSET) - 1U; const uint32_t TOYOTA_PARAM_ALT_BRAKE = 1UL << TOYOTA_PARAM_OFFSET; const uint32_t TOYOTA_PARAM_STOCK_LONGITUDINAL = 2UL << TOYOTA_PARAM_OFFSET; const uint32_t TOYOTA_PARAM_LTA = 4UL << TOYOTA_PARAM_OFFSET; -const uint32_t TOYOTA_PARAM_GAS_INTERCEPTOR = 8UL << TOYOTA_PARAM_OFFSET; bool toyota_alt_brake = false; bool toyota_stock_longitudinal = false; @@ -122,17 +100,6 @@ static uint32_t toyota_get_checksum(const CANPacket_t *to_push) { return (uint8_t)(GET_BYTE(to_push, checksum_byte)); } -static uint8_t toyota_get_counter(const CANPacket_t *to_push) { - int addr = GET_ADDR(to_push); - - uint8_t cnt = 0U; - if (addr == 0x201) { - // Signal: COUNTER_PEDAL - cnt = GET_BYTE(to_push, 4) & 0x0FU; - } - return cnt; -} - static bool toyota_get_quality_flag_valid(const CANPacket_t *to_push) { int addr = GET_ADDR(to_push); @@ -185,9 +152,7 @@ static void toyota_rx_hook(const CANPacket_t *to_push) { pcm_cruise_check(cruise_engaged); // sample gas pedal - if (!enable_gas_interceptor) { - gas_pressed = !GET_BIT(to_push, 4U); - } + gas_pressed = !GET_BIT(to_push, 4U); } // sample speed @@ -210,15 +175,6 @@ static void toyota_rx_hook(const CANPacket_t *to_push) { brake_pressed = GET_BIT(to_push, bit); } - // sample gas interceptor - if ((addr == 0x201) && enable_gas_interceptor) { - int gas_interceptor = TOYOTA_GET_INTERCEPTOR(to_push); - gas_pressed = gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRSLD; - - // TODO: remove this, only left in for gas_interceptor_prev test - gas_interceptor_prev = gas_interceptor; - } - bool stock_ecu_detected = addr == 0x2E4; // STEERING_LKA if (!toyota_stock_longitudinal && (addr == 0x343)) { stock_ecu_detected = true; // ACC_CONTROL @@ -234,14 +190,6 @@ static bool toyota_tx_hook(const CANPacket_t *to_send) { // Check if msg is sent on BUS 0 if (bus == 0) { - - // GAS PEDAL: safety check - if (addr == 0x200) { - if (longitudinal_interceptor_checks(to_send)) { - tx = false; - } - } - // ACCEL: safety check on byte 1-2 if (addr == 0x343) { int desired_accel = (GET_BYTE(to_send, 0) << 8) | GET_BYTE(to_send, 1); @@ -357,29 +305,17 @@ static safety_config toyota_init(uint16_t param) { toyota_alt_brake = GET_FLAG(param, TOYOTA_PARAM_ALT_BRAKE); toyota_stock_longitudinal = GET_FLAG(param, TOYOTA_PARAM_STOCK_LONGITUDINAL); toyota_lta = GET_FLAG(param, TOYOTA_PARAM_LTA); - enable_gas_interceptor = GET_FLAG(param, TOYOTA_PARAM_GAS_INTERCEPTOR); toyota_dbc_eps_torque_factor = param & TOYOTA_EPS_FACTOR; - // Gas interceptor should not be used if openpilot is not controlling longitudinal - if (toyota_stock_longitudinal) { - enable_gas_interceptor = false; - } - safety_config ret; if (toyota_stock_longitudinal) { SET_TX_MSGS(TOYOTA_TX_MSGS, ret); } else { - enable_gas_interceptor ? SET_TX_MSGS(TOYOTA_INTERCEPTOR_TX_MSGS, ret) : \ - SET_TX_MSGS(TOYOTA_LONG_TX_MSGS, ret); + SET_TX_MSGS(TOYOTA_LONG_TX_MSGS, ret); } - if (enable_gas_interceptor) { - toyota_lta ? SET_RX_CHECKS(toyota_lta_interceptor_rx_checks, ret) : \ - SET_RX_CHECKS(toyota_lka_interceptor_rx_checks, ret); - } else { - toyota_lta ? SET_RX_CHECKS(toyota_lta_rx_checks, ret) : \ - SET_RX_CHECKS(toyota_lka_rx_checks, ret); - } + toyota_lta ? SET_RX_CHECKS(toyota_lta_rx_checks, ret) : \ + SET_RX_CHECKS(toyota_lka_rx_checks, ret); return ret; } @@ -413,6 +349,5 @@ const safety_hooks toyota_hooks = { .fwd = toyota_fwd_hook, .get_checksum = toyota_get_checksum, .compute_checksum = toyota_compute_checksum, - .get_counter = toyota_get_counter, .get_quality_flag_valid = toyota_get_quality_flag_valid, }; diff --git a/board/safety/safety_volkswagen_pq.h b/board/safety/safety_volkswagen_pq.h index 1922cf4671..de147cb58a 100644 --- a/board/safety/safety_volkswagen_pq.h +++ b/board/safety/safety_volkswagen_pq.h @@ -185,7 +185,7 @@ static bool volkswagen_pq_tx_hook(const CANPacket_t *to_send) { } uint32_t hca_status = ((GET_BYTE(to_send, 1) >> 4) & 0xFU); - bool steer_req = (hca_status == 5U); + bool steer_req = ((hca_status == 5U) || (hca_status == 7U)); if (steer_torque_cmd_checks(desired_torque, steer_req, VOLKSWAGEN_PQ_STEERING_LIMITS)) { tx = false; diff --git a/board/safety_declarations.h b/board/safety_declarations.h index 64b55f2033..4140f56e34 100644 --- a/board/safety_declarations.h +++ b/board/safety_declarations.h @@ -203,7 +203,6 @@ bool longitudinal_speed_checks(int desired_speed, const LongitudinalLimits limit bool longitudinal_gas_checks(int desired_gas, const LongitudinalLimits limits); bool longitudinal_transmission_rpm_checks(int desired_transmission_rpm, const LongitudinalLimits limits); bool longitudinal_brake_checks(int desired_brake, const LongitudinalLimits limits); -bool longitudinal_interceptor_checks(const CANPacket_t *to_send); void pcm_cruise_check(bool cruise_engaged); void safety_tick(const safety_config *safety_config); @@ -211,8 +210,6 @@ void safety_tick(const safety_config *safety_config); // This can be set by the safety hooks bool controls_allowed = false; bool relay_malfunction = false; -bool enable_gas_interceptor = false; -int gas_interceptor_prev = 0; bool gas_pressed = false; bool gas_pressed_prev = false; bool brake_pressed = false; diff --git a/board/stm32fx/board.h b/board/stm32f4/board.h similarity index 93% rename from board/stm32fx/board.h rename to board/stm32f4/board.h index 808f773829..bf95d58eaa 100644 --- a/board/stm32fx/board.h +++ b/board/stm32f4/board.h @@ -5,12 +5,10 @@ #include "boards/unused_funcs.h" // ///// Board definition and detection ///// // -#include "stm32fx/lladc.h" +#include "stm32f4/lladc.h" #include "drivers/harness.h" #include "drivers/fan.h" -#include "stm32fx/llfan.h" -#include "stm32fx/llrtc.h" -#include "drivers/rtc.h" +#include "stm32f4/llfan.h" #include "drivers/clock_source.h" #include "boards/white.h" #include "boards/grey.h" diff --git a/board/stm32fx/clock.h b/board/stm32f4/clock.h similarity index 91% rename from board/stm32fx/clock.h rename to board/stm32f4/clock.h index 19be574438..f0084faccb 100644 --- a/board/stm32fx/clock.h +++ b/board/stm32f4/clock.h @@ -1,7 +1,7 @@ void clock_init(void) { // enable external oscillator register_set_bits(&(RCC->CR), RCC_CR_HSEON); - while ((RCC->CR & RCC_CR_HSERDY) == 0); + while ((RCC->CR & RCC_CR_HSERDY) == 0U); // divide things // AHB = 96MHz @@ -20,7 +20,7 @@ void clock_init(void) { // start PLL register_set_bits(&(RCC->CR), RCC_CR_PLLON); - while ((RCC->CR & RCC_CR_PLLRDY) == 0); + while ((RCC->CR & RCC_CR_PLLRDY) == 0U); // Configure Flash prefetch, Instruction cache, Data cache and wait state // *** without this, it breaks *** diff --git a/board/stm32fx/inc/cmsis_compiler.h b/board/stm32f4/inc/cmsis_compiler.h similarity index 100% rename from board/stm32fx/inc/cmsis_compiler.h rename to board/stm32f4/inc/cmsis_compiler.h diff --git a/board/stm32fx/inc/cmsis_gcc.h b/board/stm32f4/inc/cmsis_gcc.h similarity index 100% rename from board/stm32fx/inc/cmsis_gcc.h rename to board/stm32f4/inc/cmsis_gcc.h diff --git a/board/stm32fx/inc/cmsis_version.h b/board/stm32f4/inc/cmsis_version.h similarity index 100% rename from board/stm32fx/inc/cmsis_version.h rename to board/stm32f4/inc/cmsis_version.h diff --git a/board/stm32fx/inc/core_cm3.h b/board/stm32f4/inc/core_cm3.h similarity index 100% rename from board/stm32fx/inc/core_cm3.h rename to board/stm32f4/inc/core_cm3.h diff --git a/board/stm32fx/inc/core_cm4.h b/board/stm32f4/inc/core_cm4.h similarity index 100% rename from board/stm32fx/inc/core_cm4.h rename to board/stm32f4/inc/core_cm4.h diff --git a/board/stm32fx/inc/mpu_armv7.h b/board/stm32f4/inc/mpu_armv7.h similarity index 100% rename from board/stm32fx/inc/mpu_armv7.h rename to board/stm32f4/inc/mpu_armv7.h diff --git a/board/stm32fx/inc/stm32f413xx.h b/board/stm32f4/inc/stm32f413xx.h similarity index 100% rename from board/stm32fx/inc/stm32f413xx.h rename to board/stm32f4/inc/stm32f413xx.h diff --git a/board/stm32fx/inc/stm32f4xx.h b/board/stm32f4/inc/stm32f4xx.h similarity index 100% rename from board/stm32fx/inc/stm32f4xx.h rename to board/stm32f4/inc/stm32f4xx.h diff --git a/board/stm32fx/inc/stm32f4xx_hal_def.h b/board/stm32f4/inc/stm32f4xx_hal_def.h similarity index 100% rename from board/stm32fx/inc/stm32f4xx_hal_def.h rename to board/stm32f4/inc/stm32f4xx_hal_def.h diff --git a/board/stm32fx/inc/stm32f4xx_hal_gpio_ex.h b/board/stm32f4/inc/stm32f4xx_hal_gpio_ex.h similarity index 100% rename from board/stm32fx/inc/stm32f4xx_hal_gpio_ex.h rename to board/stm32f4/inc/stm32f4xx_hal_gpio_ex.h diff --git a/board/stm32fx/inc/system_stm32f4xx.h b/board/stm32f4/inc/system_stm32f4xx.h similarity index 100% rename from board/stm32fx/inc/system_stm32f4xx.h rename to board/stm32f4/inc/system_stm32f4xx.h diff --git a/board/stm32fx/interrupt_handlers.h b/board/stm32f4/interrupt_handlers.h similarity index 100% rename from board/stm32fx/interrupt_handlers.h rename to board/stm32f4/interrupt_handlers.h diff --git a/board/stm32fx/lladc.h b/board/stm32f4/lladc.h similarity index 100% rename from board/stm32fx/lladc.h rename to board/stm32f4/lladc.h diff --git a/board/stm32fx/llbxcan.h b/board/stm32f4/llbxcan.h similarity index 100% rename from board/stm32fx/llbxcan.h rename to board/stm32f4/llbxcan.h diff --git a/board/stm32fx/llfan.h b/board/stm32f4/llfan.h similarity index 100% rename from board/stm32fx/llfan.h rename to board/stm32f4/llfan.h diff --git a/board/stm32fx/llflash.h b/board/stm32f4/llflash.h similarity index 100% rename from board/stm32fx/llflash.h rename to board/stm32f4/llflash.h diff --git a/board/stm32fx/llspi.h b/board/stm32f4/llspi.h similarity index 100% rename from board/stm32fx/llspi.h rename to board/stm32f4/llspi.h diff --git a/board/stm32fx/lluart.h b/board/stm32f4/lluart.h similarity index 96% rename from board/stm32fx/lluart.h rename to board/stm32f4/lluart.h index ffe7e74da0..64094119f4 100644 --- a/board/stm32fx/lluart.h +++ b/board/stm32f4/lluart.h @@ -5,7 +5,7 @@ void uart_tx_ring(uart_ring *q){ // Send out next byte of TX buffer if (q->w_ptr_tx != q->r_ptr_tx) { // Only send if transmit register is empty (aka last byte has been sent) - if ((q->uart->SR & USART_SR_TXE) != 0) { + if ((q->uart->SR & USART_SR_TXE) != 0U) { q->uart->DR = q->elems_tx[q->r_ptr_tx]; // This clears TXE q->r_ptr_tx = (q->r_ptr_tx + 1U) % q->tx_fifo_size; } @@ -46,7 +46,7 @@ void uart_rx_ring(uart_ring *q){ } void uart_send_break(uart_ring *u) { - while ((u->uart->CR1 & USART_CR1_SBK) != 0); + while ((u->uart->CR1 & USART_CR1_SBK) != 0U); u->uart->CR1 |= USART_CR1_SBK; } diff --git a/board/stm32fx/llusb.h b/board/stm32f4/llusb.h similarity index 97% rename from board/stm32fx/llusb.h rename to board/stm32f4/llusb.h index 20c980864b..6f15c89e11 100644 --- a/board/stm32fx/llusb.h +++ b/board/stm32f4/llusb.h @@ -8,7 +8,7 @@ USB_OTG_GlobalTypeDef *USBx = USB_OTG_FS; #define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE) #define USBD_FS_TRDT_VALUE 5UL -#define USB_OTG_SPEED_FULL 3 +#define USB_OTG_SPEED_FULL 3UL void usb_irqhandler(void); @@ -27,7 +27,7 @@ void usb_init(void) { // full speed PHY, do reset and remove power down /*puth(USBx->GRSTCTL); print(" resetting PHY\n");*/ - while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0); + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); //print("AHB idle\n"); // reset PHY here diff --git a/board/stm32fx/peripherals.h b/board/stm32f4/peripherals.h similarity index 98% rename from board/stm32fx/peripherals.h rename to board/stm32f4/peripherals.h index 79ac3c6e4c..711f1b82a0 100644 --- a/board/stm32fx/peripherals.h +++ b/board/stm32f4/peripherals.h @@ -83,7 +83,6 @@ void peripherals_init(void) { RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; // k-line init RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; // interrupt timer RCC->APB2ENR |= RCC_APB2ENR_TIM9EN; // slow loop - RCC->APB1ENR |= RCC_APB1ENR_TIM12EN; // gmlan_alt } void enable_interrupt_timer(void) { diff --git a/board/stm32fx/startup_stm32f413xx.s b/board/stm32f4/startup_stm32f413xx.s similarity index 100% rename from board/stm32fx/startup_stm32f413xx.s rename to board/stm32f4/startup_stm32f413xx.s diff --git a/board/stm32fx/stm32fx_config.h b/board/stm32f4/stm32f4_config.h similarity index 79% rename from board/stm32fx/stm32fx_config.h rename to board/stm32f4/stm32f4_config.h index 8b59da28f0..85baff25b5 100644 --- a/board/stm32fx/stm32fx_config.h +++ b/board/stm32f4/stm32f4_config.h @@ -1,5 +1,5 @@ -#include "stm32fx/inc/stm32f4xx.h" -#include "stm32fx/inc/stm32f4xx_hal_gpio_ex.h" +#include "stm32f4/inc/stm32f4xx.h" +#include "stm32f4/inc/stm32f4xx_hal_gpio_ex.h" #define MCU_IDCODE 0x463U // from the linker script @@ -50,32 +50,28 @@ #include "drivers/registers.h" #include "drivers/interrupts.h" #include "drivers/gpio.h" -#include "stm32fx/peripherals.h" -#include "stm32fx/interrupt_handlers.h" +#include "stm32f4/peripherals.h" +#include "stm32f4/interrupt_handlers.h" #include "drivers/timers.h" -#include "stm32fx/board.h" -#include "stm32fx/clock.h" +#include "stm32f4/board.h" +#include "stm32f4/clock.h" #include "drivers/watchdog.h" #include "drivers/spi.h" -#include "stm32fx/llspi.h" +#include "stm32f4/llspi.h" #if !defined(BOOTSTUB) #include "drivers/uart.h" - #include "stm32fx/lluart.h" -#endif - -#if defined(PANDA) && !defined(BOOTSTUB) - #include "stm32fx/llexti.h" + #include "stm32f4/lluart.h" #endif #ifdef BOOTSTUB - #include "stm32fx/llflash.h" + #include "stm32f4/llflash.h" #else - #include "stm32fx/llbxcan.h" + #include "stm32f4/llbxcan.h" #endif -#include "stm32fx/llusb.h" +#include "stm32f4/llusb.h" void early_gpio_float(void) { RCC->AHB1ENR = RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN; diff --git a/board/stm32fx/stm32f4_flash.ld b/board/stm32f4/stm32f4_flash.ld similarity index 100% rename from board/stm32fx/stm32f4_flash.ld rename to board/stm32f4/stm32f4_flash.ld diff --git a/board/stm32fx/llexti.h b/board/stm32fx/llexti.h deleted file mode 100644 index 6de13ab7f4..0000000000 --- a/board/stm32fx/llexti.h +++ /dev/null @@ -1,56 +0,0 @@ -void EXTI_IRQ_Handler(void); - -void exti_irq_init(void) { - SYSCFG->EXTICR[2] &= ~(SYSCFG_EXTICR3_EXTI8_Msk); - if (harness.status == HARNESS_STATUS_FLIPPED) { - // CAN2_RX - current_board->enable_can_transceiver(3U, false); - SYSCFG->EXTICR[2] |= (SYSCFG_EXTICR3_EXTI8_PA); - - // IRQ on falling edge for PC3 (SBU2, EXTI3) - SYSCFG->EXTICR[0] &= ~(SYSCFG_EXTICR1_EXTI3_Msk); - SYSCFG->EXTICR[0] |= (SYSCFG_EXTICR1_EXTI3_PC); - EXTI->IMR |= EXTI_IMR_MR3; - EXTI->RTSR &= ~EXTI_RTSR_TR3; // rising edge - EXTI->FTSR |= EXTI_FTSR_TR3; // falling edge - REGISTER_INTERRUPT(EXTI3_IRQn, EXTI_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_EXTI) - NVIC_EnableIRQ(EXTI3_IRQn); - } else { - // CAN0_RX - current_board->enable_can_transceiver(1U, false); - SYSCFG->EXTICR[2] |= (SYSCFG_EXTICR3_EXTI8_PB); - - // IRQ on falling edge for PC0 (SBU1, EXTI0) - SYSCFG->EXTICR[0] &= ~(SYSCFG_EXTICR1_EXTI0_Msk); - SYSCFG->EXTICR[0] |= (SYSCFG_EXTICR1_EXTI0_PC); - EXTI->IMR |= EXTI_IMR_MR0; - EXTI->RTSR &= ~EXTI_RTSR_TR0; // rising edge - EXTI->FTSR |= EXTI_FTSR_TR0; // falling edge - REGISTER_INTERRUPT(EXTI0_IRQn, EXTI_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_EXTI) - NVIC_EnableIRQ(EXTI0_IRQn); - } - // CAN0 or CAN2 IRQ on falling edge (EXTI8) - EXTI->IMR |= EXTI_IMR_MR8; - EXTI->RTSR &= ~EXTI_RTSR_TR8; // rising edge - EXTI->FTSR |= EXTI_FTSR_TR8; // falling edge - REGISTER_INTERRUPT(EXTI9_5_IRQn, EXTI_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_EXTI) - NVIC_EnableIRQ(EXTI9_5_IRQn); -} - -bool check_exti_irq(void) { - return ((EXTI->PR & EXTI_PR_PR8) || (EXTI->PR & EXTI_PR_PR3) || (EXTI->PR & EXTI_PR_PR0)); -} - -void exti_irq_clear(void) { - // Clear pending bits - EXTI->PR |= EXTI_PR_PR8; - EXTI->PR |= EXTI_PR_PR0; - EXTI->PR |= EXTI_PR_PR3; - EXTI->PR |= EXTI_PR_PR22; - - // Disable all active EXTI IRQs - EXTI->IMR &= ~EXTI_IMR_MR8; - EXTI->IMR &= ~EXTI_IMR_MR0; - EXTI->IMR &= ~EXTI_IMR_MR3; - EXTI->IMR &= ~EXTI_IMR_MR22; -} diff --git a/board/stm32fx/llrtc.h b/board/stm32fx/llrtc.h deleted file mode 100644 index a9b61917e7..0000000000 --- a/board/stm32fx/llrtc.h +++ /dev/null @@ -1,69 +0,0 @@ -void enable_bdomain_protection(void) { - register_clear_bits(&(PWR->CR), PWR_CR_DBP); -} - -void disable_bdomain_protection(void) { - register_set_bits(&(PWR->CR), PWR_CR_DBP); -} - -void rtc_init(void){ - uint32_t bdcr_opts = RCC_BDCR_RTCEN; - uint32_t bdcr_mask = (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL); - if (current_board->has_rtc_battery) { - bdcr_opts |= (RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON); - bdcr_mask |= (RCC_BDCR_LSEMOD | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON); - } else { - bdcr_opts |= RCC_BDCR_RTCSEL_1; - RCC->CSR |= RCC_CSR_LSION; - while((RCC->CSR & RCC_CSR_LSIRDY) == 0){} - } - - // Initialize RTC module and clock if not done already. - if((RCC->BDCR & bdcr_mask) != bdcr_opts){ - print("Initializing RTC\n"); - // Reset backup domain - register_set_bits(&(RCC->BDCR), RCC_BDCR_BDRST); - - // Disable write protection - disable_bdomain_protection(); - - // Clear backup domain reset - register_clear_bits(&(RCC->BDCR), RCC_BDCR_BDRST); - - // Set RTC options - register_set(&(RCC->BDCR), bdcr_opts, bdcr_mask); - - // Enable write protection - enable_bdomain_protection(); - } -} - -void rtc_wakeup_init(void) { - EXTI->IMR |= EXTI_IMR_MR22; - EXTI->RTSR |= EXTI_RTSR_TR22; // rising edge - EXTI->FTSR &= ~EXTI_FTSR_TR22; // falling edge - - NVIC_DisableIRQ(RTC_WKUP_IRQn); - - // Disable write protection - disable_bdomain_protection(); - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - RTC->CR &= ~RTC_CR_WUTE; - while((RTC->ISR & RTC_ISR_WUTWF) == 0){} - - RTC->CR &= ~RTC_CR_WUTIE; - RTC->ISR &= ~RTC_ISR_WUTF; - //PWR->CR |= PWR_CR_CWUF; - - RTC->WUTR = DEEPSLEEP_WAKEUP_DELAY; - // Wakeup timer interrupt enable, wakeup timer enable, select 1Hz rate - RTC->CR |= RTC_CR_WUTE | RTC_CR_WUTIE | RTC_CR_WUCKSEL_2; - - // Re-enable write protection - RTC->WPR = 0x00; - enable_bdomain_protection(); - - NVIC_EnableIRQ(RTC_WKUP_IRQn); -} diff --git a/board/stm32h7/board.h b/board/stm32h7/board.h index d293a54cfe..f5a8e55aa8 100644 --- a/board/stm32h7/board.h +++ b/board/stm32h7/board.h @@ -9,10 +9,8 @@ #include "drivers/harness.h" #include "drivers/fan.h" #include "stm32h7/llfan.h" -#include "stm32h7/llrtc.h" #include "stm32h7/lldac.h" #include "drivers/fake_siren.h" -#include "drivers/rtc.h" #include "drivers/clock_source.h" #include "boards/red.h" #include "boards/red_chiplet.h" diff --git a/board/stm32h7/clock.h b/board/stm32h7/clock.h index 7d65d080ec..2e3ab701d8 100644 --- a/board/stm32h7/clock.h +++ b/board/stm32h7/clock.h @@ -21,20 +21,22 @@ void clock_init(void) { // 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 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) == 0); + while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0U); while ((PWR->CSR1 & PWR_CSR1_ACTVOS) != (PWR->D3CR & PWR_D3CR_VOS)); // check that VOS level was actually set // Configure Flash ACR register LATENCY and WRHIGHFREQ (VOS0 range!) register_set(&(FLASH->ACR), FLASH_ACR_LATENCY_2WS | 0x20U, 0x3FU); // VOS2, AXI 100MHz-150MHz // enable external oscillator HSE register_set_bits(&(RCC->CR), RCC_CR_HSEON); - while ((RCC->CR & RCC_CR_HSERDY) == 0); + while ((RCC->CR & RCC_CR_HSERDY) == 0U); // enable internal HSI48 for USB FS kernel register_set_bits(&(RCC->CR), RCC_CR_HSI48ON); - while ((RCC->CR & RCC_CR_HSI48RDY) == 0); + while ((RCC->CR & RCC_CR_HSI48RDY) == 0U); // Specify the frequency source for PLL1, divider for DIVM1, DIVM2, DIVM3 : HSE, 5, 5, 5 register_set(&(RCC->PLLCKSELR), RCC_PLLCKSELR_PLLSRC_HSE | RCC_PLLCKSELR_DIVM1_0 | RCC_PLLCKSELR_DIVM1_2 | RCC_PLLCKSELR_DIVM2_0 | RCC_PLLCKSELR_DIVM2_2 | RCC_PLLCKSELR_DIVM3_0 | RCC_PLLCKSELR_DIVM3_2, 0x3F3F3F3U); @@ -45,7 +47,7 @@ void clock_init(void) { register_set(&(RCC->PLLCFGR), RCC_PLLCFGR_PLL1RGE_2 | RCC_PLLCFGR_DIVP1EN | RCC_PLLCFGR_DIVQ1EN | RCC_PLLCFGR_DIVR1EN, 0x7000CU); // Enable PLL1 register_set_bits(&(RCC->CR), RCC_CR_PLL1ON); - while((RCC->CR & RCC_CR_PLL1RDY) == 0); + while((RCC->CR & RCC_CR_PLL1RDY) == 0U); // *** PLL1 end *** //////////////OTHER CLOCKS//////////////////// diff --git a/board/stm32h7/lladc.h b/board/stm32h7/lladc.h index 01342a4d05..7d818f27af 100644 --- a/board/stm32h7/lladc.h +++ b/board/stm32h7/lladc.h @@ -7,7 +7,7 @@ void adc_init(void) { ADC1->CR &= ~(ADC_CR_ADCALDIF); // Choose single-ended calibration ADC1->CR |= ADC_CR_ADCALLIN; // Lineriality calibration ADC1->CR |= ADC_CR_ADCAL; // Start calibrtation - while((ADC1->CR & ADC_CR_ADCAL) != 0); + while((ADC1->CR & ADC_CR_ADCAL) != 0U); ADC1->ISR |= ADC_ISR_ADRDY; ADC1->CR |= ADC_CR_ADEN; @@ -17,11 +17,11 @@ void adc_init(void) { uint16_t adc_get_raw(uint8_t channel) { uint16_t res = 0U; ADC1->SQR1 &= ~(ADC_SQR1_L); - ADC1->SQR1 = ((uint32_t) channel << 6U); + ADC1->SQR1 = (uint32_t)channel << 6U; - ADC1->SMPR1 = (0x2U << (channel * 3U)); + ADC1->SMPR1 = 0x2UL << (channel * 3UL); ADC1->PCSEL_RES0 = (0x1UL << channel); - ADC1->CFGR2 = (127U << ADC_CFGR2_OVSR_Pos) | (0x7U << ADC_CFGR2_OVSS_Pos) | ADC_CFGR2_ROVSE; + ADC1->CFGR2 = (127UL << ADC_CFGR2_OVSR_Pos) | (0x7U << ADC_CFGR2_OVSS_Pos) | ADC_CFGR2_ROVSE; ADC1->CR |= ADC_CR_ADSTART; while (!(ADC1->ISR & ADC_ISR_EOC)); diff --git a/board/stm32h7/llexti.h b/board/stm32h7/llexti.h deleted file mode 100644 index 46d0acab67..0000000000 --- a/board/stm32h7/llexti.h +++ /dev/null @@ -1,63 +0,0 @@ -void EXTI_IRQ_Handler(void); - -void exti_irq_init(void) { - if (harness.status == HARNESS_STATUS_FLIPPED) { - // CAN2_RX IRQ on falling edge (EXTI10) - current_board->enable_can_transceiver(3U, false); - SYSCFG->EXTICR[2] &= ~(SYSCFG_EXTICR3_EXTI10_Msk); - SYSCFG->EXTICR[2] |= (SYSCFG_EXTICR3_EXTI10_PG); - EXTI->IMR1 |= EXTI_IMR1_IM10; - EXTI->RTSR1 &= ~EXTI_RTSR1_TR10; // rising edge - EXTI->FTSR1 |= EXTI_FTSR1_TR10; // falling edge - - // IRQ on falling edge for PA1 (SBU2, EXTI1) - SYSCFG->EXTICR[0] &= ~(SYSCFG_EXTICR1_EXTI1_Msk); - SYSCFG->EXTICR[0] |= (SYSCFG_EXTICR1_EXTI1_PA); - EXTI->IMR1 |= EXTI_IMR1_IM1; - EXTI->RTSR1 &= ~EXTI_RTSR1_TR1; // rising edge - EXTI->FTSR1 |= EXTI_FTSR1_TR1; // falling edge - REGISTER_INTERRUPT(EXTI1_IRQn, EXTI_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_EXTI) - NVIC_EnableIRQ(EXTI1_IRQn); - REGISTER_INTERRUPT(EXTI15_10_IRQn, EXTI_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_EXTI) - NVIC_EnableIRQ(EXTI15_10_IRQn); - } else { - // CAN0_RX IRQ on falling edge (EXTI8) - current_board->enable_can_transceiver(1U, false); - SYSCFG->EXTICR[2] &= ~(SYSCFG_EXTICR3_EXTI8_Msk); - SYSCFG->EXTICR[2] |= (SYSCFG_EXTICR3_EXTI8_PB); - EXTI->IMR1 |= EXTI_IMR1_IM8; - EXTI->RTSR1 &= ~EXTI_RTSR1_TR8; // rising edge - EXTI->FTSR1 |= EXTI_FTSR1_TR8; // falling edge - - // IRQ on falling edge for PC4 (SBU1, EXTI4) - SYSCFG->EXTICR[1] &= ~(SYSCFG_EXTICR2_EXTI4_Msk); - SYSCFG->EXTICR[1] |= (SYSCFG_EXTICR2_EXTI4_PC); - EXTI->IMR1 |= EXTI_IMR1_IM4; - EXTI->RTSR1 &= ~EXTI_RTSR1_TR4; // rising edge - EXTI->FTSR1 |= EXTI_FTSR1_TR4; // falling edge - REGISTER_INTERRUPT(EXTI4_IRQn, EXTI_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_EXTI) - NVIC_EnableIRQ(EXTI4_IRQn); - REGISTER_INTERRUPT(EXTI9_5_IRQn, EXTI_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_EXTI) - NVIC_EnableIRQ(EXTI9_5_IRQn); - } -} - -bool check_exti_irq(void) { - return ((EXTI->PR1 & EXTI_PR1_PR8) || (EXTI->PR1 & EXTI_PR1_PR10) || (EXTI->PR1 & EXTI_PR1_PR1) || (EXTI->PR1 & EXTI_PR1_PR4)); -} - -void exti_irq_clear(void) { - // Clear pending bits - EXTI->PR1 |= EXTI_PR1_PR8; - EXTI->PR1 |= EXTI_PR1_PR10; - EXTI->PR1 |= EXTI_PR1_PR4; - EXTI->PR1 |= EXTI_PR1_PR1; // works - EXTI->PR1 |= EXTI_PR1_PR19; // works - - // Disable all active EXTI IRQs - EXTI->IMR1 &= ~EXTI_IMR1_IM8; - EXTI->IMR1 &= ~EXTI_IMR1_IM10; - EXTI->IMR1 &= ~EXTI_IMR1_IM4; - EXTI->IMR1 &= ~EXTI_IMR1_IM1; - EXTI->IMR1 &= ~EXTI_IMR1_IM19; -} diff --git a/board/stm32h7/llfdcan.h b/board/stm32h7/llfdcan.h index 4bb6d3d04e..db42024c43 100644 --- a/board/stm32h7/llfdcan.h +++ b/board/stm32h7/llfdcan.h @@ -55,7 +55,7 @@ bool fdcan_request_init(FDCAN_GlobalTypeDef *FDCANx) { // Request init uint32_t timeout_counter = 0U; FDCANx->CCCR |= FDCAN_CCCR_INIT; - while ((FDCANx->CCCR & FDCAN_CCCR_INIT) == 0) { + while ((FDCANx->CCCR & FDCAN_CCCR_INIT) == 0U) { // Delay for about 1ms delay(10000); timeout_counter++; @@ -73,7 +73,7 @@ bool fdcan_exit_init(FDCAN_GlobalTypeDef *FDCANx) { FDCANx->CCCR &= ~(FDCAN_CCCR_INIT); uint32_t timeout_counter = 0U; - while ((FDCANx->CCCR & FDCAN_CCCR_INIT) != 0) { + while ((FDCANx->CCCR & FDCAN_CCCR_INIT) != 0U) { // Delay for about 1ms delay(10000); timeout_counter++; @@ -118,7 +118,7 @@ bool llcan_set_speed(FDCAN_GlobalTypeDef *FDCANx, uint32_t speed, uint32_t data_ uint32_t seg2 = CAN_SEG2(tq, sp); uint8_t sjw = MIN(127U, seg2); - FDCANx->NBTP = (((sjw & 0x7FU)-1U)<NBTP = (((sjw & 0x7FUL)-1U)<DBTP = (((sjw & 0xFU)-1U)<DBTP = (((sjw & 0xFUL)-1U)<CR2, I2C_CR2_ADD10); - I2C->CR2 = ((addr << 1U) & I2C_CR2_SADD_Msk); + I2C->CR2 = ((uint32_t)addr << 1U) & I2C_CR2_SADD_Msk; register_clear_bits(&I2C->CR2, I2C_CR2_RD_WRN); register_set_bits(&I2C->CR2, I2C_CR2_AUTOEND); - I2C->CR2 |= (2 << I2C_CR2_NBYTES_Pos); + I2C->CR2 |= 2UL << I2C_CR2_NBYTES_Pos; I2C->CR2 |= I2C_CR2_START; if(!i2c_status_wait(&I2C->CR2, I2C_CR2_START, 0U)) { @@ -61,10 +61,10 @@ bool i2c_read_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t *value) { bool ret = false; for(uint32_t i=0U; i<10U; i++) { register_clear_bits(&I2C->CR2, I2C_CR2_ADD10); - I2C->CR2 = ((addr << 1U) & I2C_CR2_SADD_Msk); + I2C->CR2 = ((uint32_t)addr << 1U) & I2C_CR2_SADD_Msk; register_clear_bits(&I2C->CR2, I2C_CR2_RD_WRN); register_clear_bits(&I2C->CR2, I2C_CR2_AUTOEND); - I2C->CR2 |= (1 << I2C_CR2_NBYTES_Pos); + I2C->CR2 |= 1UL << I2C_CR2_NBYTES_Pos; I2C->CR2 |= I2C_CR2_START; if(!i2c_status_wait(&I2C->CR2, I2C_CR2_START, 0U)) { @@ -92,7 +92,7 @@ bool i2c_read_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t *value) { I2C->TXDR = reg; // Restart - I2C->CR2 = (((addr << 1) | 0x1U) & I2C_CR2_SADD_Msk) | (1U << I2C_CR2_NBYTES_Pos) | I2C_CR2_RD_WRN | I2C_CR2_START; + I2C->CR2 = (((addr << 1) | 0x1U) & I2C_CR2_SADD_Msk) | (1UL << I2C_CR2_NBYTES_Pos) | I2C_CR2_RD_WRN | I2C_CR2_START; ret = i2c_status_wait(&I2C->CR2, I2C_CR2_START, 0U); if(!ret) { goto end; diff --git a/board/stm32h7/llrtc.h b/board/stm32h7/llrtc.h deleted file mode 100644 index 03787d0db2..0000000000 --- a/board/stm32h7/llrtc.h +++ /dev/null @@ -1,69 +0,0 @@ -void enable_bdomain_protection(void) { - register_clear_bits(&(PWR->CR1), PWR_CR1_DBP); -} - -void disable_bdomain_protection(void) { - register_set_bits(&(PWR->CR1), PWR_CR1_DBP); -} - -void rtc_init(void){ - uint32_t bdcr_opts = RCC_BDCR_RTCEN; - uint32_t bdcr_mask = (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL); - if (current_board->has_rtc_battery) { - bdcr_opts |= (RCC_BDCR_LSEDRV_1 | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON); - bdcr_mask |= (RCC_BDCR_LSEDRV | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON); - } else { - bdcr_opts |= RCC_BDCR_RTCSEL_1; - RCC->CSR |= RCC_CSR_LSION; - while((RCC->CSR & RCC_CSR_LSIRDY) == 0){} - } - - // Initialize RTC module and clock if not done already. - if((RCC->BDCR & bdcr_mask) != bdcr_opts){ - print("Initializing RTC\n"); - // Reset backup domain - register_set_bits(&(RCC->BDCR), RCC_BDCR_BDRST); - - // Disable write protection - disable_bdomain_protection(); - - // Clear backup domain reset - register_clear_bits(&(RCC->BDCR), RCC_BDCR_BDRST); - - // Set RTC options - register_set(&(RCC->BDCR), bdcr_opts, bdcr_mask); - - // Enable write protection - enable_bdomain_protection(); - } -} - -void rtc_wakeup_init(void) { - EXTI->IMR1 |= EXTI_IMR1_IM19; - EXTI->RTSR1 |= EXTI_RTSR1_TR19; // rising edge - EXTI->FTSR1 &= ~EXTI_FTSR1_TR19; // falling edge - - NVIC_DisableIRQ(RTC_WKUP_IRQn); - - // Disable write protection - disable_bdomain_protection(); - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - RTC->CR &= ~RTC_CR_WUTE; - while((RTC->ISR & RTC_ISR_WUTWF) == 0){} - - RTC->CR &= ~RTC_CR_WUTIE; - RTC->ISR &= ~RTC_ISR_WUTF; - //PWR->CR1 |= PWR_CR1_CWUF; - - RTC->WUTR = DEEPSLEEP_WAKEUP_DELAY; - // Wakeup timer interrupt enable, wakeup timer enable, select 1Hz rate - RTC->CR |= RTC_CR_WUTE | RTC_CR_WUTIE | RTC_CR_WUCKSEL_2; - - // Re-enable write protection - RTC->WPR = 0x00; - enable_bdomain_protection(); - - NVIC_EnableIRQ(RTC_WKUP_IRQn); -} diff --git a/board/stm32h7/llspi.h b/board/stm32h7/llspi.h index 1947803ac2..903f6a5ecc 100644 --- a/board/stm32h7/llspi.h +++ b/board/stm32h7/llspi.h @@ -71,7 +71,7 @@ void SPI4_IRQ_Handler(void) { // clear flag SPI4->IFCR |= (0x1FFU << 3U); - if (spi_tx_dma_done && ((SPI4->SR & SPI_SR_TXC) != 0)) { + if (spi_tx_dma_done && ((SPI4->SR & SPI_SR_TXC) != 0U)) { spi_tx_dma_done = false; spi_tx_done(false); } diff --git a/board/stm32h7/lluart.h b/board/stm32h7/lluart.h index 0ad7b6a867..6ca6dcec3d 100644 --- a/board/stm32h7/lluart.h +++ b/board/stm32h7/lluart.h @@ -29,7 +29,7 @@ void uart_tx_ring(uart_ring *q){ // Send out next byte of TX buffer if (q->w_ptr_tx != q->r_ptr_tx) { // Only send if transmit register is empty (aka last byte has been sent) - if ((q->uart->ISR & USART_ISR_TXE_TXFNF) != 0) { + if ((q->uart->ISR & USART_ISR_TXE_TXFNF) != 0U) { q->uart->TDR = q->elems_tx[q->r_ptr_tx]; // This clears TXE q->r_ptr_tx = (q->r_ptr_tx + 1U) % q->tx_fifo_size; } diff --git a/board/stm32h7/llusb.h b/board/stm32h7/llusb.h index ada1630f8b..2975f62be6 100644 --- a/board/stm32h7/llusb.h +++ b/board/stm32h7/llusb.h @@ -32,7 +32,7 @@ void usb_init(void) { USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; delay(250000); // Wait for about 25ms (explicitly stated in H7 ref manual) // Wait for AHB master IDLE state. - while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0); + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); // Core Soft Reset USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); diff --git a/board/stm32h7/stm32h7_config.h b/board/stm32h7/stm32h7_config.h index 6f36a5aaf4..64f149848d 100644 --- a/board/stm32h7/stm32h7_config.h +++ b/board/stm32h7/stm32h7_config.h @@ -76,10 +76,6 @@ separate IRQs for RX and TX. #include "stm32h7/board.h" #include "stm32h7/clock.h" -#if !defined(BOOTSTUB) && defined(PANDA) - #include "stm32h7/llexti.h" -#endif - #ifdef BOOTSTUB #include "stm32h7/llflash.h" #else diff --git a/examples/can_bit_transition.py b/examples/can_bit_transition.py index bc9b68ae89..1e7bad54e7 100755 --- a/examples/can_bit_transition.py +++ b/examples/can_bit_transition.py @@ -66,7 +66,7 @@ def load(self, filename, start, end): message_id = message_id[2:] # remove leading '0x' else: message_id = hex(int(message_id))[2:] # old message IDs are in decimal - message_id = '%s:%s' % (bus, message_id) + message_id = f'{bus}:{message_id}' data = row[CSV_KEYS[dtype]["data"]] if data.startswith('0x'): diff --git a/examples/can_unique.py b/examples/can_unique.py index bc582f016f..05977afb0a 100755 --- a/examples/can_unique.py +++ b/examples/can_unique.py @@ -52,7 +52,7 @@ def __init__(self): def load(self, filename): """Given a CSV file, adds information about message IDs and their values.""" - with open(filename, 'r') as inp: + with open(filename) as inp: reader = csv.reader(inp) header = next(reader, None) if header[0] == 'time': @@ -64,7 +64,7 @@ def cabana(self, reader): for row in reader: bus = row[2] message_id = hex(int(row[1]))[2:] - message_id = '%s:%s' % (bus, message_id) + message_id = f'{bus}:{message_id}' data = row[3] self.store(message_id, data) @@ -75,7 +75,7 @@ def logger(self, reader): message_id = row[1][2:] # remove leading '0x' else: message_id = hex(int(row[1]))[2:] # old message IDs are in decimal - message_id = '%s:%s' % (bus, message_id) + message_id = f'{bus}:{message_id}' if row[1].startswith('0x'): data = row[2][2:] # remove leading '0x' else: diff --git a/examples/query_fw_versions.py b/examples/query_fw_versions.py index 4f4e3fa66b..fe70bf96ab 100755 --- a/examples/query_fw_versions.py +++ b/examples/query_fw_versions.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 import argparse -from typing import List, Optional from tqdm import tqdm from panda import Panda from panda.python.uds import UdsClient, MessageTimeoutError, NegativeResponseError, InvalidSubAddressError, \ @@ -25,7 +24,7 @@ addrs += [0x18da0000 + (i << 8) + 0xf1 for i in range(256)] results = {} - sub_addrs: List[Optional[int]] = [None] + sub_addrs: list[int | None] = [None] if args.sub_addr: if args.sub_addr == "scan": sub_addrs = list(range(0xff + 1)) diff --git a/pyproject.toml b/pyproject.toml index 72bce22bec..375885e54d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,15 @@ # https://beta.ruff.rs/docs/configuration/#using-pyprojecttoml [tool.ruff] -select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF100", "A"] -ignore = ["W292", "E741", "E402", "C408", "ISC003"] line-length = 160 target-version="py311" + +[tool.ruff.lint] +select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF100", "A"] +ignore = ["W292", "E741", "E402", "C408", "ISC003"] flake8-implicit-str-concat.allow-multiline=false +[tool.ruff.lint.flake8-tidy-imports.banned-api] +"pytest.main".msg = "pytest.main requires special handling that is easy to mess up!" + [tool.pytest.ini_options] -# FIXME: pytest 8.0.0 now collects all files, stop pytest-cpp from running these -# the `not Base` filter is needed due to a bug in pytest w/ unittest: https://github.com/pytest-dev/pytest/issues/11552 -addopts = "--ignore=test.sh -n auto -k 'not Base'" +addopts = "-n auto" diff --git a/python/__init__.py b/python/__init__.py index acf6ea4834..8567118f24 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -6,10 +6,8 @@ import struct import hashlib import binascii -import datetime import logging from functools import wraps, partial -from typing import Optional from itertools import accumulate from .base import BaseHandle @@ -150,9 +148,6 @@ class Panda: SERIAL_LIN2 = 3 SERIAL_SOM_DEBUG = 4 - GMLAN_CAN2 = 1 - GMLAN_CAN3 = 2 - USB_PIDS = (0xddee, 0xddcc) REQUEST_IN = usb1.ENDPOINT_IN | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE REQUEST_OUT = usb1.ENDPOINT_OUT | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE @@ -170,9 +165,9 @@ class Panda: HW_TYPE_CUATRO = b'\x0a' CAN_PACKET_VERSION = 4 - HEALTH_PACKET_VERSION = 15 + HEALTH_PACKET_VERSION = 16 CAN_HEALTH_PACKET_VERSION = 5 - HEALTH_STRUCT = struct.Struct(" bool: + return isinstance(self._handle, PandaSpiHandle) + @classmethod def spi_connect(cls, serial, ignore_version=False): # get UID to confirm slave is present and up @@ -363,7 +361,7 @@ def usb_connect(cls, serial, claim=True): try: this_serial = device.getSerialNumber() except Exception: - continue + logging.exception("failed to get serial number of panda") if serial is None or this_serial == serial: logging.debug("opening device %s %s", this_serial, hex(device.getProductID())) @@ -414,7 +412,7 @@ def usb_list(cls): else: logging.warning(f"found device with panda descriptors but invalid serial: {serial}", RuntimeWarning) except Exception: - continue + logging.exception("error connecting to panda") except Exception: logging.exception("exception while listing pandas") return ret @@ -439,6 +437,8 @@ def reset(self, enter_bootstub=False, enter_bootloader=False, reconnect=True): self._handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'', timeout=timeout, expect_disconnect=True) except Exception: pass + + self.close() if not enter_bootloader and reconnect: self.reconnect() @@ -530,7 +530,7 @@ def flash(self, fn=None, code=None, reconnect=True): if reconnect: self.reconnect() - def recover(self, timeout: Optional[int] = 60, reset: bool = True) -> bool: + def recover(self, timeout: int | None = 60, reset: bool = True) -> bool: dfu_serial = self.get_dfu_serial() if reset: @@ -549,7 +549,7 @@ def recover(self, timeout: Optional[int] = 60, reset: bool = True) -> bool: return True @staticmethod - def wait_for_dfu(dfu_serial: Optional[str], timeout: Optional[int] = None) -> bool: + 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): @@ -561,7 +561,7 @@ def wait_for_dfu(dfu_serial: Optional[str], timeout: Optional[int] = None) -> bo return True @staticmethod - def wait_for_panda(serial: Optional[str], timeout: int) -> bool: + 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): @@ -596,26 +596,25 @@ def health(self): "safety_rx_invalid": a[4], "tx_buffer_overflow": a[5], "rx_buffer_overflow": a[6], - "gmlan_send_errs": a[7], - "faults": a[8], - "ignition_line": a[9], - "ignition_can": a[10], - "controls_allowed": a[11], - "car_harness_status": a[12], - "safety_mode": a[13], - "safety_param": a[14], - "fault_status": a[15], - "power_save_enabled": a[16], - "heartbeat_lost": a[17], - "alternative_experience": a[18], - "interrupt_load": a[19], - "fan_power": a[20], - "safety_rx_checks_invalid": a[21], - "spi_checksum_error_count": a[22], - "fan_stall_count": a[23], - "sbu1_voltage_mV": a[24], - "sbu2_voltage_mV": a[25], - "som_reset_triggered": a[26], + "faults": a[7], + "ignition_line": a[8], + "ignition_can": a[9], + "controls_allowed": a[10], + "car_harness_status": a[11], + "safety_mode": a[12], + "safety_param": a[13], + "fault_status": a[14], + "power_save_enabled": a[15], + "heartbeat_lost": a[16], + "alternative_experience": a[17], + "interrupt_load": a[18], + "fan_power": a[19], + "safety_rx_checks_invalid": a[20], + "spi_checksum_error_count": a[21], + "fan_stall_count": a[22], + "sbu1_voltage_mV": a[23], + "sbu2_voltage_mV": a[24], + "som_reset_triggered": a[25], } @ensure_can_health_packet_version @@ -752,21 +751,10 @@ def get_interrupt_call_rate(self, irqnum): def set_power_save(self, power_save_enabled=0): self._handle.controlWrite(Panda.REQUEST_OUT, 0xe7, int(power_save_enabled), 0, b'') - def enable_deepsleep(self): - self._handle.controlWrite(Panda.REQUEST_OUT, 0xfb, 0, 0, b'') - def set_safety_mode(self, mode=SAFETY_SILENT, param=0): self._handle.controlWrite(Panda.REQUEST_OUT, 0xdc, mode, param, b'') - def set_gmlan(self, bus=2): - # TODO: check panda type - if bus is None: - self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 0, 0, b'') - elif bus in (Panda.GMLAN_CAN2, Panda.GMLAN_CAN3): - self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'') - def set_obd(self, obd): - # TODO: check panda type self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, int(obd), 0, b'') def set_can_loopback(self, enable): @@ -894,21 +882,6 @@ def send_heartbeat(self, engaged=True): def set_heartbeat_disabled(self): self._handle.controlWrite(Panda.REQUEST_OUT, 0xf8, 0, 0, b'') - # ******************* RTC ******************* - def set_datetime(self, dt): - self._handle.controlWrite(Panda.REQUEST_OUT, 0xa1, int(dt.year), 0, b'') - self._handle.controlWrite(Panda.REQUEST_OUT, 0xa2, int(dt.month), 0, b'') - self._handle.controlWrite(Panda.REQUEST_OUT, 0xa3, int(dt.day), 0, b'') - self._handle.controlWrite(Panda.REQUEST_OUT, 0xa4, int(dt.isoweekday()), 0, b'') - self._handle.controlWrite(Panda.REQUEST_OUT, 0xa5, int(dt.hour), 0, b'') - self._handle.controlWrite(Panda.REQUEST_OUT, 0xa6, int(dt.minute), 0, b'') - self._handle.controlWrite(Panda.REQUEST_OUT, 0xa7, int(dt.second), 0, b'') - - def get_datetime(self): - dat = self._handle.controlRead(Panda.REQUEST_IN, 0xa0, 0, 0, 8) - a = struct.unpack("HBBBBBB", dat) - return datetime.datetime(a[0], a[1], a[2], a[4], a[5], a[6]) - # ****************** Timer ***************** def get_microsecond_timer(self): dat = self._handle.controlRead(Panda.REQUEST_IN, 0xa8, 0, 0, 4) diff --git a/python/constants.py b/python/constants.py index fede52424c..8b09593084 100644 --- a/python/constants.py +++ b/python/constants.py @@ -1,6 +1,6 @@ import os import enum -from typing import List, NamedTuple +from typing import NamedTuple BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../") FW_PATH = os.path.join(BASEDIR, "board/obj/") @@ -10,7 +10,7 @@ class McuConfig(NamedTuple): mcu: str mcu_idcode: int - sector_sizes: List[int] + sector_sizes: list[int] sector_count: int # total sector count, used for MCU identification in DFU mode uid_address: int block_size: int diff --git a/python/dfu.py b/python/dfu.py index 01ff037f84..9beba45e55 100644 --- a/python/dfu.py +++ b/python/dfu.py @@ -2,7 +2,6 @@ import usb1 import struct import binascii -from typing import List, Optional from .base import BaseSTBootloaderHandle from .spi import STBootloaderSPIHandle, PandaSpiException @@ -11,9 +10,9 @@ class PandaDFU: - def __init__(self, dfu_serial: Optional[str]): + def __init__(self, dfu_serial: str | None): # try USB, then SPI - handle: Optional[BaseSTBootloaderHandle] + handle: BaseSTBootloaderHandle | None self._context, handle = PandaDFU.usb_connect(dfu_serial) if handle is None: self._context, handle = PandaDFU.spi_connect(dfu_serial) @@ -38,7 +37,7 @@ def close(self): self._context.close() @staticmethod - def usb_connect(dfu_serial: Optional[str]): + def usb_connect(dfu_serial: str | None): handle = None context = usb1.USBContext() context.open() @@ -56,7 +55,7 @@ def usb_connect(dfu_serial: Optional[str]): return context, handle @staticmethod - def spi_connect(dfu_serial: Optional[str]): + def spi_connect(dfu_serial: str | None): handle = None this_dfu_serial = None @@ -72,13 +71,7 @@ def spi_connect(dfu_serial: Optional[str]): return None, handle @staticmethod - def list() -> List[str]: - ret = PandaDFU.usb_list() - ret += PandaDFU.spi_list() - return list(set(ret)) - - @staticmethod - def usb_list() -> List[str]: + def usb_list() -> list[str]: dfu_serials = [] try: with usb1.USBContext() as context: @@ -93,7 +86,7 @@ def usb_list() -> List[str]: return dfu_serials @staticmethod - def spi_list() -> List[str]: + def spi_list() -> list[str]: try: _, h = PandaDFU.spi_connect(None) if h is not None: @@ -134,3 +127,9 @@ def recover(self): code = f.read() self.program_bootstub(code) self.reset() + + @staticmethod + def list() -> list[str]: + ret = PandaDFU.usb_list() + ret += PandaDFU.spi_list() + return list(set(ret)) diff --git a/python/isotp.py b/python/isotp.py index 3334deb8ed..d0bef7d942 100644 --- a/python/isotp.py +++ b/python/isotp.py @@ -79,10 +79,10 @@ def isotp_send(panda, x, addr, bus=0, recvaddr=None, subaddr=None, rate=None): sends = [] while len(x) > 0: if subaddr: - sends.append(((bytes([subaddr, 0x20 + (idx & 0xF)]) + x[0:6]).ljust(8, b"\x00"))) + sends.append((bytes([subaddr, 0x20 + (idx & 0xF)]) + x[0:6]).ljust(8, b"\x00")) x = x[6:] else: - sends.append(((bytes([0x20 + (idx & 0xF)]) + x[0:7]).ljust(8, b"\x00"))) + sends.append((bytes([0x20 + (idx & 0xF)]) + x[0:7]).ljust(8, b"\x00")) x = x[7:] idx += 1 diff --git a/python/serial.py b/python/serial.py index 9ac58862b5..c2e965b76c 100644 --- a/python/serial.py +++ b/python/serial.py @@ -1,5 +1,5 @@ # mimic a python serial port -class PandaSerial(object): +class PandaSerial: def __init__(self, panda, port, baud): self.panda = panda self.port = port diff --git a/python/spi.py b/python/spi.py index 48dc84d49e..be4f7dcf46 100644 --- a/python/spi.py +++ b/python/spi.py @@ -9,7 +9,7 @@ import threading from contextlib import contextmanager from functools import reduce -from typing import Callable, List, Optional +from collections.abc import Callable from .base import BaseHandle, BaseSTBootloaderHandle, TIMEOUT from .constants import McuType, MCU_TYPE_BY_IDCODE, USBPACKET_MAX_SIZE @@ -251,7 +251,7 @@ def _get_version(spi) -> bytes: version_bytes = spi.readbytes(len(vers_str) + 2) if bytes(version_bytes).startswith(vers_str): break - if (time.monotonic() - start) > 0.01: + if (time.monotonic() - start) > 0.001: raise PandaSpiMissingAck rlen = struct.unpack(" bytes: + def _cmd_no_retry(self, cmd: int, data: list[bytes] | None = None, read_bytes: int = 0, predata=None) -> bytes: ret = b"" with self.dev.acquire() as spi: # sync + command spi.xfer([self.SYNC, ]) spi.xfer([cmd, cmd ^ 0xFF]) - self._get_ack(spi, timeout=0.1) + self._get_ack(spi, timeout=0.01) # "predata" - for commands that send the first data without a checksum if predata is not None: @@ -371,7 +371,7 @@ def _cmd_no_retry(self, cmd: int, data: Optional[List[bytes]] = None, read_bytes return bytes(ret) - def _cmd(self, cmd: int, data: Optional[List[bytes]] = None, read_bytes: int = 0, predata=None) -> bytes: + def _cmd(self, cmd: int, data: list[bytes] | None = None, read_bytes: int = 0, predata=None) -> bytes: exc = PandaSpiException() for n in range(MAX_XFER_RETRY_COUNT): try: diff --git a/python/uds.py b/python/uds.py index aaa0697f90..32b0de0961 100644 --- a/python/uds.py +++ b/python/uds.py @@ -1,7 +1,8 @@ import time import struct from collections import deque -from typing import Callable, NamedTuple, Tuple, List, Deque, Generator, Optional, cast +from typing import NamedTuple, Deque, cast +from collections.abc import Callable, Generator from enum import IntEnum from functools import partial @@ -300,8 +301,8 @@ def get_dtc_status_names(status): return result class CanClient(): - def __init__(self, can_send: Callable[[int, bytes, int], None], can_recv: Callable[[], List[Tuple[int, int, bytes, int]]], - tx_addr: int, rx_addr: int, bus: int, sub_addr: Optional[int] = None, debug: bool = False): + def __init__(self, can_send: Callable[[int, bytes, int], None], can_recv: Callable[[], list[tuple[int, int, bytes, int]]], + tx_addr: int, rx_addr: int, bus: int, sub_addr: int | None = None, debug: bool = False): self.tx = can_send self.rx = can_recv self.tx_addr = tx_addr @@ -335,7 +336,7 @@ def _recv_buffer(self, drain: bool = False) -> None: msgs = self.rx() if drain: if self.debug: - print("CAN-RX: drain - {}".format(len(msgs))) + print(f"CAN-RX: drain - {len(msgs)}") self.rx_buff.clear() else: for rx_addr, _, rx_data, rx_bus in msgs or []: @@ -366,7 +367,7 @@ def recv(self, drain: bool = False) -> Generator[bytes, None, None]: except IndexError: pass # empty - def send(self, msgs: List[bytes], delay: float = 0) -> None: + def send(self, msgs: list[bytes], delay: float = 0) -> None: for i, msg in enumerate(msgs): if delay and i != 0: if self.debug: @@ -443,7 +444,7 @@ def _tx_first_frame(self, setup_only: bool = False) -> None: if not setup_only: self._can_client.send([msg]) - def recv(self, timeout=None) -> Tuple[Optional[bytes], bool]: + def recv(self, timeout=None) -> tuple[bytes | None, bool]: if timeout is None: timeout = self.timeout @@ -454,7 +455,8 @@ def recv(self, timeout=None) -> Tuple[Optional[bytes], bool]: for msg in self._can_client.recv(): frame_type = self._isotp_rx_next(msg) start_time = time.monotonic() - rx_in_progress = frame_type == ISOTP_FRAME_TYPE.CONSECUTIVE + # Anything that signifies we're building a response + rx_in_progress = frame_type in (ISOTP_FRAME_TYPE.FIRST, ISOTP_FRAME_TYPE.CONSECUTIVE) if self.tx_done and self.rx_done: return self.rx_dat, False # no timeout indicates non-blocking @@ -472,6 +474,7 @@ def _isotp_rx_next(self, rx_data: bytes) -> ISOTP_FRAME_TYPE: # assert len(rx_data) == self.max_len, f"isotp - rx: invalid CAN frame length: {len(rx_data)}" if rx_data[0] >> 4 == ISOTP_FRAME_TYPE.SINGLE: + assert self.rx_dat == b"" or self.rx_done, "isotp - rx: single frame with active frame" self.rx_len = rx_data[0] & 0x0F assert self.rx_len < self.max_len, f"isotp - rx: invalid single frame length: {self.rx_len}" self.rx_dat = rx_data[1:1 + self.rx_len] @@ -482,8 +485,11 @@ def _isotp_rx_next(self, rx_data: bytes) -> ISOTP_FRAME_TYPE: return ISOTP_FRAME_TYPE.SINGLE elif rx_data[0] >> 4 == ISOTP_FRAME_TYPE.FIRST: + # Once a first frame is received, further frames must be consecutive + assert self.rx_dat == b"" or self.rx_done, "isotp - rx: first frame with active frame" self.rx_len = ((rx_data[0] & 0x0F) << 8) + rx_data[1] - assert self.max_len <= self.rx_len, f"isotp - rx: invalid first frame length: {self.rx_len}" + assert self.rx_len >= self.max_len, f"isotp - rx: invalid first frame length: {self.rx_len}" + assert len(rx_data) == self.max_len, f"isotp - rx: invalid CAN frame length: {len(rx_data)}" self.rx_dat = rx_data[2:] self.rx_idx = 0 self.rx_done = False @@ -566,11 +572,11 @@ def get_rx_addr_for_tx_addr(tx_addr, rx_offset=0x8): # standard 29 bit response addr (flip last two bytes) return (tx_addr & 0xFFFF0000) + (tx_addr << 8 & 0xFF00) + (tx_addr >> 8 & 0xFF) - raise ValueError("invalid tx_addr: {}".format(tx_addr)) + raise ValueError(f"invalid tx_addr: {tx_addr}") class UdsClient(): - def __init__(self, panda, tx_addr: int, rx_addr: Optional[int] = None, bus: int = 0, sub_addr: Optional[int] = None, timeout: float = 1, + def __init__(self, panda, tx_addr: int, rx_addr: int | None = None, bus: int = 0, sub_addr: int | None = None, timeout: float = 1, debug: bool = False, tx_timeout: float = 1, response_pending_timeout: float = 10): self.bus = bus self.tx_addr = tx_addr @@ -583,7 +589,7 @@ def __init__(self, panda, tx_addr: int, rx_addr: Optional[int] = None, bus: int self.response_pending_timeout = response_pending_timeout # generic uds request - def _uds_request(self, service_type: SERVICE_TYPE, subfunction: Optional[int] = None, data: Optional[bytes] = None) -> bytes: + def _uds_request(self, service_type: SERVICE_TYPE, subfunction: int | None = None, data: bytes | None = None) -> bytes: req = bytes([service_type]) if subfunction is not None: req += bytes([subfunction]) @@ -623,12 +629,12 @@ def _uds_request(self, service_type: SERVICE_TYPE, subfunction: Optional[int] = if self.debug: print("UDS-RX: response pending") continue - raise NegativeResponseError('{} - {}'.format(service_desc, error_desc), service_id, error_code) + raise NegativeResponseError(f'{service_desc} - {error_desc}', service_id, error_code) # positive response if service_type + 0x40 != resp_sid: resp_sid_hex = hex(resp_sid) if resp_sid is not None else None - raise InvalidServiceIdError('invalid response service id: {}'.format(resp_sid_hex)) + raise InvalidServiceIdError(f'invalid response service id: {resp_sid_hex}') if subfunction is not None: resp_sfn = resp[1] if len(resp) > 1 else None @@ -671,7 +677,7 @@ def communication_control(self, control_type: CONTROL_TYPE, message_type: MESSAG def tester_present(self, ): self._uds_request(SERVICE_TYPE.TESTER_PRESENT, subfunction=0x00) - def access_timing_parameter(self, timing_parameter_type: TIMING_PARAMETER_TYPE, parameter_values: Optional[bytes] = None): + def access_timing_parameter(self, timing_parameter_type: TIMING_PARAMETER_TYPE, parameter_values: bytes | None = None): write_custom_values = timing_parameter_type == TIMING_PARAMETER_TYPE.SET_TO_GIVEN_VALUES read_values = (timing_parameter_type == TIMING_PARAMETER_TYPE.READ_CURRENTLY_ACTIVE or timing_parameter_type == TIMING_PARAMETER_TYPE.READ_EXTENDED_SET) @@ -714,8 +720,8 @@ def response_on_event(self, response_event_type: RESPONSE_EVENT_TYPE, store_even "data": resp[2:], # TODO: parse the reset of response } - def link_control(self, link_control_type: LINK_CONTROL_TYPE, baud_rate_type: Optional[BAUD_RATE_TYPE] = None): - data: Optional[bytes] + def link_control(self, link_control_type: LINK_CONTROL_TYPE, baud_rate_type: BAUD_RATE_TYPE | None = None): + data: bytes | None if link_control_type == LINK_CONTROL_TYPE.VERIFY_BAUDRATE_TRANSITION_WITH_FIXED_BAUDRATE: # baud_rate_type = BAUD_RATE_TYPE @@ -733,21 +739,21 @@ def read_data_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_TYPE): resp = self._uds_request(SERVICE_TYPE.READ_DATA_BY_IDENTIFIER, subfunction=None, data=data) resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None if resp_id != data_identifier_type: - raise ValueError('invalid response data identifier: {} expected: {}'.format(hex(resp_id), hex(data_identifier_type))) + raise ValueError(f'invalid response data identifier: {hex(resp_id)} expected: {hex(data_identifier_type)}') return resp[2:] def read_memory_by_address(self, memory_address: int, memory_size: int, memory_address_bytes: int = 4, memory_size_bytes: int = 1): if memory_address_bytes < 1 or memory_address_bytes > 4: - raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + raise ValueError(f'invalid memory_address_bytes: {memory_address_bytes}') if memory_size_bytes < 1 or memory_size_bytes > 4: - raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + raise ValueError(f'invalid memory_size_bytes: {memory_size_bytes}') data = bytes([memory_size_bytes << 4 | memory_address_bytes]) if memory_address >= 1 << (memory_address_bytes * 8): - raise ValueError('invalid memory_address: {}'.format(memory_address)) + raise ValueError(f'invalid memory_address: {memory_address}') data += struct.pack('!I', memory_address)[4 - memory_address_bytes:] if memory_size >= 1 << (memory_size_bytes * 8): - raise ValueError('invalid memory_size: {}'.format(memory_size)) + raise ValueError(f'invalid memory_size: {memory_size}') data += struct.pack('!I', memory_size)[4 - memory_size_bytes:] resp = self._uds_request(SERVICE_TYPE.READ_MEMORY_BY_ADDRESS, subfunction=None, data=data) @@ -758,7 +764,7 @@ def read_scaling_data_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_ resp = self._uds_request(SERVICE_TYPE.READ_SCALING_DATA_BY_IDENTIFIER, subfunction=None, data=data) resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None if resp_id != data_identifier_type: - raise ValueError('invalid response data identifier: {}'.format(hex(resp_id))) + raise ValueError(f'invalid response data identifier: {hex(resp_id)}') return resp[2:] # TODO: parse the response def read_data_by_periodic_identifier(self, transmission_mode_type: TRANSMISSION_MODE_TYPE, periodic_data_identifier: int): @@ -767,11 +773,11 @@ def read_data_by_periodic_identifier(self, transmission_mode_type: TRANSMISSION_ self._uds_request(SERVICE_TYPE.READ_DATA_BY_PERIODIC_IDENTIFIER, subfunction=None, data=data) def dynamically_define_data_identifier(self, dynamic_definition_type: DYNAMIC_DEFINITION_TYPE, dynamic_data_identifier: int, - source_definitions: List[DynamicSourceDefinition], memory_address_bytes: int = 4, memory_size_bytes: int = 1): + source_definitions: list[DynamicSourceDefinition], memory_address_bytes: int = 4, memory_size_bytes: int = 1): if memory_address_bytes < 1 or memory_address_bytes > 4: - raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + raise ValueError(f'invalid memory_address_bytes: {memory_address_bytes}') if memory_size_bytes < 1 or memory_size_bytes > 4: - raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + raise ValueError(f'invalid memory_size_bytes: {memory_size_bytes}') data = struct.pack('!H', dynamic_data_identifier) if dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.DEFINE_BY_IDENTIFIER: @@ -781,15 +787,15 @@ def dynamically_define_data_identifier(self, dynamic_definition_type: DYNAMIC_DE data += bytes([memory_size_bytes << 4 | memory_address_bytes]) for s in source_definitions: if s.memory_address >= 1 << (memory_address_bytes * 8): - raise ValueError('invalid memory_address: {}'.format(s.memory_address)) + raise ValueError(f'invalid memory_address: {s.memory_address}') data += struct.pack('!I', s.memory_address)[4 - memory_address_bytes:] if s.memory_size >= 1 << (memory_size_bytes * 8): - raise ValueError('invalid memory_size: {}'.format(s.memory_size)) + raise ValueError(f'invalid memory_size: {s.memory_size}') data += struct.pack('!I', s.memory_size)[4 - memory_size_bytes:] elif dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.CLEAR_DYNAMICALLY_DEFINED_DATA_IDENTIFIER: pass else: - raise ValueError('invalid dynamic identifier type: {}'.format(hex(dynamic_definition_type))) + raise ValueError(f'invalid dynamic identifier type: {hex(dynamic_definition_type)}') self._uds_request(SERVICE_TYPE.DYNAMICALLY_DEFINE_DATA_IDENTIFIER, subfunction=dynamic_definition_type, data=data) def write_data_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_TYPE, data_record: bytes): @@ -797,20 +803,20 @@ def write_data_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_TYPE, d resp = self._uds_request(SERVICE_TYPE.WRITE_DATA_BY_IDENTIFIER, subfunction=None, data=data) resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None if resp_id != data_identifier_type: - raise ValueError('invalid response data identifier: {}'.format(hex(resp_id))) + raise ValueError(f'invalid response data identifier: {hex(resp_id)}') def write_memory_by_address(self, memory_address: int, memory_size: int, data_record: bytes, memory_address_bytes: int = 4, memory_size_bytes: int = 1): if memory_address_bytes < 1 or memory_address_bytes > 4: - raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + raise ValueError(f'invalid memory_address_bytes: {memory_address_bytes}') if memory_size_bytes < 1 or memory_size_bytes > 4: - raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + raise ValueError(f'invalid memory_size_bytes: {memory_size_bytes}') data = bytes([memory_size_bytes << 4 | memory_address_bytes]) if memory_address >= 1 << (memory_address_bytes * 8): - raise ValueError('invalid memory_address: {}'.format(memory_address)) + raise ValueError(f'invalid memory_address: {memory_address}') data += struct.pack('!I', memory_address)[4 - memory_address_bytes:] if memory_size >= 1 << (memory_size_bytes * 8): - raise ValueError('invalid memory_size: {}'.format(memory_size)) + raise ValueError(f'invalid memory_size: {memory_size}') data += struct.pack('!I', memory_size)[4 - memory_size_bytes:] data += data_record @@ -864,7 +870,7 @@ def input_output_control_by_identifier(self, data_identifier_type: DATA_IDENTIFI resp = self._uds_request(SERVICE_TYPE.INPUT_OUTPUT_CONTROL_BY_IDENTIFIER, subfunction=None, data=data) resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None if resp_id != data_identifier_type: - raise ValueError('invalid response data identifier: {}'.format(hex(resp_id))) + raise ValueError(f'invalid response data identifier: {hex(resp_id)}') return resp[2:] def routine_control(self, routine_control_type: ROUTINE_CONTROL_TYPE, routine_identifier_type: ROUTINE_IDENTIFIER_TYPE, routine_option_record: bytes = b''): @@ -872,23 +878,23 @@ def routine_control(self, routine_control_type: ROUTINE_CONTROL_TYPE, routine_id resp = self._uds_request(SERVICE_TYPE.ROUTINE_CONTROL, subfunction=routine_control_type, data=data) resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None if resp_id != routine_identifier_type: - raise ValueError('invalid response routine identifier: {}'.format(hex(resp_id))) + raise ValueError(f'invalid response routine identifier: {hex(resp_id)}') return resp[2:] def request_download(self, memory_address: int, memory_size: int, memory_address_bytes: int = 4, memory_size_bytes: int = 4, data_format: int = 0x00): data = bytes([data_format]) if memory_address_bytes < 1 or memory_address_bytes > 4: - raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + raise ValueError(f'invalid memory_address_bytes: {memory_address_bytes}') if memory_size_bytes < 1 or memory_size_bytes > 4: - raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + raise ValueError(f'invalid memory_size_bytes: {memory_size_bytes}') data += bytes([memory_size_bytes << 4 | memory_address_bytes]) if memory_address >= 1 << (memory_address_bytes * 8): - raise ValueError('invalid memory_address: {}'.format(memory_address)) + raise ValueError(f'invalid memory_address: {memory_address}') data += struct.pack('!I', memory_address)[4 - memory_address_bytes:] if memory_size >= 1 << (memory_size_bytes * 8): - raise ValueError('invalid memory_size: {}'.format(memory_size)) + raise ValueError(f'invalid memory_size: {memory_size}') data += struct.pack('!I', memory_size)[4 - memory_size_bytes:] resp = self._uds_request(SERVICE_TYPE.REQUEST_DOWNLOAD, subfunction=None, data=data) @@ -896,7 +902,7 @@ def request_download(self, memory_address: int, memory_size: int, memory_address if max_num_bytes_len >= 1 and max_num_bytes_len <= 4: max_num_bytes = struct.unpack('!I', (b"\x00" * (4 - max_num_bytes_len)) + resp[1:max_num_bytes_len + 1])[0] else: - raise ValueError('invalid max_num_bytes_len: {}'.format(max_num_bytes_len)) + raise ValueError(f'invalid max_num_bytes_len: {max_num_bytes_len}') return max_num_bytes # max number of bytes per transfer data request @@ -904,16 +910,16 @@ def request_upload(self, memory_address: int, memory_size: int, memory_address_b data = bytes([data_format]) if memory_address_bytes < 1 or memory_address_bytes > 4: - raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + raise ValueError(f'invalid memory_address_bytes: {memory_address_bytes}') if memory_size_bytes < 1 or memory_size_bytes > 4: - raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + raise ValueError(f'invalid memory_size_bytes: {memory_size_bytes}') data += bytes([memory_size_bytes << 4 | memory_address_bytes]) if memory_address >= 1 << (memory_address_bytes * 8): - raise ValueError('invalid memory_address: {}'.format(memory_address)) + raise ValueError(f'invalid memory_address: {memory_address}') data += struct.pack('!I', memory_address)[4 - memory_address_bytes:] if memory_size >= 1 << (memory_size_bytes * 8): - raise ValueError('invalid memory_size: {}'.format(memory_size)) + raise ValueError(f'invalid memory_size: {memory_size}') data += struct.pack('!I', memory_size)[4 - memory_size_bytes:] resp = self._uds_request(SERVICE_TYPE.REQUEST_UPLOAD, subfunction=None, data=data) @@ -921,7 +927,7 @@ def request_upload(self, memory_address: int, memory_size: int, memory_address_b if max_num_bytes_len >= 1 and max_num_bytes_len <= 4: max_num_bytes = struct.unpack('!I', (b"\x00" * (4 - max_num_bytes_len)) + resp[1:max_num_bytes_len + 1])[0] else: - raise ValueError('invalid max_num_bytes_len: {}'.format(max_num_bytes_len)) + raise ValueError(f'invalid max_num_bytes_len: {max_num_bytes_len}') return max_num_bytes # max number of bytes per transfer data request @@ -930,7 +936,7 @@ def transfer_data(self, block_sequence_count: int, data: bytes = b''): resp = self._uds_request(SERVICE_TYPE.TRANSFER_DATA, subfunction=None, data=data) resp_id = resp[0] if len(resp) > 0 else None if resp_id != block_sequence_count: - raise ValueError('invalid block_sequence_count: {}'.format(resp_id)) + raise ValueError(f'invalid block_sequence_count: {resp_id}') return resp[1:] def request_transfer_exit(self): diff --git a/setup.py b/setup.py index c419056a94..25ee669236 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Panda CAN Controller Dongle ~~~~~ diff --git a/tests/black_white_loopback_test.py b/tests/black_white_loopback_test.py index 5b2312befb..8198a30d5f 100755 --- a/tests/black_white_loopback_test.py +++ b/tests/black_white_loopback_test.py @@ -82,7 +82,7 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration): print("\ntest can: ", send_bus, " OBD: ", obd) # set OBD on black panda - black_panda.set_gmlan(True if obd else None) + black_panda.set_obd(True if obd else None) # clear and flush if direction: diff --git a/tests/black_white_relay_endurance.py b/tests/black_white_relay_endurance.py index db19e72539..005277c15a 100755 --- a/tests/black_white_relay_endurance.py +++ b/tests/black_white_relay_endurance.py @@ -90,7 +90,7 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration): print("\ntest can: ", send_bus, " OBD: ", obd) # set OBD on black panda - black_panda.set_gmlan(True if obd else None) + black_panda.set_obd(True if obd else None) # clear and flush if direction: diff --git a/tests/black_white_relay_test.py b/tests/black_white_relay_test.py index 90b33be681..38db06a1a5 100755 --- a/tests/black_white_relay_test.py +++ b/tests/black_white_relay_test.py @@ -86,7 +86,7 @@ def test_buses(black_panda, other_panda, test_obj): other_panda.send_heartbeat() # Set OBD on send panda - other_panda.set_gmlan(True if obd else None) + other_panda.set_obd(True if obd else None) # clear and flush other_panda.can_clear(send_bus) diff --git a/tests/bulk_write_test.py b/tests/bulk_write_test.py index bc5bad3317..278766a199 100755 --- a/tests/bulk_write_test.py +++ b/tests/bulk_write_test.py @@ -2,7 +2,7 @@ import os import time import threading -from typing import Any, List +from typing import Any from panda import Panda @@ -38,7 +38,7 @@ def flood_tx(panda): threading.Thread(target=flood_tx, args=(sender,)).start() # Receive as much as we can in a few second time period - rx: List[Any] = [] + rx: list[Any] = [] old_len = 0 start_time = time.time() while time.time() - start_time < 3 or len(rx) > old_len: diff --git a/tests/elm_car_simulator.py b/tests/elm_car_simulator.py index 119c6b682a..56e825f5dd 100755 --- a/tests/elm_car_simulator.py +++ b/tests/elm_car_simulator.py @@ -190,7 +190,7 @@ def _process_obd(self, mode, pid): if pid == 0x02: # Show VIN return b"1D4GP00R55B123456" if pid == 0xFC: # test long multi message. Ligned up for LIN responses - return b''.join((struct.pack(">BBH", 0xAA, 0xAA, num + 1) for num in range(80))) + return b''.join(struct.pack(">BBH", 0xAA, 0xAA, num + 1) for num in range(80)) if pid == 0xFD: # test long multi message parts = (b'\xAA\xAA\xAA' + struct.pack(">I", num) for num in range(80)) return b'\xAA\xAA\xAA' + b''.join(parts) @@ -199,7 +199,7 @@ def _process_obd(self, mode, pid): return b'\xAA\xAA\xAA' + b''.join(parts) + b'\xAA' if pid == 0xFF: return b'\xAA\x00\x00' + \ - b"".join(((b'\xAA' * 5) + struct.pack(">H", num + 1) for num in range(584))) + b"".join((b'\xAA' * 5) + struct.pack(">H", num + 1) for num in range(584)) #return b"\xAA"*100#(0xFFF-3) diff --git a/tests/elm_throughput.py b/tests/elm_throughput.py index 75fb1c652b..983d4a1416 100755 --- a/tests/elm_throughput.py +++ b/tests/elm_throughput.py @@ -6,7 +6,7 @@ class Reader(threading.Thread): def __init__(self, s, *args, **kwargs): - super(Reader, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._s = s self.__stop = False diff --git a/tests/fan/fan_tuning.py b/tests/fan/fan_tuning.py index e9158d609d..2bdfab79a2 100755 --- a/tests/fan/fan_tuning.py +++ b/tests/fan/fan_tuning.py @@ -33,7 +33,7 @@ def logger(event): for l in drain_serial(p)[::-1]: ns = l.decode('utf8').strip().split(' ') if len(ns) == 4: - target_rpm, rpm_fast, power, stall_count = [int(n, 16) for n in ns] + target_rpm, rpm_fast, power, stall_count = (int(n, 16) for n in ns) break dat = { diff --git a/tests/get_version.py b/tests/get_version.py index 116d8abecd..a0138122ba 100755 --- a/tests/get_version.py +++ b/tests/get_version.py @@ -4,4 +4,4 @@ if __name__ == "__main__": for p in Panda.list(): pp = Panda(p) - print("%s: %s" % (pp.get_serial()[0], pp.get_version())) + print(f"{pp.get_serial()[0]}: {pp.get_version()}") diff --git a/tests/gmbitbang/recv.py b/tests/gmbitbang/recv.py deleted file mode 100755 index 73285e7e59..0000000000 --- a/tests/gmbitbang/recv.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 -from typing import Optional - -from panda import Panda - -if __name__ == "__main__": - p = Panda() - p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - p.set_gmlan(bus=2) - #p.can_send(0xaaa, b"\x00\x00", bus=3) - last_add: Optional[int] = None - while True: - ret = p.can_recv() - if len(ret) > 0: - add = ret[0][0] - if last_add is not None and add != last_add + 1: - print("MISS: ", last_add, add) - last_add = add - print(ret) diff --git a/tests/gmbitbang/rigol.py b/tests/gmbitbang/rigol.py deleted file mode 100755 index 818df748f1..0000000000 --- a/tests/gmbitbang/rigol.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -# pylint: skip-file -# type: ignore -import numpy as np -import visa -import matplotlib.pyplot as plt - -resources = visa.ResourceManager() -print(resources.list_resources()) - -scope = resources.open_resource('USB0::0x1AB1::0x04CE::DS1ZA184652242::INSTR', timeout=2000, chunk_size=1024000) -print(scope.query('*IDN?').strip()) - -#voltscale = scope.ask_for_values(':CHAN1:SCAL?')[0] -#voltoffset = scope.ask_for_values(":CHAN1:OFFS?")[0] - -#scope.write(":STOP") -scope.write(":WAV:POIN:MODE RAW") -scope.write(":WAV:DATA? CHAN1")[10:] -rawdata = scope.read_raw() -data = np.frombuffer(rawdata, 'B') -print(data.shape) - -s1 = data[0:650] -s2 = data[650:] -s1i = np.argmax(s1 > 100) -s2i = np.argmax(s2 > 100) -s1 = s1[s1i:] -s2 = s2[s2i:] - -plt.plot(s1) -plt.plot(s2) -plt.show() -#data = (data - 130.0 - voltoffset/voltscale*25) / 25 * voltscale - -print(data) diff --git a/tests/gmbitbang/test.py b/tests/gmbitbang/test.py deleted file mode 100755 index b8041136d8..0000000000 --- a/tests/gmbitbang/test.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python3 -import time -from panda import Panda - -p1 = Panda('380016000551363338383037') -p2 = Panda('430026000951363338383037') - -# this is a test, no safety -p1.set_safety_mode(Panda.SAFETY_ALLOUTPUT) -p2.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - -# get versions -print(p1.get_version()) -print(p2.get_version()) - -# this sets bus 2 to actually be GMLAN -p2.set_gmlan(bus=2) - -# send w bitbang then without -#iden = 123 -iden = 18000 -#dat = "\x01\x02" -dat = "\x01\x02\x03\x04\x05\x06\x07\x08" -while 1: - iden += 1 - p1.set_gmlan(bus=None) - p1.can_send(iden, dat, bus=3) - #p1.set_gmlan(bus=2) - #p1.can_send(iden, dat, bus=3) - time.sleep(0.01) - print(p2.can_recv()) - #exit(0) diff --git a/tests/gmbitbang/test_one.py b/tests/gmbitbang/test_one.py deleted file mode 100755 index 981edc5236..0000000000 --- a/tests/gmbitbang/test_one.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python3 -import time -from panda import Panda - -p = Panda() -p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - -# hack anything on bus -p.set_gmlan(bus=2) -time.sleep(0.1) -while len(p.can_recv()) > 0: - print("clearing") - time.sleep(0.1) -print("cleared") -p.set_gmlan(bus=None) - -iden = 18000 -dat = "\x01\x02\x03\x04\x05\x06\x07\x08" -while 1: - iden += 1 - p.can_send(iden, dat, bus=3) - time.sleep(0.01) diff --git a/tests/gmbitbang/test_packer.c b/tests/gmbitbang/test_packer.c deleted file mode 100644 index 63c0131006..0000000000 --- a/tests/gmbitbang/test_packer.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -#define CANPACKET_DATA_SIZE_MAX 8 -#include "../../board/can_definitions.h" - -#include "../../board/drivers/canbitbang.h" - -int main() { - char out[300]; - CANPacket_t to_bang = {0}; - to_bang.addr = 20 << 18; - to_bang.data_len_code = 1; - to_bang.data[0] = 1; - - int len = get_bit_message(out, &to_bang); - printf("T:"); - for (int i = 0; i < len; i++) { - printf("%d", out[i]); - } - printf("\n"); - printf("R:0000010010100000100010000010011110111010100111111111111111"); - printf("\n"); - return 0; -} - - - diff --git a/tests/gmlan_harness_test.py b/tests/gmlan_harness_test.py deleted file mode 100755 index 950918cff2..0000000000 --- a/tests/gmlan_harness_test.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 - -import time - -from panda import Panda - -WHITE_GMLAN_BUS = 3 -OTHER_GMLAN_BUS = 1 - -def set_gmlan(p): - if p.get_type() == Panda.HW_TYPE_WHITE_PANDA: - p.set_gmlan(2) - else: - p.set_obd(True) - -def set_speed_kbps(p, speed): - if p.get_type() == Panda.HW_TYPE_WHITE_PANDA: - p.set_can_speed_kbps(WHITE_GMLAN_BUS, speed) - else: - p.set_can_speed_kbps(OTHER_GMLAN_BUS, speed) - -def send(p, id_, msg): - if p.get_type() == Panda.HW_TYPE_WHITE_PANDA: - p.can_send(id_, msg, WHITE_GMLAN_BUS) - else: - p.can_send(id_, msg, OTHER_GMLAN_BUS) - -if __name__ == "__main__": - pl = Panda.list() - assert(len(pl) == 2) - p0 = Panda(pl[1]) - p1 = Panda(pl[0]) - - p0.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - p1.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - - print("0: ", p0.get_type()) - print("1: ", p1.get_type()) - - set_gmlan(p0) - set_gmlan(p1) - - p0.can_clear(0xFFFF) - p1.can_clear(0xFFFF) - - try: - loops = 0 - while True: - for speed in [33.3, 83.3]: - set_speed_kbps(p0, speed) - set_speed_kbps(p1, speed) - p0.can_clear(0xFFFF) - p1.can_clear(0xFFFF) - - print(f"Speed: {speed}") - time.sleep(0.1) - - print("Send 1 -> 0") - send(p1, 1, b"1to0:" + bytes(str(loops%100), "utf-8")) - time.sleep(0.05) - rx = list(filter(lambda x: x[3] < 128, p0.can_recv())) - print(rx) - assert(len(rx) == 1) - - print("Send 0 -> 1") - send(p0, 1, b"0to1:" + bytes(str(loops%100), "utf-8")) - time.sleep(0.05) - rx = list(filter(lambda x: x[3] < 128, p1.can_recv())) - print(rx) - assert(len(rx) == 1) - - time.sleep(0.5) - - - loops += 1 - print(f"Completed {loops} loops") - except Exception: - print("Test failed somehow. Did you power the black panda using the GMLAN harness?") diff --git a/tests/hitl/2_health.py b/tests/hitl/2_health.py index acb993f50d..12c75f561d 100644 --- a/tests/hitl/2_health.py +++ b/tests/hitl/2_health.py @@ -2,66 +2,6 @@ import pytest from panda import Panda -from panda import PandaJungle -from panda.tests.hitl.conftest import PandaGroup - - -def test_ignition(p, panda_jungle): - # Set harness orientation to #2, since the ignition line is on the wrong SBU bus :/ - panda_jungle.set_harness_orientation(PandaJungle.HARNESS_ORIENTATION_2) - p.reset() - - for ign in (True, False): - panda_jungle.set_ignition(ign) - time.sleep(0.1) - assert p.health()['ignition_line'] == ign - - -@pytest.mark.test_panda_types(PandaGroup.GEN2) -def test_harness_status(p, panda_jungle): - flipped = None - for ignition in [True, False]: - for orientation in [Panda.HARNESS_STATUS_NC, Panda.HARNESS_STATUS_NORMAL, Panda.HARNESS_STATUS_FLIPPED]: - panda_jungle.set_harness_orientation(orientation) - panda_jungle.set_ignition(ignition) - time.sleep(1) - - health = p.health() - detected_orientation = health['car_harness_status'] - print(f"set: {orientation} detected: {detected_orientation}") - - # Orientation - if orientation == Panda.HARNESS_STATUS_NC: - assert detected_orientation == Panda.HARNESS_STATUS_NC - else: - if flipped is None: - flipped = (detected_orientation != orientation) - - if orientation == Panda.HARNESS_STATUS_NORMAL: - assert detected_orientation == (Panda.HARNESS_STATUS_FLIPPED if flipped else Panda.HARNESS_STATUS_NORMAL) - else: - assert detected_orientation == (Panda.HARNESS_STATUS_NORMAL if flipped else Panda.HARNESS_STATUS_FLIPPED) - - # Line ignition - assert health['ignition_line'] == (False if orientation == Panda.HARNESS_STATUS_NC else ignition) - - # SBU voltages - supply_voltage_mV = 1800 if p.get_type() in [Panda.HW_TYPE_TRES, ] else 3300 - - if orientation == Panda.HARNESS_STATUS_NC: - assert health['sbu1_voltage_mV'] > 0.9 * supply_voltage_mV - assert health['sbu2_voltage_mV'] > 0.9 * supply_voltage_mV - else: - relay_line = 'sbu1_voltage_mV' if (detected_orientation == Panda.HARNESS_STATUS_FLIPPED) else 'sbu2_voltage_mV' - ignition_line = 'sbu2_voltage_mV' if (detected_orientation == Panda.HARNESS_STATUS_FLIPPED) else 'sbu1_voltage_mV' - - assert health[relay_line] < 0.1 * supply_voltage_mV - assert health[ignition_line] > health[relay_line] - if ignition: - assert health[ignition_line] < 0.3 * supply_voltage_mV - else: - assert health[ignition_line] > 0.9 * supply_voltage_mV - @pytest.mark.skip_panda_types((Panda.HW_TYPE_DOS, )) diff --git a/tests/hitl/3_usb_to_can.py b/tests/hitl/3_usb_to_can.py index 9321eb4e85..c0a9035fe4 100644 --- a/tests/hitl/3_usb_to_can.py +++ b/tests/hitl/3_usb_to_can.py @@ -1,9 +1,7 @@ import time -import pytest from flaky import flaky from panda import Panda -from panda.tests.hitl.conftest import SPEED_NORMAL, SPEED_GMLAN, PandaGroup from panda.tests.hitl.helpers import time_many_sends def test_can_loopback(p): @@ -81,45 +79,6 @@ def test_throughput(p): print("loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct)) -@pytest.mark.test_panda_types(PandaGroup.GMLAN) -def test_gmlan(p): - p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - p.set_can_loopback(True) - - # set gmlan on CAN2 - for bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3, Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]: - p.set_gmlan(bus) - comp_kbps_gmlan = time_many_sends(p, 3) - assert comp_kbps_gmlan > (0.8 * SPEED_GMLAN) - assert comp_kbps_gmlan < (1.0 * SPEED_GMLAN) - - p.set_gmlan(None) - comp_kbps_normal = time_many_sends(p, bus) - assert comp_kbps_normal > (0.8 * SPEED_NORMAL) - assert comp_kbps_normal < (1.0 * SPEED_NORMAL) - - print("%d: %.2f kbps vs %.2f kbps" % (bus, comp_kbps_gmlan, comp_kbps_normal)) - -@pytest.mark.test_panda_types(PandaGroup.GMLAN) -def test_gmlan_bad_toggle(p): - p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - p.set_can_loopback(True) - - # GMLAN_CAN2 - for bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]: - p.set_gmlan(bus) - comp_kbps_gmlan = time_many_sends(p, 3) - assert comp_kbps_gmlan > (0.6 * SPEED_GMLAN) - assert comp_kbps_gmlan < (1.0 * SPEED_GMLAN) - - # normal - for bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]: - p.set_gmlan(None) - comp_kbps_normal = time_many_sends(p, bus) - assert comp_kbps_normal > (0.6 * SPEED_NORMAL) - assert comp_kbps_normal < (1.0 * SPEED_NORMAL) - - # this will fail if you have hardware serial connected def test_serial_debug(p): _ = p.serial_read(Panda.SERIAL_DEBUG) # junk diff --git a/tests/hitl/4_can_loopback.py b/tests/hitl/4_can_loopback.py index f00bc95471..a7e1aea1ee 100644 --- a/tests/hitl/4_can_loopback.py +++ b/tests/hitl/4_can_loopback.py @@ -24,7 +24,7 @@ def test(p_send, p_recv): saturation_pct = (comp_kbps / speed) * 100.0 assert 80 < saturation_pct < 100 - print("two pandas bus {}, 100 messages at speed {:4d}, comp speed is {:7.2f}, {:6.2f}%".format(bus, speed, comp_kbps, saturation_pct)) + print(f"two pandas bus {bus}, 100 messages at speed {speed:4d}, comp speed is {comp_kbps:7.2f}, {saturation_pct:6.2f}%") # Run tests in both directions p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) @@ -59,7 +59,7 @@ def test(p_send, p_recv): r_echo = p_send.can_recv() if len(r) == 0 or len(r_echo) == 0: - print("r: {}, r_echo: {}".format(r, r_echo)) + print(f"r: {r}, r_echo: {r_echo}") assert len(r) == 1 assert len(r_echo) == 1 diff --git a/tests/hitl/8_misc.py b/tests/hitl/8_misc.py new file mode 100644 index 0000000000..3c47ed492b --- /dev/null +++ b/tests/hitl/8_misc.py @@ -0,0 +1,13 @@ +import time + +from panda import Panda + +def test_boot_time(p): + # boot time should be instant + st = time.monotonic() + p.reset(reconnect=False) + assert Panda.wait_for_panda(p.get_usb_serial(), timeout=3.0) + + # USB enumeration is slow, so SPI is faster + assert time.monotonic() - st < (1.0 if p.spi else 5.0) + diff --git a/tests/hitl/9_harness.py b/tests/hitl/9_harness.py new file mode 100644 index 0000000000..5689892b8a --- /dev/null +++ b/tests/hitl/9_harness.py @@ -0,0 +1,77 @@ +import time +import pytest +import itertools + +from panda import Panda +from panda.tests.hitl.conftest import PandaGroup + +# TODO: test relay + +@pytest.mark.panda_expect_can_error +@pytest.mark.test_panda_types(PandaGroup.GEN2) +def test_harness_status(p, panda_jungle): + # map from jungle orientations to panda orientations + orientation_map = { + Panda.HARNESS_STATUS_NC: Panda.HARNESS_STATUS_NC, + } + + # this shouldn't be parameterized since we don't want the panda to be reset + # between the tests. + for ignition, orientation in itertools.product([True, False], [Panda.HARNESS_STATUS_NC, Panda.HARNESS_STATUS_NORMAL, Panda.HARNESS_STATUS_FLIPPED]): + print() + p.set_safety_mode(Panda.SAFETY_ELM327) + panda_jungle.set_harness_orientation(orientation) + panda_jungle.set_ignition(ignition) + + # wait for orientation detection + time.sleep(0.25) + + health = p.health() + detected_orientation = health['car_harness_status'] + print(f"orientation set: {orientation} detected: {detected_orientation}") + + if detected_orientation not in orientation_map: + assert detected_orientation != Panda.HARNESS_STATUS_NC + other = {Panda.HARNESS_STATUS_NORMAL: Panda.HARNESS_STATUS_FLIPPED, Panda.HARNESS_STATUS_FLIPPED: Panda.HARNESS_STATUS_NORMAL} + orientation_map.update({ + orientation: detected_orientation, + other[orientation]: other[detected_orientation], + }) + + # Orientation + assert orientation_map[detected_orientation] == orientation + + # Line ignition + assert health['ignition_line'] == (False if orientation == Panda.HARNESS_STATUS_NC else ignition) + + # CAN traffic + if orientation != Panda.HARNESS_STATUS_NC: + for bus in range(3): + panda_jungle.can_send(0x123, f"{bus}".encode(), bus) + time.sleep(0.5) + + msgs = p.can_recv() + buses = {int(dat): bus for _, _, dat, bus in msgs if bus <= 3} + print(msgs) + + # jungle doesn't actually switch buses when switching orientation + flipped = orientation == Panda.HARNESS_STATUS_FLIPPED + assert buses[0] == (2 if flipped else 0) + assert buses[2] == (0 if flipped else 2) + + # SBU voltages + supply_voltage_mV = 1800 if p.get_type() in [Panda.HW_TYPE_TRES, ] else 3300 + + if orientation == Panda.HARNESS_STATUS_NC: + assert health['sbu1_voltage_mV'] > 0.9 * supply_voltage_mV + assert health['sbu2_voltage_mV'] > 0.9 * supply_voltage_mV + else: + relay_line = 'sbu1_voltage_mV' if (detected_orientation == Panda.HARNESS_STATUS_FLIPPED) else 'sbu2_voltage_mV' + ignition_line = 'sbu2_voltage_mV' if (detected_orientation == Panda.HARNESS_STATUS_FLIPPED) else 'sbu1_voltage_mV' + + assert health[relay_line] < 0.1 * supply_voltage_mV + assert health[ignition_line] > health[relay_line] + if ignition: + assert health[ignition_line] < 0.3 * supply_voltage_mV + else: + assert health[ignition_line] > 0.9 * supply_voltage_mV diff --git a/tests/hitl/conftest.py b/tests/hitl/conftest.py index b7844354fc..1c4db1e921 100644 --- a/tests/hitl/conftest.py +++ b/tests/hitl/conftest.py @@ -11,8 +11,7 @@ sys.stdout = sys.stderr SPEED_NORMAL = 500 -SPEED_GMLAN = 33.3 -BUS_SPEEDS = [(0, SPEED_NORMAL), (1, SPEED_NORMAL), (2, SPEED_NORMAL), (3, SPEED_GMLAN)] +BUS_SPEEDS = [(0, SPEED_NORMAL), (1, SPEED_NORMAL), (2, SPEED_NORMAL)] JUNGLE_SERIAL = os.getenv("PANDAS_JUNGLE") @@ -28,8 +27,6 @@ class PandaGroup: H7 = (Panda.HW_TYPE_RED_PANDA, Panda.HW_TYPE_RED_PANDA_V2, Panda.HW_TYPE_TRES) GEN2 = (Panda.HW_TYPE_BLACK_PANDA, Panda.HW_TYPE_UNO, Panda.HW_TYPE_DOS) + H7 - GMLAN = (Panda.HW_TYPE_WHITE_PANDA, Panda.HW_TYPE_GREY_PANDA) - TESTED = (Panda.HW_TYPE_WHITE_PANDA, Panda.HW_TYPE_BLACK_PANDA, Panda.HW_TYPE_RED_PANDA, Panda.HW_TYPE_RED_PANDA_V2, Panda.HW_TYPE_UNO) if HW_TYPES is not None: @@ -136,7 +133,8 @@ def func_fixture_panda(request, module_panda): if _all_pandas[p.get_usb_serial()] in skip_types: pytest.skip(f"Not applicable to {skip_types}") - # TODO: reset is slow (2+ seconds) + # this is 2+ seconds on USB pandas due to slow + # enumeration on the host side p.reset() # ensure FW hasn't changed @@ -201,7 +199,6 @@ def cnnct(s): p.reset(reconnect=True) p.set_can_loopback(False) - p.set_gmlan(None) p.set_power_save(False) for bus, speed in BUS_SPEEDS: p.set_can_speed_kbps(bus, speed) diff --git a/tests/hitl/helpers.py b/tests/hitl/helpers.py index d7ac4da0d6..4eee437311 100644 --- a/tests/hitl/helpers.py +++ b/tests/hitl/helpers.py @@ -1,6 +1,5 @@ import time import random -from typing import Optional def get_random_can_messages(n): @@ -52,7 +51,7 @@ def time_many_sends(p, bus, p_recv=None, msg_count=100, two_pandas=False, msg_le return comp_kbps -def clear_can_buffers(panda, speed: Optional[int] = None): +def clear_can_buffers(panda, speed: int | None = None): if speed is not None: for bus in range(3): panda.set_can_speed_kbps(bus, speed) diff --git a/tests/libpanda/libpanda_py.py b/tests/libpanda/libpanda_py.py index 1b07543d63..6f888ac60e 100644 --- a/tests/libpanda/libpanda_py.py +++ b/tests/libpanda/libpanda_py.py @@ -1,6 +1,6 @@ import os from cffi import FFI -from typing import Any, List, Protocol +from typing import Any, Protocol from panda import LEN_TO_DLC from panda.tests.libpanda.safety_helpers import PandaSafety, setup_safety_helpers @@ -40,7 +40,6 @@ } can_ring; extern can_ring *rx_q; -extern can_ring *txgmlan_q; extern can_ring *tx1_q; extern can_ring *tx2_q; extern can_ring *tx3_q; @@ -64,14 +63,13 @@ class CANPacket: returned: int extended: int addr: int - data: List[int] + data: list[int] class Panda(PandaSafety, Protocol): # CAN tx1_q: Any tx2_q: Any tx3_q: Any - txgmlan_q: Any def can_set_checksum(self, p: CANPacket) -> None: ... # safety diff --git a/tests/libpanda/panda.c b/tests/libpanda/panda.c index 8efb6de4d5..f34c028048 100644 --- a/tests/libpanda/panda.c +++ b/tests/libpanda/panda.c @@ -2,7 +2,6 @@ #include "config.h" #include "can_definitions.h" -bool bitbang_gmlan(CANPacket_t *to_bang) { return true; } bool can_init(uint8_t can_number) { return true; } void process_can(uint8_t can_number) { } //int safety_tx_hook(CANPacket_t *to_send) { return 1; } @@ -21,7 +20,6 @@ void can_tx_comms_resume_spi(void) { }; #include "drivers/can_common.h" can_ring *rx_q = &can_rx_q; -can_ring *txgmlan_q = &can_txgmlan_q; can_ring *tx1_q = &can_tx1_q; can_ring *tx2_q = &can_tx2_q; can_ring *tx3_q = &can_tx3_q; diff --git a/tests/libpanda/safety_helpers.h b/tests/libpanda/safety_helpers.h index 074463d319..36887c8963 100644 --- a/tests/libpanda/safety_helpers.h +++ b/tests/libpanda/safety_helpers.h @@ -43,10 +43,6 @@ bool get_relay_malfunction(void){ return relay_malfunction; } -int get_gas_interceptor_prev(void){ - return gas_interceptor_prev; -} - bool get_gas_pressed_prev(void){ return gas_pressed_prev; } diff --git a/tests/libpanda/safety_helpers.py b/tests/libpanda/safety_helpers.py index 28f3349dc6..ea41264ae0 100644 --- a/tests/libpanda/safety_helpers.py +++ b/tests/libpanda/safety_helpers.py @@ -10,7 +10,6 @@ def setup_safety_helpers(ffi): int get_alternative_experience(void); void set_relay_malfunction(bool c); bool get_relay_malfunction(void); - int get_gas_interceptor_prev(void); bool get_gas_pressed_prev(void); bool get_brake_pressed_prev(void); bool get_regen_braking_prev(void); @@ -61,7 +60,6 @@ def set_alternative_experience(self, mode: int) -> None: ... def get_alternative_experience(self) -> int: ... def set_relay_malfunction(self, c: bool) -> None: ... def get_relay_malfunction(self) -> bool: ... - def get_gas_interceptor_prev(self) -> int: ... def get_gas_pressed_prev(self) -> bool: ... def get_brake_pressed_prev(self) -> bool: ... def get_regen_braking_prev(self) -> bool: ... diff --git a/tests/loopback_test.py b/tests/loopback_test.py index d4f8bebf85..a95c2ea228 100755 --- a/tests/loopback_test.py +++ b/tests/loopback_test.py @@ -37,18 +37,18 @@ def run_test_w_pandas(pandas, sleep_duration): print("health", ho[0], h[ho[0]].health()) # **** test can line loopback **** - for bus, gmlan in [(0, False), (1, False), (2, False), (1, True), (2, True)]: + for bus, obd in [(0, False), (1, False), (2, False), (1, True), (2, True)]: print("\ntest can", bus) # flush cans_echo = panda0.can_recv() cans_loop = panda1.can_recv() - panda0.set_gmlan(None) - panda1.set_gmlan(None) + panda0.set_obd(None) + panda1.set_obd(None) - if gmlan is True: - panda0.set_gmlan(bus) - panda1.set_gmlan(bus) + if obd is True: + panda0.set_obd(bus) + panda1.set_obd(bus) bus = 3 # send the characters diff --git a/tests/message_drop_test.py b/tests/message_drop_test.py index 99d35b043d..bf485e4545 100755 --- a/tests/message_drop_test.py +++ b/tests/message_drop_test.py @@ -5,7 +5,7 @@ import struct import itertools import threading -from typing import Any, Union, List +from typing import Any from panda import Panda @@ -16,7 +16,7 @@ # Generate unique messages NUM_MESSAGES_PER_BUS = 10000 messages = [bytes(struct.pack("Q", i)) for i in range(NUM_MESSAGES_PER_BUS)] -tx_messages = list(itertools.chain.from_iterable(([[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] for msg in messages))) +tx_messages = list(itertools.chain.from_iterable([[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] for msg in messages)) def flood_tx(panda): print('Sending!') @@ -35,7 +35,7 @@ def flood_tx(panda): if __name__ == "__main__": serials = Panda.list() - receiver: Union[Panda, PandaJungle] + receiver: Panda | PandaJungle if JUNGLE: sender = Panda() receiver = PandaJungle() @@ -52,7 +52,7 @@ def flood_tx(panda): threading.Thread(target=flood_tx, args=(sender,)).start() # Receive as much as we can, and stop when there hasn't been anything for a second - rx: List[Any] = [] + rx: list[Any] = [] old_len = 0 last_change = time.monotonic() while time.monotonic() - last_change < 1: diff --git a/tests/misra/install.sh b/tests/misra/install.sh index a29b111176..8b264aa61b 100755 --- a/tests/misra/install.sh +++ b/tests/misra/install.sh @@ -10,10 +10,10 @@ fi cd $CPPCHECK_DIR -VERS="2.13.0" +VERS="2.13.4" git fetch --all --tags git checkout $VERS -git cherry-pick -n f6b538e855f0bacea33c4074664628024ef39dc6 +git cherry-pick -n f6b538e855f0bacea33c4074664628024ef39dc6 b11b42087ff29569bc3740f5aa07eb6616ea4f63 #make clean make MATCHCOMPILTER=yes CXXFLAGS="-O2" -j8 diff --git a/tests/misra/suppressions.txt b/tests/misra/suppressions.txt index be4b0e0265..c3e260dfba 100644 --- a/tests/misra/suppressions.txt +++ b/tests/misra/suppressions.txt @@ -18,10 +18,11 @@ unusedFunction:*/interrupt_handlers*.h # all of the below suppressions are from new checks introduced after updating # cppcheck from 2.5 -> 2.13. they are listed here to separate the update from # fixing the violations and all are intended to be removed soon after -misra-config -misra-c2012-1.2 # this is from the extensions (e.g. __typeof__) used in the MIN, MAX, ABS, and CLAMP macros -misra-c2012-2.5 +misra-c2012-1.2 # this is from the extensions (e.g. __typeof__) used in the MIN, MAX, ABS, and CLAMP macros +misra-c2012-2.5 # unused macros. a few legit, rest aren't common between F4/H7 builds. should we do this in the unusedFunction pass? misra-c2012-8.7 misra-c2012-8.4 -misra-c2012-10.6 misra-c2012-21.15 + +# FIXME: violations are in ST's F4 headers +misra-c2012-12.2 diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index 9fdbea1df7..982a62e740 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -10,7 +10,7 @@ NC='\033[0m' : "${CPPCHECK_DIR:=$DIR/cppcheck/}" # install cppcheck if missing -if [ -z "${SKIP_BUILD}" ]; then +if [ -z "${SKIP_CPPCHECK_INSTALL}" ]; then $DIR/install.sh fi @@ -29,13 +29,17 @@ if [ -z "${SKIP_BUILD}" ]; then fi cppcheck() { + # get all gcc defines: arm-none-eabi-gcc -dM -E - < /dev/null + COMMON_DEFINES="-D__GNUC__=9 -UCMSIS_NVIC_VIRTUAL -UCMSIS_VECTAB_VIRTUAL" + # note that cppcheck build cache results in inconsistent results as of v2.13.0 OUTPUT=$DIR/.output.log - $CPPCHECK_DIR/cppcheck --force --inline-suppr -I $PANDA_DIR/board/ \ - -I $gcc_inc "$(arm-none-eabi-gcc -print-file-name=include)" \ + $CPPCHECK_DIR/cppcheck --inline-suppr -I $PANDA_DIR/board/ \ + -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 \ - --platform=arm32-wchar_t2 \ + --platform=arm32-wchar_t4 $COMMON_DEFINES \ "$@" |& tee $OUTPUT # cppcheck bug: some MISRA errors won't result in the error exit code, @@ -48,10 +52,10 @@ cppcheck() { PANDA_OPTS="--enable=all --disable=unusedFunction -DPANDA --addon=misra" printf "\n${GREEN}** PANDA F4 CODE **${NC}\n" -cppcheck $PANDA_OPTS -DSTM32F4 -DUID_BASE $PANDA_DIR/board/main.c +cppcheck $PANDA_OPTS -DSTM32F4 -DSTM32F413xx $PANDA_DIR/board/main.c printf "\n${GREEN}** PANDA H7 CODE **${NC}\n" -cppcheck $PANDA_OPTS -DSTM32H7 -DUID_BASE $PANDA_DIR/board/main.c +cppcheck $PANDA_OPTS -DSTM32H7 -DSTM32H725xx $PANDA_DIR/board/main.c # unused needs to run globally #printf "\n${GREEN}** UNUSED ALL CODE **${NC}\n" diff --git a/tests/misra/test_mutation.py b/tests/misra/test_mutation.py index cc3666f136..06ce266e8f 100755 --- a/tests/misra/test_mutation.py +++ b/tests/misra/test_mutation.py @@ -14,21 +14,22 @@ 'board/obj', 'board/jungle', 'board/stm32h7/inc', - 'board/stm32fx/inc', + 'board/stm32f4/inc', 'board/fake_stm.h', # bootstub only files 'board/flasher.h', 'board/bootstub.c', 'board/bootstub_declarations.h', - 'board/stm32fx/llflash.h' + 'board/stm32h7/llflash.h', + 'board/stm32f4/llflash.h', ) mutations = [ # default (None, None, False), # F4 only - ("board/stm32fx/llbxcan.h", "s/1U/1/g", True), + ("board/stm32f4/llbxcan.h", "s/1U/1/g", True), # H7 only ("board/stm32h7/llfdcan.h", "s/return ret;/if (true) { return ret; } else { return false; }/g", True), # general safety @@ -60,7 +61,7 @@ all_files = glob.glob('board/**', root_dir=ROOT, recursive=True) files = [f for f in all_files if f.endswith(('.c', '.h')) and not f.startswith(IGNORED_PATHS)] -assert len(files) > 70, all(d in files for d in ('board/main.c', 'board/stm32fx/llbxcan.h', 'board/stm32h7/llfdcan.h', 'board/safety/safety_toyota.h')) +assert len(files) > 70, all(d in files for d in ('board/main.c', 'board/stm32f4/llbxcan.h', 'board/stm32h7/llfdcan.h', 'board/safety/safety_toyota.h')) for p in patterns: mutations.append((random.choice(files), p, True)) @@ -79,6 +80,3 @@ def test_misra_mutation(fn, patch, should_fail): r = subprocess.run("tests/misra/test_misra.sh", cwd=tmp, shell=True) failed = r.returncode != 0 assert failed == should_fail - -if __name__ == "__main__": - pytest.main([__file__, "-n 8"]) diff --git a/tests/read_winusb_descriptors.py b/tests/read_winusb_descriptors.py index ec0534ebab..5d311c9ea9 100755 --- a/tests/read_winusb_descriptors.py +++ b/tests/read_winusb_descriptors.py @@ -12,23 +12,23 @@ print('Microsoft OS String Descriptor') dat = p._handle.controlRead(Panda.REQUEST_IN, 0x06, 3 << 8 | 238, 0, length[0]) if DEBUG: - print('LEN: {}'.format(hex(length[0]))) + print(f'LEN: {hex(length[0])}') hexdump("".join(map(chr, dat))) ms_vendor_code = dat[16] if DEBUG: - print('MS_VENDOR_CODE: {}'.format(hex(length[0]))) + print(f'MS_VENDOR_CODE: {hex(length[0])}') print('\nMicrosoft Compatible ID Feature Descriptor') length = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 4, 1) if DEBUG: - print('LEN: {}'.format(hex(length[0]))) + print(f'LEN: {hex(length[0])}') dat = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 4, length[0]) hexdump("".join(map(chr, dat))) print('\nMicrosoft Extended Properties Feature Descriptor') length = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 5, 1) if DEBUG: - print('LEN: {}'.format(hex(length[0]))) + print(f'LEN: {hex(length[0])}') dat = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 5, length[0]) hexdump("".join(map(chr, dat))) diff --git a/tests/rtc_test.py b/tests/rtc_test.py deleted file mode 100755 index 01c9f4ddd8..0000000000 --- a/tests/rtc_test.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -import datetime - -from panda import Panda - -if __name__ == "__main__": - p = Panda() - - p.set_datetime(datetime.datetime.now()) - print(p.get_datetime()) diff --git a/tests/safety/common.py b/tests/safety/common.py index 8b70966aea..e111ff7eff 100644 --- a/tests/safety/common.py +++ b/tests/safety/common.py @@ -3,7 +3,7 @@ import unittest import importlib import numpy as np -from typing import Callable, Dict, List, Optional, Tuple +from collections.abc import Callable from opendbc.can.packer import CANPacker # pylint: disable=import-error from panda import ALTERNATIVE_EXPERIENCE @@ -77,7 +77,7 @@ def _tx(self, msg): def _generic_limit_safety_check(self, msg_function: MessageFunction, min_allowed_value: float, max_allowed_value: float, min_possible_value: float, max_possible_value: float, test_delta: float = 1, inactive_value: float = 0, - msg_allowed = True, additional_setup: Optional[Callable[[float], None]] = None): + msg_allowed = True, additional_setup: Callable[[float], None] | None = None): """ Enforces that a signal within a message is only allowed to be sent within a specific range, min_allowed_value -> max_allowed_value. Tests the range of min_possible_value -> max_possible_value with a delta of test_delta. @@ -118,91 +118,6 @@ def _common_measurement_test(self, msg_func: Callable, min_value: float, max_val self.assertEqual(meas_max_func(), 0) -class GasInterceptorSafetyTest(PandaSafetyTestBase): - - INTERCEPTOR_THRESHOLD = 0 - - cnt_gas_cmd = 0 - cnt_user_gas = 0 - - packer: CANPackerPanda - - @classmethod - def setUpClass(cls): - if cls.__name__ == "GasInterceptorSafetyTest" or cls.__name__.endswith("Base"): - cls.safety = None - raise unittest.SkipTest - - def _interceptor_gas_cmd(self, gas: int): - values: dict[str, float | int] = {"COUNTER_PEDAL": self.__class__.cnt_gas_cmd & 0xF} - if gas > 0: - values["GAS_COMMAND"] = gas * 255. - values["GAS_COMMAND2"] = gas * 255. - self.__class__.cnt_gas_cmd += 1 - return self.packer.make_can_msg_panda("GAS_COMMAND", 0, values) - - def _interceptor_user_gas(self, gas: int): - values = {"INTERCEPTOR_GAS": gas, "INTERCEPTOR_GAS2": gas, - "COUNTER_PEDAL": self.__class__.cnt_user_gas} - self.__class__.cnt_user_gas += 1 - return self.packer.make_can_msg_panda("GAS_SENSOR", 0, values) - - # Skip non-interceptor user gas tests - def test_prev_gas(self): - pass - - def test_disengage_on_gas(self): - pass - - def test_alternative_experience_no_disengage_on_gas(self): - pass - - def test_prev_gas_interceptor(self): - self._rx(self._interceptor_user_gas(0x0)) - self.assertFalse(self.safety.get_gas_interceptor_prev()) - self._rx(self._interceptor_user_gas(0x1000)) - self.assertTrue(self.safety.get_gas_interceptor_prev()) - self._rx(self._interceptor_user_gas(0x0)) - - def test_disengage_on_gas_interceptor(self): - for g in range(0x1000): - self._rx(self._interceptor_user_gas(0)) - self.safety.set_controls_allowed(True) - self._rx(self._interceptor_user_gas(g)) - remain_enabled = g <= self.INTERCEPTOR_THRESHOLD - self.assertEqual(remain_enabled, self.safety.get_controls_allowed()) - self._rx(self._interceptor_user_gas(0)) - - def test_alternative_experience_no_disengage_on_gas_interceptor(self): - self.safety.set_controls_allowed(True) - self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS) - for g in range(0x1000): - self._rx(self._interceptor_user_gas(g)) - # Test we allow lateral, but not longitudinal - self.assertTrue(self.safety.get_controls_allowed()) - self.assertEqual(g <= self.INTERCEPTOR_THRESHOLD, self.safety.get_longitudinal_allowed()) - # Make sure we can re-gain longitudinal actuation - self._rx(self._interceptor_user_gas(0)) - self.assertTrue(self.safety.get_longitudinal_allowed()) - - def test_allow_engage_with_gas_interceptor_pressed(self): - self._rx(self._interceptor_user_gas(0x1000)) - self.safety.set_controls_allowed(1) - self._rx(self._interceptor_user_gas(0x1000)) - self.assertTrue(self.safety.get_controls_allowed()) - self._rx(self._interceptor_user_gas(0)) - - def test_gas_interceptor_safety_check(self): - for gas in np.arange(0, 4000, 100): - for controls_allowed in [True, False]: - self.safety.set_controls_allowed(controls_allowed) - if controls_allowed: - send = True - else: - send = gas == 0 - self.assertEqual(send, self._tx(self._interceptor_gas_cmd(gas))) - - class LongitudinalAccelSafetyTest(PandaSafetyTestBase, abc.ABC): MAX_ACCEL: float = 2.0 @@ -245,13 +160,13 @@ def test_accel_actuation_limits(self, stock_longitudinal=False): class LongitudinalGasBrakeSafetyTest(PandaSafetyTestBase, abc.ABC): MIN_BRAKE: int = 0 - MAX_BRAKE: Optional[int] = None - MAX_POSSIBLE_BRAKE: Optional[int] = None + MAX_BRAKE: int | None = None + MAX_POSSIBLE_BRAKE: int | None = None MIN_GAS: int = 0 - MAX_GAS: Optional[int] = None + MAX_GAS: int | None = None INACTIVE_GAS = 0 - MAX_POSSIBLE_GAS: Optional[int] = None + MAX_POSSIBLE_GAS: int | None = None def test_gas_brake_limits_correct(self): self.assertIsNotNone(self.MAX_POSSIBLE_BRAKE) @@ -665,9 +580,9 @@ def test_reset_torque_measurements(self): class AngleSteeringSafetyTest(PandaSafetyTestBase): DEG_TO_CAN: float - ANGLE_RATE_BP: List[float] - ANGLE_RATE_UP: List[float] # windup limit - ANGLE_RATE_DOWN: List[float] # unwind limit + ANGLE_RATE_BP: list[float] + ANGLE_RATE_UP: list[float] # windup limit + ANGLE_RATE_DOWN: list[float] # unwind limit @classmethod def setUpClass(cls): @@ -771,14 +686,13 @@ def test_angle_cmd_when_disabled(self): class PandaSafetyTest(PandaSafetyTestBase): - TX_MSGS: Optional[List[List[int]]] = None + TX_MSGS: list[list[int]] | None = None SCANNED_ADDRS = [*range(0x800), # Entire 11-bit CAN address space *range(0x18DA00F1, 0x18DB00F1, 0x100), # 29-bit UDS physical addressing *range(0x18DB00F1, 0x18DC00F1, 0x100), # 29-bit UDS functional addressing - *range(0x3300, 0x3400), # Honda - 0x10400060, 0x104c006c] # GMLAN (exceptions, range/format unclear) - FWD_BLACKLISTED_ADDRS: Dict[int, List[int]] = {} # {bus: [addr]} - FWD_BUS_LOOKUP: Dict[int, int] = {} + *range(0x3300, 0x3400)] # Honda + FWD_BLACKLISTED_ADDRS: dict[int, list[int]] = {} # {bus: [addr]} + FWD_BUS_LOOKUP: dict[int, int] = {} @classmethod def setUpClass(cls): @@ -895,9 +809,9 @@ def test_tx_hook_on_wrong_safety_mode(self): @add_regen_tests class PandaCarSafetyTest(PandaSafetyTest): - STANDSTILL_THRESHOLD: Optional[float] = None + STANDSTILL_THRESHOLD: float | None = None GAS_PRESSED_THRESHOLD = 0 - RELAY_MALFUNCTION_ADDRS: Optional[Dict[int, Tuple[int, ...]]] = None + RELAY_MALFUNCTION_ADDRS: dict[int, tuple[int, ...]] | None = None @classmethod def setUpClass(cls): diff --git a/tests/safety/hyundai_common.py b/tests/safety/hyundai_common.py index 3fd36a0e1a..da18671af5 100644 --- a/tests/safety/hyundai_common.py +++ b/tests/safety/hyundai_common.py @@ -1,4 +1,3 @@ -from typing import Tuple import unittest import panda.tests.safety.common as common @@ -77,8 +76,8 @@ def test_sampling_cruise_buttons(self): class HyundaiLongitudinalBase(common.LongitudinalAccelSafetyTest): # pylint: disable=no-member,abstract-method - DISABLED_ECU_UDS_MSG: Tuple[int, int] - DISABLED_ECU_ACTUATION_MSG: Tuple[int, int] + DISABLED_ECU_UDS_MSG: tuple[int, int] + DISABLED_ECU_ACTUATION_MSG: tuple[int, int] @classmethod def setUpClass(cls): diff --git a/tests/safety/test_ford.py b/tests/safety/test_ford.py index 14e656b88e..1be3a273cc 100755 --- a/tests/safety/test_ford.py +++ b/tests/safety/test_ford.py @@ -215,11 +215,11 @@ def test_rx_hook(self): self.assertEqual(quality_flag, self._rx(to_push)) self.assertEqual(quality_flag, self.safety.get_controls_allowed()) - # Mess with checksum to make it fail - to_push[0].data[1] = 0 # Speed 2 checksum + # Mess with checksum to make it fail, checksum is not checked for 2nd speed to_push[0].data[3] = 0 # Speed checksum & half of yaw signal - self.assertFalse(self._rx(to_push)) - self.assertFalse(self.safety.get_controls_allowed()) + should_rx = msg == "speed_2" and quality_flag + self.assertEqual(should_rx, self._rx(to_push)) + self.assertEqual(should_rx, self.safety.get_controls_allowed()) def test_rx_hook_speed_mismatch(self): # Ford relies on speed for driver curvature limiting, so it checks two sources diff --git a/tests/safety/test_gm.py b/tests/safety/test_gm.py index 587aa3f1cf..c6c5ac6b3a 100755 --- a/tests/safety/test_gm.py +++ b/tests/safety/test_gm.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 import unittest -from typing import Dict, List from panda import Panda from panda.tests.libpanda import libpanda_py import panda.tests.safety.common as common @@ -145,10 +144,9 @@ def _button_msg(self, buttons): class TestGmAscmSafety(GmLongitudinalBase, TestGmSafetyBase): TX_MSGS = [[0x180, 0], [0x409, 0], [0x40A, 0], [0x2CB, 0], [0x370, 0], # pt bus [0xA1, 1], [0x306, 1], [0x308, 1], [0x310, 1], # obs bus - [0x315, 2], # ch bus - [0x104c006c, 3], [0x10400060, 3]] # gmlan - FWD_BLACKLISTED_ADDRS: Dict[int, List[int]] = {} - FWD_BUS_LOOKUP: Dict[int, int] = {} + [0x315, 2]] # ch bus + FWD_BLACKLISTED_ADDRS: dict[int, list[int]] = {} + FWD_BUS_LOOKUP: dict[int, int] = {} BRAKE_BUS = 2 MAX_GAS = 3072 diff --git a/tests/safety/test_honda.py b/tests/safety/test_honda.py index d12ba55a22..6808f3218c 100755 --- a/tests/safety/test_honda.py +++ b/tests/safety/test_honda.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import unittest import numpy as np -from typing import Optional from panda import Panda from panda.tests.libpanda import libpanda_py @@ -25,8 +24,6 @@ class Btn: # * Nidec # * normal (PCM-enable) # * alt SCM messages (PCM-enable) -# * gas interceptor (button-enable) -# * gas interceptor with alt SCM messages (button-enable) # * Bosch # * Bosch with Longitudinal Support # * Bosch Radarless @@ -170,9 +167,9 @@ def test_buttons(self): class HondaBase(common.PandaCarSafetyTest): MAX_BRAKE = 255 - PT_BUS: Optional[int] = None # must be set when inherited - STEER_BUS: Optional[int] = None # must be set when inherited - BUTTONS_BUS: Optional[int] = None # must be set when inherited, tx on this bus, rx on PT_BUS + PT_BUS: int | None = None # must be set when inherited + STEER_BUS: int | None = None # must be set when inherited + BUTTONS_BUS: int | None = None # must be set when inherited, tx on this bus, rx on PT_BUS STANDSTILL_THRESHOLD = 0 RELAY_MALFUNCTION_ADDRS = {0: (0xE4, 0x194)} # STEERING_CONTROL @@ -353,21 +350,6 @@ def test_disable_control_allowed_from_cruise(self): pass -class TestHondaNidecGasInterceptorSafety(common.GasInterceptorSafetyTest, HondaButtonEnableBase, TestHondaNidecSafetyBase): - """ - Covers the Honda Nidec safety mode with a gas interceptor, switches to a button-enable car - """ - - TX_MSGS = HONDA_N_COMMON_TX_MSGS + [[0x200, 0]] - INTERCEPTOR_THRESHOLD = 492 - - def setUp(self): - self.packer = CANPackerPanda("honda_civic_touring_2016_can_generated") - self.safety = libpanda_py.libpanda - self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, Panda.FLAG_HONDA_GAS_INTERCEPTOR) - self.safety.init_tests() - - class TestHondaNidecPcmAltSafety(TestHondaNidecPcmSafety): """ Covers the Honda Nidec safety mode with alt SCM messages @@ -390,33 +372,6 @@ def _button_msg(self, buttons, main_on=False, bus=None): return self.packer.make_can_msg_panda("SCM_BUTTONS", bus, values) -class TestHondaNidecAltGasInterceptorSafety(common.GasInterceptorSafetyTest, HondaButtonEnableBase, TestHondaNidecSafetyBase): - """ - Covers the Honda Nidec safety mode with alt SCM messages and gas interceptor, switches to a button-enable car - """ - - TX_MSGS = HONDA_N_COMMON_TX_MSGS + [[0x200, 0]] - INTERCEPTOR_THRESHOLD = 492 - - def setUp(self): - self.packer = CANPackerPanda("acura_ilx_2016_can_generated") - self.safety = libpanda_py.libpanda - self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, Panda.FLAG_HONDA_NIDEC_ALT | Panda.FLAG_HONDA_GAS_INTERCEPTOR) - self.safety.init_tests() - - def _acc_state_msg(self, main_on): - values = {"MAIN_ON": main_on, "COUNTER": self.cnt_acc_state % 4} - self.__class__.cnt_acc_state += 1 - return self.packer.make_can_msg_panda("SCM_BUTTONS", self.PT_BUS, values) - - def _button_msg(self, buttons, main_on=False, bus=None): - bus = self.PT_BUS if bus is None else bus - values = {"CRUISE_BUTTONS": buttons, "MAIN_ON": main_on, "COUNTER": self.cnt_button % 4} - self.__class__.cnt_button += 1 - return self.packer.make_can_msg_panda("SCM_BUTTONS", bus, values) - - - # ********************* Honda Bosch ********************** diff --git a/tests/safety/test_subaru.py b/tests/safety/test_subaru.py index 61d3d9183e..7d07f79aaf 100755 --- a/tests/safety/test_subaru.py +++ b/tests/safety/test_subaru.py @@ -129,7 +129,7 @@ class TestSubaruLongitudinalSafetyBase(TestSubaruSafetyBase, common.Longitudinal MAX_POSSIBLE_BRAKE = 2**16 MIN_RPM = 0 - MAX_RPM = 2400 + MAX_RPM = 3600 MAX_POSSIBLE_RPM = 2**13 FWD_BLACKLISTED_ADDRS = {2: [SubaruMsg.ES_LKAS, SubaruMsg.ES_Brake, SubaruMsg.ES_Distance, diff --git a/tests/safety/test_tesla.py b/tests/safety/test_tesla.py index 0b425ae19a..9461ff68f9 100755 --- a/tests/safety/test_tesla.py +++ b/tests/safety/test_tesla.py @@ -108,6 +108,17 @@ def test_acc_buttons(self): self.assertEqual(tx, should_tx) +class TestTeslaRavenSteeringSafety(TestTeslaSteeringSafety): + def setUp(self): + self.packer = CANPackerPanda("tesla_can") + self.safety = libpanda_py.libpanda + self.safety.set_safety_hooks(Panda.SAFETY_TESLA, Panda.FLAG_TESLA_RAVEN) + self.safety.init_tests() + + def _angle_meas_msg(self, angle: float): + values = {"EPAS_internalSAS": angle} + return self.packer.make_can_msg_panda("EPAS3P_sysStatus", 2, values) + class TestTeslaLongitudinalSafety(TestTeslaSafety): def setUp(self): raise unittest.SkipTest diff --git a/tests/safety/test_toyota.py b/tests/safety/test_toyota.py index 0743c67e83..80bf9ce9a1 100755 --- a/tests/safety/test_toyota.py +++ b/tests/safety/test_toyota.py @@ -14,7 +14,6 @@ [0x128, 1], [0x141, 1], [0x160, 1], [0x161, 1], [0x470, 1], # DSU bus 1 [0x411, 0], # PCS_HUD [0x750, 0]] # radar diagnostic address -GAS_INTERCEPTOR_TX_MSGS = [[0x200, 0]] class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.LongitudinalAccelSafetyTest): @@ -127,32 +126,6 @@ def test_rx_hook(self): self.assertFalse(self.safety.get_controls_allowed()) -class TestToyotaSafetyGasInterceptorBase(common.GasInterceptorSafetyTest, TestToyotaSafetyBase): - - TX_MSGS = TOYOTA_COMMON_TX_MSGS + TOYOTA_COMMON_LONG_TX_MSGS + GAS_INTERCEPTOR_TX_MSGS - INTERCEPTOR_THRESHOLD = 805 - - def setUp(self): - super().setUp() - self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, self.safety.get_current_safety_param() | - Panda.FLAG_TOYOTA_GAS_INTERCEPTOR) - self.safety.init_tests() - - def test_stock_longitudinal(self): - # If stock longitudinal is set, the gas interceptor safety param should not be respected - self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, self.safety.get_current_safety_param() | - Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL) - self.safety.init_tests() - - # Spot check a few gas interceptor tests: (1) reading interceptor, - # (2) behavior around interceptor, and (3) txing interceptor msgs - for test in (self.test_prev_gas_interceptor, self.test_disengage_on_gas_interceptor, - self.test_gas_interceptor_safety_check): - with self.subTest(test=test.__name__): - with self.assertRaises(AssertionError): - test() - - class TestToyotaSafetyTorque(TestToyotaSafetyBase, common.MotorTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest): MAX_RATE_UP = 15 @@ -175,10 +148,6 @@ def setUp(self): self.safety.init_tests() -class TestToyotaSafetyTorqueGasInterceptor(TestToyotaSafetyGasInterceptorBase, TestToyotaSafetyTorque): - pass - - class TestToyotaSafetyAngle(TestToyotaSafetyBase, common.AngleSteeringSafetyTest): # Angle control limits @@ -292,10 +261,6 @@ def test_angle_measurements(self): self.assertEqual(self.safety.get_angle_meas_max(), 0) -class TestToyotaSafetyAngleGasInterceptor(TestToyotaSafetyGasInterceptorBase, TestToyotaSafetyAngle): - pass - - class TestToyotaAltBrakeSafety(TestToyotaSafetyTorque): def setUp(self): @@ -313,10 +278,6 @@ def test_lta_steer_cmd(self): pass -class TestToyotaAltBrakeSafetyGasInterceptor(TestToyotaSafetyGasInterceptorBase, TestToyotaAltBrakeSafety): - pass - - class TestToyotaStockLongitudinalBase(TestToyotaSafetyBase): TX_MSGS = TOYOTA_COMMON_TX_MSGS diff --git a/tests/safety/test_volkswagen_pq.py b/tests/safety/test_volkswagen_pq.py index 68def8bf62..f2bc317868 100755 --- a/tests/safety/test_volkswagen_pq.py +++ b/tests/safety/test_volkswagen_pq.py @@ -69,8 +69,8 @@ def _torque_driver_msg(self, torque): return self.packer.make_can_msg_panda("Lenkhilfe_3", 0, values) # openpilot steering output torque - def _torque_cmd_msg(self, torque, steer_req=1): - values = {"LM_Offset": abs(torque), "LM_OffSign": torque < 0, "HCA_Status": 5 if steer_req else 3} + def _torque_cmd_msg(self, torque, steer_req=1, hca_status=5): + values = {"LM_Offset": abs(torque), "LM_OffSign": torque < 0, "HCA_Status": hca_status if steer_req else 3} return self.packer.make_can_msg_panda("HCA_1", 0, values) # ACC engagement and brake light switch status @@ -188,6 +188,12 @@ def test_main_switch(self): self._rx(self._motor_5_msg(main_switch=False)) self.assertFalse(self.safety.get_controls_allowed(), "controls allowed after ACC main switch off") + def test_torque_cmd_enable_variants(self): + # The EPS rack accepts either 5 or 7 for an enabled status, with different low speed tuning behavior + self.safety.set_controls_allowed(1) + for enabled_status in (5, 7): + self.assertTrue(self._tx(self._torque_cmd_msg(self.MAX_RATE_UP, steer_req=1, hca_status=enabled_status)), + f"torque cmd rejected with {enabled_status=}") if __name__ == "__main__": unittest.main() diff --git a/tests/som/on-device.py b/tests/som/on-device.py index f88d5a99bb..421271d6a8 100755 --- a/tests/som/on-device.py +++ b/tests/som/on-device.py @@ -16,8 +16,8 @@ flag_set = True # shutdown when told - dt = p.get_datetime() - if dt.year == 2040 and dt.month == 8: + ch = p.can_health(0) + if ch['can_data_speed'] == 1000: os.system("sudo poweroff") except Exception as e: print(str(e)) diff --git a/tests/som/test_bootkick.py b/tests/som/test_bootkick.py index 6c08e1a844..98d3f95b80 100644 --- a/tests/som/test_bootkick.py +++ b/tests/som/test_bootkick.py @@ -1,6 +1,5 @@ import time import pytest -import datetime from panda import Panda, PandaJungle @@ -19,7 +18,7 @@ def pj(): yield jungle - jungle.set_panda_power(False) + #jungle.set_panda_power(False) jungle.close() @pytest.fixture(scope="function") @@ -86,7 +85,7 @@ def check_som_boot_flag(panda): return h['safety_mode'] == Panda.SAFETY_ELM327 and h['safety_param'] == 30 def set_som_shutdown_flag(panda): - panda.set_datetime(datetime.datetime(year=2040, month=8, day=23)) + panda.set_can_data_speed_kbps(0, 1000) def wait_for_boot(panda, jungle, reset_expected=False, bootkick=False, timeout=120): st = time.monotonic() diff --git a/tests/tucan_loopback.py b/tests/tucan_loopback.py deleted file mode 100755 index 457facdffc..0000000000 --- a/tests/tucan_loopback.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python3 - -import os -import time -import random -import argparse -from itertools import permutations - -from panda import Panda - -def get_test_string(): - return b"test" + os.urandom(10) - -def run_test(sleep_duration): - pandas = Panda.list() - print(pandas) - - if len(pandas) < 2: - raise Exception("Two pandas are needed for test") - - run_test_w_pandas(pandas, sleep_duration) - -def run_test_w_pandas(pandas, sleep_duration): - h = [Panda(x) for x in pandas] - print("H", h) - - for hh in h: - hh.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - - # test both directions - for ho in permutations(list(range(len(h))), r=2): - print("***************** TESTING", ho) - - panda0, panda1 = h[ho[0]], h[ho[1]] - - # **** test health packet **** - print("health", ho[0], h[ho[0]].health()) - - # **** test can line loopback **** - # for bus, gmlan in [(0, None), (1, False), (2, False), (1, True), (2, True)]: - for bus, gmlan in [(0, None), (1, None)]: - print("\ntest can", bus) - # flush - cans_echo = panda0.can_recv() - cans_loop = panda1.can_recv() - - if gmlan is not None: - panda0.set_gmlan(gmlan, bus) - panda1.set_gmlan(gmlan, bus) - - # send the characters - # pick addresses high enough to not conflict with honda code - at = random.randint(1024, 2000) - st = get_test_string()[0:8] - panda0.can_send(at, st, bus) - time.sleep(0.1) - - # check for receive - cans_echo = panda0.can_recv() - cans_loop = panda1.can_recv() - - print("Bus", bus, "echo", cans_echo, "loop", cans_loop) - - assert len(cans_echo) == 1 - assert len(cans_loop) == 1 - - assert cans_echo[0][0] == at - assert cans_loop[0][0] == at - - assert cans_echo[0][2] == st - assert cans_loop[0][2] == st - - assert cans_echo[0][3] == 0x80 | bus - if cans_loop[0][3] != bus: - print("EXPECTED %d GOT %d" % (bus, cans_loop[0][3])) - assert cans_loop[0][3] == bus - - print("CAN pass", bus, ho) - time.sleep(sleep_duration) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("-n", type=int, help="Number of test iterations to run") - parser.add_argument("-sleep", type=int, help="Sleep time between tests", default=0) - args = parser.parse_args() - - if args.n is None: - while True: - run_test(sleep_duration=args.sleep) - else: - for _ in range(args.n): - run_test(sleep_duration=args.sleep) diff --git a/tests/usbprotocol/test_comms.py b/tests/usbprotocol/test_comms.py index c08551b709..8efefef7ca 100755 --- a/tests/usbprotocol/test_comms.py +++ b/tests/usbprotocol/test_comms.py @@ -8,7 +8,7 @@ lpp = libpanda_py.libpanda CHUNK_SIZE = USBPACKET_MAX_SIZE -TX_QUEUES = (lpp.tx1_q, lpp.tx2_q, lpp.tx3_q, lpp.txgmlan_q) +TX_QUEUES = (lpp.tx1_q, lpp.tx2_q, lpp.tx3_q) def unpackage_can_msg(pkt): @@ -33,7 +33,7 @@ def setUp(self): lpp.comms_can_reset() def test_tx_queues(self): - for bus in range(4): + for bus in range(len(TX_QUEUES)): message = (0x100, 0, b"test", bus) can_pkt_tx = libpanda_py.make_CANPacket(message[0], message[3], message[2])