Skip to content

Instantly share code, notes, and snippets.

@monkeymademe
Last active August 3, 2024 14:34
Show Gist options
  • Save monkeymademe/82a575c63ee4a52c83a5aa0f6793307b to your computer and use it in GitHub Desktop.
Save monkeymademe/82a575c63ee4a52c83a5aa0f6793307b to your computer and use it in GitHub Desktop.
import os
import time
import shutil
import subprocess
import signal
import sys
import argparse
#If the applescript stops working or you don't want the function, set enableapplescript to False
enableapplescript = True
applescript_code = '''tell application "System Events"
try
set _groups to groups of UI element 1 of scroll area 1 of group 1 of window "Notification Center" of application process "NotificationCenter"
repeat with _group in _groups
set temp to value of static text 1 of _group
if temp contains "Disk Not Ejected Properly" then
perform (first action of _group where description is "Close")
end if
end repeat
end try
end tell'''
def execute_applescript(code):
subprocess.run(['osascript', '-e', code], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def exit_gracefully(signum, frame):
# Exit the program gracefully
print("\nExiting...")
sys.exit(0)
# Register the signal handler for SIGINT (Ctrl+C)
signal.signal(signal.SIGINT, exit_gracefully)
# Create the argument parser
parser = argparse.ArgumentParser(description='Pico Firmware Flasher')
parser.add_argument('uf2_file_path', metavar='PATH', type=str, help='PATH: location of a uf2 formatted flash file')
parser.add_argument('-v', '--volume_path', type=str, help='Path to the volume (optional)')
# Parse the command-line arguments
args = parser.parse_args()
# Check if the uf2_file_path argument is provided
if not args.uf2_file_path:
parser.error("uf2 file location is missing.")
# Check if the volume_path argument is provided, otherwise use the default value
if args.volume_path:
volume_path = args.volume_path
else:
volume_path = "/Volumes/RPI-RP2"
# Print the initial message
print("Press CTRL+C to exit - Warning: Exiting while flashing a Pico could damage the Pico.")
# Loop indefinitely
while True:
# Check if the RP2 drive is available
if os.path.exists(volume_path):
print("Pico detected - Attempting to write firmware")
try:
# Copy the UF2 file to the RP2 drive
shutil.copy2(args.uf2_file_path, volume_path)
# Wait for the copy operation to complete before printing the message
with open(os.path.join(volume_path, os.path.basename(args.uf2_file_path)), 'rb') as f:
os.fsync(f.fileno())
# Print a message indicating that the firmware has been installed
print("Firmware installed - Rebooting Pico")
except PermissionError:
print("Permission Error: Unable to copy firmware to the Pico. Please reconnect the Pico and try again.")
except FileNotFoundError:
print("Error: UF2 file not found. Please check the file location.")
except Exception as e:
if str(e) == "[Errno 2] No such file or directory: '{}'".format(volume_path):
print("Error: Volume path '{}' not found. Please check the volume path.".format(volume_path))
else:
print("Unknown Error: {}".format(e))
# Wait for 5 seconds before checking again
time.sleep(5)
if enableapplescript:
execute_applescript(applescript_code)
time.sleep(5)
@monkeymademe
Copy link
Author

monkeymademe commented Jun 16, 2023

Revision 3

Massive rewrite

  • Arguments: now you have to tell the script where the u2f file is without editing the script - but the volume path is optional
  • AppleScript that will close the Disk was not ejected notifications cause no one likes those - Tested only on Ventura - function runs every 5 seconds
  • Ability to disable AppleScript so you don't need to rewrite chunks of code
  • Parsing some errors I found
  • Basic device detection (really seeing the volume is there)

@TheTrainGoes
Copy link

@monkeymademe this is fantastic! Saving me a ton of time while I flash about 350 boards.

Do you have a tip jar?

@monkeymademe
Copy link
Author

@monkeymademe this is fantastic! Saving me a ton of time while I flash about 350 boards.

Do you have a tip jar?

Woah what you doing with 350 boards! Glad this script helps. Actually I don't have a tip jar setup but I run a Raspberry Jam in Berlin and welcome donations via pay pal - raspberryjamberlin@gmail.com if that works

@TheTrainGoes
Copy link

I'm using this to make my life easier flashing firmware onto the RP2040 Advanced Breakout Board for the GP2040-CE project.

@monkeymademe
Copy link
Author

I'm using this to make my life easier flashing firmware onto the RP2040 Advanced Breakout Board for the GP2040-CE project.

Nice! tomorrow is a Jam so I will take a look after (bandwidth is low with Jams being tomorrow) One thing I will say I will make a simple windows version of this script for those that are Macless. So if you need windows I'll linky a file next week.

@monkeymademe
Copy link
Author

For the windows users here is the counterpart to this script pico-autoflash-windows.py

It works and functions the same way just a little simpler as we don't need to remove the Drive was not ejected messages that are on windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment