Add files via upload
This commit is contained in:
parent
ffdd049589
commit
0bd86793ac
18 changed files with 3628 additions and 1 deletions
187
qmk_flash_tools/lib/device_detection.sh
Normal file
187
qmk_flash_tools/lib/device_detection.sh
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# Device Detection Library
|
||||
# =============================================================================
|
||||
# Functions for detecting and identifying RP2040 devices in bootloader mode
|
||||
# Uses HOST-side USB information (serial, port location)
|
||||
# =============================================================================
|
||||
|
||||
# ----------------------
|
||||
# Function: wait_for_rp2040
|
||||
# Wait until an RP2040 UF2 device is mounted on any of the configured paths
|
||||
# Returns the mount point
|
||||
# Usage: mount_point=$(wait_for_rp2040)
|
||||
# ----------------------
|
||||
wait_for_rp2040() {
|
||||
local usb_mount_paths=("${USB_MOUNT_PATHS[@]:-/media/$USER /run/media/$USER /mnt}")
|
||||
local rp2040_pattern="${RP2040_PATTERN:-*RP2040*}"
|
||||
local wait_interval="${USB_WAIT_INTERVAL:-0.5}"
|
||||
|
||||
echo "⏳ Waiting for RP2040 UF2 device..." >&2
|
||||
local device=""
|
||||
while true; do
|
||||
for path in "${usb_mount_paths[@]}"; do
|
||||
device=$(find "$path" -maxdepth 2 -type d -name "$rp2040_pattern" 2>/dev/null | head -n1)
|
||||
if [[ -n "$device" ]]; then
|
||||
echo "✅ Found RP2040 device at $device" >&2
|
||||
echo "$device"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
sleep "$wait_interval"
|
||||
done
|
||||
}
|
||||
|
||||
# ----------------------
|
||||
# Function: get_usb_serial_from_host
|
||||
# Get the USB serial number from the HOST system (not from the device itself)
|
||||
# This is the ONLY reliable way to identify devices when EEPROM is wiped
|
||||
# Usage: serial=$(get_usb_serial_from_host "/media/user/RPI-RP2")
|
||||
# ----------------------
|
||||
get_usb_serial_from_host() {
|
||||
local mount_point="$1"
|
||||
|
||||
if [[ -z "$mount_point" ]]; then
|
||||
echo "" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Method 1: Get the block device, then trace to USB serial
|
||||
local dev
|
||||
dev=$(findmnt -n -o SOURCE --target "$mount_point" 2>/dev/null || echo "")
|
||||
|
||||
if [[ -n "$dev" ]]; then
|
||||
local block_dev=$(basename "$dev")
|
||||
|
||||
# Try to find USB serial through sysfs
|
||||
local sys_path="/sys/class/block/$block_dev"
|
||||
|
||||
# Walk up the device tree to find the USB device
|
||||
local current_path=$(readlink -f "$sys_path/device" 2>/dev/null || echo "")
|
||||
|
||||
while [[ -n "$current_path" && "$current_path" != "/sys" ]]; do
|
||||
# Check if this directory has a serial file
|
||||
if [[ -f "$current_path/serial" ]]; then
|
||||
cat "$current_path/serial"
|
||||
return 0
|
||||
fi
|
||||
# Also check for idVendor/idProduct to confirm it's a USB device
|
||||
if [[ -f "$current_path/idVendor" ]]; then
|
||||
# Found USB device level, check for serial
|
||||
if [[ -f "$current_path/serial" ]]; then
|
||||
cat "$current_path/serial"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
# Move up one level
|
||||
current_path=$(dirname "$current_path")
|
||||
done
|
||||
fi
|
||||
|
||||
# Method 2: Use udevadm to get USB info
|
||||
if [[ -n "$dev" ]]; then
|
||||
local serial
|
||||
serial=$(udevadm info --query=property --name="$dev" 2>/dev/null | grep "ID_SERIAL_SHORT=" | cut -d'=' -f2)
|
||||
if [[ -n "$serial" ]]; then
|
||||
echo "$serial"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# No serial found
|
||||
echo ""
|
||||
return 1
|
||||
}
|
||||
|
||||
# ----------------------
|
||||
# Function: get_usb_device_path
|
||||
# Get a unique identifier based on USB physical port location
|
||||
# This persists even when serial is not available
|
||||
# Usage: usbpath=$(get_usb_device_path "/media/user/RPI-RP2")
|
||||
# ----------------------
|
||||
get_usb_device_path() {
|
||||
local mount_point="$1"
|
||||
|
||||
if [[ -z "$mount_point" ]]; then
|
||||
echo "" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local dev
|
||||
dev=$(findmnt -n -o SOURCE --target "$mount_point" 2>/dev/null || echo "")
|
||||
|
||||
if [[ -n "$dev" ]]; then
|
||||
# Get the physical USB path (bus and port numbers)
|
||||
local devpath
|
||||
devpath=$(udevadm info --query=property --name="$dev" 2>/dev/null | grep "DEVPATH=" | cut -d'=' -f2)
|
||||
if [[ -n "$devpath" ]]; then
|
||||
# Extract the USB bus and port info (e.g., /devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0)
|
||||
local usbpath=$(echo "$devpath" | grep -oP 'usb\d+/\d+-[\d.]+')
|
||||
if [[ -n "$usbpath" ]]; then
|
||||
echo "$usbpath"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
return 1
|
||||
}
|
||||
|
||||
# ----------------------
|
||||
# Function: get_device_identifier
|
||||
# Get the best available identifier for the USB device
|
||||
# Prefers USB serial, falls back to USB port location, then mount path
|
||||
# Usage: device_id=$(get_device_identifier "/media/user/RPI-RP2")
|
||||
# Returns: "serial:ABC123" or "usbpath:usb1/1-3" or "mount:RPI-RP2"
|
||||
# ----------------------
|
||||
get_device_identifier() {
|
||||
local mount_point="$1"
|
||||
|
||||
if [[ -z "$mount_point" ]]; then
|
||||
echo "Error: mount_point required" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Try to get USB serial from host (PREFERRED)
|
||||
local usb_serial
|
||||
usb_serial=$(get_usb_serial_from_host "$mount_point")
|
||||
|
||||
if [[ -n "$usb_serial" ]]; then
|
||||
echo "serial:$usb_serial"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Try USB device path (FALLBACK 1)
|
||||
local usb_path
|
||||
usb_path=$(get_usb_device_path "$mount_point")
|
||||
if [[ -n "$usb_path" ]]; then
|
||||
echo "usbpath:$usb_path"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Final fallback: use mount point basename (FALLBACK 2)
|
||||
echo "mount:$(basename "$mount_point")"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ----------------------
|
||||
# Function: print_device_info
|
||||
# Print detailed information about a detected device (for debugging)
|
||||
# Usage: print_device_info "/media/user/RPI-RP2"
|
||||
# ----------------------
|
||||
print_device_info() {
|
||||
local mount_point="$1"
|
||||
|
||||
echo "Device Information:"
|
||||
echo " Mount Point: $mount_point"
|
||||
|
||||
local serial=$(get_usb_serial_from_host "$mount_point")
|
||||
echo " USB Serial: ${serial:-[not available]}"
|
||||
|
||||
local usbpath=$(get_usb_device_path "$mount_point")
|
||||
echo " USB Path: ${usbpath:-[not available]}"
|
||||
|
||||
local device_id=$(get_device_identifier "$mount_point")
|
||||
echo " Identifier: $device_id"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue