Version: V1.0.0 | Author: Tom Hong | Date: 2026-04-24
A Windows GUI tool for flashing firmware and configuring FUSE bits on the ATmega4809 microcontroller via a SerialUPDI (HV UPDI Friend) programmer.
GUI running on Windows 10
| Main Window |
|---|
(connect your programmer and launch main.py) |
| # | Feature | Description |
|---|---|---|
| 1 | COM Port Detection | Auto-scans all COM ports, shows VID/PID for easy CH340E identification |
| 2 | HEX File Selection | File browser, validates file size against 48 KB Flash limit |
| 3 | FUSE Configuration | Dropdown menus for BOD, Clock, Reset Pin, EEPROM, Startup Time, Bootloader |
| 4 | Write HEX | Erase → Write → Verify in one click |
| 5 | Write FUSE | Writes each FUSE byte individually with --verify |
| 6 | Write HEX & FUSE | Full flash cycle in one click |
| 7 | Chip Erase | Erase with mandatory confirmation dialog |
| 8 | Read FUSE | Reads current FUSE values from chip and maps them back to UI dropdowns |
| 9 | FUSE Preview | Live Hex byte preview updates with every dropdown change |
| 10 | Progress Bar | Animated progress indicator during any chip operation |
| 11 | Abort Button | Force-terminates the running pymcuprog process |
| 12 | Real-time Log | Color-coded output, save to .txt file |
| Item | Specification |
|---|---|
| Programmer | HV UPDI Friend (SerialUPDI) |
| USB-UART chip | CH340E |
| Target MCU | ATmega4809 |
| Driver | CH341SER (Windows CH340 driver) |
Connection: PC → USB → CH340E → UPDI pin of ATmega4809
Download the release package from the Releases page.
ATMEGA4809_UPDI_DOWNLOAD_TOOL_V1.0.0/
├── ATMEGA4809_UPDI_DOWNLOAD_TOOL_V1.0.0.exe ← double-click to run
└── _internal/
├── pymcuprog.EXE ← bundled, no install needed
└── ...
Requirements: Python 3.10+
pip install -r requirements.txt
python main.pypip install pyinstaller
pyinstaller ATMEGA4809_UPDI_DOWNLOAD_TOOL.spec --clean -yOutput will be in dist/ATMEGA4809_UPDI_DOWNLOAD_TOOL_V1.0.0/.
| Offset | Register | Default | Description |
|---|---|---|---|
| 0x00 | WDTCFG | 0x00 | Watchdog Timer — disabled |
| 0x01 | BODCFG | 0x54 | BOD 2.6 V, Active=Enabled, Sleep=Disabled |
| 0x02 | OSCCFG | 0x02 | Internal 20 MHz oscillator |
| 0x05 | SYSCFG0 | 0xC8 | CRC=disabled, PF6=RESET pin, EESAVE=0 |
| 0x06 | SYSCFG1 | 0x07 | Startup time = 64 ms |
| 0x07 | APPEND | 0x00 | No application partition |
| 0x08 | BOOTEND | 0x00 | No bootloader partition |
SYSCFG0 bit layout:
CRCSRC[7:6]=11(fixed) |RSTPINCFG[3]|EESAVE[0]Note:
RSTPINCFGcontrols PF6 only.
The UPDI interface lives on a separate pin (PF0) and is always available regardless of this setting.
├── main.py # Entry point
├── config.py # Constants, FUSE option definitions
├── requirements.txt
├── ATMEGA4809_UPDI_DOWNLOAD_TOOL.spec # PyInstaller build config
├── gui/
│ ├── main_window.py # Main window layout
│ ├── fuse_panel.py # FUSE settings panel
│ └── log_panel.py # Log output widget
├── backend/
│ ├── burner.py # pymcuprog subprocess wrapper + abort
│ ├── fuse_calculator.py # FUSE option → byte value mapping
│ └── port_scanner.py # COM port enumeration
└── assets/ # Icons and resources
- Windows only — COM port naming and paths are Windows-specific.
- pymcuprog baud rate flag is
-c(--clk), not-b(--bytes). Mixing them causes a "115200 bytes outside boundary" error. - FUSE writes are per-byte — pymcuprog does not support batch FUSE writes; each offset is written individually.
- The portable EXE's
_internal/folder must stay alongside the.exefile.
| Package | Version | Purpose |
|---|---|---|
| customtkinter | ≥ 5.2.0 | Modern Tkinter UI |
| pyserial | ≥ 3.5 | COM port enumeration |
| pymcuprog | ≥ 3.19.0 | UPDI programming backend |
This project is licensed under the MIT License.
| Version | Date | Notes |
|---|---|---|
| V1.0.0 | 2026-04-24 | Initial release — full feature set, PyInstaller portable build |