From 5c1f2578efb7c25d971e53f2b8c42407602977f4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 23 Feb 2026 12:47:39 -0800 Subject: [PATCH 1/2] use vendored cppcheck from dependencies repo (#2347) --- .github/workflows/test.yaml | 14 --------- .github/workflows/update-cppcheck.yml | 41 --------------------------- pyproject.toml | 1 + tests/misra/install.sh | 18 ------------ tests/misra/test_misra.sh | 7 +---- 5 files changed, 2 insertions(+), 79 deletions(-) delete mode 100644 .github/workflows/update-cppcheck.yml delete mode 100755 tests/misra/install.sh diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 175788fa..06a69c35 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -66,12 +66,6 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v4 - - name: Cache cppcheck - id: cppcheck-cache - uses: actions/cache@v4 - with: - path: tests/misra/cppcheck - key: cppcheck-${{ hashFiles('tests/misra/*') }} - run: ./setup.sh - name: Build FW run: ${{ env.RUN }} "scons -j$(nproc)" @@ -84,16 +78,8 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v4 - - name: Cache cppcheck - id: cppcheck-cache - uses: actions/cache@v4 - with: - path: tests/misra/cppcheck - key: cppcheck-${{ hashFiles('tests/misra/*') }} - run: ./setup.sh - name: Build FW run: ${{ env.RUN }} "scons -j$(nproc)" - - name: tests/misra/install.sh - run: ${{ env.RUN }} "cd tests/misra && ./install.sh" - name: MISRA mutation tests run: ${{ env.RUN }} "cd tests/misra && pytest test_mutation.py" diff --git a/.github/workflows/update-cppcheck.yml b/.github/workflows/update-cppcheck.yml deleted file mode 100644 index 5fd4a51e..00000000 --- a/.github/workflows/update-cppcheck.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Update cppcheck - -on: - #push: - schedule: - - cron: "0 14 * * 1" # every Monday at 2am UTC (6am PST) - workflow_dispatch: - -jobs: - update-cppcheck: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - uses: actions/checkout@v4 - - name: Get latest cppcheck version - id: version - run: | - # Tags are sorted by time (newest first), so get the first version-like tag - LATEST=$(curl -fsSL "https://api.github.com/repos/danmar/cppcheck/tags?per_page=20" | \ - jq -r '.[].name' | \ - grep -E '^[0-9]+\.[0-9]+(\.[0-9]+)?$' | \ - head -n 1) - echo "vers=$LATEST" >> "$GITHUB_OUTPUT" - - name: Update VERS in install.sh - run: | - sed -i "s/^VERS=\".*\"/VERS=\"${{ steps.version.outputs.vers }}\"/" tests/misra/install.sh - grep VERS tests/misra/install.sh - - name: Create Pull Request - uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83 - with: - author: Vehicle Researcher - token: ${{ secrets.ACTIONS_CREATE_PR_PAT }} - commit-message: "[bot] Update cppcheck to ${{ steps.version.outputs.vers }}" - title: "[bot] Update cppcheck to ${{ steps.version.outputs.vers }}" - body: "See all cppcheck releases: https://github.com/danmar/cppcheck/releases" - branch: "update-cppcheck" - base: "master" - delete-branch: true - labels: bot diff --git a/pyproject.toml b/pyproject.toml index ed9d8203..1af5798a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ dev = [ "setuptools", "spidev; platform_system == 'Linux'", "gcc-arm-none-eabi @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=gcc-arm-none-eabi", + "cppcheck @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=cppcheck", ] [build-system] diff --git a/tests/misra/install.sh b/tests/misra/install.sh deleted file mode 100755 index 9c8fd385..00000000 --- a/tests/misra/install.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -: "${CPPCHECK_DIR:=$DIR/cppcheck/}" - -if [ ! -d "$CPPCHECK_DIR" ]; then - git clone https://github.com/danmar/cppcheck.git $CPPCHECK_DIR -fi - -cd $CPPCHECK_DIR - -VERS="2.16.0" -git fetch --all --tags --force -git checkout $VERS - -#make clean -make MATCHCOMPILTER=yes CXXFLAGS="-O2" -j8 diff --git a/tests/misra/test_misra.sh b/tests/misra/test_misra.sh index d7b9c6ef..5d59c1a3 100755 --- a/tests/misra/test_misra.sh +++ b/tests/misra/test_misra.sh @@ -10,12 +10,7 @@ YELLOW="\e[1;33m" RED="\e[1;31m" NC='\033[0m' -: "${CPPCHECK_DIR:=$DIR/cppcheck/}" - -# install cppcheck if missing -if [ -z "${SKIP_CPPCHECK_INSTALL}" ]; then - $DIR/install.sh -fi +: "${CPPCHECK_DIR:=$(python3 -c "import cppcheck; print(cppcheck.DIR)")}" # ensure checked in coverage table is up to date cd $DIR From 3ffe9591a7305c71f67a70355f8098c9b5d2a611 Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Wed, 25 Feb 2026 16:55:03 -0800 Subject: [PATCH 2/2] measure sound output level (#2354) * measure sound output level * average instead * this was wrong * fix calc? * try vu meter * abs per buf * more testing * debug * debug2 * debug3 * reset to 0 * fix parsing bug * fix parsing bug * this works * minor cleanup * fix misra * docs --- board/health.h | 3 ++- board/main_comms.h | 2 ++ board/main_declarations.h | 3 +++ board/stm32h7/sound.h | 23 ++++++++++++++++++++--- python/__init__.py | 5 +++-- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/board/health.h b/board/health.h index a7498118..60f12460 100644 --- a/board/health.h +++ b/board/health.h @@ -2,7 +2,7 @@ // When changing these structs, python/__init__.py needs to be kept up to date! -#define HEALTH_PACKET_VERSION 17 +#define HEALTH_PACKET_VERSION 18 struct __attribute__((packed)) health_t { uint32_t uptime_pkt; uint32_t voltage_pkt; @@ -29,6 +29,7 @@ struct __attribute__((packed)) health_t { uint16_t sbu1_voltage_mV; uint16_t sbu2_voltage_mV; uint8_t som_reset_triggered; + uint16_t sound_output_level_pkt; }; #define CAN_HEALTH_PACKET_VERSION 5 diff --git a/board/main_comms.h b/board/main_comms.h index fdcfd68f..0627bf9e 100644 --- a/board/main_comms.h +++ b/board/main_comms.h @@ -42,6 +42,8 @@ static int get_health_pkt(void *dat) { health->som_reset_triggered = bootkick_reset_triggered; + health->sound_output_level_pkt = sound_output_level; + return sizeof(*health); } diff --git a/board/main_declarations.h b/board/main_declarations.h index 52aaa6c1..19411340 100644 --- a/board/main_declarations.h +++ b/board/main_declarations.h @@ -20,3 +20,6 @@ extern bool heartbeat_disabled; // siren state extern bool siren_enabled; + +// sound +extern uint16_t sound_output_level; diff --git a/board/stm32h7/sound.h b/board/stm32h7/sound.h index f9445dde..83ba457f 100644 --- a/board/stm32h7/sound.h +++ b/board/stm32h7/sound.h @@ -12,6 +12,7 @@ __attribute__((section(".sram4"))) static uint16_t mic_tx_buf[2][MIC_TX_BUF_SIZE static uint8_t sound_idle_count; static uint8_t mic_idle_count; static uint8_t mic_buffer_count; +uint16_t sound_output_level; void sound_tick(void) { if (sound_idle_count > 0U) { @@ -19,6 +20,7 @@ void sound_tick(void) { if (sound_idle_count == 0U) { current_board->set_amp_enabled(false); register_clear_bits(&DMA1_Stream1->CR, DMA_SxCR_EN); + sound_output_level = 0U; } } @@ -72,14 +74,31 @@ static void BDMA_Channel0_IRQ_Handler(void) { // process samples (shift to 12b and bias to be unsigned) bool sound_playing = false; + uint32_t abs_sum = 0U; + for (uint16_t i=0U; i < SOUND_RX_BUF_SIZE; i += 2U) { // since we are playing mono and receiving stereo, we take every other sample - sound_tx_buf[playback_buf][i/2U] = ((sound_rx_buf[rx_buf_idx][i] + (1UL << 14)) >> 3); + uint16_t sample = ((sound_rx_buf[rx_buf_idx][i] + (1UL << 14)) >> 3) & 0xFFFU; + sound_tx_buf[playback_buf][i/2U] = sample; if (sound_rx_buf[rx_buf_idx][i] > 0U) { sound_playing = true; } + + // this assumes all audio is "zero" centered + if (sample > 0x7FFU) { + abs_sum += (uint32_t)sample - 0x7FFU; + } else { + abs_sum += 0x7FFU - (uint32_t)sample; + } } + // VU meter: fast attack, slow decay (~460ms half-life at ~96Hz ISR rate) + uint16_t level = (uint16_t)(abs_sum / (SOUND_RX_BUF_SIZE / 2U)); + if (level >= sound_output_level) { + sound_output_level = level; + } + sound_output_level -= (sound_output_level >> 6U); + // manage amp state if (sound_playing) { if (sound_idle_count == 0U) { @@ -102,8 +121,6 @@ static void BDMA_Channel0_IRQ_Handler(void) { DFSDM1_Filter0->FLTCR1 |= DFSDM_FLTCR1_RSWSTART; } mic_idle_count = SOUND_IDLE_TIMEOUT; - - sound_tick(); } void sound_init_dac(void) { diff --git a/python/__init__.py b/python/__init__.py index 52700350..4ede7517 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -118,9 +118,9 @@ class Panda: HW_TYPE_BODY = b'\xb1' CAN_PACKET_VERSION = 4 - HEALTH_PACKET_VERSION = 17 + HEALTH_PACKET_VERSION = 18 CAN_HEALTH_PACKET_VERSION = 5 - HEALTH_STRUCT = struct.Struct("