Created
November 2, 2026 13:13
-
-
Save EmbeddedAndroid/3de51907c36ea1a2a483bed037e7fc98 to your computer and use it in GitHub Desktop.
alpaca-edl-check.sh: QTAC's Alpaca bootToEDL sequence (bit 4 + power key), lists the USB devices that appear
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Put an Alpaca (EPM) driven QRD into EDL the way Qualcomm's test automation | |
| # controller does (bootToEDL in configurations/TAC_PSOC_44.tcnf, legacy | |
| # command table in TACPSOCLegacyCommands.cpp), and report every USB device | |
| # the board brings up, so a missing serial or an unexpected port shows. | |
| # | |
| # Run on the cdba host with cdba-server NOT holding the Alpaca tty. | |
| # Usage: alpaca-edl-check.sh <alpaca tty> <edl serial> [tries] | |
| # e.g. alpaca-edl-check.sh /dev/serial/by-id/usb-QUALCOMM_Inc._Embedded_Power_Measurement__EPM__device_6E02020C040C1F14-if01 AAFD8CDA 3 | |
| # CONTROL=1 runs the same sequence without the EDL bit (expect no 9008). | |
| # PKEY_MS (1300) is QTAC's EDL power key hold; WAIT_S (15) bounds the 9008 wait. | |
| # | |
| # Alpaca outputs (fixed by the Alpaca firmware, same on every board): | |
| # devicePower 1/0 board power on/off | |
| # usbDevicePower 1/0 board USB connected/disconnected | |
| # ttl outputBit 1 power key, 1 = pressed | |
| # ttl outputBit 2 volume down (cdba's fastboot key) | |
| # ttl outputBit 4 primary EDL (force USB boot), 1 = asserted | |
| set -u | |
| tty=${1:?alpaca tty}; want=${2:?edl serial, e.g. AAFD8CDA}; tries=${3:-3} | |
| pkey_ms=${PKEY_MS:-1300}; wait_s=${WAIT_S:-15}; control=${CONTROL:-0} | |
| usb=${SYSFS_USB:-/sys/bus/usb/devices} | |
| log=$(mktemp /tmp/alpaca-edl-check.XXXXXX) | |
| if [ -n "${DRYRUN:-}" ]; then | |
| cmd() { echo "> $*"; } | |
| ms() { echo " (sleep ${1} ms)"; } | |
| else | |
| stty -F "$tty" 115200 raw -echo cs8 clocal cread || exit 1 | |
| cat "$tty" >> "$log" & reader=$! | |
| trap 'kill $reader 2>/dev/null' EXIT | |
| cmd() { printf '%s\r' "$*" > "$tty"; sleep 0.1; } | |
| ms() { sleep "$(awk "BEGIN{print $1/1000}")"; } | |
| fi | |
| # One line per Qualcomm or fastboot USB device: <port path> <vid:pid> product=.. serial=.. | |
| snapshot() { | |
| local d v p | |
| for d in "$usb"/*; do | |
| [ -r "$d/idVendor" ] || continue | |
| v=$(cat "$d/idVendor"); p=$(cat "$d/idProduct") | |
| case "$v" in 05c6|18d1) ;; *) continue ;; esac | |
| printf '%s %s:%s product=%s serial=%s\n' "${d##*/}" "$v" "$p" \ | |
| "$(cat "$d/product" 2>/dev/null || echo -)" \ | |
| "$(cat "$d/serial" 2>/dev/null || echo -)" | |
| done | sort | |
| } | |
| # EDL serial is the "_SN:<serial>" token of iProduct (qdl --serial matches the same token). | |
| edl_match() { | |
| grep ' 05c6:9008 ' | grep -i "_SN:${want}\(_\| \|\$\)" | |
| } | |
| all_off() { | |
| cmd devicePower 0 | |
| cmd usbDevicePower 0 | |
| cmd ttl outputBit 1 0 | |
| cmd ttl outputBit 2 0 | |
| cmd ttl outputBit 4 0 | |
| } | |
| boot_to_edl() { | |
| all_off | |
| [ "$control" = 1 ] || cmd ttl outputBit 4 1 | |
| ms 500 | |
| cmd devicePower 1 | |
| ms 900 | |
| cmd usbDevicePower 1 | |
| ms 30 | |
| cmd ttl outputBit 1 1 | |
| ms "$pkey_ms" | |
| cmd ttl outputBit 1 0 | |
| cmd ttl outputBit 4 0 | |
| } | |
| all_off; [ -n "${DRYRUN:-}" ] || sleep 3 | |
| before=$(snapshot) | |
| if printf '%s\n' "$before" | edl_match >/dev/null; then | |
| echo "EDL device $want is already present with the board off: another board or a stale device; stop." | |
| printf '%s\n' "$before"; exit 2 | |
| fi | |
| hits=0 | |
| for i in $(seq 1 "$tries"); do | |
| echo "== try $i/$tries ($([ "$control" = 1 ] && echo control, EDL bit not set || echo EDL bit 4 high))" | |
| boot_to_edl | |
| got=; new= | |
| for _ in $(seq 1 "$wait_s"); do | |
| [ -n "${DRYRUN:-}" ] || sleep 1 | |
| now=$(snapshot) | |
| new=$(comm -13 <(printf '%s\n' "$before") <(printf '%s\n' "$now")) | |
| got=$(printf '%s\n' "$new" | edl_match) && break | |
| done | |
| echo "new USB devices:"; printf ' %s\n' "${new:-(none)}" | |
| if [ -n "$got" ]; then | |
| echo "EDL: $got"; hits=$((hits + 1)) | |
| elif printf '%s\n' "$new" | grep -q ' 05c6:9008 '; then | |
| echo "EDL device present but without _SN:$want (see product/serial above)" | |
| else | |
| echo "no EDL device" | |
| fi | |
| all_off; [ -n "${DRYRUN:-}" ] || sleep 3 | |
| done | |
| echo "== Alpaca replies (look for 'Command not recognized'):" | |
| tr '\r' '\n' < "$log" | grep -v '^$' | sort | uniq -c | sort -rn | head -20 | |
| rm -f "$log" | |
| echo "RESULT: $hits/$tries tries reached EDL $want ($([ "$control" = 1 ] && echo control || echo bit 4))" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment