├── .github └── workflows │ ├── stale.yml │ └── sync_issues.yml ├── .gitignore ├── README.md ├── ambd_flash_tool.exe ├── ambd_flash_tool.py ├── firmware ├── WioTerminal_USB2Serial_Burn8720.ino.bin ├── km0_boot_all.bin ├── km0_km4_image2.bin └── km4_boot_all.bin ├── imgtool_flashloader_amebad.bin ├── requirements.txt └── tool ├── linux ├── amebad_image_tool └── bossac ├── macos ├── amebad_image_tool └── bossac └── windows ├── amebad_image_tool.exe ├── bossac.exe └── cygwin1.dll /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PRs' 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '0 4 * * *' 7 | 8 | jobs: 9 | stale: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v4 15 | 16 | - name: Checkout script repository 17 | uses: actions/checkout@v4 18 | with: 19 | repository: Seeed-Studio/sync-github-all-issues 20 | path: ci 21 | 22 | - name: Run script 23 | run: ./ci/tools/stale.sh 24 | env: 25 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/workflows/sync_issues.yml: -------------------------------------------------------------------------------- 1 | name: Automate Issue Management 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - edited 8 | - assigned 9 | - unassigned 10 | - labeled 11 | - unlabeled 12 | - reopened 13 | 14 | jobs: 15 | add_issue_to_project: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Add issue to GitHub Project 19 | uses: actions/add-to-project@v1.0.2 20 | with: 21 | project-url: https://github.com/orgs/Seeed-Studio/projects/17 22 | github-token: ${{ secrets.ISSUE_ASSEMBLE }} 23 | labeled: bug 24 | label-operator: NOT -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | build/ 3 | dist/ 4 | debug.log 5 | *.spec 6 | /km0_boot_all.bin 7 | /km4_boot_all.bin 8 | /km0_km4_image2.bin 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ambd_flash_tool 2 | -------------------------------------------------------------------------------- /ambd_flash_tool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/ambd_flash_tool.exe -------------------------------------------------------------------------------- /ambd_flash_tool.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import platform 4 | import shutil 5 | import struct 6 | import re 7 | import time 8 | 9 | try: 10 | import pathlib 11 | except ImportError: 12 | print("Installing pathlib module") 13 | res = os.system("pip3 install pathlib") 14 | if res != 0: 15 | print("pathlib module installation failed") 16 | sys.exit(1) 17 | import pathlib 18 | 19 | from pathlib import Path 20 | 21 | try: 22 | import click 23 | except ImportError: 24 | print("Installing click module") 25 | res = os.system("pip3 install click") 26 | if res != 0: 27 | print("click module installation failed") 28 | sys.exit(1) 29 | import click 30 | 31 | try: 32 | import colorama 33 | except ImportError: 34 | print("Installing colorama module") 35 | res = os.system("pip3 install colorama") 36 | if res != 0: 37 | print("Colorama module installation failed") 38 | sys.exit(1) 39 | import colorama 40 | 41 | from colorama import init, Fore, Back, Style 42 | 43 | try: 44 | import serial 45 | except ImportError: 46 | print("Installing pyserial module") 47 | res = os.system("pip3 install pyserial") 48 | if res != 0: 49 | print("pyserial module installation failed") 50 | sys.exit(1) 51 | import serial 52 | 53 | if os.name == 'nt': # sys.platform == 'win32': 54 | from serial.tools.list_ports_windows import comports 55 | elif os.name == 'posix': 56 | from serial.tools.list_ports_posix import comports 57 | else: 58 | raise ImportError("Sorry: no implementation for your platform ('{}') available".format(os.name)) 59 | 60 | # List of supported board USB IDs. Each board is a tuple of unique USB vendor 61 | # ID, USB product ID. 62 | BOARD_IDS = \ 63 | [{ 64 | "name": "wio terminal", 65 | "info": ("2886", "802D"), 66 | "isbootloader": False 67 | }, 68 | { 69 | "name": "wio terminal", 70 | "info": ("2886", "002D"), 71 | "isbootloader": True 72 | }] 73 | 74 | def getAllPortInfo(): 75 | return comports(include_links=False) 76 | 77 | def getAvailableBoard(): 78 | for info in getAllPortInfo(): 79 | port, desc, hwid = info 80 | ii = hwid.find("VID:PID") 81 | #hwid: USB VID:PID=2886:002D SER=4D68990C5337433838202020FF123244 LOCATION=7-3.1.3:1. 82 | if ii != -1: 83 | for b in BOARD_IDS: 84 | (vid, pid) = b["info"] 85 | if vid == hwid[ii + 8: ii + 8 + 4] and pid == hwid[ii + 8 + 5 :ii + 8 + 5 + 4 ]: 86 | if b["isbootloader"] == True : 87 | return port, True 88 | else: 89 | return port, False 90 | return None, False 91 | 92 | def stty(port): 93 | 94 | if port == None: 95 | _port, _isbootloader = getAvailableBoard() 96 | if _port == None: 97 | print(Fore.RED + "Sorry, the device you should have is not plugged in.") 98 | sys.exit(1) 99 | else: 100 | _port = port 101 | 102 | if os.name == "posix": 103 | if platform.uname().system == "Darwin": 104 | return "stty -f " + _port + " %d" 105 | return "stty -F " + _port + " %d" 106 | elif os.name == "nt": 107 | return "MODE " + _port + ":BAUD=%d PARITY=N DATA=8" 108 | 109 | return "echo not support" 110 | 111 | def get_flash_tool(): 112 | _tool = str(Path(os.path.split(os.path.realpath(__file__))[0], 'tool')) 113 | _platform = platform.platform() 114 | if _platform.find('Windows') >= 0: 115 | _tool = str(Path(_tool, 'windows', "amebad_image_tool.exe")) 116 | elif _platform.find('Linux') >= 0: 117 | _tool = str(Path(_tool, 'linux', 'amebad_image_tool')) 118 | elif _platform.find('Darwin') >= 0: 119 | _tool = str(Path(_tool, 'macos', 'amebad_image_tool')) 120 | elif _platform.find('macOS') >= 0: 121 | _tool = str(Path(_tool, 'macos', 'amebad_image_tool')) 122 | else: 123 | _tool = "" 124 | print(Fore.RED, "No support yet!") 125 | sys.exit(1) 126 | return _tool 127 | 128 | def get_bossac_tool(): 129 | _tool = str(Path(os.path.split(os.path.realpath(__file__))[0], 'tool')) 130 | _platform = platform.platform() 131 | if _platform.find('Windows') >= 0: 132 | _tool = str(Path(_tool, 'windows', "bossac.exe")) 133 | elif _platform.find('Linux') >= 0: 134 | _tool = str(Path(_tool, 'linux', 'bossac')) 135 | elif _platform.find('Darwin') >= 0: 136 | _tool = str(Path(_tool, 'macos', 'bossac')) 137 | elif _platform.find('macOS') >= 0: 138 | _tool = str(Path(_tool, 'macos', 'bossac')) 139 | else: 140 | _tool = "" 141 | print(Fore.RED, "No support yet!") 142 | sys.exit(1) 143 | return _tool 144 | 145 | 146 | def make_empty_img(length): 147 | _empty = struct.pack('B', 0xFF) 148 | with open("km0_boot_all.bin", "wb") as _km0_boot_all_bin: 149 | for i in range(8192): 150 | i 151 | _km0_boot_all_bin.write(_empty) 152 | _km0_boot_all_bin.close() 153 | 154 | with open("km4_boot_all.bin", "wb") as _km4_boot_all_bin: 155 | for i in range(4096): 156 | i 157 | _km4_boot_all_bin.write(_empty) 158 | _km4_boot_all_bin.close() 159 | 160 | with open("km0_km4_image2.bin", "wb") as _km0_km4_image2_bin: 161 | for i in range(length - 12): 162 | i 163 | for j in range(1024): 164 | j 165 | _km0_km4_image2_bin.write(_empty) 166 | _km0_km4_image2_bin.close() 167 | 168 | def copy_img(dir): 169 | _local_dir = str(Path(os.path.split(os.path.realpath(__file__))[0])) 170 | _km0_boot_all_bin = str(Path(dir, "km0_boot_all.bin")) 171 | _km4_boot_all_bin = str(Path(dir, "km4_boot_all.bin")) 172 | _km0_km4_image2_bin = str(Path(dir, "km0_km4_image2.bin")) 173 | if not os.path.exists(_km0_boot_all_bin): 174 | print(Fore.RED + _km0_boot_all_bin + " not exists!") 175 | sys.exit(1) 176 | if not os.path.exists(_km4_boot_all_bin): 177 | print(Fore.RED + _km4_boot_all_bin + " not exists!") 178 | sys.exit(1) 179 | if not os.path.exists(_km0_km4_image2_bin): 180 | print(Fore.RED + _km0_km4_image2_bin + " not exists!") 181 | sys.exit(1) 182 | print(Fore.GREEN + "copy img to workspace...") 183 | shutil.copyfile(_km0_boot_all_bin, str(Path(_local_dir, "km0_boot_all.bin"))) 184 | shutil.copyfile(_km4_boot_all_bin, str(Path(_local_dir, "km4_boot_all.bin"))) 185 | shutil.copyfile(_km0_km4_image2_bin, str(Path(_local_dir, "km0_km4_image2.bin"))) 186 | 187 | 188 | @click.group() 189 | @click.version_option(version='0.6.0') 190 | def cli(): 191 | """RTL872XD Flash tool 192 | 193 | This tool is used to burn rtl8720d firmware. 194 | """ 195 | init(autoreset=True) 196 | pass 197 | 198 | @cli.command() 199 | @click.option( 200 | "--length", 201 | "-l", 202 | default=2048, 203 | type=click.INT, 204 | help="Length(kB) (default 2048kB).", 205 | metavar="DELAY", 206 | ) 207 | @click.option( 208 | "--port", 209 | "-p", 210 | required=False, 211 | type=click.STRING, 212 | help="Name of serial port for connected board.", 213 | metavar="PORT", 214 | ) 215 | def erase(length, port): 216 | if port == None: 217 | _port, _isbootloader = getAvailableBoard() 218 | if _port == None: 219 | print(Fore.RED + "Sorry, the device you should have is not plugged in.") 220 | sys.exit(1) 221 | else: 222 | _port = port 223 | 224 | if _isbootloader == False: 225 | _cmd = stty(_port) 226 | print(_cmd) 227 | if _cmd != "echo not support": 228 | os.system(_cmd%1200) 229 | time.sleep(2) 230 | _port, _isbootloader = getAvailableBoard() 231 | if _isbootloader == True: 232 | _tool = get_bossac_tool() 233 | _cmd = _tool + " -i -d --port=" + _port + " -U -i --offset=0x4000 -w -v " + str(Path(os.getcwd(), 'firmware')) + "/WioTerminal_USB2Serial_Burn8720.ino.bin -R" 234 | os.system(_cmd) 235 | 236 | for i in range(0, 3): 237 | print(Fore.GREEN + "wait...") 238 | time.sleep(1) 239 | 240 | _port, _isbootloader = getAvailableBoard() 241 | if _port == None: 242 | print(Fore.RED + "Sorry, the device you should have is not plugged in.") 243 | sys.exit(1) 244 | 245 | make_empty_img(length) 246 | 247 | _tool = get_flash_tool() 248 | 249 | _cmd = _tool + " " + _port 250 | 251 | print(Fore.GREEN + "Flashing...") 252 | obj = os.popen(_cmd) 253 | ret = obj.read() 254 | print(ret) 255 | if ret.find('successfully') >= 0: 256 | print(Fore.GREEN + "Success!") 257 | else: 258 | print(Fore.RED + "Error!") 259 | 260 | @cli.command() 261 | @click.option( 262 | "--port", 263 | "-p", 264 | required=False, 265 | type=click.STRING, 266 | help="Name of serial port for connected board.", 267 | metavar="PORT", 268 | ) 269 | @click.option( 270 | "--dir", 271 | "-d", 272 | required=False, 273 | type=click.STRING, 274 | help="Specifies the location of the directory where the firmware is located", 275 | metavar="DIR", 276 | ) 277 | def flash(port, dir): 278 | if port == None: 279 | _port, _isbootloader = getAvailableBoard() 280 | if _port == None: 281 | print(Fore.RED + "Sorry, the device you should have is not plugged in.") 282 | sys.exit(1) 283 | else: 284 | _port = port 285 | 286 | print(_port) 287 | 288 | if _isbootloader == False: 289 | _cmd = stty(_port) 290 | print(_cmd) 291 | if _cmd != "echo not support": 292 | os.system(_cmd%1200) 293 | time.sleep(2) 294 | _port, _isbootloader = getAvailableBoard() 295 | if _isbootloader == True: 296 | _tool = get_bossac_tool() 297 | _cmd = _tool + " -i -d --port=" + _port + " -U -i --offset=0x4000 -w -v " + str(Path(os.getcwd(), 'firmware')) + "/WioTerminal_USB2Serial_Burn8720.ino.bin -R" 298 | os.system(_cmd) 299 | 300 | for i in range(0, 3): 301 | print(Fore.GREEN + "wait...") 302 | time.sleep(1) 303 | 304 | _port, _isbootloader = getAvailableBoard() 305 | 306 | if _port == None: 307 | print(Fore.RED + "Sorry, the device you should have is not plugged in.") 308 | sys.exit(1) 309 | 310 | if dir == None: 311 | dir = str(Path(os.getcwd(), 'firmware')) 312 | 313 | copy_img(dir) 314 | 315 | _tool = get_flash_tool() 316 | 317 | _cmd = _tool + " " + _port 318 | 319 | print(Fore.GREEN + "Flashing...") 320 | obj = os.popen(_cmd) 321 | ret = obj.read() 322 | print(ret) 323 | if ret.find('successfully') >= 0: 324 | print(Fore.GREEN + "Success!") 325 | else: 326 | print(Fore.RED + "Error!") 327 | 328 | if __name__ == "__main__": 329 | try: 330 | cli() 331 | except OSError: 332 | print("error") 333 | -------------------------------------------------------------------------------- /firmware/WioTerminal_USB2Serial_Burn8720.ino.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/firmware/WioTerminal_USB2Serial_Burn8720.ino.bin -------------------------------------------------------------------------------- /firmware/km0_boot_all.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/firmware/km0_boot_all.bin -------------------------------------------------------------------------------- /firmware/km0_km4_image2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/firmware/km0_km4_image2.bin -------------------------------------------------------------------------------- /firmware/km4_boot_all.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/firmware/km4_boot_all.bin -------------------------------------------------------------------------------- /imgtool_flashloader_amebad.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/imgtool_flashloader_amebad.bin -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Click 2 | colorama 3 | pyserial -------------------------------------------------------------------------------- /tool/linux/amebad_image_tool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/tool/linux/amebad_image_tool -------------------------------------------------------------------------------- /tool/linux/bossac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/tool/linux/bossac -------------------------------------------------------------------------------- /tool/macos/amebad_image_tool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/tool/macos/amebad_image_tool -------------------------------------------------------------------------------- /tool/macos/bossac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/tool/macos/bossac -------------------------------------------------------------------------------- /tool/windows/amebad_image_tool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/tool/windows/amebad_image_tool.exe -------------------------------------------------------------------------------- /tool/windows/bossac.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/tool/windows/bossac.exe -------------------------------------------------------------------------------- /tool/windows/cygwin1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seeed-Studio/ambd_flash_tool/de56db9716f9cbf5641fe6e440b1c96033c41962/tool/windows/cygwin1.dll --------------------------------------------------------------------------------