Files
RP2040_UPS_Loader/rp2040_Loader.py
T
William Henderson 001014099f V1.0.1
2025-07-23 11:59:43 +01:00

136 lines
4.6 KiB
Python

import os
import json
import subprocess
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox
import serial.tools.list_ports
class RP2040UploaderApp:
def __init__(self, master):
self.master = master
self.folder_path = os.path.join(os.getcwd(), "Resources/RP2040")
self.config_path = os.path.join(self.folder_path, "config.json")
self.mpremote_path = os.path.join(os.getcwd(), "Resources", "mpremote.exe")
self.label = tk.Label(master, text="Searching for RP2040...")
self.label.pack(pady=10)
self.port = self.find_rp2040_port()
if self.port:
self.label.config(text=f"RP2040 detected on {self.port}")
else:
self.label.config(text="RP2040 not found.")
# Config entry fields
self.ip_entry = self.create_labeled_entry("IP Address:")
self.subnet_entry = self.create_labeled_entry("Subnet Mask:")
self.gateway_entry = self.create_labeled_entry("Gateway:")
self.load_config()
self.upload_button = ttk.Button(master, text="Upload Files", style="Accent.TButton", command=self.upload_files, state=tk.NORMAL if self.port else tk.DISABLED)
self.upload_button.pack(pady=10)
def create_labeled_entry(self, label_text):
frame = tk.Frame(self.master)
frame.pack(pady=2)
label = tk.Label(frame, text=label_text)
label.pack(side=tk.LEFT)
entry = tk.Entry(frame, width=20)
entry.pack(side=tk.RIGHT)
return entry
def find_rp2040_port(self):
target_vid = 0x239A
target_pid = 0x80F2
ports = serial.tools.list_ports.comports()
for port in ports:
if port.vid == target_vid and port.pid == target_pid:
return port.device
return None
def load_config(self):
if os.path.isfile(self.config_path):
try:
with open(self.config_path, "r") as f:
config = json.load(f)
self.ip_entry.insert(0, config.get("ip", ""))
self.subnet_entry.insert(0, config.get("subnet", ""))
self.gateway_entry.insert(0, config.get("gateway", ""))
except Exception as e:
messagebox.showerror("Error", f"Failed to read config.json:\n{e}")
else:
messagebox.showwarning("Missing File", f"No config.json found in {self.folder_path}")
def save_config(self):
config = {
"ip": self.ip_entry.get(),
"subnet": self.subnet_entry.get(),
"gateway": self.gateway_entry.get()
}
try:
with open(self.config_path, "w") as f:
json.dump(config, f, indent=4)
except Exception as e:
messagebox.showerror("Error", f"Failed to save config.json:\n{e}")
def upload_files(self):
if not os.path.isdir(self.folder_path):
messagebox.showerror("Error", f"Folder '{self.folder_path}' not found.")
return
self.save_config()
success = True
for filename in os.listdir(self.folder_path):
full_path = os.path.join(self.folder_path, filename)
if os.path.isfile(full_path):
self.label.config(text=f"Uploading {filename}...")
self.master.update()
result = subprocess.run(
[self.mpremote_path, "connect", self.port, "fs", "cp", full_path, f":{filename}"],
capture_output=True,
text=True
)
if result.returncode != 0:
success = False
messagebox.showerror("Upload Failed", f"Failed to upload {filename}:\n{result.stderr}")
break
if success:
self.label.config(text=f"DONE")
self.master.update()
messagebox.showinfo("Success", "All files uploaded successfully!")
if __name__ == "__main__":
root = tk.Tk()
app = RP2040UploaderApp(root)
root.title("RP2040 Loader V1.0.1")
root.iconbitmap(r'Resources/icon1.ico')
# Simply set the theme
root.tk.call("source", "Resources/azure.tcl")
root.tk.call("set_theme", "dark")
# Set a minsize for the window, and place it in the middle
root.update()
root.minsize(400, 200)
# Footer label in bottom right
footer_frame = tk.Frame(root)
footer_frame.pack(side=tk.BOTTOM, fill=tk.X)
footer_label = tk.Label(footer_frame, text="Made by Hendo 22/07/2025", anchor="e", justify="right", font=("TkDefaultFont", 7, "bold"))
footer_label.pack(side=tk.RIGHT, padx=10, pady=5)
root.mainloop()