Skip to content

Fixed detection and upload of driver for Mark 2 device#24

Open
builderjer wants to merge 7 commits into
devfrom
fix/mark2
Open

Fixed detection and upload of driver for Mark 2 device#24
builderjer wants to merge 7 commits into
devfrom
fix/mark2

Conversation

@builderjer

@builderjer builderjer commented Aug 17, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Bug Fixes

    • Improved compatibility with newer Linux kernels.
    • Corrected SJ201 HID boot image and made button overlay selection board-aware (Raspberry Pi 5 vs others).
    • Fixed ReSpeaker 4‑Mic detection path and made i2c device selection/write more robust with directory checks and clearer error messages.
    • Adjusted HiFiBerry Pro handling to better enable headphone jack support.
  • Refactor

    • Simplified kernel-version checks and removed unused helper routines.

@coderabbitai

coderabbitai Bot commented Aug 17, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Removed kernel-version helper functions and replaced them with an early-captured kernel string; updated SJ201 boot image and made SJ201 button overlay board-aware; adjusted ReSpeaker/HiFiBerry/4-mic detection and i2c_device_name handling; hardened writing of detected device to /etc/OpenVoiceOS/i2c_platform.

Changes

Cohort / File(s) Summary
Kernel/version handling
ovos-i2csound
Removed sort_version() and compare_kernel_version(); capture uname -r into current_kernel and replace helper calls with inline regex checks (e.g., [[ $current_kernel =~ "6.6." ]]).
SJ201 updates
ovos-i2csound
Boot image changed to .../xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin; button overlay selection made board-aware (sj201-buttons-overlay-pi5 for RPI5, otherwise sj201-buttons-overlay).
ReSpeaker / HiFiBerry / 4-mic blocks
ovos-i2csound
Moved i2c_device_name assignment into correct conditional blocks; added unconditional hifiberry-dacplus-pro overlay path and separate block to enable headphone jack when HIFIBERRYAMP is true; duplicated HIFIBERRYPRO application path present.
Write-to-file robustness
ovos-i2csound
Final write to /etc/OpenVoiceOS/i2c_platform now only occurs when i2c_device_name is set; checks target directory exists and emits explicit errors on missing dir or write failure.
Comments & formatting
ovos-i2csound
Minor formatting/indentation tweaks and added/adjusted comments around Mark 2 / VocalFusion sections; no functional changes beyond the above.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Script as ovos-i2csound
  participant Kernel
  participant HW as I2C_Devices
  participant FS as /etc/OpenVoiceOS

  User->>Script: run detection/config script
  Script->>Kernel: uname -r -> current_kernel
  Script->>HW: probe devices (SJ201, ReSpeaker, VocalFusion, HiFiBerry...)
  alt SJ201 detected
    Script->>HW: load boot image app_xvf3510_int_spi_boot_v4_2_0.bin
    Script->>Kernel: apply sj201 overlay (pi5 vs default)
  else Device detected (ReSpeaker/HiFiBerry/etc.)
    Script->>HW: configure device, set i2c_device_name
  end
  Script->>FS: check directory exists
  alt dir exists and i2c_device_name set
    Script->>FS: write i2c_platform file
    FS-->>Script: success/failure
  else
    Script-->>User: report missing dir or write failure
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • j1nx

Poem

"I hopped through kernels, trimmed the version line,
SJ201 boots in v4_2_0 shine.
Buttons pick Pi5 or the default way,
I set the i2c name and saved it that day.
A rabbit's small patch — then off to play." 🐰✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/mark2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
ovos-i2csound (2)

69-71: Kernel version check: simplify and de-brittle (use glob match; drop sed trimming).

The sed pattern assumes a dash followed by digits (e.g., 6.6.X-123), which doesn’t match common RPi kernels like 6.6.X-v8+ or 6.6.X+rpt—so the trimming does nothing. Since you only need to branch on 6.6.*, use a simple glob; it’s clearer and avoids regex pitfalls.

Apply this diff:

-    # Variable to hold current kernel
-    local current_kernel=$(uname -r | sed -re 's/(^[0-9]*\.[0-9]*\.[0-9]*-[0-9]*)(.*)/\1/')
+    # Variable to hold current kernel (full string, e.g. "6.6.31-v8+")
+    local current_kernel
+    current_kernel=$(uname -r)
@@
-        if [[ $current_kernel =~ "6.6." ]]; then
+        if [[ $current_kernel == 6.6.* ]]; then

Also applies to: 219-219


229-231: Guard the new firmware flash path; add fallback and error handling.

Bumping to v4_2_0 is fine, but if the firmware file or flasher isn’t present, setup will fail silently or break SJ201 init on some images. Guard it and optionally fall back to the previous v4_1_0.

Apply this diff:

-/usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+bin="/usr/libexec/xvf3510-flash"
+fw_new="/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+fw_old="/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_1_0.bin"
+if [[ -x "$bin" ]]; then
+    if [[ -f "$fw_new" ]]; then
+        "$bin" --direct "$fw_new" || echo "Warning: xvf3510-flash failed with $fw_new" >&2
+    elif [[ -f "$fw_old" ]]; then
+        echo "Warning: $fw_new not found; falling back to $fw_old" >&2
+        "$bin" --direct "$fw_old" || echo "Warning: xvf3510-flash failed with $fw_old" >&2
+    else
+        echo "Warning: Firmware not found: $fw_new or $fw_old" >&2
+    fi
+else
+    echo "Warning: xvf3510-flash not found at $bin" >&2
+fi

Follow-up checks:

  • Ensure /usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin exists on all target images.
  • Confirm whether flashing is still required on 6.6 with the xvf3510 overlay; if the overlay handles firmware, we can skip this entirely.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bcb8cd6 and 50ed58a.

📒 Files selected for processing (1)
  • ovos-i2csound (5 hunks)
🔇 Additional comments (3)
ovos-i2csound (3)

211-213: Helpful context comments.

The added Mark 2 / VocalFusion comments improve maintainability and operator understanding.


249-249: Status log placement LGTM.

“Configuring buttons” log right before overlay selection is clear and consistent with the surrounding steps.


179-179: Structural fix acknowledged.

The corrected block termination for the ReSpeaker 4-mic section looks good; i2c_device_name is set before exiting the block.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (2)
ovos-i2csound (2)

95-102: check_mark_1() was removed but is still called — this will break Mark-1 detection.

This call will fail (function/command not found), setting mk1 empty and incorrectly falling back to WM8960. Either reinstate the function or guard the call.

Minimal guard suggestion (outside the changed lines):

# Safely detect Mark-1 only if helper is available
if command -v check_mark_1 >/dev/null 2>&1; then
    mk1="$(check_mark_1)"
else
    mk1=""
fi

If Mark-1 support is intentionally dropped, remove this branch and associated amixer/dtoverlay ops to avoid misleading logs and dead code.


297-305: compare_kernel_version() usage is both undefined and syntactically wrong here.

  • The helper appears removed; this results in a runtime failure.
  • Even if present, if $(compare_kernel_version "6.1.77"); then is invalid: it tries to execute the function’s stdout as a command.

Replace with a version compare using sort -V against kernel_base derived earlier.

Suggested replacement (outside the changed lines):

# Choose overlay based on kernel version >= 6.1.77
if [[ "$(printf '%s\n' '6.1.77' "$kernel_base" | sort -V | tail -n1)" == "$kernel_base" ]]; then
    dtoverlay hifiberry-dacplus
else
    dtoverlay hifiberry-dacplus-pro
fi

If you want me to push a patch that wires this with the earlier kernel_base change, say the word.

🧹 Nitpick comments (3)
ovos-i2csound (3)

71-73: Simplify kernel capture; also derive a stable base for comparisons.

The sed trim is brittle and unnecessary. Capture uname -r as-is and derive a base version via parameter expansion for later comparisons.

Apply this diff:

-    # Variable to hold current kernel
-    local current_kernel=$(uname -r | sed -re 's/(^[0-9]*\.[0-9]*\.[0-9]*-[0-9]*)(.*)/\1/')
+    # Variables to hold current kernel full string and base (strip suffix after first '-')
+    local current_kernel="$(uname -r)"
+    local kernel_base="${current_kernel%%-*}"

221-229: Anchor the kernel check and avoid a quoted regex; use a glob against the base version.

Quoting the regex is unnecessary, and matching a literal major.minor is clearer. Also, prefer comparing against kernel_base.

Apply this diff:

-        if [[ $current_kernel =~ "6.6." ]]; then
+        if [[ $kernel_base == 6.6.* ]]; then

313-320: Optionally create the target directory before writing; keep the improved error handling.

Currently, you error out if the directory doesn’t exist. Consider creating it to make first-boot flows smoother.

Apply this diff:

-        if [[ -d "$(dirname "$i2c_device_file")" ]]; then
+        if [[ -d "$(dirname "$i2c_device_file")" ]] || mkdir -p "$(dirname "$i2c_device_file")"; then
             echo "$i2c_device_name" > "$i2c_device_file" || echo "Error: Failed to write to $i2c_device_file" >&2
         else
             echo "Error: Directory $(dirname "$i2c_device_file") does not exist" >&2
         fi

Optionally, for safer writes: write to a temp file then mv into place to reduce partial-write risks.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 50ed58a and e2af2b3.

📒 Files selected for processing (1)
  • ovos-i2csound (6 hunks)
🔇 Additional comments (3)
ovos-i2csound (3)

181-181: No functional change.

Formatting-only change (closing fi); nothing to flag.


213-216: Helpful context comments.

Clear and relevant notes around Mark 2 / VocalFusion handling.


252-256: Board-aware button overlays: LGTM.

Correct selection of sj201 button overlay for RPI5 vs others.

Comment thread ovos-i2csound
Comment on lines +231 to 234
/usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
# Initializing Texas Instruments 5806 Amplifier
/usr/bin/tas5806-init
if [[ ${detection_results[SJ201LED]} == true ]] ; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Guard firmware flashing with existence checks and actionable errors.

Hard fails here can brick the flow. Verify binary and firmware are present/executable/readable and surface a clear error.

Apply this diff:

-        /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        if [[ -x /usr/libexec/xvf3510-flash && -r /usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin ]]; then
+            /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        else
+            echo "Error: Missing xvf3510 flasher or firmware image; cannot initialize XMOS" >&2
+        fi

If you want, I can add retries/backoff or a pre-check that the xvf3510 device node is present before flashing.


🏁 Script executed:

#!/bin/bash
set -eux

# Locate the flashing call and its surrounding context
rg -nP "/usr/libexec/xvf3510-flash" -C3

# Check for existing guards around the amplifier initializer
rg -nP "tas5806-init" -C3

Length of output: 969


Add safety checks before flashing firmware

The xvf3510-flash call at ovos-i2csound:231 runs without verifying that the flasher or firmware image is present, which can hard-fail and disrupt startup. Please wrap it in an existence check with a clear error path:

• File: ovos-i2csound
• Lines: 231–234

Suggested diff:

-        /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        if [[ -x /usr/libexec/xvf3510-flash && -r /usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin ]]; then
+            /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        else
+            echo "Error: xvf3510 flasher or firmware image missing/unreadable; cannot initialize XMOS" >&2
+            exit 1
+        fi

This ensures any missing executable or firmware is caught early with an actionable message.

@JarbasAl JarbasAl requested review from goldyfruit and j1nx August 17, 2025 13:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (2)
ovos-i2csound (2)

337-345: Broken call to removed compare_kernel_version and conflicting overlay selection.

compare_kernel_version() no longer exists, so this block will fail. Additionally, a second HIFIBERRYPRO block below unconditionally applies hifiberry-dacplus-pro, causing duplicate/conflicting overlay loads.

Minimal, safe fix: remove this entire block and keep the unified block below.

-    if [[ ${detection_results[HIFIBERRYPRO]} == true ]] ; then
-        echo "Installing HiFi Berry Pro"
-        if $(compare_kernel_version "6.1.77"); then
-            dtoverlay hifiberry-dacplus
-        else
-            dtoverlay hifiberry-dacplus-pro
-        fi
-        i2c_device_name="HIFIBERRYPRO"
-    
-        if [[ ${detection_results[HIFIBERRYAMP]} == true ]] ; then
-            echo "Enabling hifi berry headphone jack"
-            /usr/sbin/i2cset -y 1 0x60 0x01 0xc0
-            /usr/sbin/i2cset -y 1 0x60 0x02 0x31
-        fi
-    fi

If you do want kernel-conditional selection here, define a small helper and use it with current_kernel:

Add near the top (after current_kernel):

ver_ge() {  # returns 0 if $1 >= $2 using version sort
  [ -n "$1" ] && [ -n "$2" ] && printf '%s\n' "$2" "$1" | sort -V -C
}

Then:

if ver_ge "$current_kernel" "6.1.77"; then
  dtoverlay hifiberry-dacplus-pro
else
  dtoverlay hifiberry-dacplus
fi

Please confirm which overlay is correct for which kernel threshold before enabling this branch.


65-98: Unresolved merge conflict in ovos-i2csound detection logic

The file ovos-i2csound still contains Git conflict markers that must be removed and the intended code path selected:

  • Location: ovos-i2csound, lines 132–136
    <<<<<<< HEAD
    #         atmega328p=$(avrdude -p atmega328p -C /etc/avrdude-gpio.conf -c linuxgpio -U signature:r:-:i -F 2>/dev/null | head -n1)
    #         if [ "${atmega328p}" == ":030000001E950F3B" ] ; then
    =======
    >>>>>>> e2af2b36e849b943e116f26380ef4f81b43737f8
    – Remove <<<<<<<, =======, >>>>>>> markers.
    – Decide whether to keep the AVR signature check or the simpler Mark 1 assignment (detection_results[MARK1]=true).

Optional reliability improvement (serial port settings):
Before echo "system.version" >&3, you may initialize the serial device for consistent behavior:

stty -F "$dev" 115200 -echo -icrnl -ixon -ixoff -brkint
♻️ Duplicate comments (1)
ovos-i2csound (1)

271-273: Guard firmware flash with existence checks and actionable errors.

Flashing unconditionally is brittle during boot. Check presence/readability of flasher and firmware; fail fast with a clear message. Also consider guarding tas5806-init similarly.

Apply:

-        /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        if [[ -x /usr/libexec/xvf3510-flash && -r /usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin ]]; then
+            /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        else
+            echo "Error: Missing xvf3510 flasher or firmware image; cannot initialize XMOS" >&2
+        fi
         # Initializing Texas Instruments 5806 Amplifier
-        /usr/bin/tas5806-init
+        if [[ -x /usr/bin/tas5806-init ]]; then
+            /usr/bin/tas5806-init
+        else
+            echo "Warning: tas5806-init not found; skipping amplifier init" >&2
+        fi
🧹 Nitpick comments (5)
ovos-i2csound (5)

106-108: Make kernel parsing robust and future-proof.

The current sed extracts “X.Y.Z-build” only if it exactly matches “digits.digits.digits-digits”. Kernel strings often include +, rpt, rc, etc. Prefer extracting just the numeric X.Y.Z reliably.

Apply:

-    local current_kernel=$(uname -r | sed -re 's/(^[0-9]*\.[0-9]*\.[0-9]*-[0-9]*)(.*)/\1/')
+    # Extract strictly the numeric part X.Y.Z from uname -r, ignoring any suffixes (+, -rpt, -v8, etc.)
+    local current_kernel="$(uname -r | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/')"

261-269: Use an exact-major.minor match for 6.6 kernels.

The regex "6.6." treats dots as “any character” in [[ =~ ]]. Escape dots and anchor to start to avoid false positives (e.g., matching “16.6.x”).

Apply:

-        if [[ $current_kernel =~ "6.6." ]]; then
+        if [[ "$current_kernel" =~ ^6\.6\. ]]; then

353-363: Consolidated HiFiBerry block looks fine; keep this single source of truth.

Post removal of the earlier conflicting block, this becomes the canonical path (overlay + optional headphone jack). Consider adding a brief comment here explaining kernel/board assumptions.


137-142: Fix log messages to avoid empty/unbound variable expansions.

$MARK1 and $WM8960 aren’t set; logs will print blanks. Use plain messages or the detected flag.

Apply:

-            echo "Mark-1 enclosure $MARK1"
+            echo "Mark-1 enclosure detected"
...
-            echo "WM8960 based 2-mic $WM8960"
+            echo "WM8960 based 2-mic detected"

109-112: Quote file paths when removing existing i2c_platform.

Minor robustness: quote the path in case of spaces; no behavioral change otherwise.

Apply:

-    if [[ -f $i2c_device_file ]]; then
-        rm -f $i2c_device_file
+    if [[ -f "$i2c_device_file" ]]; then
+        rm -f "$i2c_device_file"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e2af2b3 and 3341703.

📒 Files selected for processing (1)
  • ovos-i2csound (8 hunks)
🔇 Additional comments (1)
ovos-i2csound (1)

365-372: LGTM — safer write semantics.

Writing only when a device was detected and verifying the directory exists is a good hardening step. The fallback error messages are clear.

Comment thread ovos-i2csound Outdated
Comment thread ovos-i2csound
Comment on lines 223 to 224
if [[ ${detection_results[RESPEAKER6]} == true ]] && [[ ${detection_results[RESPEAKER4]} == true ]] ; then
echo "Installing and configuring ReSpeaker 6mic"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

6-mic ReSpeaker condition is unreachable; fix the logic.

Requiring both RESPEAKER6 and RESPEAKER4 to be true makes this block never execute. Likely intended: run when 6-mic is present and 4-mic is not.

Apply:

-    if [[ ${detection_results[RESPEAKER6]} == true ]] && [[ ${detection_results[RESPEAKER4]} == true ]] ; then
+    if [[ ${detection_results[RESPEAKER6]} == true ]] && [[ ${detection_results[RESPEAKER4]} == false ]] ; then
🤖 Prompt for AI Agents
In ovos-i2csound around lines 223-224, the conditional requires both RESPEAKER6
and RESPEAKER4 to be true making the 6-mic branch unreachable; change the logic
to run when RESPEAKER6 is true and RESPEAKER4 is not true (or simply when
RESPEAKER6 is true and RESPEAKER4 == false) so the script installs/configures
ReSpeaker 6mic only if the 6-mic is detected and the 4-mic is not present.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
ovos-i2csound (1)

332-358: Fix: removed function still referenced + duplicate HiFiBerry block.

  • compare_kernel_version was removed, but it’s still called here, causing a runtime error.
  • The HIFIBERRYPRO logic is duplicated (second block at Lines 348–358), potentially applying overlays twice.

Consolidate into a single block and drop the removed function reference. If kernel specificity is still needed, key off current_kernel; otherwise keep it simple and always use the pro overlay:

-    if [[ ${detection_results[HIFIBERRYPRO]} == true ]] ; then
-        echo "Installing HiFi Berry Pro"
-        if $(compare_kernel_version "6.1.77"); then
-            dtoverlay hifiberry-dacplus
-        else
-            dtoverlay hifiberry-dacplus-pro
-        fi
-        i2c_device_name="HIFIBERRYPRO"
-
-        if [[ ${detection_results[HIFIBERRYAMP]} == true ]] ; then
-            echo "Enabling hifi berry headphone jack"
-            /usr/sbin/i2cset -y 1 0x60 0x01 0xc0
-            /usr/sbin/i2cset -y 1 0x60 0x02 0x31
-        fi
-    fi
-
-    if [[ ${detection_results[HIFIBERRYPRO]} == true ]] ; then
-        echo "Installing HiFi Berry Pro"
-        dtoverlay hifiberry-dacplus-pro
-        i2c_device_name="HIFIBERRYPRO"
-
-        if [[ ${detection_results[HIFIBERRYAMP]} == true ]] ; then
-            echo "Enabling hifi berry headphone jack"
-            /usr/sbin/i2cset -y 1 0x60 0x01 0xc0
-            /usr/sbin/i2cset -y 1 0x60 0x02 0x31
-        fi
-    fi
+    if [[ ${detection_results[HIFIBERRYPRO]} == true ]] ; then
+        echo "Installing HiFi Berry Pro"
+        # Single, consistent overlay. If kernel-specific handling is required,
+        # derive it from current_kernel rather than using the removed compare_kernel_version().
+        dtoverlay hifiberry-dacplus-pro
+        i2c_device_name="HIFIBERRYPRO"
+        if [[ ${detection_results[HIFIBERRYAMP]} == true ]] ; then
+            echo "Enabling hifi berry headphone jack"
+            /usr/sbin/i2cset -y 1 0x60 0x01 0xc0
+            /usr/sbin/i2cset -y 1 0x60 0x02 0x31
+        fi
+    fi

If you prefer to keep version branching, I can provide a compare using sort -V or dpkg --compare-versions driven by current_kernel to avoid reintroducing helpers.

♻️ Duplicate comments (2)
ovos-i2csound (2)

218-240: 6‑mic ReSpeaker branch is unreachable due to condition.

This requires both RESPEAKER6 and RESPEAKER4 to be true. The 4‑mic branch above already runs when RESPEAKER4 is true, so this 6‑mic block will never execute.

Apply:

-    if [[ ${detection_results[RESPEAKER6]} == true ]] && [[ ${detection_results[RESPEAKER4]} == true ]] ; then
+    if [[ ${detection_results[RESPEAKER6]} == true ]] && [[ ${detection_results[RESPEAKER4]} == false ]] ; then

Optional follow‑up: convert the ReSpeaker 4/6 handling into a mutually exclusive if/elif chain to make intent explicit.


266-266: Guard XMOS firmware flashing with existence checks and actionable errors.

Calling the flasher without verifying binary/image presence can hard-fail startup.

Apply:

-        /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        if [[ -x /usr/libexec/xvf3510-flash && -r /usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin ]]; then
+            /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        else
+            echo "Error: Missing xvf3510 flasher or firmware image; cannot initialize XMOS" >&2
+        fi

If desired, I can add a pre-check for the xvf3510 device node and retries/backoff.

🧹 Nitpick comments (2)
ovos-i2csound (2)

106-108: Simplify kernel capture; the sed regex is unnecessary.

You only use a substring match later. Keeping the raw uname is simpler and avoids edge cases with distro-specific suffixes.

Apply:

-    local current_kernel=$(uname -r | sed -re 's/(^[0-9]*\.[0-9]*\.[0-9]*-[0-9]*)(.*)/\1/')
+    local current_kernel
+    current_kernel=$(uname -r)

1-17: Optional: adopt safer shell defaults for early fail/visibility.

Consider strict mode to surface failures early in hardware init steps (especially around overlays and i2c operations).

Apply near the top (after the license header):

+set -euo pipefail
+# Note: if you expect some commands to fail and continue (e.g., amixer on missing cards),
+# wrap them with `|| true` locally rather than disabling `-e` globally.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3341703 and 3f76107.

📒 Files selected for processing (1)
  • ovos-i2csound (9 hunks)
🔇 Additional comments (3)
ovos-i2csound (3)

66-98: Nice robustness on Mark 1 serial probe.

Good defensive checks (device perms), bounded read with timeout, and proper FD cleanup. This will reduce flaky detections.


256-264: LGTM: kernel-aware overlay selection for SJ201.

Switching to xvf3510 overlay for 6.6 kernels and maintaining board-aware overlays for others looks correct.


360-367: LGTM: safer write to i2c_platform.

Conditional write with dir check and explicit error message is a solid hardening.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
ovos-i2csound (2)

218-221: 6‑mic condition likely unreachable; fix the logic

Requiring both RESPEAKER6 and RESPEAKER4 to be true makes the 6‑mic branch run only when both are detected. That’s usually not intended and was raised previously.

Apply:

-    if [[ ${detection_results[RESPEAKER6]} == true ]] && [[ ${detection_results[RESPEAKER4]} == true ]] ; then
+    if [[ ${detection_results[RESPEAKER6]} == true ]] && [[ ${detection_results[RESPEAKER4]} == false ]] ; then

266-269: Guard XMOS flashing with existence checks (prevents hard failures)

This runs unconditionally and can fail if the flasher or firmware isn’t present. This was flagged earlier; please add guards and a clear error path.

-        /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        if [[ -x /usr/libexec/xvf3510-flash && -r /usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin ]]; then
+            /usr/libexec/xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_2_0.bin"
+        else
+            echo "Error: xvf3510 flasher or firmware image missing/unreadable; cannot initialize XMOS" >&2
+            exit 1
+        fi

To confirm there are no other unguarded flashing calls, you can run:

#!/usr/bin/env bash
rg -n -C2 -F "/usr/libexec/xvf3510-flash"
🧹 Nitpick comments (3)
ovos-i2csound (3)

106-108: Make kernel detection robust and intent-revealing

String-substring matching on the full uname -r can be brittle. Extract major.minor once and compare explicitly.

-    # Variable to hold current kernel
-    local current_kernel=$(uname -r | sed -re 's/(^[0-9]*\.[0-9]*\.[0-9]*-[0-9]*)(.*)/\1/')
+    # Extract major.minor (e.g., "6.6" from "6.6.31-v8+")
+    local kernel_mm="$(uname -r | sed -E 's/^([0-9]+)\.([0-9]+).*/\1.\2/')"

256-259: Use the extracted major.minor for the kernel check

Follow-up to the previous comment so the condition reflects the intended match on major.minor.

-        if [[ $current_kernel =~ "6.6." ]]; then
+        if [[ "$kernel_mm" == "6.6" ]]; then

344-351: Create the target directory and fail fast on write errors

Instead of only warning when the directory is missing, create it and ensure the write either succeeds or fails loudly.

-        if [[ -d "$(dirname "$i2c_device_file")" ]]; then
-            echo "$i2c_device_name" > "$i2c_device_file" || echo "Error: Failed to write to $i2c_device_file" >&2
-        else
-            echo "Error: Directory $(dirname "$i2c_device_file") does not exist" >&2
-        fi
+        dir="$(dirname "$i2c_device_file")"
+        mkdir -p "$dir" || { echo "Error: Failed to create $dir" >&2; exit 1; }
+        echo "$i2c_device_name" > "$i2c_device_file" || { echo "Error: Failed to write to $i2c_device_file" >&2; exit 1; }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3f76107 and f94bc48.

📒 Files selected for processing (1)
  • ovos-i2csound (8 hunks)
🔇 Additional comments (2)
ovos-i2csound (2)

191-216: ReSpeaker 4-mic path looks correct

Overlay + mixer init sequence and setting i2c_device_name="RESPEAKER4" inside the block is appropriate.


287-291: Board-aware button overlay selection looks good

Selecting sj201-buttons-overlay-pi5 on RPI5 and the generic overlay otherwise is correct and clear.

Comment thread ovos-i2csound
Comment on lines 89 to +91
# Cleanup
exec 3>&-

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Close both ends of FD 3 to avoid a persistent TTY handle leak

exec 3<>"$dev" opens FD 3 for read+write, but only the write end is closed. This leaks the read end and can hold the serial device open past function scope.

Apply this diff:

-    exec 3>&-
+    # Close both read and write ends of FD 3
+    exec 3>&- 3<&-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Cleanup
exec 3>&-
# Cleanup
# Close both read and write ends of FD 3
exec 3>&- 3<&-
🤖 Prompt for AI Agents
In ovos-i2csound around lines 89 to 91, the cleanup currently only closes FD 3's
write end which leaks the read end and can keep the TTY open; after using exec
3<>"$dev" explicitly close both ends of FD 3 (close the read and write
descriptors) — e.g. perform both the write-close and read-close (exec 3>&- and
exec 3<&- or a combined close) in the cleanup section so the serial device is
fully released.

@builderjer

Copy link
Copy Markdown
Collaborator Author

Resolves #18

Note: This is just for detection and setup. Drivers still need to be installed, and the required files need to be available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant