Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion cores/rp2040/SerialUSB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "pico/mutex.h"
#include "hardware/watchdog.h"
#include "pico/unique_id.h"
#include "hardware/resets.h"

#ifndef DISABLE_USB_SERIAL
// Ensure we are installed in the USB chain
Expand Down Expand Up @@ -174,8 +175,18 @@ SerialUSB::operator bool() {
static bool _dtr = false;
static bool _rts = false;
static int _bps = 115200;
static bool _rebooting = false;
static void CheckSerialReset() {
if ((_bps == 1200) && (!_dtr)) {
__holdUpPendSV = 1; // Ensure we don't get swapped out by FreeRTOS
if (!_rebooting && (_bps == 1200) && (!_dtr)) {
_rebooting = true;
// Disable NVIC IRQ, so that we don't get bothered anymore
irq_set_enabled(USBCTRL_IRQ, false);
// Reset the whole USB hardware block
reset_block(RESETS_RESET_USBCTRL_BITS);
unreset_block(RESETS_RESET_USBCTRL_BITS);
// Delay a bit, so the PC can figure out that we have disconnected.
sleep_ms(3);
reset_usb_boot(0, 0);
while (1); // WDT will fire here
}
Expand Down
70 changes: 51 additions & 19 deletions tools/uf2conv.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,23 @@ def convert_from_hex_to_uf2(buf):
def to_str(b):
return b.decode("utf-8", "replace")

def possibly_add(p, q):
if p not in q:
if os.path.isdir(p):
if os.access(p, os.W_OK):
q.append(p)

def possibly_anydir(p, q):
if os.path.isdir(p):
if os.access(p, os.R_OK):
r = glob.glob(p + "/*")
for t in r:
possibly_add(t, q)

def possibly_any(p, q, r):
possibly_anydir(p, q)
possibly_anydir(p + r, q)

def get_drives():
drives = []
if sys.platform == "win32":
Expand All @@ -240,10 +257,6 @@ def get_drives():
"Format-Table -Property DeviceID, DriveType, Filesystem, VolumeName"],
stdin = nul)
nul.close()
except FileNotFoundError:
print("ERROR: Unable to execute powershell or wmic commands, can't continue.")
print("ERROR: Please make sure either PowerShell or WMIC is installed and in your %PATH%.")
sys.exit(1)
except:
print("Unable to build drive list");
sys.exit(1)
Expand All @@ -252,21 +265,9 @@ def get_drives():
if len(words) >= 3 and words[1] == "2" and words[2] == "FAT":
drives.append(words[0])
else:
rootpath = "/run/media"
if not os.path.isdir(rootpath):
rootpath = "/media"
if not os.path.isdir(rootpath):
rootpath = "/opt/media"
if sys.platform == "darwin":
rootpath = "/Volumes"
possibly_anydir("/Volumes", drives)
elif sys.platform == "linux":
tmp = rootpath + "/" + os.environ["USER"]
if os.path.isdir(tmp):
rootpath = tmp
for d in os.listdir(rootpath):
drives.append(os.path.join(rootpath, d))

if (len(drives) == 0) and (sys.platform == "linux"):
globexpr = "/dev/disk/by-id/usb-RPI_RP2*-part1"
rpidisk = glob.glob(globexpr)
if len(rpidisk) > 0:
Expand All @@ -281,6 +282,19 @@ def get_drives():
except Exception as ex:
print("Exception executing udisksctl. Exception: {}".format(ex))
# If it fails, no problem since it was a heroic attempt
'''
Generate a list and scan those too.
First add the usual suspects.
Then Scan a returned list.
'''
u="/" + os.environ["USER"]
possibly_anydir("/mnt", drives)
possibly_any("/media", drives, u)
possibly_any("/opt/media", drives, u)
possibly_any("/run/media", drives, u)
possibly_any("/var/run/media", drives, u)
# Add from udisksctl info?
# Add from /proc/mounts?

def has_info(d):
try:
Expand Down Expand Up @@ -351,8 +365,15 @@ def error(msg):
try:
print("Resetting " + str(args.serial))
try:
ser = serial.Serial(args.serial, 1200)
ser = serial.Serial()
ser.port = args.serial
ser.open()
ser.baudrate = 9600
ser.dtr = True
time.sleep(0.1)
ser.dtr = False
ser.baudrate = 1200
ser.close()
except:
pass # Ignore error in the case it is already in upload mode
except:
Expand Down Expand Up @@ -388,7 +409,7 @@ def error(msg):
now = time.time()
drives = []
while (time.time() - now < 10.0) and (len(drives) == 0):
time.sleep(0.5) # Avoid 100% CPU use while waiting for drive to appear
time.sleep(1.0) # Avoid 100% CPU use while waiting for drive to appear
drives = get_drives()

if args.output:
Expand All @@ -400,6 +421,17 @@ def error(msg):
print("Flashing %s (%s)" % (d, board_id(d)))
write_file(d + "/NEW.UF2", outbuf)

# Wait until serial port (if defined) re-appears, or 2s timeout unless UF2 drive direct upload
try:
if args.serial != "UF2 Board":
timeout = time.time() + 2.0
while time.time() < timeout:
if os.access(args.serial, os.W_OK):
break
time.sleep(0.2)
except:
pass


if __name__ == "__main__":
main()