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}",
"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": [
@@ -28,10 +36,34 @@
"RelativeDocumentMoniker": "rp2040_Loader.py",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py",
"RelativeToolTip": "rp2040_Loader.py",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAABNAAAAAAAAAA==",
"ViewState": "AgIAAHUAAAAAAAAAAAAAwKUAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|",
"WhenOpened": "2025-07-10T14:11:57.024Z",
"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}",
"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": [
@@ -28,10 +36,34 @@
"RelativeDocumentMoniker": "rp2040_Loader.py",
"ToolTip": "C:\\Users\\william\\Documents\\Git\\RP2040_UPS_Loader\\rp2040_Loader.py",
"RelativeToolTip": "rp2040_Loader.py",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAABNAAAAAAAAAA==",
"ViewState": "AgIAAHIAAAAAAAAAAAAAwKUAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|",
"WhenOpened": "2025-07-10T14:11:57.024Z",
"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": [
""
"",
"\\Resources",
"\\Resources\\RP2040"
],
"SelectedNode": "\\rp2040_Loader.py",
"PreviewInSolutionExplorer": false
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+30 -1
View File
@@ -16,4 +16,33 @@ RP2040 Loader V1.0.0 - 22/07/2025
RP2040 Loader V1.0.1 - 23/07/2025
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 math
start_time = time.time()
# --- CH9120 Network Configuration ---
MODE = 0
@@ -135,12 +134,6 @@ def update_ip_configuration(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():
ch9120_configure()
+55 -25
View File
@@ -1,10 +1,14 @@
import os
import json
import subprocess
import time
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox
import serial.tools.list_ports
import sys
from mpremote.main import main as mpremote_main
class RP2040UploaderApp:
@@ -13,17 +17,15 @@ class RP2040UploaderApp:
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 = tk.Label(master, text="Searching for board...")
self.label.pack(pady=10)
self.port = self.find_rp2040_port()
self.port, self.board_name = self.find_supported_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:
self.label.config(text="RP2040 not found.")
self.label.config(text="No supported board found.")
# Config entry fields
self.ip_entry = self.create_labeled_entry("IP Address:")
@@ -32,7 +34,13 @@ class RP2040UploaderApp:
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)
def create_labeled_entry(self, label_text):
@@ -44,17 +52,20 @@ class RP2040UploaderApp:
entry.pack(side=tk.RIGHT)
return entry
def find_rp2040_port(self):
target_vid = 0x239A
target_pid = 0x80F2
def find_supported_port(self):
# List of supported boards (VID, PID, Name)
supported_boards = [
(0x239A, 0x80F2, "RP2040"),
(0x2E8A, 0x0005, "RP2350"),
]
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
for vid, pid, name in supported_boards:
if port.vid == vid and port.pid == pid:
return port.device, name
return None, None
def load_config(self):
if os.path.isfile(self.config_path):
@@ -94,31 +105,50 @@ class RP2040UploaderApp:
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:
# 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
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
finally:
sys.argv = original_argv # Always restore original argv
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()
messagebox.showinfo("Success", "All files uploaded successfully!")
if __name__ == "__main__":
root = tk.Tk()
app = RP2040UploaderApp(root)
root.title("RP2040 Loader V1.0.1")
root.title("RP Loader V1.2.0")
root.iconbitmap(r'Resources/icon1.ico')
# Simply set the theme
# Set the theme
root.tk.call("source", "Resources/azure.tcl")
root.tk.call("set_theme", "dark")
@@ -129,7 +159,7 @@ if __name__ == "__main__":
# 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 = 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)
root.mainloop()