diff --git a/reset_sifive_usb.sh b/reset_sifive_usb.sh new file mode 100644 index 0000000..036999e --- /dev/null +++ b/reset_sifive_usb.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# A script to automatically find and reset the FTDI USB-to-Serial converter +# commonly used on SiFive development boards like the P550. This is useful +# when a tool like OpenOCD takes exclusive control and doesn't release the +# ttyUSB devices correctly. + +set -e + +# --- Configuration --- +# The Vendor and Product ID for the FTDI FT4232H Quad-HS USB-UART/FIFO IC. +# You can verify this for your board by running `lsusb`. +VENDOR_ID="0403" +PRODUCT_ID="6011" + +# --- Sanity Checks --- +if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run as root. Please use 'sudo'." >&2 + exit 1 +fi + +if ! [ -d /sys/bus/usb/drivers/usb ]; then + echo "Error: USB drivers not found at /sys/bus/usb/drivers/usb." >&2 + exit 1 +fi + +# --- Main Logic --- +echo "Searching for USB device with ID ${VENDOR_ID}:${PRODUCT_ID}..." + +FOUND_BUS_ID="" +for dir in /sys/bus/usb/devices/*; do + if [ -f "${dir}/idVendor" ] && [ -f "${dir}/idProduct" ]; then + if [ "$(cat "${dir}/idVendor")" == "${VENDOR_ID}" ] && [ "$(cat "${dir}/idProduct")" == "${PRODUCT_ID}" ]; then + FOUND_BUS_ID=$(basename "${dir}") + echo "Found SiFive board on USB bus ID: ${FOUND_BUS_ID}" + break + fi + fi +done + +if [ -z "${FOUND_BUS_ID}" ]; then + echo "Error: Could not find a connected SiFive board (FTDI ${VENDOR_ID}:${PRODUCT_ID})." >&2 + echo "Please ensure the board is connected." >&2 + exit 1 +fi + +echo "Resetting USB device..." + +# Unbind the device from the kernel +echo " - Unbinding driver from ${FOUND_BUS_ID}..." +echo -n "${FOUND_BUS_ID}" > /sys/bus/usb/drivers/usb/unbind + +# Give it a moment to process +sleep 1 + +# Bind the device, prompting the kernel to re-attach the driver +echo " - Binding driver to ${FOUND_BUS_ID}..." +echo -n "${FOUND_BUS_ID}" > /sys/bus/usb/drivers/usb/bind + +echo "Done. The /dev/ttyUSB* devices should reappear shortly."