{"id":26051473,"url":"https://github.com/josverl/mpflash","last_synced_at":"2025-06-30T13:41:04.070Z","repository":{"id":279691534,"uuid":"939625603","full_name":"Josverl/mpflash","owner":"Josverl","description":"mpflash is a command-line tool for working with MicroPython firmware. It provides features to help you flash and update MicroPython on one or more attached microcontrollers.","archived":false,"fork":false,"pushed_at":"2025-03-03T11:59:35.000Z","size":8907,"stargazers_count":2,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-07T17:45:50.038Z","etag":null,"topics":["dfu-programmer","esptool","microcontroller","micropython","uf2"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Josverl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-26T20:57:22.000Z","updated_at":"2025-03-02T17:33:27.000Z","dependencies_parsed_at":"2025-02-26T22:38:00.454Z","dependency_job_id":null,"html_url":"https://github.com/Josverl/mpflash","commit_stats":null,"previous_names":["josverl/mpflash"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Josverl%2Fmpflash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Josverl%2Fmpflash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Josverl%2Fmpflash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Josverl%2Fmpflash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Josverl","download_url":"https://codeload.github.com/Josverl/mpflash/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242501078,"owners_count":20139320,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dfu-programmer","esptool","microcontroller","micropython","uf2"],"created_at":"2025-03-08T04:55:17.598Z","updated_at":"2025-06-30T13:41:04.043Z","avatar_url":"https://github.com/Josverl.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MPFLASH\n  [![pypi version](https://badgen.net/pypi/v/mpflash)](https://pypi.org/project/mpflash/)\n  [![python versions](https://badgen.net/pypi/python/mpflash)](https://badgen.net/pypi/python/mpflash)\n[![Downloads](https://static.pepy.tech/badge/mpflash)](https://pepy.tech/project/mpflash)\n\n\n`mpflash` is a command-line tool for working with MicroPython firmware. It provides features to help you flash and update Micropython on one or more attached microcontrollers.\n\nThis tool was initially created to be used in a CI/CD pipeline to automate the process of downloading and flashing MicroPython firmware to multiple boards, but it has been extend with a TUI to be used for manual downloadig, flashing and development.\n\n`mpflash` has been tested on:  \n - OS: Windows x64, Linux X64, and macOS.\n - Micropython (hardware) ports: \n    - `rp2`, using `.uf2`, using filecopy \n    - `samd`, using ` .uf2`, using filecopy \n    - `esp32`, using `.bin`, using esptool,\n    - `esp8266`, using `.bin`, using esptool\n    - `stm32`, using ` .dfu`, using pydfu (also in Windows) \n\nNot yet implemented: `nrf`, `cc3200`, `mimxrt`, `renesas`\n\n## Release v1.25.0(.post2)\n\nThis release includes several new features and improvements:\n- **New features:**\n  - Added support for `--variant` option to specify a specific variant of the board when flashing.\n  - mpflash now uses a slqlite database to store information on all possible micropython firmwares, and the management of the downloaded firmware files.\n  - This allows for a better identification of boards, and matches to the correct firmware.\n  - Use the MicroPython v1.25.0 `sys.implementation._build` to as board_id when avaialable\n  - Automatically try to download firmware if not yet available locally. No lonmger need to specify the `--download` option.\n  - Restructured mpboard_id to use a SQLite db to be able to ID more boards and variants\n  - vendored and adapted `board_database.py` from mpflash, kudos @mattytrentini\n\n \n## Features\n 1. List the connected boards including their firmware details, in a tabular or json format\n 2. Download MicroPython firmware for versions, and matching a specified board or matches your current attached board.\n 3. Flash one or all connected MicroPython boards with a specific firmware or version.  \n \n## Installation\nTo install mpflash, you can use either of the following commands: \n- `uv tool install mpflash`\n- `pipx install mpflash`\n- `pip install mpflash`\n\n## Basic usage\nYou can use mpflash to perform various operations on your MicroPython boards. Here is an example of basic usage:\n\n| Command | Description |\n|---------|-------------|\n| `mpflash list` | List the connected board(s) including their firmware details |\n| `mpflash flash` | Flash the latest stable firmware to the connected board(s), downloading the firmware if needed |\n| `mpflash download` | Download the MicroPython firmware(s) for the connected board(s) |\n\n**Listing connected boards:**  \n`mpflash list` will list all connected boards in a table , including their serial port, family, board name, CPU, version and build number.\nOptions are available to list the boards in a json format, or to filter the list by serial port or board type.\n\n\n**Flashing boards with new firmware:**  \n`mpflash flash` will flash the latest stable firmware to all connected boards, downloading the firmware if needed.\nIt will try to determine the current micropython borad and variant, download the firmware if needed, and flash the correct firmware to each board.\n\nCommon options are:\n\n - `--version` to specify the version of the firmware to flash, defaults to the latest stable version.\n - `--serial` to specify the serial port(s) to flash, defaults to all connected boards.\n - `--board` to specify which firmware to flash to a single board\n - `--variant` to specify a specific variant of the board\n\n**Downloading firmware:**\n`mpflash download` will download the latest stable firmware for all connected boards, or a specific board if specified. It will download the firmware from the official MicroPython website and save it in your `Downloads/firmware` directory.  \nWhen a board is specified for which multiple variants are available, all variants will be downloaded.\n\nCommon options are:\n\n - `--version` to specify the version of the firmware to download, defaults to the latest stable version. (e.g. `stable`, `preview`, `x.y.z`)\n - `--serial` to specify the serial port(s) to flash, defaults to all connected boards.\n - `--board` to specify which firmware to flash to a single board\n\n## Setting the Firmware Files and Database Location\n\nYou can override the default location for firmware files and the MPFlash database by setting the `MPFLASH_FIRMWARE` environment variable. For example, in a Bash shell:\n\n```bash\nexport MPFLASH_FIRMWARE=\"/path/to/custom/firmware\"\n```\n\nWhen this variable is set, `mpflash` will use that location to store firmware files and estabish it's database.\n\n## Selecting or ignoring specific serial ports\n\nYou can use the `--serial` option to select a specific serial port(s) to flash,  \nOr you can use the `--ignore` option to ignore a specific serial port(s).  \n\nEither option can be specified multiple times, can be globs (e.g. COM*) or exact port names (e.g. /dev/ttyUSB0).\nTo permenently ignore a port, you can set the `MPFLASH_IGNORE` environment variable to a space-separated list of serial ports or globs.\n\nIn addition there is a --bluetooth option to simplify ignoring bluetooth ports, where the default is to ignore bluetooth ports.\n\n```\n--serial,--serial-port      -s      SERIALPORT  Serial port(s) (or globs) to list. [default: *]                                                                                                                                                                           \u003e \u003e --ignore                    -i      SERIALPORT  Serial port(s) (or globs) to ignore. Defaults to MPFLASH_IGNORE.                                                                                                                                                          │\n--bluetooth/--no-bluetooth  -b/-nb              Include bluetooth ports in the list [default: no-bluetooth] \n```\n\n## Distinguishing similar boards \nThe `mpflash list` command will list all connected boards, but sometimes you have multiple boards of the same type connected.\nTo help you identify the boards, you can add a board_info.toml file to the top/default folder for the board.\nThis file can contain a description of the board, which will be shown in the list and json output.\n```toml\ndescription = \"Blue Norwegian actuator\"\n```\n\nIf you want the board to be ignored by mpflash, no matter which serial port it is connected to, you can add the following to the `board_info.toml` file:\n```toml\ndescription = \"Blue Norwegian actuator\"\n[mpflash]\nignore = true\n```\n\n\n## Linux permissions to access usb devices \nIn order to flash the firmware to the board, you need to have the correct permissions to access the USB devices.\nOn Windows this will not be an issue, but on Linux you can use  udev rules to give non-root users access to the USB devices.\n[See the stm32_permissions documentation](docs/stm32_udev_rules.md) for more information.\n\n## Use MPFlash in your own project\n\nMPFlash can be used as a library in your own project. mpflash is used in [micropython-stubber]() to download and flash the firmware to the connected boards.\n\nThe interface is not well documented other than the code itself, but you can use the following example to get started:  - docs/mpflash_api_example.ipynb\n\n## Detailed usage\nYou can list the connected boards using the following command:\n```bash\n$\u003e mpflash list\n                                               Connected boards\n┏━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━┓\n┃ Serial  ┃Family       ┃Port  ┃Board                                      ┃CPU     ┃Version          ┃build ┃\n┡━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━┩\n│ COM21   │micropython  │rp2   │RPI_PICO                                   │RP2040  │v1.23.0-preview  │  236 │\n│         │             │      │Raspberry Pi Pico with RP2040              │        │                 │      │\n│ COM23   │micropython  │rp2   │RPI_PICO_W                                 │RP2040  │v1.23.0-preview  │  176 │\n│         │             │      │Raspberry Pi Pico W with RP2040            │        │                 │      │\n│ COM9    │micropython  │rp2   │ARDUINO_NANO_RP2040_CONNECT                │RP2040  │v1.23.0-preview  │  341 │\n│         │             │      │Arduino Nano RP2040 Connect with RP2040    │        │                 │      │\n└─────────┴─────────────┴──────┴───────────────────────────────────────────┴────────┴─────────────────┴──────┘\n```\n## Download the firmware\n\nTo download the MicroPython firmware for some boards, use the following command: \n - `mpflash download` download the latest stable firmware for all connected boards\n - `mpflash download --version preview` download the current preview for all connected boards\n - `mpflash download --board ESP8266_GENERIC --board SEEED_WIO_TERMINAL` download these specific boards\n - `mpflash download --version ? --board ?` prompt to select a specific version and board to download\n\nThese will try to download the prebuilt MicroPython firmware for the boards from https://micropython.org/download/ and save it in your downloads folder in the  `firmware` directory.\nThe stable version (default) is determined based on the most recent published release,\nother options are `--version stable`, `--version preview` and `--version x.y.z` to download the latest stable, preview or version x.y.z respectively.\n\nBy default the firmware will be downloaded to your OS's preferred `Downloads/firmware` folder, but you can speciy a different directory using the `--dir` option.\n\nThe directory structure will be something like this:\n\n``` text\nDownloads/firmware\n|   firmware.jsonl\n+---esp8266\n|       ESP8266_GENERIC-FLASH_1M-v1.22.2.bin\n|       ESP8266_GENERIC-FLASH_512K-v1.22.2.bin\n|       ESP8266_GENERIC-OTA-v1.22.2.bin\n|       ESP8266_GENERIC-v1.22.2.bin\n\\---samd\n        SEEED_WIO_TERMINAL-v1.22.2.uf2\n```\n\n## Flashing the firmware\nAfter you have downloaded a firmware you can  flash the firmware to a board using the following command: `mpflash flash`\nThis will (try to) autodetect the connected boards, and determine the correct firmware to flash to each board.\n\n- `mpflash flash` will flash the latest stable firmware to all connected boards.\nIf you have a board withouth a running micropython version, you will need to specify the board and the serial port to flash.\n- `mpflash flash --serial ? --board ?` will prompt to select a specific serial port and board to flash. (the firmware must be dowloaded earlier)\n\nIn order to flash the firmware some boards need to be put in bootloader mode, this is done automatically by mpflash where possible and supported by the boards hardware and current bootloader.\nThe supported `--bootloader` options are:\n\n- `touch1200` bootloader is activated by connecting to the board at 1200 baud \n- `mpy`  using  micropython to enter the bootloader\n- `manual` manual intervention is needed to enter the bootloader \n- `none`   mpflash assumes the board is ready to flash\n\nFor ESP32 and ESP8266 boards the `esptool` is used to flash the firmware, and this includes activating the bootloader.\n\n### Flashing all connected boards with the latest stable firmware\n```bash\n\u003e mpflash flash\n22:15:55 | ℹ️  - Using latest stable version: v1.22.2\n                                       Connected boards\n┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓\n┃ Serial ┃ Family      ┃ Port    ┃ Board              ┃ CPU         ┃ Version        ┃ build ┃\n┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩\n│ COM11  │ micropython │ rp2     │ RPI_PICO_W         │ RP2040      │ 1.20.0         │       │\n│ COM12  │ micropython │ esp8266 │ ESP8266_GENERIC    │ ESP8266     │ 1.22.2         │       │\n│ COM18  │ micropython │ rp2     │ RPI_PICO_W         │ RP2040      │ 1.23.0-preview │ 155   │\n│ COM3   │ micropython │ samd    │ SEEED_WIO_TERMINAL │ SAMD51P19A  │ 1.23.0-preview │ 155   │\n│ COM5   │ micropython │ stm32   │ PYBV11             │ STM32F405RG │ 1.23.0-preview │ 166   │\n│ COM8   │ micropython │ esp32   │ ESP32_GENERIC_S3   │ ESP32S3     │ 1.23.0-preview │ 155   │\n└────────┴─────────────┴─────────┴────────────────────┴─────────────┴────────────────┴───────┘\n22:15:58 | ℹ️  - Found v1.22.2 firmware rp2\\RPI_PICO_W-v1.22.2.uf2 for RPI_PICO_W on COM11.\n22:15:58 | ℹ️  - Found v1.22.2 firmware esp8266\\ESP8266_GENERIC-v1.22.2.bin for ESP8266_GENERIC on COM12.\n22:15:58 | ℹ️  - Found v1.22.2 firmware rp2\\RPI_PICO_W-v1.22.2.uf2 for RPI_PICO_W on COM18.\n22:15:58 | ℹ️  - Found v1.22.2 firmware samd\\SEEED_WIO_TERMINAL-v1.22.2.uf2 for SEEED_WIO_TERMINAL on COM3.\n22:15:58 | ⚠️  - Trying to find a firmware for the board PYBV11\n22:15:58 | ❌  - No v1.22.2 firmware found for PYBV11 on COM5.\n22:15:58 | ⚠️  - Trying to find a firmware for the board ESP32-GENERIC-S3\n22:15:58 | ❌  - No v1.22.2 firmware found for ESP32_GENERIC_S3 on COM8.\n22:15:58 | ℹ️  - Updating RPI_PICO_W on COM11 to 1.22.2\n22:15:58 | ℹ️  - Erasing not yet implemented for UF2 flashing.\n22:15:58 | ℹ️  - Entering UF2 bootloader on RPI_PICO_W on COM11\n22:15:58 | ℹ️  - Waiting for mcu to mount as a drive : 10 seconds left\n22:15:59 | ℹ️  - Waiting for mcu to mount as a drive : 9 seconds left\n22:16:00 | ℹ️  - Board is in bootloader mode\n22:16:00 | ℹ️  - Copying firmware\\rp2\\RPI_PICO_W-v1.22.2.uf2 to F:\n22:16:13 | ✅  - Done copying, resetting the board and wait for it to restart\n22:16:23 | ℹ️  - Updating ESP8266_GENERIC on COM12 to 1.22.2\n22:16:23 | ℹ️  - Flashing firmware\\esp8266\\ESP8266_GENERIC-v1.22.2.bin on ESP8266_GENERIC on COM12\n22:16:23 | ℹ️  - Running esptool --chip ESP8266 --port COM12 erase_flash \nesptool.py v4.7.0\nSerial port COM12\nConnecting....\n...\nChip erase completed successfully in 6.5s\nHard resetting via RTS pin...\n22:16:31 | ℹ️  - Running esptool --chip ESP8266 --port COM12 -b 460800 write_flash --flash_size=detect 0x0 firmware\\esp8266\\ESP8266_GENERIC-v1.22.2.bin \nesptool.py v4.7.0\nSerial port COM12\nConnecting....\n...\nLeaving...\nHard resetting via RTS pin...\n22:16:43 | ℹ️  - Done flashing, resetting the board and wait for it to restart\n22:16:49 | ✅  - Flashed 1.22.2 to ESP8266_GENERIC on COM12 done\n22:16:49 | ℹ️  - Updating RPI_PICO_W on COM18 to 1.22.2\n22:16:49 | ℹ️  - Erasing not yet implemented for UF2 flashing.\n22:16:49 | ℹ️  - Entering UF2 bootloader on RPI_PICO_W on COM18\n22:16:49 | ℹ️  - Waiting for mcu to mount as a drive : 10 seconds left\n22:16:50 | ℹ️  - Waiting for mcu to mount as a drive : 9 seconds left\n22:16:51 | ℹ️  - Board is in bootloader mode\n22:16:51 | ℹ️  - Copying firmware\\rp2\\RPI_PICO_W-v1.22.2.uf2 to F:[/bold]\n22:17:02 | ✅  - Done copying, resetting the board and wait for it to restart\n22:17:12 | ℹ️  - Updating SEEED_WIO_TERMINAL on COM3 to 1.22.2\n22:17:12 | ℹ️  - Erasing not yet implemented for UF2 flashing.\n22:17:12 | ℹ️  - Entering UF2 bootloader on SEEED_WIO_TERMINAL on COM3\n22:17:12 | ℹ️  - Waiting for mcu to mount as a drive : 10 seconds left\n22:17:13 | ℹ️  - Waiting for mcu to mount as a drive : 9 seconds left\n22:17:14 | ℹ️  - Board is in bootloader mode\n22:17:14 | ℹ️  - Copying firmware\\samd\\SEEED_WIO_TERMINAL-v1.22.2.uf2 to F:[/bold]\n22:17:17 | ✅  - Done copying, resetting the board and wait for it to restart\n22:17:27 | ℹ️  - Flashed 4 boards\n                               Connected boards after flashing\n┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓\n┃ Serial ┃ Family      ┃ Port    ┃ Board              ┃ CPU         ┃ Version        ┃ build ┃\n┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩\n│ COM11  │ micropython │ rp2     │ RPI_PICO_W         │ RP2040      │ 1.22.2         │       │\n│ COM12  │ micropython │ esp8266 │ ESP8266_GENERIC    │ ESP8266     │ 1.22.2         │       │\n│ COM18  │ micropython │ rp2     │ RPI_PICO_W         │ RP2040      │ 1.22.2         │       │\n│ COM3   │ micropython │ samd    │ SEEED_WIO_TERMINAL │ SAMD51P19A  │ 1.22.2         │       │\n│ COM5   │ micropython │ stm32   │ PYBV11             │ STM32F405RG │ 1.23.0-preview │ 166   │\n│ COM8   │ micropython │ esp32   │ ESP32_GENERIC_S3   │ ESP32S3     │ 1.23.0-preview │ 155   │\n└────────┴─────────────┴─────────┴────────────────────┴─────────────┴────────────────┴───────┘\n```\nNote that if no matching firmware can be found for a board, it will be skipped.\n(For example, the PYBV11 and ESP32_GENERIC_S3 boards in the example above.)\n\n## Issues and bug reports\nPlease report any issues or bugs in the [issue tracker](https://github.com/Josverl/mpflash/issues).\n\n## License\nmpflash is licensed under the MIT license. See the LICENSE file for more details.\n\n# Contributions\n\u003c!-- spell-checker: disable --\u003e\n\u003c!-- \nTo add via the cli run the following command:\nnpx all-contributors-cli add user things\n\n - bug\n - tool\n - stubs\n - test\n - doc\n - code\n - research\n - ideas\n - content\n - mpflash\n --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/Josverl\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/981654?v=4?s=100\" width=\"100px;\" alt=\"Jos Verlinde\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJos Verlinde\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/Josverl/mpflash/commits?author=josverl\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#research-josverl\" title=\"Research\"\u003e🔬\u003c/a\u003e \u003ca href=\"#ideas-josverl\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"#content-josverl\" title=\"Content\"\u003e🖋\u003c/a\u003e \u003ca href=\"#test-josverl\" title=\"Test\"\u003e✅\u003c/a\u003e \u003ca href=\"#mpflash-josverl\" title=\"mpflash\"\u003e💥\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/shariltumin\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/186120?v=4?s=100\" width=\"100px;\" alt=\"shariltumin\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eshariltumin\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-shariltumin\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-shariltumin\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/mattytrentini\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/194201?v=4?s=100\" width=\"100px;\" alt=\"Matt Trentini\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMatt Trentini\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-mattytrentini\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-mattytrentini\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://scruss.com/blog/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/425706?v=4?s=100\" width=\"100px;\" alt=\"Stewart Russell\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eStewart Russell\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-scruss\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-scruss\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://www.gitlab.com/alelec\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/3318786?v=4?s=100\" width=\"100px;\" alt=\"Andrew Leech\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndrew Leech\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-andrewleech\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-andrewleech\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/wovo\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/9039468?v=4?s=100\" width=\"100px;\" alt=\"Wouter van Ooijen\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eWouter van Ooijen\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-wovo\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-wovo\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/shaneapowell\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/12113620?v=4?s=100\" width=\"100px;\" alt=\"Shane Powell\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eShane Powell\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-shaneapowell\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-shaneapowell\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/robert-hh\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/12476868?v=4?s=100\" width=\"100px;\" alt=\"Robert Hammelrath\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRobert Hammelrath\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-robert-hh\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-robert-hh\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/beetlegigg\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/34552737?v=4?s=100\" width=\"100px;\" alt=\"Bg\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBg\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-beetlegigg\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-beetlegigg\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/rkompass\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/90282516?v=4?s=100\" width=\"100px;\" alt=\"Raul Kompaß\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRaul Kompaß\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-rkompass\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-rkompass\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/garryp4\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/96994876?v=4?s=100\" width=\"100px;\" alt=\"garryp4\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003egarryp4\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-garryp4\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-garryp4\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/shanepowell-ast\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/102747617?v=4?s=100\" width=\"100px;\" alt=\"Shane Powell\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eShane Powell\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-shanepowell-ast\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-shanepowell-ast\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://andypiper.org/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/552452?v=4?s=100\" width=\"100px;\" alt=\"Andy Piper\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndy Piper\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-andypiper\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-andypiper\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/DavesCodeMusings\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/61114342?v=4?s=100\" width=\"100px;\" alt=\"David Horton\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eDavid Horton\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mpflash-DavesCodeMusings\" title=\"mpflash\"\u003e💥\u003c/a\u003e \u003ca href=\"#test-DavesCodeMusings\" title=\"Test\"\u003e✅\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosverl%2Fmpflash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjosverl%2Fmpflash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosverl%2Fmpflash/lists"}