10 Commits

Author SHA1 Message Date
Hende 8c48186d08 Update rp2040_Loader.py 2026-04-27 16:43:02 +01:00
William Henderson b7de32a0ea 1.2.0 2025-10-08 15:51:03 +01:00
William Henderson 865129b04b Mistakes... 2025-10-08 11:09:20 +01:00
William Henderson 5ce820df8d Update CHANGE LOG.txt 2025-10-08 10:55:37 +01:00
William Henderson 2f6a5b7104 V1.1.1 2025-10-08 10:51:10 +01:00
Hende 4dbfdbc9ac 1.1.1 2025-10-08 10:43:59 +01:00
William Henderson e1e80e2cbe Typo 2025-10-06 13:46:28 +01:00
William Henderson 0359342777 V1.1.0 2025-10-06 13:39:41 +01:00
William Henderson 1bf9e1779f V1.0.3 2025-07-23 22:17:21 +01:00
William Henderson e2d99380ae VS 2025-07-23 12:14:39 +01:00
25 changed files with 154 additions and 36 deletions
Binary file not shown.
@@ -5,6 +5,14 @@
{ {
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}", "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}" "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Resources\\RP2040\\main.py||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Resources\\RP2040\\main.py||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Releases\\CHANGE LOG.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Releases\\CHANGE LOG.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
} }
], ],
"DocumentGroupContainers": [ "DocumentGroupContainers": [
@@ -28,10 +36,34 @@
"RelativeDocumentMoniker": "rp2040_Loader.py", "RelativeDocumentMoniker": "rp2040_Loader.py",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py", "ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py",
"RelativeToolTip": "rp2040_Loader.py", "RelativeToolTip": "rp2040_Loader.py",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAABNAAAAAAAAAA==", "ViewState": "AgIAAHUAAAAAAAAAAAAAwKUAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|",
"WhenOpened": "2025-07-10T14:11:57.024Z", "WhenOpened": "2025-07-10T14:11:57.024Z",
"EditorCaption": "" "EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "CHANGE LOG.txt",
"DocumentMoniker": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Releases\\CHANGE LOG.txt",
"RelativeDocumentMoniker": "Releases\\CHANGE LOG.txt",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Releases\\CHANGE LOG.txt",
"RelativeToolTip": "Releases\\CHANGE LOG.txt",
"ViewState": "AgIAAAYAAAAAAAAAAAAAACUAAAA+AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
"WhenOpened": "2025-10-06T12:33:48.161Z"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "main.py",
"DocumentMoniker": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Resources\\RP2040\\main.py",
"RelativeDocumentMoniker": "Resources\\RP2040\\main.py",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Resources\\RP2040\\main.py",
"RelativeToolTip": "Resources\\RP2040\\main.py",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABEAAABqAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|",
"WhenOpened": "2025-07-23T11:07:29.706Z"
} }
] ]
} }
+33 -1
View File
@@ -5,6 +5,14 @@
{ {
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}", "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}" "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:rp2040_Loader.py||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Resources\\RP2040\\main.py||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Resources\\RP2040\\main.py||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Releases\\CHANGE LOG.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Releases\\CHANGE LOG.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
} }
], ],
"DocumentGroupContainers": [ "DocumentGroupContainers": [
@@ -28,10 +36,34 @@
"RelativeDocumentMoniker": "rp2040_Loader.py", "RelativeDocumentMoniker": "rp2040_Loader.py",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py", "ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py",
"RelativeToolTip": "rp2040_Loader.py", "RelativeToolTip": "rp2040_Loader.py",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAABNAAAAAAAAAA==", "ViewState": "AgIAAHIAAAAAAAAAAAAAwKUAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|",
"WhenOpened": "2025-07-10T14:11:57.024Z", "WhenOpened": "2025-07-10T14:11:57.024Z",
"EditorCaption": "" "EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "CHANGE LOG.txt",
"DocumentMoniker": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Releases\\CHANGE LOG.txt",
"RelativeDocumentMoniker": "Releases\\CHANGE LOG.txt",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Releases\\CHANGE LOG.txt",
"RelativeToolTip": "Releases\\CHANGE LOG.txt",
"ViewState": "AgIAAAYAAAAAAAAAAAAAACUAAAA+AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
"WhenOpened": "2025-10-06T12:33:48.161Z"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "main.py",
"DocumentMoniker": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Resources\\RP2040\\main.py",
"RelativeDocumentMoniker": "Resources\\RP2040\\main.py",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\Resources\\RP2040\\main.py",
"RelativeToolTip": "Resources\\RP2040\\main.py",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABEAAABqAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|",
"WhenOpened": "2025-07-23T11:07:29.706Z"
} }
] ]
} }
+3 -1
View File
@@ -1,6 +1,8 @@
{ {
"ExpandedNodes": [ "ExpandedNodes": [
"" "",
"\\Resources",
"\\Resources\\RP2040"
], ],
"SelectedNode": "\\rp2040_Loader.py", "SelectedNode": "\\rp2040_Loader.py",
"PreviewInSolutionExplorer": false "PreviewInSolutionExplorer": false
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+29
View File
@@ -17,3 +17,32 @@ RP2040 Loader V1.0.1 - 23/07/2025
Improvements: Improvements:
- Integrated `mpremote` into the application package to support mp file uploads without requiring external installation - Integrated `mpremote` into the application package to support mp file uploads without requiring external installation
RP2040 Loader V1.0.2 - 23/07/2025
Improvements:
- Added logging to see which files get uploaded or skipped (if unchanged)
Bug Fixes:
- Fixed `mpremote`
RP Loader V1.1.0 - 06/10/2025
Improvements:
- Added support for the RP2350-ETH (Pico 2 platform)
RP Loader V1.1.1 - 08/10/2025
Improvements:
- Included the firmware for the RP2350-ETH (Pico 2 platform) in the Firmware folder
- Updated firmwares to latest version of MicroPython (V1.26.1)
- Removed various unnecessary parts of the program to make it even faster to run :)
Bug Fixes:
- Fixed support for the RP2350-ETH (Pico 2 platform)
RP Loader V1.2.0 - 08/10/2025
Improvements:
- Automatic reset of the microcontroller once the code is loaded
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-7
View File
@@ -5,7 +5,6 @@ from ch9120 import CH9120
import ujson import ujson
import math import math
start_time = time.time()
# --- CH9120 Network Configuration --- # --- CH9120 Network Configuration ---
MODE = 0 MODE = 0
@@ -135,12 +134,6 @@ def update_ip_configuration(ip, gateway, subnet):
save_network_config(ip, gateway, subnet) save_network_config(ip, gateway, subnet)
def get_uptime():
seconds = int(time.time() - start_time)
hrs = seconds // 3600
mins = (seconds % 3600) // 60
secs = seconds % 60
return f"{hrs:02d}:{mins:02d}:{secs:02d}"
def main(): def main():
ch9120_configure() ch9120_configure()
+55 -25
View File
@@ -1,10 +1,14 @@
import os import os
import json import json
import subprocess import subprocess
import time
import tkinter as tk import tkinter as tk
from tkinter import ttk from tkinter import ttk
from tkinter import filedialog, messagebox from tkinter import filedialog, messagebox
import serial.tools.list_ports import serial.tools.list_ports
import sys
from mpremote.main import main as mpremote_main
class RP2040UploaderApp: class RP2040UploaderApp:
@@ -13,17 +17,15 @@ class RP2040UploaderApp:
self.folder_path = os.path.join(os.getcwd(), "Resources/RP2040") self.folder_path = os.path.join(os.getcwd(), "Resources/RP2040")
self.config_path = os.path.join(self.folder_path, "config.json") 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 board...")
self.label = tk.Label(master, text="Searching for RP2040...")
self.label.pack(pady=10) self.label.pack(pady=10)
self.port = self.find_rp2040_port() self.port, self.board_name = self.find_supported_port()
if self.port: if self.port:
self.label.config(text=f"RP2040 detected on {self.port}") self.label.config(text=f"{self.board_name} detected on {self.port}")
else: else:
self.label.config(text="RP2040 not found.") self.label.config(text="No supported board found.")
# Config entry fields # Config entry fields
self.ip_entry = self.create_labeled_entry("IP Address:") self.ip_entry = self.create_labeled_entry("IP Address:")
@@ -32,7 +34,13 @@ class RP2040UploaderApp:
self.load_config() 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 = 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) self.upload_button.pack(pady=10)
def create_labeled_entry(self, label_text): def create_labeled_entry(self, label_text):
@@ -44,17 +52,20 @@ class RP2040UploaderApp:
entry.pack(side=tk.RIGHT) entry.pack(side=tk.RIGHT)
return entry return entry
def find_rp2040_port(self): def find_supported_port(self):
target_vid = 0x239A # List of supported boards (VID, PID, Name)
target_pid = 0x80F2 supported_boards = [
(0x239A, 0x80F2, "RP2040"),
(0x2E8A, 0x0005, "RP2350"),
]
ports = serial.tools.list_ports.comports() ports = serial.tools.list_ports.comports()
for port in ports: for port in ports:
if port.vid == target_vid and port.pid == target_pid: for vid, pid, name in supported_boards:
return port.device if port.vid == vid and port.pid == pid:
return port.device, name
return None
return None, None
def load_config(self): def load_config(self):
if os.path.isfile(self.config_path): if os.path.isfile(self.config_path):
@@ -94,31 +105,50 @@ class RP2040UploaderApp:
if os.path.isfile(full_path): if os.path.isfile(full_path):
self.label.config(text=f"Uploading {filename}...") self.label.config(text=f"Uploading {filename}...")
self.master.update() 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: # Save original sys.argv and replace it with mpremote-style args
original_argv = sys.argv
sys.argv = ["mpremote", "connect", self.port, "fs", "cp", full_path, f":{filename}"]
try:
mpremote_main()
except SystemExit as e:
success = False success = False
messagebox.showerror("Upload Failed", f"Failed to upload {filename}:\n{result.stderr}") messagebox.showerror("Upload Failed", f"Failed to upload {filename} (mpremote exited with code {e.code}).")
break break
finally:
sys.argv = original_argv # Always restore original argv
if success: if success:
self.label.config(text=f"DONE")
# --- Soft reset the board ---
self.label.config(text="Resetting board...")
print("Resetting board...")
self.master.update()
original_argv = sys.argv
sys.argv = ["mpremote", "connect", self.port, "reset"]
try:
mpremote_main()
except SystemExit:
pass
finally:
sys.argv = original_argv
time.sleep(0.4)
self.label.config(text="DONE")
self.master.update() self.master.update()
messagebox.showinfo("Success", "All files uploaded successfully!") messagebox.showinfo("Success", "All files uploaded successfully!")
if __name__ == "__main__": if __name__ == "__main__":
root = tk.Tk() root = tk.Tk()
app = RP2040UploaderApp(root) app = RP2040UploaderApp(root)
root.title("RP2040 Loader V1.0.1") root.title("RP Loader V1.2.0")
root.iconbitmap(r'Resources/icon1.ico') root.iconbitmap(r'Resources/icon1.ico')
# Simply set the theme # Set the theme
root.tk.call("source", "Resources/azure.tcl") root.tk.call("source", "Resources/azure.tcl")
root.tk.call("set_theme", "dark") root.tk.call("set_theme", "dark")
@@ -129,7 +159,7 @@ if __name__ == "__main__":
# Footer label in bottom right # Footer label in bottom right
footer_frame = tk.Frame(root) footer_frame = tk.Frame(root)
footer_frame.pack(side=tk.BOTTOM, fill=tk.X) 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 = tk.Label(footer_frame, text="Made by Hendo 08/10/2025", anchor="e", justify="right", font=("TkDefaultFont", 7, "bold"))
footer_label.pack(side=tk.RIGHT, padx=10, pady=5) footer_label.pack(side=tk.RIGHT, padx=10, pady=5)
root.mainloop() root.mainloop()