Skip to content

Commit c9f2538

Browse files
authored
Merge pull request #500 from OpenVoiceOS/fix/i2c-primary-bus-detection
Tighten Mark II I2C detection on Raspberry Pi
2 parents 84b1819 + 266f5d8 commit c9f2538

3 files changed

Lines changed: 74 additions & 68 deletions

File tree

tests/bats/hardware_detection.bats

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ EOF
278278
assert_success
279279
}
280280

281-
@test "function_i2c_scan_recovers_mark2_from_installer_state_when_live_scan_misses" {
281+
@test "function_i2c_scan_does_not_restore_cached_mark2_state_when_live_scan_misses" {
282282
RASPBERRYPI_MODEL="Raspberry Pi 4"
283283
DISTRO_NAME="debian"
284284
DISTRO_VERSION_ID="13"
@@ -305,17 +305,17 @@ EOF
305305
return 0
306306
}
307307
function i2c_get() {
308-
return 1 # Live scan misses; should recover from state.
308+
return 1
309309
}
310310
export -f dtparam lsmod modprobe i2c_get
311311

312312
i2c_scan
313313
assert_equal "$?" "0"
314314

315-
has_detected_device "tas5806"
316-
assert_equal "$?" "0"
317-
assert_equal "$DISPLAY_SERVER" "eglfs"
318-
assert_equal "$CHANNEL" "alpha"
315+
run has_detected_device "tas5806"
316+
assert_failure
317+
assert_equal "$DISPLAY_SERVER" "N/A"
318+
assert_equal "$CHANNEL" "testing"
319319

320320
rm -rf "$RUN_AS_HOME"
321321
}
@@ -370,6 +370,51 @@ EOF
370370
# Should not attempt I2C operations
371371
}
372372

373+
@test "function_i2c_scan_ignores_non_primary_bus_false_positives_by_default" {
374+
run bash -lc "
375+
source '$BATS_TEST_DIRNAME/../../utils/constants.sh'
376+
source '$BATS_TEST_DIRNAME/../../utils/common.sh'
377+
LOG_FILE=\"\$(mktemp /tmp/ovos-installer-bats.XXXXXX)\"
378+
RASPBERRYPI_MODEL='Raspberry Pi 5'
379+
I2C_BUS='1'
380+
DISTRO_NAME='debian'
381+
DISTRO_VERSION_ID='13'
382+
DISTRO_VERSION='Debian GNU/Linux 13 (trixie)'
383+
DISPLAY_SERVER='N/A'
384+
CHANNEL='testing'
385+
FEATURE_GUI='false'
386+
DETECTED_DEVICES=()
387+
388+
dtparam() { return 0; }
389+
lsmod() { return 0; }
390+
modprobe() { return 0; }
391+
i2cdetect() {
392+
printf 'i2c-bus:%s\n' \"\$3\" >>\"\$LOG_FILE\"
393+
if [[ \"\$3\" == '13' ]]; then
394+
printf '%s\n' '2f'
395+
else
396+
printf '\n'
397+
fi
398+
}
399+
export -f dtparam lsmod modprobe i2cdetect
400+
401+
i2c_scan >/dev/null
402+
if has_detected_device 'tas5806'; then
403+
printf '%s\n' 'tas5806:present'
404+
else
405+
printf '%s\n' 'tas5806:absent'
406+
fi
407+
printf 'feature_gui:%s\n' \"\$FEATURE_GUI\"
408+
printf 'channel:%s\n' \"\$CHANNEL\"
409+
grep -o 'i2c-bus:[0-9]\\+' \"\$LOG_FILE\" | sort -u
410+
"
411+
assert_success
412+
assert_output --partial "tas5806:absent"
413+
assert_output --partial "feature_gui:false"
414+
assert_output --partial "channel:testing"
415+
assert_output --partial "i2c-bus:1"
416+
}
417+
373418
@test "function_enforce_mark2_devkit_trixie_requirement_accepts_debian_trixie" {
374419
DETECTED_DEVICES=("tas5806")
375420
DISTRO_NAME="debian"

tests/bats/i2c.bats

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,26 @@ function setup() {
2828
unset i2cdetect
2929
}
3030

31+
@test "function_install_i2c_get_uses_only_primary_bus_by_default" {
32+
I2C_BUS="1"
33+
export I2C_BUS
34+
35+
function i2cdetect() {
36+
if [[ "$3" == "13" ]]; then
37+
echo "2f"
38+
else
39+
echo ""
40+
fi
41+
}
42+
export -f i2cdetect
43+
44+
run i2c_get "2f"
45+
assert_failure
46+
47+
unset i2cdetect
48+
unset I2C_BUS
49+
}
50+
3151
@test "function_install_i2c_get_falls_back_to_other_buses" {
3252
OVOS_I2C_SCAN_BUSES="1 10"
3353
export OVOS_I2C_SCAN_BUSES

utils/common.sh

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,11 +1407,11 @@ function ver() {
14071407

14081408
# Check if a specific hexadecimal address exists on the I2C bus.
14091409
# Takes an argument like "2f" which is converted to "0x2f".
1410-
# Only used when a Raspberry Pi board is detected.
1410+
# By default only the primary I2C bus is probed; additional buses must be
1411+
# explicitly requested through OVOS_I2C_SCAN_BUSES.
14111412
function i2c_get() {
14121413
local address="$1"
14131414
local bus=""
1414-
local bus_dev=""
14151415
local -a i2c_buses=()
14161416
local override_buses="${OVOS_I2C_SCAN_BUSES:-}"
14171417

@@ -1424,19 +1424,7 @@ function i2c_get() {
14241424
# Accept either comma- or space-separated values.
14251425
read -r -a i2c_buses <<<"${override_buses//,/ }"
14261426
else
1427-
if [ -n "${I2C_BUS:-}" ]; then
1428-
i2c_buses+=("$I2C_BUS")
1429-
fi
1430-
1431-
for bus_dev in /dev/i2c-*; do
1432-
[ -e "$bus_dev" ] || continue
1433-
bus="${bus_dev##*-}"
1434-
[[ "$bus" =~ ^[0-9]+$ ]] || continue
1435-
1436-
if [ "$bus" != "${I2C_BUS:-}" ]; then
1437-
i2c_buses+=("$bus")
1438-
fi
1439-
done
1427+
i2c_buses+=("${I2C_BUS:-1}")
14401428
fi
14411429

14421430
for bus in "${i2c_buses[@]}"; do
@@ -1480,15 +1468,6 @@ function i2c_scan() {
14801468
fi
14811469
done
14821470

1483-
# If the live scan does not detect any supported devices during an
1484-
# existing-install rerun, recover the last known I2C device list from
1485-
# installer state to keep Mark II/DevKit gating deterministic.
1486-
if [ "${EXISTING_INSTANCE:-false}" == "true" ] && \
1487-
! has_detected_device "atmega328p" && \
1488-
! has_detected_device "attiny1614" && \
1489-
! has_detected_device "tas5806"; then
1490-
restore_detected_devices_from_state || true
1491-
fi
14921471
echo -e "[$done_format]"
14931472
fi
14941473

@@ -1513,44 +1492,6 @@ function has_detected_device() {
15131492
return 1
15141493
}
15151494

1516-
# Restore known I2C devices from installer state when live probing did not
1517-
# detect anything (for example, re-runs after partial installs).
1518-
function restore_detected_devices_from_state() {
1519-
local run_as_home="${RUN_AS_HOME:-}"
1520-
local state_file="${INSTALLER_STATE_FILE:-}"
1521-
local cached_device=""
1522-
local restored_device="false"
1523-
1524-
if [ -z "$state_file" ]; then
1525-
if [ -z "$run_as_home" ]; then
1526-
return 1
1527-
fi
1528-
state_file="${run_as_home}/.local/state/ovos/installer.json"
1529-
fi
1530-
1531-
if [ ! -f "$state_file" ] || ! command -v jq &>>"$LOG_FILE"; then
1532-
return 1
1533-
fi
1534-
1535-
while IFS= read -r cached_device; do
1536-
case "$cached_device" in
1537-
atmega328p | attiny1614 | tas5806)
1538-
if ! has_detected_device "$cached_device"; then
1539-
DETECTED_DEVICES+=("$cached_device")
1540-
restored_device="true"
1541-
fi
1542-
;;
1543-
esac
1544-
done < <(jq -r '.i2c_devices[]? // empty' "$state_file" 2>>"$LOG_FILE")
1545-
1546-
if [ "$restored_device" == "true" ]; then
1547-
printf '%s\n' "[info] Restored detected I2C devices from installer state: ${DETECTED_DEVICES[*]}" &>>"$LOG_FILE"
1548-
return 0
1549-
fi
1550-
1551-
return 1
1552-
}
1553-
15541495
# Returns success for Mark II/DevKit family hardware (tas5806 present).
15551496
function is_mark2_or_devkit_detected() {
15561497
has_detected_device "tas5806"

0 commit comments

Comments
 (0)