├── .github
└── workflows
│ ├── close-stale.yml
│ ├── lock-closed.yml
│ └── unlock-reopened.yml
├── .gitignore
├── LICENSE
├── README.md
├── doc
├── Linux.md
├── Module_Connections.md
├── New_Bootloader.md
├── Serial_Monitor.md
└── Troubleshooting.md
├── img
├── cp2102.png
├── dfu-recovery.png
├── flash-multi.jpg
├── maple-dfu-no-driver.png
├── maple-dfu-with-driver.png
├── maple-dfu.jpg
├── maple-reset.jpg
├── maple-usb-no-bootloader.png
├── maple-usb.png
├── serial-monitor.jpg
└── zadig.jpg
├── linux
├── bootloader
│ ├── AtmegaMultiBoot.hex
│ ├── StmMulti4in1_Legacy.bin
│ └── StmMulti4in1_StickyDfu.bin
├── default.nix
├── flash-multi
├── multi-bootreloader
└── tools
│ ├── 32bit
│ ├── avrdude
│ ├── avrdude.conf
│ ├── dfu-util
│ ├── maple-reset
│ └── stm32flash
│ ├── 45-maple.rules
│ ├── 64bit
│ ├── avrdude
│ ├── avrdude.conf
│ ├── dfu-util
│ ├── maple-reset
│ └── stm32flash
│ ├── BootReloader_Legacy.bin
│ ├── BootReloader_StickyDfu.bin
│ ├── install.sh
│ ├── macos
│ ├── avrdude
│ ├── avrdude.conf
│ ├── dfu-util
│ ├── maple-reset
│ └── stm32flash
│ └── src
│ └── maple-reset
│ └── maple-reset.c
└── src
├── Multi Logo Tall.bmp
├── Multi Logo.bmp
├── flash-multi.iss
├── flash-multi.nsi
├── flash-multi.sln
├── flash-multi
├── CenterWinDialog.cs
├── ComPort.cs
├── Devices
│ ├── MapleDevice.cs
│ ├── SerialDevice.cs
│ └── UsbAspDevice.cs
├── Dialogs
│ ├── DfuRecoveryDialog.Designer.cs
│ ├── DfuRecoveryDialog.cs
│ ├── DfuRecoveryDialog.resx
│ ├── SerialMonitor.Designer.cs
│ ├── SerialMonitor.cs
│ ├── SerialMonitor.fr.resx
│ ├── SerialMonitor.resx
│ ├── UsbSupportErrorDialog.Designer.cs
│ ├── UsbSupportErrorDialog.cs
│ ├── UsbSupportErrorDialog.resx
│ ├── UsbSupportWarningDialog.Designer.cs
│ ├── UsbSupportWarningDialog.cs
│ └── UsbSupportWarningDialog.resx
├── Eeprom
│ ├── AtmegaEepromUtils.cs
│ └── Stm32EepromUtils.cs
├── FileUtils.cs
├── FlashMulti.Designer.cs
├── FlashMulti.cs
├── FlashMulti.fr.resx
├── FlashMulti.resx
├── GPL.txt
├── Localization
│ ├── Strings.Designer.cs
│ └── Strings.resx
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── README.txt
├── RunCommand.cs
├── UpdateCheck.cs
├── UsbDeviceInfo.cs
├── UsbNotification.cs
├── app.config
├── flash-multi.csproj
├── icon.ico
├── license.txt
├── packages.config
└── stylecop.json
├── make_release.bat
├── make_release.sh
└── tools
├── bootloaders
├── AtmegaMultiBoot.hex
├── StmMulti4in1_Legacy.bin
└── StmMulti4in1_StickyDfu.bin
├── drivers
├── install_drivers.bat
└── wdi-simple.exe
└── tools
├── BootReloader_Legacy.bin
├── BootReloader_StickyDfu.bin
├── avrdude.conf
├── avrdude.exe
├── dfu-util-multi.exe
├── erase1.bin
├── erase118.bin
├── erase120.bin
├── erase32.bin
├── libusb-1.0.dll
├── libusb0.dll
├── maple-reset.exe
└── stm32flash.exe
/.github/workflows/close-stale.yml:
--------------------------------------------------------------------------------
1 | #
2 | # close-stale.yml
3 | # Close open issues after a period of inactivity
4 | #
5 |
6 | name: Close Stale Issues
7 |
8 | on:
9 | schedule:
10 | - cron: '0 1,13 * * *'
11 |
12 | jobs:
13 | stale:
14 | name: Close Stale Issues
15 | if: github.repository == 'benlye/flash-multi'
16 |
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - uses: actions/stale@v3
21 | with:
22 | repo-token: ${{ secrets.GITHUB_TOKEN }}
23 | stale-issue-message: >
24 | This issue has been automatically marked as stale because it has not had any
25 | recent activity. Please add a reply if you want to keep this issue active,
26 | otherwise it will be automatically closed in 5 days.
27 | days-before-stale: 14
28 | days-before-close: 5
29 | exempt-issue-labels: 'enhancement,work-in-progress'
30 |
--------------------------------------------------------------------------------
/.github/workflows/lock-closed.yml:
--------------------------------------------------------------------------------
1 | #
2 | # lock-closed.yml
3 | # Lock closed issues after a period of inactivity
4 | #
5 |
6 | name: Lock Closed Issues
7 |
8 | on:
9 | schedule:
10 | - cron: '0 1,13 * * *'
11 |
12 | jobs:
13 | lock:
14 | name: Lock Closed Issues
15 | if: github.repository == 'benlye/flash-multi'
16 |
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - uses: dessant/lock-threads@v2
21 | with:
22 | github-token: ${{ github.token }}
23 | process-only: 'issues'
24 | issue-lock-inactive-days: '21'
25 | issue-exclude-created-before: ''
26 | issue-exclude-labels: 'no-locking'
27 | issue-lock-labels: ''
28 | issue-lock-comment: >
29 | This issue has been automatically locked because there was no further activity
30 | after it was closed. Please open a new issue for any related problems.
31 | issue-lock-reason: ''
32 |
--------------------------------------------------------------------------------
/.github/workflows/unlock-reopened.yml:
--------------------------------------------------------------------------------
1 | #
2 | # unlock-reopened.yml
3 | # Unlock an issue whenever it is re-opened
4 | #
5 |
6 | name: Unlock Reopened Issue
7 |
8 | on:
9 | issues:
10 | types: [reopened]
11 |
12 | jobs:
13 | unlock:
14 | name: Unlock Reopened Issues
15 | if: github.repository == 'benlye/flash-multi'
16 |
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - uses: OSDKDev/unlock-issues@v1.1
21 | with:
22 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
332 | # Coverity
333 | cov-int/
334 | cov-int.zip
335 |
336 | # nix stuff
337 | **/result
338 |
--------------------------------------------------------------------------------
/doc/Linux.md:
--------------------------------------------------------------------------------
1 | # Flashing From Linux or Mac
2 | A bash script and toolchain is provided for flashing Multiprotocol modules from Linux and Mac operating systems.
3 |
4 | Like the Flash Multi Window application, the Linux and Mac script will automatically determine which upload method to use, will preserve the EEPROM data during flashes, and will write the bootloader as needed.
5 |
6 | ## Installing
7 | 1. Download and extract the latest Linux release, for example:
8 |
9 | ```
10 | wget https://github.com/benlye/flash-multi/releases/download/0.6.0/flash-multi-0.6.0.tar.gz
11 | tar -xvzf flash-multi-0.6.0.tar.gz
12 | ```
13 |
14 | 1. Change to the flash-multi directory, for example:
15 |
16 | `cd flash-multi-0.6.0`
17 |
18 | 1. Configure serial device permissions by running `tools/install.sh` as root to update the udev rules and add the current user to the dialout group, e.g.:
19 |
20 | `sudo ./tools/install.sh`
21 |
22 | If you prefer you can configure the permissions manually, for example:
23 | ```
24 | sudo cp -v ./tools/45-maple.rules /etc/udev/rules.d/45-maple.rules
25 | sudo chown root:root /etc/udev/rules.d/45-maple.rules
26 | sudo chmod 644 /etc/udev/rules.d/45-maple.rules
27 | sudo udevadm control --reload-rules
28 | sudo usermod -a -G plugdev $USER
29 | sudo usermod -a -G dialout $USER
30 | ```
31 | ### Mac
32 | macOS requires the libusb library to be installed. The easiest way to install the library is using the Homebrew package manager for macOS by running the two commands below in a Terminal.
33 |
34 | 1. Install Homebrew
35 |
36 | `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`
37 |
38 | 1. Use Homebrew to install libusb
39 |
40 | `brew install libusb`
41 |
42 | ## Use
43 | 1. Download the latest pre-compiled firmware from https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases
44 | 1. Plug in your Multiprotocol module
45 | 1. Run the flash-multi shell script, specifiying the serial device and firmware file:
46 |
47 | `./flash-multi -f [firmware file] -p [serial device]`
48 |
49 | For example:
50 |
51 | `./flash-multi -f /tmp/multi-stm-opentx-aetr-inv-v1.2.1.85.bin -p /dev/ttyUSB0 `
52 |
53 | *Note: On OSX the device might be `/dev/tty.SLAB_USBtoUART`
54 |
55 | For firmware compiled from recent source code the ouput will look similar to what is shown below, firmware from older source will not display information about the firmware configuration:
56 |
57 | ```
58 | ben@ben-ubuntu:~/flash-multi-0.4.3$ ./flash-multi -f /tmp/multi-stm-opentx-aetr-inv-v1.2.1.85.bin -p /dev/ttyUSB0
59 | flash-multi 0.4.3
60 |
61 | This program is Free Sofware and has NO WARRANTY.
62 | https://github.com/benlye/flash-multi/
63 |
64 | Multi Firmware Version: 1.2.1.85 (STM32)
65 | Expected Channel Order: AETR
66 | Multi Telemetry Type: OpenTX
67 | Invert Telemetry Enabled: True
68 | Flash From Radio Enabled: True
69 | Bootloader Enabled: True
70 | Serial Debug Enabled: False
71 |
72 | Proceed with firmware update? [Y]es or [N]o:y
73 |
74 | Attempting serial upload using stm32flash
75 |
76 | [1/3] Erasing flash...
77 | ./tools/64bit/stm32flash -o -S 0x8000000:129024 -b 115200 "/dev/ttyUSB0"
78 | stm32flash Arduino_STM32_0.9
79 |
80 | http://github.com/rogerclarkmelbourne/arduino_stm32
81 |
82 | Interface serial_posix: 115200 8E1
83 | Version : 0x22
84 | Option 1 : 0x00
85 | Option 2 : 0x00
86 | Device ID : 0x0410 (Medium-density)
87 | - RAM : 20KiB (512b reserved by bootloader)
88 | - Flash : 128KiB (sector size: 4x1024)
89 | - Option RAM : 16b
90 | - System RAM : 2KiB
91 | Erasing flash
92 |
93 | [2/3] Writing bootloader...
94 | ./tools/64bit/stm32flash -v -e 0 -g 0x8000000 -b 115200 -w "./bootloader/StmMulti4in1.bin" "/dev/ttyUSB0"
95 | stm32flash Arduino_STM32_0.9
96 |
97 | http://github.com/rogerclarkmelbourne/arduino_stm32
98 |
99 | Using Parser : Raw BINARY
100 | Interface serial_posix: 115200 8E1
101 | Version : 0x22
102 | Option 1 : 0x00
103 | Option 2 : 0x00
104 | Device ID : 0x0410 (Medium-density)
105 | - RAM : 20KiB (512b reserved by bootloader)
106 | - Flash : 128KiB (sector size: 4x1024)
107 | - Option RAM : 16b
108 | - System RAM : 2KiB
109 | Write to memory
110 | Wrote and verified address 0x08001ff0 (100.00%) Done.
111 |
112 | Starting execution at address 0x08000000... done.
113 |
114 | [3/3] Writing firmware...
115 | ./tools/64bit/stm32flash -v -s 8 -e 0 -g 0x8002000 -b 115200 -w "/tmp/multi-stm-opentx-aetr-inv-v1.2.1.85.bin" "/dev/ttyUSB0"
116 | stm32flash Arduino_STM32_0.9
117 |
118 | http://github.com/rogerclarkmelbourne/arduino_stm32
119 |
120 | Using Parser : Raw BINARY
121 | Interface serial_posix: 115200 8E1
122 | Version : 0x22
123 | Option 1 : 0x00
124 | Option 2 : 0x00
125 | Device ID : 0x0410 (Medium-density)
126 | - RAM : 20KiB (512b reserved by bootloader)
127 | - Flash : 128KiB (sector size: 4x1024)
128 | - Option RAM : 16b
129 | - System RAM : 2KiB
130 | Write to memory
131 | Wrote and verified address 0x08018954 (100.00%) Done.
132 |
133 | Starting execution at address 0x08002000... done.
134 |
135 | Firmware flashed successfully.
136 |
137 | ```
138 |
139 | # Using `nix`
140 |
141 | In case you happen to have [`nix`](https://nixos.org/explore.html) installed,
142 | you can simply use the `default.nix` file in the linux folder to build a
143 | compatible derivation of both `flash-multi` and `multi-bootreloader`. To
144 | install it in your users environment, simply run `nix-env -f . -i`.
145 |
146 | Beware: This does not alter udev rules, so you likely will run into permission
147 | problems with the DFU device and/or the serial device. Possible solution in
148 | descending level of recommendability:
149 |
150 | + install appropiate udev rules in your system
151 | + run the script in question as `root` user
152 | + run `while true; do sudo chown $USER /dev/bus/usb/*; done` while using the
153 | script. Afterwards run `sudo udevadm control --reload-rules && udevadm trigger` to
154 | reaply all udev rules in question.
155 |
--------------------------------------------------------------------------------
/doc/Module_Connections.md:
--------------------------------------------------------------------------------
1 | # Connecting Your Multiprotocol Module
2 | There are three ways that a Multiprotocol module can be connected to a PC and knowing which you can (or should) use can be confusing. The purpose of this page is to help you to identify and use your device's connection(s).
3 |
4 | The three connection types are:
5 | * Native USB port
6 | * External USB-to-serial Adapter
7 | * Internal USB-to-serial Adapter
8 |
9 | The connections available to you will depend on the specific module you have.
10 |
11 | **Note:** 'FTDI' is commonly used as a synonym for USB-to-serial, but is in fact one specific chip used in USB-to-serial adapters. For the purpose of the Flash Multi documentation 'FTDI Adapter' means 'USB-to-serial Adapter' anywhere it may be used.
12 |
13 | ## Native USB Port
14 | The 'native' USB port (also known as the Maple port) is a USB port which interfaces directly with the STM32 micro-controller in the Multiprotocol module.
15 |
16 | Using the native port requires that, at a minimum, the USB bootloader has been flashed to the module.
17 |
18 | **Note:** Multiprotocol module manufacturers only recently started shipping their modules with the USB bootloader installed. You may have a module which has a native USB port, but does not have the bootloader installed.
19 |
20 | _**Tip:** Using the native USB port is the fastest way to flash your Multiprotocol module._
21 |
22 | ### Drivers
23 | The native USB port requires two drivers, Maple Serial and Maple DFU, both of which are included with Flash Multi.
24 |
25 | ### Modes
26 | The native USB port has two modes, USB and DFU. DFU, or Device Firmware Update, mode is used when flashing the module. In USB mode the module appears as a serial (COM) port.
27 |
28 | Assuming the PC has the drivers installed, and the module has the correct (USB-enabled) firmware installed, when the module is plugged in it will briefly appear as a Maple DFU device and then reappear as a Maple Serial device (COM port).
29 |
30 | Flash Multi will automatically switch the module into DFU mode during the firmware flash process.
31 |
32 | ### How it Appears
33 | The native USB device has a device ID of `VID_1EAF&PID_0003` in DFU mode or `VID_1EAF&PID_0004` in USB mode. It can appear differently in Device Manager, depending on what firmware, bootloader, and drivers are installed.
34 |
35 | #### No Bootloader
36 | Windows will report an unrecognized and/or malfunctioning USB device.
37 |
38 | If there is no bootloader installed, it doesn't matter whether the module has firmware installed or not, or whether or not any installed firmware was built with or without USB support, Windows won't recognize the device and will probably tell you it's malfunctioning.
39 |
40 | **Note:** This will also happen if you forget to remove the `BOOT0` jumper before connecting the native USB port!
41 |
42 | #### No Drivers Installed
43 | Windows will detect the module as `Maple` under `Other devices`. There will be a yellow exclamation on the device and double-clicking it will tell you that the drivers are not installed.
44 |
45 | #### Drivers and Bootloader Installed, but firmware doesn't have USB support (or no firmware is present)
46 | Windows will detect the module as `Maple 003` under `Other devices`.
47 |
48 | #### Bootloader, Drivers, and Firmware Installed
49 | In USB mode, the module will appear as a serial (COM) port under `Ports (COM & LPT)`. In DFU mode, the module will appear as `Maple DFU` under `libusb-win32 devices`. Congratulations!
50 |
51 | ## External USB-to-serial Adapter
52 | An _external_ USB-to-serial adapter is a small USB device which provides a USB-to-serial interface. The adapter is used to connect to the serial pins on the STM32 micro-controller. Common USB-to-serial adapters use well-known chips such as `FTDI`, `FT232RL`, `CH340`, `CP2102`.
53 |
54 | Serial support is built into the STM32 and can _always_ be used to program the device. An external USB-to-serial adapter is a useful tool to have as it will ensure you can always recover your Multiprotocol module from a bad firmware flash, should one occur.
55 |
56 | Using an external USB-to-serial adapter to flash the module requires connecting a special pin on the board called `BOOT0` to 5V. There is usually a header, or connections for a header, for this on the board and the connection is made by placing a jumper on two pins to make the connection.
57 |
58 | ### Drivers
59 | Windows 10 includes drivers for many USB-to-serial adapters, but not all. Older version of Windows will typically need drivers installed manually. You should refer to your USB-to-serial adapter's instructions.
60 |
61 | ### How it Appears
62 | With the correct drivers installed, your USB-to-serial adapter should appear as a serial (COM) port in Device Manager.
63 |
64 | ## Internal USB-to-Serial Adapter
65 | The _internal_ USB-to-serial adapter is (at this time) unique to newer Jumper JP4IN1 modules, such as the module shipped with the Jumper T16.
66 |
67 | The _internal_ USB-to-serial adapter in the JP4IN1 is functionally the same as an _external_ USB-to-serial adapter except that it does not require manually connecting the `BOOT0` pin, because `BOOT0` is hard-wired to the USB port.
68 |
69 | ### Drivers
70 | The _internal_ USB-to-serial adapter in the JP4IN1 requires the Silicon Labs CP210x driver to be manually installed on all versions of Windows. The driver can be downloaded from https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers.
71 |
72 | ### How it Appears
73 | With the CP210x driver installed, the device will appear as a serial (COM) port in Device Manager.
74 |
--------------------------------------------------------------------------------
/doc/New_Bootloader.md:
--------------------------------------------------------------------------------
1 | # New MULTI-Module Bootloader
2 |
3 | If you have:
4 | * A radio with an internal MULTI-Module (e.g. T16, T18, TX16S), or
5 | * A Jumper JP4IN1-SE or RadioBoss JP4IN1 MULTI-Module, or
6 | * Any other MULTI-Module which is identified as a CP2102 device when you plug it, or
7 | * Any Atmega32p-based MULTI-Module
8 |
9 | You can stop reading now - this does not matter to you.
10 |
11 | **If you have a Jumper JP4IN1, iRangeX IRX4, Banggood, or any other STM32 MULTI-Module, please read this information - if you use the USB port on your module, you will need to take action!**
12 |
13 | If you want to cut to the chase, skip to the [what you need to do](#what-you-need-to-do) section.
14 |
15 | ## Introduction
16 | The latest version of Flash Multi, v0.5.0, gives you the ability to flash a new bootloader to your MULTI-Module.
17 |
18 | The new bootloader changes the behaviour of the USB port on your MULTI-module when you plug the module into a computer.
19 |
20 | | Action | Old Bootloader (COM Port Mode) | New Bootloader (Sticky DFU Mode) |
21 | | --- | --- | --- |
22 | | Connect the module to the computer, radio is off | Module starts in DFU mode then switches to COM port mode | Module starts in DFU mode and stays in DFU mode |
23 | | Connect the module to the computer, radio is on | Computer will detect a USB COM port | Computer will detect an unidentified device |
24 |
25 | ## Reason for Change
26 | Historically, the MULTI-Module firmware has always included code to make the USB COM port work when the module is running. However, the USB COM port is only used in two ways:
27 | * Switching the module to firmware update (DFU) mode when it is being flashed by using Flash Multi or the Arduino IDE
28 | * Debug output when running a debug-enabled build (typically only used by developers)
29 |
30 | And, there is never need for an internal MULTI-Module to have the USB COM port code, but it was always included. When this decision was made the firmware was around 80KB, and we had plenty of free space in the 128KB available flash on the STM32 MCU.
31 |
32 | Fast-forward three years and we have all but run out of space in the STM32. In an effort to free some space up, we are removing USB support from the firmware. **This change saves 5KB of flash.** This may not seem like much, but it's room for several more protocols.
33 |
34 | **Firmware without USB support will start to be released later in 2020.**
35 |
36 | Because we're removing the mechanism that would allow flashing tools to put the module into DFU mode, we have to provide a different way to do that.
37 |
38 | This is where the new bootloader comes in - it keeps the module in DFU mode when it is plugged in via USB, removing the need to use the COM port to switch it into DFU mode.
39 |
40 | ## What you need to do
41 | **You will need to use Flash Multi to upgrade the bootloader on your MULTI-Module _before_ you flash firmware which does not have USB support.**
42 |
43 | ### Upgrading to the new bootloader
44 | There is a one-time process to update the bootloader on the module. After the bootloader upgrade you will need to flash new firmware to your module.
45 |
46 | 1. Launch Flash Multi
47 | 1. Tell Flash Multi to use the new bootloader (Flash Multi v0.5.x only; not required for v0.6.0 or higher):
48 | 1. Click **Advanced** -> **Settings** -> **USB Port Mode** -> **Sticky DFU Mode (New)**
49 | 1. Plug your module in
50 | 1. Ensure that the correct COM port is selected
51 | 1. Flash the new bootloader to your module:
52 | 1. Click **Advanced** -> **Actions** -> **Flash Module Bootloader**
53 | 1. Wait for the red LED to go out
54 | 1. Unplug the module
55 |
56 | **You must pay attention to the instructions. DO NOT unplug the module until the red LED has gone out for at least two seconds.**
57 |
58 | You will now need to write new MULTI-Module firmware to the module in the normal way:
59 | 1. Check that the COM port is set to **DFU Device**
60 | 1. Select the firmware file
61 | 1. Click **Write Module**
62 |
63 | You will get a warning reminding you that you needed to update the bootloader, you may check the box to stop the message showing again.
64 |
65 | Once you have written new firmware to your module, if you unplug it and plug it back in, the module should stay in DFU mode with the red LED blinking continuously.
66 |
67 | ## Frequently Asked Questions
68 | ## When should I update the bootloader?
69 | You can do it any time after the release of Flash Multi v0.5.0. The new bootloader works with all previous MULTI-Module firmware releases.
70 |
71 | ### If I only ever flash my MULTI-Module from the radio do I have to do the bootloader update?
72 | No, you don't have to do it. You can also wait and do it later if you want to.
73 |
74 | ### How do I know which bootloader my MULTI-Module has?
75 | Plug it in via USB
76 | * If the red LED blinks rapidly then starts to blink slowly and the green LED comes on you have the old bootloader
77 | * If the red LED blinks rapidly continuously you have the new bootloader
78 | * If the green LED comes on and the red LED stays off you have a module which does not use the bootloader for the USB port
79 |
80 | ### I flashed new firmware without USB support from the radio and now my USB port doesn't work, how do I fix it?
81 | You have the old bootloader. Use Flash Multi to flash the module bootloader, as explained above. You will have to unplug and replug the module when instructed.
82 |
83 | ### I have to unplug and re-plug my module every time I flash it, how do I fix it?
84 | You have the old bootloader. Use Flash Multi to flash the module bootloader, as explained above. You will have to unplug and replug the module when instructed.
85 |
86 | ### I'm trying to update but I get a message saying no DFU device was found, and unplugging and re-plugging the module does nothing, how do I fix it?
87 | You need to reinstall the MULTI-Module device drivers.
88 | * Reset the module by unplugging it and plugging it back in
89 | * Click **Advanced** -> **Actions** -> **Upgrade USB Drivers**
90 |
91 | See [this page](/doc/Troubleshooting.md#re-installing-the-maple-dfu-device-drivers) for more details.
92 |
93 | ### Why doesn't this apply to JP4IN1-SE or Radioboss modules?
94 | They use a different USB interface which does not use DFU mode to flash firmware. They will work happily with the old or new bootloaders and do not require updating this way.
95 |
96 | ### Why doesn't this apply to radios with internal modules?
97 | Because internal modules don't have USB ports they do not require any update to work properly with the new firmware which does not have USB support.
98 |
--------------------------------------------------------------------------------
/doc/Serial_Monitor.md:
--------------------------------------------------------------------------------
1 | # Serial Monitor
2 | The Serial Monitor can be used to view debug information emitted by a Multimodule which has been flashed with firmware with `DEBUG_SERIAL` enabled.
3 |
4 | This can be useful when debugging complex firmware issues, or when capturing data using the Multimodule's [XN297L dump](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Advanced_XN297Ldump.md) feature to capture data from new transmitters so that new protocols can be added.
5 |
6 |
7 |
8 |
9 |
10 | ## Use
11 | To use the Serial Monitor simply select the serial (COM) port that the Multimodule is connected to and click the **Serial Monitor** button.
12 |
13 | When the Serial Monitor window opens it will open the serial port connection automatically. Once the window is open the serial port connection can be closed and re-opened as needed.
14 |
15 | If a firmware upload is started while the Serial Monitor window is open the connection will be automatically closed to allow the upload to occur, then be re-opened when the upload is complete.
16 |
17 | Content of the Serial Monitor window can be saved to a log file by clicking the **Save** button
18 |
--------------------------------------------------------------------------------
/doc/Troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 | Fortunately it is nearly impossible to 'brick' an STM32, so whatever state your Multiprotocol module is in, it should be possible to recover it.
3 |
4 | 1. [Re-installing the Maple DFU device drivers](#re-installing-the-maple-dfu-device-drivers)
5 | 1. [Flashing fails with JP4IN1 in the radio](#flashing-fails-when-flashing-a-jp4in1-in-the-radio)
6 | 1. [Module stuck in DFU mode after flashing](#module-stuck-in-dfu-mode-after-flashing-and-cannot-be-re-flashed)
7 |
8 | ## Re-installing the Maple DFU device drivers
9 | If reading or writing your MULTI-Module fails, and the verbose output is like the example below, you need to replace the Maple DFU device driver with a different one.
10 |
11 | ```
12 | Filter on vendor = 0x1eaf product = 0x0003
13 | Opening DFU capable USB device... ID 1eaf:0003
14 | Run-time device DFU version 0110
15 | Found DFU: [1eaf:0003] devnum=0, cfg=1, intf=0, alt=2, name="UNDEFINED"
16 | Claiming USB DFU Interface...
17 | Cannot claim interface
18 | ```
19 | ### Solution 1
20 | Use the latest version of Flash Multi to update the DFU drivers.
21 |
22 | 1. Download and install Flash Multi 0.4.0 or newer
23 | 1. Extract the files and fun `flash-multi.exe`
24 | 1. Plug your MULTI-Module into the computer
25 | 1. Ensure that the correct COM port is selected
26 | 1. Click Advanced -> Actions -> Upgrade USB Drivers
27 | 1. Follow the on screen prompts to upgrade the drivers
28 | 1. Disconnect and reconnect the MULTI-Module
29 |
30 | ### Solution 2
31 | Use Zadig to replace the DFU drivers.
32 |
33 | 1. Download and extract or install the latest version of Zadig from https://zadig.akeo.ie/
34 | 1. Put the MULTI-Module into DFU mode
35 | 1. Open a **Command Prompt**
36 | 1. Change to the directory where you have installed or extracted Flash Multi
37 | 1. Plug your MULTI-Module in, noting the COM port which appears in Device Manager
38 | 1. Run this command, substituting `COMX` for your COM port
39 |
40 | `.\tools\maple-reset.exe COMX`
41 |
42 | 
43 |
44 | 1. Device Manager should now show the Maple DFU device
45 |
46 | 
47 | 1. Use Zadig to replace the driver
48 | 1. Run **Zadig** from the location where you installed or extracted it
49 | 1. Click **Options** -> **List all Devices**
50 | 1. In the drop-down device list select `Maple 003` or `Maple DFU`, whichever is listed
51 | 1. Set the right-hand driver selector to `libusbK (v3.0.7.0)`
52 | 1. Click the **Replace Driver** button
53 |
54 | 
55 |
56 | ## Flashing fails when flashing a JP4IN1 in the radio
57 | If the module is in the radio, make sure that the radio is **switched off**. The JP4IN1 will only go into 'flashing mode' (i.e. BOOT0 mode) when it is powered up from the USB port.
58 |
59 | ## Module stuck in DFU mode after flashing and cannot be re-flashed
60 | If your module isn't working, it shows up in Device Manager as **Maple DFU**, and attempting to re-flash it via the native USB port fails with verbose output like this:
61 | ```
62 | .\tools\dfu-util.exe -R -a 2 -d 1EAF:0003 -D "C:\Temp\Multi-STM_FTDI_INV_OPENTX-v1.2.1.67.bin"
63 |
64 | Lost Device after reset, assuming prod_id was incremented by oneNo DFU capable USB device found
65 | dfu-util - (C) 2007-2008 by OpenMoko Inc.
66 |
67 | This program is Free Software and has ABSOLUTELY NO WARRANTY
68 | ```
69 |
70 | Most likely you have flashed a non-USB enabled firmware over the USB port, making the USB port (and the module) inoperable.
71 |
72 | Luckily, the USB bootloader always starts the module up briefly in DFU mode, and we can take advantage of that to re-flash it.
73 |
74 | ### Solution
75 | 1. Download or compile the correct, **USB-enabled**, firmware
76 | 1. Open a **Command Prompt** and change to the 'tools' sub-folder in the Flash Multi folder
77 |
78 | E.g.:
79 | `cd "C:\Program Files (x86)\FlashMulti\tools"`
80 |
81 | 1. Prepare the `dfu-util.exe` flash command, but don't run it yet:
82 |
83 | `dfu-util.exe -R -a 2 -d 1EAF:0003 -D "[firmware_file]"`
84 |
85 | E.g.: `dfu-util.exe -R -a 2 -d 1EAF:0003 -D "C:\Temp\Multi-STM_TXFLASH_INV_OPENTX-v1.2.1.67.bin"`
86 |
87 | 1. Unplug the module
88 | 1. Plug the module in and watch the red LED - it blinks very rapidly, then blinks slightly slower, then goes out
89 | 1. Unplug the module again
90 | 1. Plug the module in and as soon as the red LED is in the second phase, hit **[Enter]** in the Command Prompt to run the flash command
91 |
92 | You have about 0.5s to run the `dfu-util.exe` flash command while the red LED is in the second phase.
93 |
94 | You may need to try it a few times, but if you can hit enter in the command prompt as soon as the red LED changes to the second phase you will be able to re-flash the module and it will be back to normal. Once you've got the hang of the timing you'll be able to do it easily.
95 |
96 | 
97 |
98 | **Note:** `dfu-util.exe` always gives this error at the end:
99 |
100 | `error resetting after download: usb_reset: could not reset device, win error: The system cannot find the file specified.`
101 |
102 | You can ignore it.
103 |
--------------------------------------------------------------------------------
/img/cp2102.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/cp2102.png
--------------------------------------------------------------------------------
/img/dfu-recovery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/dfu-recovery.png
--------------------------------------------------------------------------------
/img/flash-multi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/flash-multi.jpg
--------------------------------------------------------------------------------
/img/maple-dfu-no-driver.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/maple-dfu-no-driver.png
--------------------------------------------------------------------------------
/img/maple-dfu-with-driver.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/maple-dfu-with-driver.png
--------------------------------------------------------------------------------
/img/maple-dfu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/maple-dfu.jpg
--------------------------------------------------------------------------------
/img/maple-reset.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/maple-reset.jpg
--------------------------------------------------------------------------------
/img/maple-usb-no-bootloader.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/maple-usb-no-bootloader.png
--------------------------------------------------------------------------------
/img/maple-usb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/maple-usb.png
--------------------------------------------------------------------------------
/img/serial-monitor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/serial-monitor.jpg
--------------------------------------------------------------------------------
/img/zadig.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/img/zadig.jpg
--------------------------------------------------------------------------------
/linux/bootloader/AtmegaMultiBoot.hex:
--------------------------------------------------------------------------------
1 | :107E0000112484B714BE9FEF9BB99CE395B991E010
2 | :107E100098B98370A9F08AEF80938500109284004E
3 | :107E200085E08093810096BBB09BFECF10928100CD
4 | :107E300093B186B181709C73892B8D3109F0B3D0D9
5 | :107E400082E08093C00088E18093C10086E0809347
6 | :107E5000C20081E28093C400259AC0E0D0E093E0A4
7 | :107E6000F92EEE24E39425E0D22E31E1C32EA9D0E1
8 | :107E7000813481F4A6D08EBBABD08EB3823811F49E
9 | :107E800085E006C08EB3813811F484E001C083E040
10 | :107E900091D086C0823411F484E103C0853419F492
11 | :107EA00085E09DD07DC0853541F48BD0C82F89D029
12 | :107EB000D0E0D82BCC0FDD1F72C0863521F484E0D2
13 | :107EC0008ED080E0E5CF843609F03DC07AD079D0FD
14 | :107ED000B82E77D0C11520E7D20718F000E011E0E6
15 | :107EE00004C0FE01F7BEE895F9CF6BD0F80181938D
16 | :107EF0008F01BE12FACFCE01905781159E4018F423
17 | :107F0000FE01F7BEE89564D0C115FEE7DF0708F073
18 | :107F100047C007B600FCFDCFFE01A0E0B1E08D91A7
19 | :107F20009D910C01E7BEE89511243296A03821E01E
20 | :107F3000B207A9F7FE01D7BEE89507B600FCFDCF52
21 | :107F4000C7BEE8952DC08437B1F43BD03AD0B82EE7
22 | :107F500038D03ED0FE01AC2EAB0C8F010F5F1F4F0F
23 | :107F6000849128D0A01205C02196BA94CB0DD11DC2
24 | :107F700017C0F801F2CF853739F42AD08EE11AD034
25 | :107F800085E918D08FE084CF813549F421D080E194
26 | :107F900011D08091C00086FFFCCF05D001C018D061
27 | :107FA00080E108D064CFE0E0F0E084918F3F09F0F9
28 | :107FB000099408959091C00095FFFCCF8093C6006E
29 | :107FC00008958091C00087FFFCCF8091C60008957E
30 | :107FD000F8DF803211F085E1EDDF84E1EBCFCF9364
31 | :107FE000C82FEFDFC150E9F7CF91F2CFA8950895E0
32 | :0C7FF000E0E6F0E098E1908380830895C3
33 | :0400000300007E007B
34 | :00000001FF
35 |
--------------------------------------------------------------------------------
/linux/bootloader/StmMulti4in1_Legacy.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/bootloader/StmMulti4in1_Legacy.bin
--------------------------------------------------------------------------------
/linux/bootloader/StmMulti4in1_StickyDfu.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/bootloader/StmMulti4in1_StickyDfu.bin
--------------------------------------------------------------------------------
/linux/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs ? import {} }:
2 |
3 | with pkgs;
4 |
5 | stdenv.mkDerivation rec {
6 | name = "flash-multi";
7 |
8 | src = ./.;
9 |
10 | nativeBuildInputs = [ autoPatchelfHook ];
11 | buildInputs = [ libusb ];
12 |
13 | installPhase = ''
14 | runHook preInstall
15 | mkdir -p $out/{bin,${name}}
16 | mv * $out/${name}/
17 | ln -s $out/${name}/flash-multi $out/bin/
18 | ln -s $out/${name}/multi-bootreloader $out/bin/
19 | runHook postInstall
20 | '';
21 | }
22 |
--------------------------------------------------------------------------------
/linux/multi-bootreloader:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | shopt -s extglob
3 |
4 | # *********************************************************************
5 | # Copyright (C) 2019 Ben Lye
6 |
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 |
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see .
19 | # *********************************************************************
20 |
21 | # Define the script version
22 | VERSION=0.2.0
23 |
24 | # Write the script header
25 | printf "multi-bootreloader $VERSION\n\nThis program is Free Software and has NO WARRANTY.\nhttps://github.com/benlye/flash-multi/\n\n";
26 |
27 | # Prepare simple help text to display when needed
28 | USAGE="Usage: multi-bootreloader [options] -p [serial device]\n\nOptions:\n -h Print this message and exit\n -l Install legacy bootloader\n\n"
29 |
30 | # Get the command line options
31 | while getopts ":f:p:hl" opt; do
32 | case $opt in
33 | f) FWFILE="$OPTARG"
34 | ;;
35 | p) PORT="$OPTARG"
36 | ;;
37 | l) LEGACY="True"
38 | ;;
39 | h) printf "$USAGE"; exit 1
40 | ;;
41 | \?) printf "Invalid argument -$OPTARG\n\n"; >&2
42 | ;;
43 | :) printf "Missing value for argument -$OPTARG\n\n"; >&2
44 | ;;
45 | esac
46 | done
47 |
48 | # Pick the bootreloader file
49 | if [[ $LEGACY == "True" ]]; then
50 | FWFILE=./tools/BootReloader_Legacy.bin
51 | else
52 | FWFILE=./tools/BootReloader_StickyDfu.bin
53 | fi
54 |
55 | # Die if the firmware file doesn't exist
56 | if [ ! -f "$FWFILE" ]; then
57 | printf "ERROR: $FWFILE does not exist!\n\n";
58 | exit 2;
59 | fi
60 |
61 | # Die if the firmware file isn't readable
62 | if [ ! -r "$FWFILE" ]; then
63 | printf "ERROR: $FWFILE cannot be read!\n\n";
64 | exit 2;
65 | fi
66 |
67 | function confirm() {
68 | while true; do
69 | read -p "$1 [Y]es or [N]o: "
70 | case $(echo $REPLY | tr '[A-Z]' '[a-z]') in
71 | y|yes) echo "yes"; return ;;
72 | n|no) echo "no" ; return ;;
73 | esac
74 | done
75 | }
76 |
77 | function list_usb()
78 | {
79 | while IFS=: read key value; do
80 | key="${key##+( )}"
81 | value="${value##+( )}"
82 | case "$key" in
83 | "Product ID")
84 | p="${value% *}"
85 | ;;
86 | "Vendor ID")
87 | v="${value%% *}"
88 | ;;
89 | "Manufacturer")
90 | m="${value}"
91 | ;;
92 | "Location ID")
93 | l="${value}"
94 | printf "%s:%s %s (%s)\n" "$v" "$p" "$l" "$m"
95 | ;;
96 | esac
97 | done < <( system_profiler SPUSBDataType )
98 | }
99 |
100 | # Check to see if a native STM32 USB device (Maple device)
101 | uname -a | grep "Darwin" 2>&1 1>/dev/null
102 | if [ $? -eq 0 ]; then
103 | MAPLE_USB_DEVICES=$(echo "$(list_usb)" | grep "1eaf" | awk '{ print $1}')
104 | else
105 | MAPLE_USB_DEVICES=$(lsusb | grep "1eaf")
106 | fi
107 |
108 | # Determine the mode of and attached STM32 device - DFU, Native (USB serial), or Unknown (not found)
109 | case $MAPLE_USB_DEVICES in
110 | *?(0x)1eaf:?(0x)0003*)
111 | MAPLE_DEVICE=DFU
112 | ;;
113 | *?(0x)1eaf:?(0x)0004*)
114 | MAPLE_DEVICE=Native
115 | ;;
116 | *)
117 | MAPLE_DEVICE=Unknown
118 | ;;
119 | esac
120 |
121 | # Check if port exists for Maple USB serial - there is no port needed for DFU
122 | if [ $MAPLE_DEVICE == "Native" ] ; then
123 | # Die if a serial port wasn't specified
124 | if [ "x" == "x$PORT" ]; then
125 | printf "ERROR: No port specified and no DFU-mode device found!\n\n";
126 | printf "$USAGE"
127 | exit 1
128 | fi
129 |
130 | # Die if the serial port doesn't exist
131 | if [ ! -c "$PORT" ]; then
132 | printf "ERROR: $PORT does not exist!\n\n";
133 | exit 3;
134 | fi
135 | fi
136 |
137 | # Die if there isn't a Maple device attached
138 | if [[ $MAPLE_DEVICE == "Unknown" ]]
139 | then
140 | # No Maple device
141 | printf "ERROR: No compatible MULTI-Module detected.\n\n"
142 | exit 2
143 | fi
144 |
145 | # Get the directory where the script is running.
146 | # DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
147 | DIR=$(dirname "$0")
148 |
149 | # Determine the binaries to use based on the platform architecture
150 | uname -a | grep "Darwin" 2>&1 1>/dev/null
151 | if [ $? -eq 0 ]; then
152 | TOOLS_DIR="$DIR/tools/macos"
153 | GREP_ARGS=""
154 | STAT_ARGS="-f %z"
155 | else
156 | uname -m | grep "x86_64" 2>&1 1>/dev/null
157 | if [ $? -eq 0 ]; then
158 | TOOLS_DIR="$DIR/tools/64bit"
159 | else
160 | TOOLS_DIR="$DIR/tools/32bit"
161 | fi
162 |
163 | GREP_ARGS="-Pa"
164 | STAT_ARGS="--printf=%s"
165 | fi
166 |
167 | RESET_UTIL="$TOOLS_DIR/maple-reset"
168 | DFU_UTIL="$TOOLS_DIR/dfu-util"
169 |
170 | if [ ! -x $RESET_UTIL ]; then
171 | printf "ERROR: Required tool $RESET_UTIL does not exist or is not executable!\n\n"; exit 3;
172 | fi
173 |
174 | if [ ! -x $DFU_UTIL ]; then
175 | printf "ERROR: Required tool $DFU_UTIL does not exist or is not executable!\n\n"; exit 3;
176 | fi
177 |
178 | # Show the instructions
179 | printf "The MULTI-Module firmware will be replaced by an application which will upgrade the module's bootloader.";
180 | printf "\nOnce begun, DO NOT interrupt the process, otherwise the bootloader will be corrupted and the module will not function.";
181 | printf "\nIf this happens a USB-to-serial (FTDI) adapter can be used to re-program the module.";
182 | printf "\n\nThe upgrade takes 4-5 seconds and will be complete once the LED goes off and remains off for at least 5 seconds.\n\n";
183 |
184 | # Ask the user to confirm
185 | if [[ "no" == $(confirm "Proceed with writing the BootReloader app?") ]]
186 | then
187 | printf "\nBootReloader aborted.\n\n"
188 | exit 0
189 | fi
190 | echo
191 |
192 | # Write the BootReloader app to the module
193 | printf "Attempting USB upload using dfu-util\n\n"
194 |
195 | STEP=1;
196 | NUM_STEPS=1;
197 |
198 | if [[ $MAPLE_DEVICE == "Native" ]] ; then
199 | NUM_STEPS=2;
200 |
201 | printf "[$STEP/$NUM_STEPS] Resetting to DFU mode...\n"
202 | printf "$RESET_UTIL $PORT\n";
203 | "${RESET_UTIL}" $PORT;
204 | [ $? -ne 0 ] && printf "ERROR: Failed to reset device!\n\n" && exit 4;
205 |
206 | # Give the board time to reset to DFU mode
207 | sleep 1
208 |
209 | STEP=$((STEP+1))
210 | fi
211 |
212 | printf "[$STEP/$NUM_STEPS] Writing BootReloader app...\n"
213 | printf "${DFU_UTIL} -d 1eaf:0003 -a 2 -D \"$FWFILE\" -R\n";
214 | "${DFU_UTIL}" -d 1eaf:0003 -a 2 -D "$FWFILE" -R;
215 | [ $? -ne 0 ] && printf "\nERROR: Failed to write BootReloader!\n\n" && exit 5;
216 |
217 | # printf "\n\n";
218 | printf "\n###################################################";
219 | printf "\n# MULTI-Module bootloader upgrade started #";
220 | printf "\n###################################################";
221 | printf "\n\nIMPORTANT: DO NOT UNPLUG THE MULTI-MODULE UNTIL THE LED GOES OFF!";
222 | printf "\n\nYou may unplug the module once the LED goes off and remains off for at least 5 seconds.";
223 | printf "\n\nYou now need to:";
224 | printf "\n\t1. Unplug then reconnect the MULTI-Module (after the LED goes off)";
225 | printf "\n\t2. Write new firmware to the MULTI-Module\n\n";
226 |
--------------------------------------------------------------------------------
/linux/tools/32bit/avrdude:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/32bit/avrdude
--------------------------------------------------------------------------------
/linux/tools/32bit/dfu-util:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/32bit/dfu-util
--------------------------------------------------------------------------------
/linux/tools/32bit/maple-reset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/32bit/maple-reset
--------------------------------------------------------------------------------
/linux/tools/32bit/stm32flash:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/32bit/stm32flash
--------------------------------------------------------------------------------
/linux/tools/45-maple.rules:
--------------------------------------------------------------------------------
1 | ATTRS{idProduct}=="0003", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple", ENV{ID_MM_DEVICE_IGNORE}="1"
2 | ATTRS{idProduct}=="0004", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple", ENV{ID_MM_DEVICE_IGNORE}="1"
3 |
--------------------------------------------------------------------------------
/linux/tools/64bit/avrdude:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/64bit/avrdude
--------------------------------------------------------------------------------
/linux/tools/64bit/dfu-util:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/64bit/dfu-util
--------------------------------------------------------------------------------
/linux/tools/64bit/maple-reset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/64bit/maple-reset
--------------------------------------------------------------------------------
/linux/tools/64bit/stm32flash:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/64bit/stm32flash
--------------------------------------------------------------------------------
/linux/tools/BootReloader_Legacy.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/BootReloader_Legacy.bin
--------------------------------------------------------------------------------
/linux/tools/BootReloader_StickyDfu.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/BootReloader_StickyDfu.bin
--------------------------------------------------------------------------------
/linux/tools/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if sudo [ -w /etc/udev/rules.d ]; then
4 | echo "Copying Maple-specific udev rules..."
5 | sudo cp -v $(dirname "$0")/45-maple.rules /etc/udev/rules.d/45-maple.rules
6 | sudo chown root:root /etc/udev/rules.d/45-maple.rules
7 | sudo chmod 644 /etc/udev/rules.d/45-maple.rules
8 | echo "Reloading udev rules"
9 | sudo udevadm control --reload-rules
10 | echo "Adding current user to dialout and plugdev groups"
11 | sudo usermod -a -G plugdev $USER
12 | sudo usermod -a -G dialout $USER
13 | else
14 | echo "Couldn't copy to /etc/udev/rules.d/; Did you run the script as root? Does your distribution of Linux include udev?"
15 | fi
16 |
--------------------------------------------------------------------------------
/linux/tools/macos/avrdude:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/macos/avrdude
--------------------------------------------------------------------------------
/linux/tools/macos/dfu-util:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/macos/dfu-util
--------------------------------------------------------------------------------
/linux/tools/macos/maple-reset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/macos/maple-reset
--------------------------------------------------------------------------------
/linux/tools/macos/stm32flash:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/linux/tools/macos/stm32flash
--------------------------------------------------------------------------------
/linux/tools/src/maple-reset/maple-reset.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Ben Lye
2 | *
3 | * This program is free software; you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation; either version 2 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * Utility to send the reset sequence on RTS and DTR and chars
9 | * which resets the libmaple and causes the bootloader to be run
10 | */
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | /* Function prototypes (belong in a seperate header file) */
23 | int openserial(char *devicename);
24 | void closeserial(void);
25 | int setDTR(unsigned short level);
26 | int setRTS(unsigned short level);
27 |
28 | /* Two globals for use by this module only */
29 | static int fd;
30 | static struct termios oldterminfo;
31 |
32 | /* Opens the serial port and sets RTS and DTR to LOW */
33 | /* Returns 1 on success or 0 on failure */
34 | int openserial(char *devicename)
35 | {
36 | struct termios attr;
37 |
38 | if ((fd = open(devicename, O_RDWR)) == -1) return 0; /* Error */
39 | atexit(closeserial);
40 |
41 | if (tcgetattr(fd, &oldterminfo) == -1) return 0; /* Error */
42 | attr = oldterminfo;
43 | attr.c_cflag |= CRTSCTS | CLOCAL;
44 | attr.c_oflag = 0;
45 | if (tcflush(fd, TCIOFLUSH) == -1) return 0; /* Error */
46 | if (tcsetattr(fd, TCSANOW, &attr) == -1) return 0; /* Error */
47 |
48 | return setRTS(0) && setDTR(0);
49 | }
50 |
51 | /* Closes the serial port */
52 | void closeserial(void)
53 | {
54 | tcsetattr(fd, TCSANOW, &oldterminfo);
55 | close(fd);
56 | }
57 |
58 | /* Sets RTS to LOW or HIGH */
59 | /* Returns 1 on success or 0 on failure */
60 | int setRTS(unsigned short level)
61 | {
62 | int status;
63 |
64 | if (ioctl(fd, TIOCMGET, &status) == -1) {
65 | perror("setRTS(): TIOCMGET");
66 | return 0;
67 | }
68 |
69 | if (level) status |= TIOCM_RTS;
70 | else status &= ~TIOCM_RTS;
71 |
72 | if (ioctl(fd, TIOCMSET, &status) == -1) {
73 | perror("setRTS(): TIOCMSET");
74 | return 0;
75 | }
76 | return 1;
77 | }
78 |
79 | /* Sets RTS to LOW or HIGH */
80 | /* Returns 1 on success or 0 on failure */
81 | int setDTR(unsigned short level)
82 | {
83 | int status;
84 |
85 | if (ioctl(fd, TIOCMGET, &status) == -1) {
86 | perror("setDTR(): TIOCMGET");
87 | return 0;
88 | }
89 | if (level) status |= TIOCM_DTR;
90 | else status &= ~TIOCM_DTR;
91 | if (ioctl(fd, TIOCMSET, &status) == -1) {
92 | perror("setDTR: TIOCMSET");
93 | return 0;
94 | }
95 | return 1;
96 | }
97 |
98 | /* Main function of the program */
99 | int main(int argc, char *argv[])
100 | {
101 | printf("maple-reset 0.1\n\n");
102 | printf("This program is Free Sofware and has NO WARRANTY\n\n");
103 |
104 | if (argc != 2)
105 | {
106 | printf("Usage: maple-reset [serial device]\n\n");
107 | return 1;
108 | }
109 |
110 | if (openserial(argv[1]))
111 | {
112 | if (setDTR(true) == 0)
113 | {
114 | fprintf(stderr, "Failed to set DTR\n\n");
115 | return 1;
116 | }
117 |
118 | usleep(50000L);
119 |
120 | if (setDTR(false) == 0)
121 | {
122 | fprintf(stderr, "Failed to set DTR\n\n");
123 | return 2;
124 | }
125 | usleep(50000L);
126 |
127 | if(!write(fd,"1EAF",4))
128 | {
129 | fprintf(stderr, "Could not send string to device.\n\n");
130 | return 3;
131 | }
132 |
133 | closeserial();
134 | fprintf(stdout, "Reset sequence sent to %s\n\n", argv[1]);
135 | return 0;
136 | }
137 | else
138 | {
139 | fprintf(stderr, "Could not open %s\n\n", argv[1]);
140 | return -1;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/Multi Logo Tall.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/Multi Logo Tall.bmp
--------------------------------------------------------------------------------
/src/Multi Logo.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/Multi Logo.bmp
--------------------------------------------------------------------------------
/src/flash-multi.iss:
--------------------------------------------------------------------------------
1 | [Setup]
2 | AppName=Flash Multi
3 | AppVersion={#MyAppVersion}
4 | AppPublisher=Ben Lye
5 | AppPublisherURL=https://github.com/benlye/flash-multi
6 | DefaultDirName={commonpf}\FlashMulti
7 | DefaultGroupName=Flash Multi
8 | UninstallDisplayIcon={app}\flash-multi.exe
9 | Compression=lzma2
10 | SolidCompression=yes
11 | OutputDir=flash-multi\bin
12 | OutputBaseFilename=flash-multi-{#MyAppVersion}
13 | InfoAfterFile=.\installer_infoafter.txt
14 | DisableWelcomePage=no
15 | LicenseFile=flash-multi\license.txt
16 |
17 | [Files]
18 | Source: "flash-multi\bin\Release\*"; Excludes: "*.pdb"; Flags: replacesameversion promptifolder recursesubdirs; DestDir: {app}; Components: main
19 |
20 | [InstallDelete]
21 | Type: filesandordirs; Name: "{app}\bin"
22 |
23 | [Icons]
24 | Name: "{group}\Flash Multi"; Filename: "{app}\flash-multi.exe"; IconFilename: "{app}\flash-multi.exe"; Components: main
25 |
26 | [Components]
27 | Name: "main"; Description: "Flash Multi Application"; Types: full compact custom; Flags: fixed
28 | Name: "drivers"; Description: "Run Maple USB Driver Installer"; Types: full
29 |
30 | [Run]
31 | ; Install the drivers - https://github.com/pbatard/libwdi/blob/master/examples/wdi-simple.iss
32 | Filename: "{app}\drivers\wdi-simple.exe"; Flags: "runhidden"; Parameters: " --vid 0x1EAF --pid 0x0003 --type 1 --name ""Maple DFU"" --dest ""{tmp}\maple-dfu"" --progressbar={wizardhwnd} --timeout 120000"; StatusMsg: "Installing Maple DFU device driver (this may take a few seconds) ..."; Components: drivers
33 | Filename: "{app}\drivers\wdi-simple.exe"; Flags: "runhidden"; Parameters: " --vid 0x1EAF --pid 0x0004 --type 3 --name ""Maple Serial"" --dest ""{tmp}\maple-serial"" --progressbar={wizardhwnd} --timeout 120000"; StatusMsg: "Installing Maple Serial device driver (this may take a few seconds) ..."; Components: drivers
34 |
--------------------------------------------------------------------------------
/src/flash-multi.nsi:
--------------------------------------------------------------------------------
1 |
2 | ; Plugins to Include
3 | !include MUI2.nsh
4 | !include "FileFunc.nsh"
5 | !include "nsProcess.nsh"
6 | !include "StrFunc.nsh"
7 |
8 | ; The name of the installer
9 | Name "Flash Multi"
10 |
11 | ; The file to write
12 | OutFile "flash-multi\bin\flash-multi-${VERSION}.exe"
13 |
14 | ; Use Unicode
15 | Unicode True
16 |
17 | ; The default installation directory
18 | InstallDir $PROGRAMFILES\FlashMulti
19 |
20 | ; Get the previous installation path from the registry
21 | InstallDirRegKey HKLM "Software\FlashMulti" "InstallDir"
22 |
23 | ; Add/Remove programs registry key
24 | !define AddRemoveProgsReg "Software\Microsoft\Windows\CurrentVersion\Uninstall\FlashMulti"
25 |
26 | ; Request application privileges
27 | RequestExecutionLevel admin
28 |
29 | ;--------------------------------
30 | ; Variables
31 | Var StartMenuFolder
32 |
33 | ;--------------------------------
34 | ; 'Declare' functions used in StrFunc.nsh
35 | ${StrRep}
36 |
37 | ;--------------------------------
38 | ;Interface Settings
39 | !define MUI_ABORTWARNING
40 | !define MUI_HEADERIMAGE
41 | !define MUI_HEADERIMAGE_BITMAP ".\Multi Logo.bmp"
42 | !define MUI_HEADERIMAGE_RIGHT
43 | !define MUI_HEADERIMAGE_UNBITMAP ".\Multi Logo.bmp"
44 | !define MUI_WELCOMEFINISHPAGE_BITMAP ".\Multi Logo Tall.bmp"
45 | !define MUI_UNWELCOMEFINISHPAGE_BITMAP ".\Multi Logo Tall.bmp"
46 |
47 | ;--------------------------------
48 | ; Installer pages
49 |
50 | ; Welcome page
51 | !insertmacro MUI_PAGE_WELCOME
52 |
53 | ; License page
54 | !define MUI_LICENSEPAGE_RADIOBUTTONS
55 | !insertmacro MUI_PAGE_LICENSE ".\flash-multi\bin\Release\license.txt"
56 |
57 | ; Components page
58 | !define MUI_COMPONENTSPAGE_NODESC
59 | !insertmacro MUI_PAGE_COMPONENTS
60 |
61 | ; Directory page
62 | !insertmacro MUI_PAGE_DIRECTORY
63 |
64 | ; Start menu page
65 | !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Flash Multi"
66 | !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
67 | !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\FlashMulti"
68 | !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "StartMenuFolder"
69 | !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
70 |
71 | ; Files page
72 | !insertmacro MUI_PAGE_INSTFILES
73 |
74 | ; Finish page
75 | !define MUI_FINISHPAGE_NOAUTOCLOSE
76 | !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt"
77 | !define MUI_FINISHPAGE_RUN "$INSTDIR\flash-multi.exe"
78 | !define MUI_FINISHPAGE_LINK 'https://github.com/benlye/flash-multi/'
79 | !define MUI_FINISHPAGE_LINK_LOCATION https://github.com/benlye/flash-multi/
80 | !insertmacro MUI_PAGE_FINISH
81 |
82 | ;--------------------------------
83 | ; Uninstaller pages
84 | !insertmacro MUI_UNPAGE_CONFIRM
85 | !insertmacro MUI_UNPAGE_INSTFILES
86 |
87 | ;--------------------------------
88 | ;Languages
89 | !insertmacro MUI_LANGUAGE "English"
90 |
91 | ;--------------------------------
92 | ; The stuff to install
93 | Section "Flash Multi" "flash_multi"
94 |
95 | SectionIn RO
96 |
97 | ; Set output path to the installation directory.
98 | SetOutPath $INSTDIR
99 |
100 | ; Get the files
101 | File /r ".\flash-multi\bin\Release\bootloaders"
102 | File /r ".\flash-multi\bin\Release\drivers"
103 | File /r ".\flash-multi\bin\Release\tools"
104 | File ".\flash-multi\bin\Release\flash-multi.exe"
105 | File ".\flash-multi\bin\Release\flash-multi.exe.config"
106 | File ".\flash-multi\bin\Release\GPL.txt"
107 | File ".\flash-multi\bin\Release\license.txt"
108 | File ".\flash-multi\bin\Release\README.txt"
109 |
110 | ; Write the uninstaller
111 | WriteUninstaller "$INSTDIR\uninstall.exe"
112 |
113 | ; Write the installation path into the registry
114 | WriteRegStr HKLM SOFTWARE\FlashMulti "InstallDir" "$INSTDIR"
115 |
116 | ; Write a flag indicating the component selections
117 | WriteRegDWORD HKLM SOFTWARE\FlashMulti "InstallDrivers" "0"
118 |
119 | ; Write the uninstall keys for Windows
120 | ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
121 | IntFmt $0 "0x%08X" $0
122 | WriteRegDWORD HKLM "${AddRemoveProgsReg}" "EstimatedSize" "$0"
123 |
124 | WriteRegStr HKLM "${AddRemoveProgsReg}""Publisher" "Ben Lye"
125 | WriteRegStr HKLM "${AddRemoveProgsReg}""DisplayIcon" '"$INSTDIR\flash-multi.exe"'
126 | WriteRegStr HKLM "${AddRemoveProgsReg}""DisplayName" "Flash Multi ${VERSION}"
127 | WriteRegStr HKLM "${AddRemoveProgsReg}""DisplayVersion" "${VERSION}"
128 | WriteRegStr HKLM "${AddRemoveProgsReg}""URLInfoAbout" "https://github.com/benlye/flash-multi/"
129 | WriteRegStr HKLM "${AddRemoveProgsReg}""UninstallString" '"$INSTDIR\uninstall.exe"'
130 | WriteRegDWORD HKLM "${AddRemoveProgsReg}""NoModify" 1
131 | WriteRegDWORD HKLM "${AddRemoveProgsReg}""NoRepair" 1
132 |
133 | ; Create Start Menu shortcuts
134 | !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
135 | CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
136 | CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Flash Multi.lnk" "$INSTDIR\flash-multi.exe" "" "$INSTDIR\flash-multi.exe" 0
137 | CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Run Maple Driver Installer.lnk" "$INSTDIR\drivers\install_drivers.bat"
138 | CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall Flash Multi.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
139 | !insertmacro MUI_STARTMENU_WRITE_END
140 | SectionEnd
141 |
142 | ; Optional section (can be disabled by the user)
143 | Section "Run the Maple USB driver installer" "install_drivers"
144 | ; Install the drivers - https://github.com/pbatard/libwdi/blob/master/examples/wdi-simple.iss
145 |
146 | SetDetailsPrint textonly ; or both
147 | DetailPrint 'Installing Maple USB driver ...'
148 | SetDetailsPrint none ; or listonly
149 | nsExec::Exec '"$INSTDIR\drivers\wdi-simple.exe" --vid 0x1EAF --pid 0x0003 --type 1 --name "Maple DFU" --dest "$TEMP\maple-dfu" --progressbar=$HWNDPARENT --timeout 120000"'
150 |
151 | SetDetailsPrint textonly ; or both
152 | DetailPrint 'Installing Maple Serial driver ...'
153 | SetDetailsPrint none ; or listonly
154 | nsExec::Exec '"$INSTDIR\drivers\wdi-simple.exe" --vid 0x1EAF --pid 0x0004 --type 3 --name "Maple Serial" --dest "$TEMP\maple-serial" --progressbar=$HWNDPARENT --timeout 120000"'
155 |
156 | ; Remember that drivers were selected
157 | WriteRegDWORD HKLM SOFTWARE\FlashMulti "InstallDrivers" "1"
158 | SectionEnd
159 |
160 | ;--------------------------------
161 | ; Uninstaller
162 | Section "Uninstall"
163 | ; Get the start menu folder
164 | !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
165 |
166 | ; Remove registry keys
167 | DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FlashMulti"
168 | DeleteRegKey HKLM SOFTWARE\FlashMulti
169 |
170 | ; Remove files
171 | Delete $INSTDIR\*.*
172 |
173 | ; Remove shortcuts, if any
174 | Delete "$SMPROGRAMS\$StartMenuFolder\*.*"
175 |
176 | ; Remove directories used
177 | RMDir "$SMPROGRAMS\$StartMenuFolder"
178 | RMDir /r "$INSTDIR"
179 | SectionEnd
180 |
181 | ; Installer initialization function - checks for previous installation
182 | Function .onInit
183 | ; Select/unselect the components based on previous selections
184 | ReadRegDWORD $0 HKLM "Software\FlashMulti" "InstallDrivers"
185 | ${If} $0 == 0
186 | SectionSetFlags ${install_drivers} 0
187 | ${Else}
188 | SectionSetFlags ${install_drivers} 1
189 | ${EndIf}
190 |
191 | ; Check for an NSIS uninstaller in the registry
192 | ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FlashMulti" "UninstallString"
193 | ${If} $R0 != ""
194 | StrCpy $0 $R0
195 | ${EndIf}
196 |
197 | ; Check for an InnoSetup uninstaller in the registry
198 | ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Flash Multi_is1" "UninstallString"
199 | ${If} $R1 != ""
200 | StrCpy $0 $R1
201 | ${EndIf}
202 |
203 | ; If we have an uninstaller, parse the path to find the installation directory
204 | ${If} $0 != ""
205 | ; Strip any double quotes from the uninstaller path
206 | ${StrRep} '$1' '$0' '$\"' ''
207 |
208 | ; Get the parent folder of the uninstaller executable
209 | ${GetParent} $1 $2
210 |
211 | ; If the uninstaller folder is not the same as the default install dir, update the install dir
212 | ${If} $2 != $INSTDIR
213 | StrCpy $INSTDIR $2
214 | ${EndIf}
215 | ${EndIf}
216 |
217 | ; Check if an uninstaller executable exists
218 | IfFileExists "$INSTDIR\unins000.exe" PreviousVersionWarn
219 | IfFileExists "$INSTDIR\uninstall.exe" PreviousVersionWarn
220 | Goto End
221 |
222 | PreviousVersionWarn:
223 | ; An uninstaller exists so ask the user if we should uninstall
224 | MessageBox MB_YESNO|MB_ICONQUESTION "Remove the existing installation of Flash Multi?$\n$\nAnswering $\"No$\" will abort the installation." /SD IDYES IDYES Uninstall
225 | Goto AbortInstall
226 |
227 | Uninstall:
228 | ; Check for InnoSetup uninstaller
229 | IfFileExists "$INSTDIR\unins000.exe" InnoUninstall
230 | ; Check for NSIS uninstaller
231 | IfFileExists "$INSTDIR\uninstall.exe" NsisUninstall
232 | Goto End
233 |
234 | InnoUninstall:
235 | ; Run the InnoSetup uninstaller silently
236 | ExecWait '"$INSTDIR\unins000.exe" /SILENT'
237 | Goto End
238 |
239 | NsisUninstall:
240 | ; Run the NSIS uninstaller silently
241 | ExecWait '"$INSTDIR\uninstall.exe" /S _=$INSTDIR'
242 | Goto End
243 |
244 | AbortInstall:
245 | abort
246 |
247 | End:
248 | FunctionEnd
249 |
250 | ; Uninstaller initialization function - checks for running program
251 | Function un.onInit
252 | ${nsProcess::FindProcess} "flash-multi.exe" $R0
253 | ${If} $R0 == 0
254 | MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "Flash Multi is running. Click OK to close it or Cancel to abort." /SD IDOK IDOK Close
255 | Abort
256 | ${Else}
257 | Goto End
258 | ${EndIf}
259 |
260 | Close:
261 | ${nsProcess::CloseProcess} "flash-multi.exe" $R0
262 | Goto End
263 |
264 | End:
265 | ${nsProcess::Unload}
266 | FunctionEnd
--------------------------------------------------------------------------------
/src/flash-multi.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29102.190
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "flash-multi", "flash-multi\flash-multi.csproj", "{72D5A55C-CC93-422C-A12F-CCE99E1C7300}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {72D5A55C-CC93-422C-A12F-CCE99E1C7300}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {72D5A55C-CC93-422C-A12F-CCE99E1C7300}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {72D5A55C-CC93-422C-A12F-CCE99E1C7300}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {72D5A55C-CC93-422C-A12F-CCE99E1C7300}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {AB4E8D22-558E-49BF-9224-52161DC7D6C9}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/src/flash-multi/CenterWinDialog.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Drawing;
25 | using System.Runtime.InteropServices;
26 | using System.Text;
27 | using System.Windows.Forms;
28 |
29 | ///
30 | /// Shows a messagebox centered on the parent window.
31 | ///
32 | internal class CenterWinDialog : IDisposable
33 | {
34 | private int mTries = 0;
35 | private Form mOwner;
36 |
37 | ///
38 | /// Initializes a new instance of the class.
39 | ///
40 | /// The form to center the messagebox over.
41 | public CenterWinDialog(Form owner)
42 | {
43 | this.mOwner = owner;
44 | owner.BeginInvoke(new MethodInvoker(this.FindDialog));
45 | }
46 |
47 | // P/Invoke declarations
48 | private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
49 |
50 | ///
51 | /// Dispose.
52 | ///
53 | public void Dispose()
54 | {
55 | this.mTries = -1;
56 | }
57 |
58 | [DllImport("user32.dll")]
59 | private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
60 |
61 | [DllImport("kernel32.dll")]
62 | private static extern int GetCurrentThreadId();
63 |
64 | [DllImport("user32.dll")]
65 | private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
66 |
67 | [DllImport("user32.dll")]
68 | private static extern bool GetWindowRect(IntPtr hWnd, out RECT rc);
69 |
70 | [DllImport("user32.dll")]
71 | private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint);
72 |
73 | private void FindDialog()
74 | {
75 | // Enumerate windows to find the message box
76 | if (this.mTries < 0)
77 | {
78 | return;
79 | }
80 |
81 | EnumThreadWndProc callback = new EnumThreadWndProc(this.CheckWindow);
82 | if (EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero))
83 | {
84 | if (++this.mTries < 10)
85 | {
86 | this.mOwner.BeginInvoke(new MethodInvoker(this.FindDialog));
87 | }
88 | }
89 | }
90 |
91 | private bool CheckWindow(IntPtr hWnd, IntPtr lp)
92 | {
93 | // Checks if is a dialog
94 | StringBuilder sb = new StringBuilder(260);
95 | GetClassName(hWnd, sb, sb.Capacity);
96 | if (sb.ToString() != "#32770")
97 | {
98 | return true;
99 | }
100 |
101 | // Got it
102 | Rectangle frmRect = new Rectangle(this.mOwner.Location, this.mOwner.Size);
103 | RECT dlgRect;
104 | GetWindowRect(hWnd, out dlgRect);
105 | MoveWindow(
106 | hWnd,
107 | frmRect.Left + ((frmRect.Width - dlgRect.Right + dlgRect.Left) / 2),
108 | frmRect.Top + ((frmRect.Height - dlgRect.Bottom + dlgRect.Top) / 2),
109 | dlgRect.Right - dlgRect.Left,
110 | dlgRect.Bottom - dlgRect.Top,
111 | true);
112 | return false;
113 | }
114 |
115 | private struct RECT
116 | {
117 | public int Left; public int Top; public int Right; public int Bottom;
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/flash-multi/ComPort.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Collections.Generic;
25 | using System.Diagnostics;
26 | using System.IO.Ports;
27 | using System.Linq;
28 | using System.Management;
29 | using System.Threading;
30 |
31 | ///
32 | /// Class for dealing with COM ports.
33 | ///
34 | internal class ComPort
35 | {
36 | ///
37 | /// Gets the name of the port.
38 | ///
39 | public string Name { get; private set; }
40 |
41 | ///
42 | /// Gets the description of the port.
43 | ///
44 | public string Description { get; private set; }
45 |
46 | ///
47 | /// Gets the displayname of the port (name + description).
48 | ///
49 | public string DisplayName { get; private set; }
50 |
51 | ///
52 | /// Enumerates the available COM ports.
53 | ///
54 | /// Returns an ordered array of COM port names.
55 | public static string[] EnumeratePorts()
56 | {
57 | // Get the list of COM port names
58 | List comPorts = SerialPort.GetPortNames().ToList();
59 |
60 | // Sort the list of ports
61 | comPorts = comPorts.OrderBy(c => c.Length).ThenBy(c => c).ToList();
62 |
63 | // Check if we there's a Maple DFU device plugged in and add it to the list
64 | if (MapleDevice.FindMaple().DeviceFound)
65 | {
66 | comPorts.Add("DFU Device");
67 | }
68 |
69 | // Check if we there's a USBasp device plugged in and add it to the list
70 | if (UsbAspDevice.FindUsbAsp().DeviceFound)
71 | {
72 | comPorts.Add("USBasp");
73 | }
74 |
75 | // Return an array of COM port names
76 | return comPorts.ToArray();
77 | }
78 |
79 | ///
80 | /// Enumerates the available COM ports without using WMI.
81 | ///
82 | /// Returns an ordered list of ports .
83 | public static List EnumeratePortList()
84 | {
85 | // Get the start time so we can write how long this takes to the debug window
86 | DateTime start = DateTime.Now;
87 | Debug.WriteLine("Enumerating COM ports");
88 |
89 | // Create a list to store the COM port names
90 | List comPorts = new List();
91 |
92 | // Get all the COM port names
93 | string[] comPortNames = SerialPort.GetPortNames().Distinct().ToArray();
94 |
95 | // Add all the COM ports to the list
96 | foreach (string portName in comPortNames)
97 | {
98 | // We only know the port name, so write that to all three properties
99 | ComPort thisPort = new ComPort
100 | {
101 | Name = portName,
102 | Description = portName,
103 | DisplayName = portName,
104 | };
105 | comPorts.Add(thisPort);
106 | }
107 |
108 | // Sort the list of ports by name
109 | comPorts = comPorts.OrderBy(c => c.Name.Length).ThenBy(c => c.Name).ToList();
110 |
111 | // Check if we there's a Maple DFU device plugged in and add it to the list
112 | if (MapleDevice.FindMaple().DfuMode)
113 | {
114 | ComPort dfuPort = new ComPort
115 | {
116 | Name = "DFU Device",
117 | Description = "DFU Device",
118 | DisplayName = "DFU Device",
119 | };
120 | comPorts.Add(dfuPort);
121 | }
122 |
123 | // Check if we there's a USBasp device plugged in and add it to the list
124 | if (UsbAspDevice.FindUsbAsp().DeviceFound)
125 | {
126 | ComPort usbAsp = new ComPort
127 | {
128 | Name = "USBasp",
129 | Description = "USBasp",
130 | DisplayName = "USBasp",
131 | };
132 | comPorts.Add(usbAsp);
133 | }
134 |
135 | // Get the time now and write how long that took
136 | DateTime end = DateTime.Now;
137 | Debug.WriteLine($"COM ports enumerated in {end - start}.");
138 |
139 | // Return the list of COM ports
140 | return comPorts;
141 | }
142 |
143 | ///
144 | /// Enumerates the available COM ports using WMI, including the device description.
145 | ///
146 | /// Returns an ordered list of ports .
147 | public static List EnumeratePortList2()
148 | {
149 | List comPorts = new List();
150 |
151 | // Get all the COM ports using WMI
152 | using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(
153 | "root\\cimv2",
154 | "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\""))
155 | {
156 | // Add all available ports to the list
157 | foreach (ManagementObject queryObj in searcher.Get())
158 | {
159 | string portCaption = queryObj["Caption"].ToString();
160 |
161 | if (portCaption.Contains("(COM"))
162 | {
163 | // Get the index number where "(COM" starts in the string
164 | int indexOfCom = portCaption.IndexOf("(COM");
165 | string portName = portCaption.Substring(indexOfCom + 1, portCaption.Length - indexOfCom - 2);
166 | string portDescription = portCaption.Substring(0, indexOfCom - 1);
167 |
168 | ComPort thisPort = new ComPort
169 | {
170 | Name = portName,
171 | Description = portDescription,
172 | DisplayName = $"{portName} ({portDescription})",
173 | };
174 |
175 | comPorts.Add(thisPort);
176 | }
177 | }
178 | }
179 |
180 | // Sort the list of ports
181 | comPorts = comPorts.OrderBy(c => c.Name.Length).ThenBy(c => c.Name).ToList();
182 |
183 | // Check if we there's a Maple device in DFU mode plugged in
184 | if (MapleDevice.FindMaple().DfuMode)
185 | {
186 | ComPort dfuPort = new ComPort
187 | {
188 | Name = "DFU Device",
189 | Description = "Maple DFU Device",
190 | DisplayName = "DFU Device",
191 | };
192 | comPorts.Add(dfuPort);
193 | }
194 |
195 | // Return a list of COM ports
196 | return comPorts;
197 | }
198 |
199 | ///
200 | /// Checks if the COM port can be opened.
201 | ///
202 | /// /// The name of the port to check.
203 | ///
204 | /// Boolean indicating whether the port could be opened.
205 | ///
206 | public static bool CheckPort(string port)
207 | {
208 | // Skip the check and return true if the selected port is 'DFU Device'
209 | if (port == "DFU Device")
210 | {
211 | return true;
212 | }
213 |
214 | bool result = false;
215 |
216 | // Try to open the serial port, catch an exception if we fail
217 | SerialPort serialPort = new SerialPort(port);
218 | try
219 | {
220 | serialPort.Open();
221 | if (serialPort.IsOpen)
222 | {
223 | result = true;
224 | }
225 | }
226 | catch (Exception ex)
227 | {
228 | Debug.WriteLine(ex.Message);
229 | }
230 | finally
231 | {
232 | Thread.Sleep(50);
233 | serialPort.Close();
234 | }
235 |
236 | return result;
237 | }
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/DfuRecoveryDialog.Designer.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2019 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | partial class DfuRecoveryDialog
24 | {
25 | ///
26 | /// Required designer variable.
27 | ///
28 | private System.ComponentModel.IContainer components = null;
29 |
30 | ///
31 | /// Clean up any resources being used.
32 | ///
33 | /// true if managed resources should be disposed; otherwise, false.
34 | protected override void Dispose(bool disposing)
35 | {
36 | if (disposing && (components != null))
37 | {
38 | components.Dispose();
39 | }
40 | base.Dispose(disposing);
41 | }
42 |
43 | #region Windows Form Designer generated code
44 |
45 | ///
46 | /// Required method for Designer support - do not modify
47 | /// the contents of this method with the code editor.
48 | ///
49 | private void InitializeComponent()
50 | {
51 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DfuRecoveryDialog));
52 | this.dialogText = new System.Windows.Forms.Label();
53 | this.buttonCancel = new System.Windows.Forms.Button();
54 | this.warningIcon = new System.Windows.Forms.PictureBox();
55 | this.panel2 = new System.Windows.Forms.Panel();
56 | this.timerProgressBar = new System.Windows.Forms.ProgressBar();
57 | ((System.ComponentModel.ISupportInitialize)(this.warningIcon)).BeginInit();
58 | this.panel2.SuspendLayout();
59 | this.SuspendLayout();
60 | //
61 | // dialogText
62 | //
63 | resources.ApplyResources(this.dialogText, "dialogText");
64 | this.dialogText.Name = "dialogText";
65 | //
66 | // buttonCancel
67 | //
68 | resources.ApplyResources(this.buttonCancel, "buttonCancel");
69 | this.buttonCancel.Name = "buttonCancel";
70 | this.buttonCancel.TabStop = false;
71 | this.buttonCancel.UseVisualStyleBackColor = true;
72 | this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
73 | //
74 | // warningIcon
75 | //
76 | resources.ApplyResources(this.warningIcon, "warningIcon");
77 | this.warningIcon.Name = "warningIcon";
78 | this.warningIcon.TabStop = false;
79 | //
80 | // panel2
81 | //
82 | this.panel2.BackColor = System.Drawing.SystemColors.ControlLightLight;
83 | this.panel2.Controls.Add(this.timerProgressBar);
84 | this.panel2.Controls.Add(this.dialogText);
85 | this.panel2.Controls.Add(this.warningIcon);
86 | resources.ApplyResources(this.panel2, "panel2");
87 | this.panel2.Name = "panel2";
88 | //
89 | // timerProgressBar
90 | //
91 | resources.ApplyResources(this.timerProgressBar, "timerProgressBar");
92 | this.timerProgressBar.Maximum = 30;
93 | this.timerProgressBar.Name = "timerProgressBar";
94 | this.timerProgressBar.Step = 1;
95 | this.timerProgressBar.Value = 30;
96 | //
97 | // DfuRecoveryDialog
98 | //
99 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
100 | resources.ApplyResources(this, "$this");
101 | this.ControlBox = false;
102 | this.Controls.Add(this.buttonCancel);
103 | this.Controls.Add(this.panel2);
104 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
105 | this.MaximizeBox = false;
106 | this.MinimizeBox = false;
107 | this.Name = "DfuRecoveryDialog";
108 | ((System.ComponentModel.ISupportInitialize)(this.warningIcon)).EndInit();
109 | this.panel2.ResumeLayout(false);
110 | this.ResumeLayout(false);
111 |
112 | }
113 |
114 | #endregion
115 |
116 | private System.Windows.Forms.Label dialogText;
117 | private System.Windows.Forms.Button buttonCancel;
118 | private System.Windows.Forms.PictureBox warningIcon;
119 | private System.Windows.Forms.Panel panel2;
120 | private System.Windows.Forms.ProgressBar timerProgressBar;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/DfuRecoveryDialog.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Threading.Tasks;
25 | using System.Windows.Forms;
26 |
27 | ///
28 | /// Class for the DFU recovery dialog form.
29 | ///
30 | public partial class DfuRecoveryDialog : Form
31 | {
32 | private Timer progressTimer = new Timer();
33 | private FlashMulti flashMulti;
34 |
35 | ///
36 | /// Initializes a new instance of the class.
37 | ///
38 | /// An instance of the form.
39 | public DfuRecoveryDialog(FlashMulti flashMulti)
40 | {
41 | this.InitializeComponent();
42 | this.flashMulti = flashMulti;
43 | this.Load += this.DfuRecoveryDialog_Load;
44 | this.Shown += this.DfuRecoveryDialog_Shown;
45 | }
46 |
47 | ///
48 | /// Prompts the user to unplug / replug the module to get it into recovery mode.
49 | ///
50 | /// Event sender.
51 | /// Event arguments.
52 | private async void DfuRecoveryDialog_Shown(object sender, EventArgs e)
53 | {
54 | // Check if we have a DFU device we need to see unplugged
55 | bool dfuCheck = MapleDevice.FindMaple().DfuMode;
56 |
57 | if (dfuCheck)
58 | {
59 | this.flashMulti.AppendLog("Waiting for DFU device to disappear ...");
60 |
61 | // Wait 30s for the DFU device to disappear and reappear
62 | await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000, true); });
63 |
64 | // Handle user cancelling DFU recovery
65 | if (this.DialogResult == DialogResult.Cancel)
66 | {
67 | return;
68 | }
69 |
70 | if (dfuCheck)
71 | {
72 | // Wait 30s for the DFU device to disappear
73 | await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000, true); });
74 |
75 | if (dfuCheck)
76 | {
77 | // The module was unplugged
78 | this.flashMulti.AppendLog(" gone.\r\n");
79 | }
80 | else
81 | {
82 | // The module wasn't unplugged when the timer expired.
83 | this.flashMulti.AppendLog(" timed out!\r\n");
84 | using (new CenterWinDialog(this.flashMulti))
85 | {
86 | MessageBox.Show("DFU device was not unplugged in time.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error);
87 | }
88 |
89 | this.DialogResult = DialogResult.Cancel;
90 | this.Close();
91 | return;
92 | }
93 | }
94 | }
95 |
96 | this.flashMulti.AppendLog("Waiting for DFU device to appear ...");
97 |
98 | // Wait for the DFU device to appear
99 | await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000 - (this.timerProgressBar.Value * 1000)); });
100 |
101 | // Handle user cancelling DFU recovery
102 | if (this.DialogResult == DialogResult.Cancel)
103 | {
104 | return;
105 | }
106 |
107 | if (dfuCheck)
108 | {
109 | // The module was plugged in
110 | this.flashMulti.AppendLog(" got it.\r\n");
111 | this.DialogResult = DialogResult.OK;
112 | this.Close();
113 | return;
114 | }
115 | else
116 | {
117 | // The module wasn't plugged in when the timer expired
118 | this.flashMulti.AppendLog(" timed out!\r\n");
119 | using (new CenterWinDialog(this))
120 | {
121 | MessageBox.Show("DFU device was not plugged in in time.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error);
122 | }
123 |
124 | this.DialogResult = DialogResult.Abort;
125 | this.Close();
126 | return;
127 | }
128 | }
129 |
130 | ///
131 | /// Handle the Cancel button being clicked.
132 | ///
133 | /// Event sender.
134 | /// Event argument.
135 | private void ButtonCancel_Click(object sender, System.EventArgs e)
136 | {
137 | this.flashMulti.AppendLog(" cancelled.\r\n");
138 | this.DialogResult = DialogResult.Cancel;
139 | this.Close();
140 | return;
141 | }
142 |
143 | ///
144 | /// Configure the timer when the form is loaded.
145 | ///
146 | /// Event sender.
147 | /// Event arguments.
148 | private void DfuRecoveryDialog_Load(object sender, EventArgs e)
149 | {
150 | // Configures the timer used to count the progress bar down
151 | this.progressTimer.Enabled = true;
152 | this.progressTimer.Interval = 1000;
153 |
154 | // Configure the progress bar
155 | this.timerProgressBar.Minimum = 0;
156 | this.timerProgressBar.Maximum = 30;
157 | this.timerProgressBar.Value = 0;
158 | this.progressTimer.Tick += new EventHandler(this.ProgressBarTimer_TickUp);
159 |
160 | // Start the timer to count the bar down
161 | this.progressTimer.Start();
162 | }
163 |
164 | ///
165 | /// Increment the progress bar when the timer ticks.
166 | ///
167 | /// Event sender.
168 | /// Event arguments.
169 | private void ProgressBarTimer_TickUp(object sender, EventArgs e)
170 | {
171 | if (this.timerProgressBar.Value != this.timerProgressBar.Maximum)
172 | {
173 | this.timerProgressBar.Value++;
174 | }
175 | else
176 | {
177 | this.progressTimer.Stop();
178 | }
179 | }
180 |
181 | ///
182 | /// Increment the progress bar when the timer ticks.
183 | ///
184 | /// Event sender.
185 | /// Event arguments.
186 | private void ProgressBarTimer_TickDown(object sender, EventArgs e)
187 | {
188 | if (this.timerProgressBar.Value != this.timerProgressBar.Minimum)
189 | {
190 | this.timerProgressBar.Value--;
191 | }
192 | else
193 | {
194 | this.progressTimer.Stop();
195 | }
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/SerialMonitor.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Flash_Multi
2 | {
3 | partial class SerialMonitor
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SerialMonitor));
32 | this.serialOutput = new System.Windows.Forms.TextBox();
33 | this.buttonClose = new System.Windows.Forms.Button();
34 | this.buttonClear = new System.Windows.Forms.Button();
35 | this.buttonSave = new System.Windows.Forms.Button();
36 | this.buttonDisconnect = new System.Windows.Forms.Button();
37 | this.buttonConnect = new System.Windows.Forms.Button();
38 | this.checkBoxAutoScroll = new System.Windows.Forms.CheckBox();
39 | this.SuspendLayout();
40 | //
41 | // serialOutput
42 | //
43 | this.serialOutput.BackColor = System.Drawing.SystemColors.ControlLightLight;
44 | resources.ApplyResources(this.serialOutput, "serialOutput");
45 | this.serialOutput.Name = "serialOutput";
46 | this.serialOutput.ReadOnly = true;
47 | //
48 | // buttonClose
49 | //
50 | resources.ApplyResources(this.buttonClose, "buttonClose");
51 | this.buttonClose.Name = "buttonClose";
52 | this.buttonClose.UseVisualStyleBackColor = true;
53 | this.buttonClose.Click += new System.EventHandler(this.ButtonClose_Click);
54 | //
55 | // buttonClear
56 | //
57 | resources.ApplyResources(this.buttonClear, "buttonClear");
58 | this.buttonClear.Name = "buttonClear";
59 | this.buttonClear.UseVisualStyleBackColor = true;
60 | this.buttonClear.Click += new System.EventHandler(this.ButtonClear_Click);
61 | //
62 | // buttonSave
63 | //
64 | resources.ApplyResources(this.buttonSave, "buttonSave");
65 | this.buttonSave.Name = "buttonSave";
66 | this.buttonSave.UseVisualStyleBackColor = true;
67 | this.buttonSave.Click += new System.EventHandler(this.ButtonSave_Click);
68 | //
69 | // buttonDisconnect
70 | //
71 | resources.ApplyResources(this.buttonDisconnect, "buttonDisconnect");
72 | this.buttonDisconnect.Name = "buttonDisconnect";
73 | this.buttonDisconnect.UseVisualStyleBackColor = true;
74 | this.buttonDisconnect.Click += new System.EventHandler(this.ButtonDisconnect_Click);
75 | //
76 | // buttonConnect
77 | //
78 | resources.ApplyResources(this.buttonConnect, "buttonConnect");
79 | this.buttonConnect.Name = "buttonConnect";
80 | this.buttonConnect.UseVisualStyleBackColor = true;
81 | this.buttonConnect.Click += new System.EventHandler(this.ButtonConnect_Click);
82 | //
83 | // checkBoxAutoScroll
84 | //
85 | resources.ApplyResources(this.checkBoxAutoScroll, "checkBoxAutoScroll");
86 | this.checkBoxAutoScroll.Checked = true;
87 | this.checkBoxAutoScroll.CheckState = System.Windows.Forms.CheckState.Checked;
88 | this.checkBoxAutoScroll.Name = "checkBoxAutoScroll";
89 | this.checkBoxAutoScroll.UseVisualStyleBackColor = true;
90 | //
91 | // SerialMonitor
92 | //
93 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
94 | resources.ApplyResources(this, "$this");
95 | this.Controls.Add(this.checkBoxAutoScroll);
96 | this.Controls.Add(this.buttonConnect);
97 | this.Controls.Add(this.buttonDisconnect);
98 | this.Controls.Add(this.buttonSave);
99 | this.Controls.Add(this.buttonClear);
100 | this.Controls.Add(this.buttonClose);
101 | this.Controls.Add(this.serialOutput);
102 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
103 | this.MaximizeBox = false;
104 | this.MinimizeBox = false;
105 | this.Name = "SerialMonitor";
106 | this.ResumeLayout(false);
107 | this.PerformLayout();
108 |
109 | }
110 |
111 | #endregion
112 |
113 | private System.Windows.Forms.TextBox serialOutput;
114 | private System.Windows.Forms.Button buttonClose;
115 | private System.Windows.Forms.Button buttonClear;
116 | private System.Windows.Forms.Button buttonSave;
117 | private System.Windows.Forms.Button buttonDisconnect;
118 | private System.Windows.Forms.Button buttonConnect;
119 | private System.Windows.Forms.CheckBox checkBoxAutoScroll;
120 | }
121 | }
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/UsbSupportErrorDialog.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Flash_Multi
2 | {
3 | partial class UsbSupportErrorDialog
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UsbSupportErrorDialog));
32 | this.panel2 = new System.Windows.Forms.Panel();
33 | this.moreInfoLinkLabel = new System.Windows.Forms.LinkLabel();
34 | this.dialogText = new System.Windows.Forms.Label();
35 | this.errorIcon = new System.Windows.Forms.PictureBox();
36 | this.buttonOK = new System.Windows.Forms.Button();
37 | this.panel2.SuspendLayout();
38 | ((System.ComponentModel.ISupportInitialize)(this.errorIcon)).BeginInit();
39 | this.SuspendLayout();
40 | //
41 | // panel2
42 | //
43 | this.panel2.BackColor = System.Drawing.SystemColors.ControlLightLight;
44 | this.panel2.Controls.Add(this.moreInfoLinkLabel);
45 | this.panel2.Controls.Add(this.dialogText);
46 | this.panel2.Controls.Add(this.errorIcon);
47 | this.panel2.Location = new System.Drawing.Point(0, 0);
48 | this.panel2.Name = "panel2";
49 | this.panel2.Size = new System.Drawing.Size(405, 147);
50 | this.panel2.TabIndex = 6;
51 | //
52 | // moreInfoLinkLabel
53 | //
54 | this.moreInfoLinkLabel.AutoSize = true;
55 | this.moreInfoLinkLabel.LinkArea = new System.Windows.Forms.LinkArea(6, 4);
56 | this.moreInfoLinkLabel.Location = new System.Drawing.Point(57, 114);
57 | this.moreInfoLinkLabel.Name = "moreInfoLinkLabel";
58 | this.moreInfoLinkLabel.Size = new System.Drawing.Size(178, 21);
59 | this.moreInfoLinkLabel.TabIndex = 3;
60 | this.moreInfoLinkLabel.TabStop = true;
61 | this.moreInfoLinkLabel.Text = "Click here for more information.";
62 | this.moreInfoLinkLabel.UseCompatibleTextRendering = true;
63 | this.moreInfoLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.MoreInfoLinkLabel_LinkClicked);
64 | //
65 | // dialogText
66 | //
67 | this.dialogText.ImeMode = System.Windows.Forms.ImeMode.NoControl;
68 | this.dialogText.Location = new System.Drawing.Point(54, 13);
69 | this.dialogText.Name = "dialogText";
70 | this.dialogText.Size = new System.Drawing.Size(306, 101);
71 | this.dialogText.TabIndex = 0;
72 | this.dialogText.Text = resources.GetString("dialogText.Text");
73 | //
74 | // errorIcon
75 | //
76 | this.errorIcon.ImeMode = System.Windows.Forms.ImeMode.NoControl;
77 | this.errorIcon.Location = new System.Drawing.Point(13, 13);
78 | this.errorIcon.Name = "errorIcon";
79 | this.errorIcon.Size = new System.Drawing.Size(34, 34);
80 | this.errorIcon.TabIndex = 2;
81 | this.errorIcon.TabStop = false;
82 | //
83 | // buttonOK
84 | //
85 | this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
86 | this.buttonOK.Location = new System.Drawing.Point(325, 153);
87 | this.buttonOK.Name = "buttonOK";
88 | this.buttonOK.Size = new System.Drawing.Size(67, 24);
89 | this.buttonOK.TabIndex = 7;
90 | this.buttonOK.TabStop = false;
91 | this.buttonOK.Text = "OK";
92 | this.buttonOK.UseVisualStyleBackColor = true;
93 | this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
94 | //
95 | // UsbSupportErrorDialog
96 | //
97 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
98 | this.ClientSize = new System.Drawing.Size(404, 187);
99 | this.ControlBox = false;
100 | this.Controls.Add(this.buttonOK);
101 | this.Controls.Add(this.panel2);
102 | this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
103 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
104 | this.MaximizeBox = false;
105 | this.MinimizeBox = false;
106 | this.Name = "UsbSupportErrorDialog";
107 | this.ShowInTaskbar = false;
108 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
109 | this.Text = "USB Support Error";
110 | this.panel2.ResumeLayout(false);
111 | this.panel2.PerformLayout();
112 | ((System.ComponentModel.ISupportInitialize)(this.errorIcon)).EndInit();
113 | this.ResumeLayout(false);
114 |
115 | }
116 |
117 | #endregion
118 | private System.Windows.Forms.Panel panel2;
119 | private System.Windows.Forms.Label dialogText;
120 | private System.Windows.Forms.PictureBox errorIcon;
121 | private System.Windows.Forms.Button buttonOK;
122 | private System.Windows.Forms.LinkLabel moreInfoLinkLabel;
123 | }
124 | }
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/UsbSupportErrorDialog.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Diagnostics;
25 | using System.Windows.Forms;
26 |
27 | ///
28 | /// Class for the USB Support warning dialog.
29 | ///
30 | public partial class UsbSupportErrorDialog : Form
31 | {
32 | ///
33 | /// Initializes a new instance of the class.
34 | ///
35 | public UsbSupportErrorDialog()
36 | {
37 | this.InitializeComponent();
38 | }
39 |
40 | ///
41 | /// Set the icon when the dialog is loaded.
42 | ///
43 | protected override void OnShown(EventArgs e)
44 | {
45 | this.errorIcon.Image = System.Drawing.SystemIcons.Error.ToBitmap();
46 | base.OnShown(e);
47 | }
48 |
49 | ///
50 | /// Handles the Cancel button being clicked.
51 | ///
52 | private void ButtonCancel_Click(object sender, EventArgs e)
53 | {
54 | // Return Cancel
55 | this.DialogResult = DialogResult.Cancel;
56 | this.Close();
57 | return;
58 | }
59 |
60 | ///
61 | /// Handles the OK button being clicked.
62 | ///
63 | private void ButtonOK_Click(object sender, EventArgs e)
64 | {
65 | // Return OK
66 | this.DialogResult = DialogResult.OK;
67 | this.Close();
68 | return;
69 | }
70 |
71 | ///
72 | /// Opens a URL in the default browser.
73 | ///
74 | /// The URL to open.
75 | private void OpenLink(string url)
76 | {
77 | try
78 | {
79 | System.Diagnostics.Process.Start(url);
80 | }
81 | catch (Exception ex)
82 | {
83 | Debug.WriteLine(ex.Message);
84 | }
85 | }
86 |
87 | private void MoreInfoLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
88 | {
89 | this.OpenLink("https://github.com/benlye/flash-multi/blob/master/doc/New_Bootloader.md");
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/UsbSupportErrorDialog.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | The selected firmware file was compiled without USB serial support and the 'USB Port Mode' setting is set to 'COM Port (Legacy)'.
122 |
123 | The MULTI-Module bootloader must be updated and the 'USB Port Mode' setting set to 'Sticky DFU Mode (New)' in order to write this firmware.
124 |
125 |
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/UsbSupportWarningDialog.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Flash_Multi
2 | {
3 | partial class UsbSupportWarningDialog
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UsbSupportWarningDialog));
32 | this.buttonCancel = new System.Windows.Forms.Button();
33 | this.panel2 = new System.Windows.Forms.Panel();
34 | this.dialogText = new System.Windows.Forms.Label();
35 | this.warningIcon = new System.Windows.Forms.PictureBox();
36 | this.buttonOK = new System.Windows.Forms.Button();
37 | this.disableUsbWarning = new System.Windows.Forms.CheckBox();
38 | this.panel2.SuspendLayout();
39 | ((System.ComponentModel.ISupportInitialize)(this.warningIcon)).BeginInit();
40 | this.SuspendLayout();
41 | //
42 | // buttonCancel
43 | //
44 | this.buttonCancel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
45 | this.buttonCancel.Location = new System.Drawing.Point(322, 121);
46 | this.buttonCancel.Name = "buttonCancel";
47 | this.buttonCancel.Size = new System.Drawing.Size(67, 24);
48 | this.buttonCancel.TabIndex = 6;
49 | this.buttonCancel.Text = "Cancel";
50 | this.buttonCancel.UseVisualStyleBackColor = true;
51 | this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
52 | //
53 | // panel2
54 | //
55 | this.panel2.BackColor = System.Drawing.SystemColors.ControlLightLight;
56 | this.panel2.Controls.Add(this.dialogText);
57 | this.panel2.Controls.Add(this.warningIcon);
58 | this.panel2.Location = new System.Drawing.Point(0, 0);
59 | this.panel2.Name = "panel2";
60 | this.panel2.Size = new System.Drawing.Size(405, 113);
61 | this.panel2.TabIndex = 6;
62 | //
63 | // dialogText
64 | //
65 | this.dialogText.ImeMode = System.Windows.Forms.ImeMode.NoControl;
66 | this.dialogText.Location = new System.Drawing.Point(54, 13);
67 | this.dialogText.Name = "dialogText";
68 | this.dialogText.Size = new System.Drawing.Size(306, 96);
69 | this.dialogText.TabIndex = 0;
70 | this.dialogText.Text = "The selected firmware file was compiled without USB serial support. The MULTI-Mod" +
71 | "ule bootloader should be updated before writing this firmware.\r\n\r\nClick OK to wr" +
72 | "ite the firmware.";
73 | //
74 | // warningIcon
75 | //
76 | this.warningIcon.Image = ((System.Drawing.Image)(resources.GetObject("warningIcon.Image")));
77 | this.warningIcon.ImeMode = System.Windows.Forms.ImeMode.NoControl;
78 | this.warningIcon.Location = new System.Drawing.Point(13, 13);
79 | this.warningIcon.Name = "warningIcon";
80 | this.warningIcon.Size = new System.Drawing.Size(34, 34);
81 | this.warningIcon.TabIndex = 2;
82 | this.warningIcon.TabStop = false;
83 | //
84 | // buttonOK
85 | //
86 | this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
87 | this.buttonOK.Location = new System.Drawing.Point(249, 121);
88 | this.buttonOK.Name = "buttonOK";
89 | this.buttonOK.Size = new System.Drawing.Size(67, 24);
90 | this.buttonOK.TabIndex = 5;
91 | this.buttonOK.Text = "OK";
92 | this.buttonOK.UseVisualStyleBackColor = true;
93 | this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
94 | //
95 | // disableUsbWarning
96 | //
97 | this.disableUsbWarning.AutoSize = true;
98 | this.disableUsbWarning.Location = new System.Drawing.Point(13, 121);
99 | this.disableUsbWarning.Name = "disableUsbWarning";
100 | this.disableUsbWarning.Size = new System.Drawing.Size(196, 19);
101 | this.disableUsbWarning.TabIndex = 4;
102 | this.disableUsbWarning.Text = "Do not show this message again";
103 | this.disableUsbWarning.UseVisualStyleBackColor = true;
104 | //
105 | // UsbSupportWarningDialog
106 | //
107 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
108 | this.ClientSize = new System.Drawing.Size(404, 152);
109 | this.ControlBox = false;
110 | this.Controls.Add(this.disableUsbWarning);
111 | this.Controls.Add(this.buttonOK);
112 | this.Controls.Add(this.buttonCancel);
113 | this.Controls.Add(this.panel2);
114 | this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
115 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
116 | this.MaximizeBox = false;
117 | this.MinimizeBox = false;
118 | this.Name = "UsbSupportWarningDialog";
119 | this.ShowInTaskbar = false;
120 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
121 | this.Text = "USB Support Warning";
122 | this.panel2.ResumeLayout(false);
123 | ((System.ComponentModel.ISupportInitialize)(this.warningIcon)).EndInit();
124 | this.ResumeLayout(false);
125 | this.PerformLayout();
126 |
127 | }
128 |
129 | #endregion
130 |
131 | private System.Windows.Forms.Button buttonCancel;
132 | private System.Windows.Forms.Panel panel2;
133 | private System.Windows.Forms.Label dialogText;
134 | private System.Windows.Forms.PictureBox warningIcon;
135 | private System.Windows.Forms.Button buttonOK;
136 | private System.Windows.Forms.CheckBox disableUsbWarning;
137 | }
138 | }
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/UsbSupportWarningDialog.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Diagnostics;
25 | using System.Windows.Forms;
26 |
27 | ///
28 | /// Class for the USB Support warning dialog.
29 | ///
30 | public partial class UsbSupportWarningDialog : Form
31 | {
32 | ///
33 | /// Initializes a new instance of the class.
34 | ///
35 | public UsbSupportWarningDialog()
36 | {
37 | this.InitializeComponent();
38 | }
39 |
40 | ///
41 | /// Set the icon when the dialog is loaded.
42 | ///
43 | protected override void OnShown(EventArgs e)
44 | {
45 | this.warningIcon.Image = System.Drawing.SystemIcons.Warning.ToBitmap();
46 | base.OnShown(e);
47 | }
48 |
49 | ///
50 | /// Handles the Cancel button being clicked.
51 | ///
52 | private void ButtonCancel_Click(object sender, EventArgs e)
53 | {
54 | // Return Cancel
55 | this.DialogResult = DialogResult.Cancel;
56 | this.Close();
57 | return;
58 | }
59 |
60 | ///
61 | /// Handles the OK button being clicked.
62 | ///
63 | private void ButtonOK_Click(object sender, EventArgs e)
64 | {
65 | // Disable the warning if the box was checked
66 | if (this.disableUsbWarning.Checked == true)
67 | {
68 | Properties.Settings.Default.WarnIfNoUSB = false;
69 | }
70 |
71 | // Return OK
72 | this.DialogResult = DialogResult.OK;
73 | this.Close();
74 | return;
75 | }
76 |
77 | ///
78 | /// Opens a URL in the default browser.
79 | ///
80 | /// The URL to open.
81 | private void OpenLink(string url)
82 | {
83 | try
84 | {
85 | System.Diagnostics.Process.Start(url);
86 | }
87 | catch (Exception ex)
88 | {
89 | Debug.WriteLine(ex.Message);
90 | }
91 | }
92 |
93 | private void MoreInfoLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
94 | {
95 | this.OpenLink("https://github.com/benlye/flash-multi/blob/master/doc/New_Bootloader.md");
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/flash-multi/Dialogs/UsbSupportWarningDialog.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 |
123 | iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
124 | wwAADsMBx2+oZAAABt1JREFUWEftVntMW9cdvkBtEiqWpVvSZGwJA5SGPqZVTVuSjqxLQqXSpdmUpZ2S
125 | JZXa0EjTUrVaknV/bOv+mbqQFwb72hjbsXkFDMYmBhtsZuJXsA0mvAkpyrJAIDYYO5hg1rTffte+Wztt
126 | Uro2qTZpn/TpXN9zzu/7ve45Zv6P/0nIlQpBk8HwXmND47tyueK7/OsvDyqVcpvB0DJnaXeAHCiWSNhk
127 | fur+g2Ul36yuqbtms5lgtzfAYDAtyWTlP+On7z8UCvnxRp0N5ubDuGheB4vFDLVG202ZeIhfcv8glbLP
128 | aLXNUZ2uAcPulZi4IoS1YSdazD5QFn7PL7s/YFk2pbKySmc02tFavxsAE2df51fQYT4LbYP5xqlTJx/j
129 | l997UPQ/bW7uuNPaWoPx7tR/OICPGFhqtsLhHKYsKAjKJH7LvYNEIl5ZU1M35nAMUsoLE8KLPMmBfuuD
130 | 8DoqYDK7YzKpbDu/7d5BJpMda2u7iAs2Flc8qZCKn8KRd3bg6JFt+N1vCvCBPx3Ohifh7hpATW19e3m5
131 | PJXf+sUhFos36vUtgR6/H+7WfPw1yuDw4SIUFf0WB4vexYEDR+A0rceENx2u1l/D1TX0cUmJ6HV++xcD
132 | NV6yWq0uHxr+Cy46T+DPA0Iszafg2NF9OHToHXLi59h/4HW4TZlAaBk6Kx/D1I1pNOlNwywrzeDNfH6I
133 | xaXft1hdt7s8LozYv0X1TsKdqIDS/2Ps3fcmXnl1H3a+vAseE80FVuGGOw127UFMBxZAZXifN/P5QKlP
134 | ra6u9U7fvAWH6U3MTwiBhYcQm0nD228VoPClV1Dwwkt4/vkfwGNcA1z/GpZGlsGhycBY/5/Q6fDepAx+
135 | hzf3n4OO3CK7w3/H4zFg3P0wEF5BXItYMA2/OLQFz+btIH4PW/O3wGdcBYynY3HgQUy0pcBW9SJmQ7eh
136 | Vldp6J5I4U1+dlDqMxp1zdemb87B1rSLhNMpxd8AZjIQm05H0YEnkPtoHjY9/RxeKMhHv2klcFmIhW4B
137 | Fn0M/JVCdLWegMc3EhWJRC/yZj87FAqVZnBoAhcdClx1fh0IrsFHExnAxBosjKzE7sJVWLZ8Ndatz0H+
138 | c0+it1GAD0k47CBeILYxaC3Jpl4Ioa6+yUHH9Are9N1BtX/c0GyeGR0dgaNxOzApRGwsDdGBZEoxgzkP
139 | g4LNDGgphKkrsCUvFz01SViwMZg1E43kANHPCqkhfwXfpXFIWekbCet3ATWNQKXSWEcvT6JdW4QZTzKi
140 | PWTQyyDkZjDfxeAWjTvzEw48vDYLu3flY6AuCdF2Em8mGhjM6GnUMTAXr4bPZYFO3zJKpbj7Z0mNt8vY
141 | YrtjNjegT5eO2yTORTxHoiEnibsY3Kbf+ws5Bx5AZs7T2LtnBwbPkQNc9CQ808Qg2EAj8bIsBS2Sl+H2
142 | jYHOhT/yMv8eEonkq1XV50acrj60Vf8IgQvJmKOIQyTKiYfsRK6+nXQDqhmcf58uoRIGXjmDSW0i8iBF
143 | HSDhQB2D6Vp6d46BvViINu1JnDd1hqVS6SZe7l9RLq842Wb1oUV/BkM6IcKcODXV34VnO4gWygKxR8ng
144 | zNsM3isSovU4gyjVPEhOcMIBEp2qIVYRKxl8IE2B4cQzsLsGoFKp63m5fwZFn1l7TjdpMplhqd6OoC05
145 | ETUJh6i5Qpw41XiOGKXnY3u5EgiwOuMpHNybhysaWsNFTuJc5HFxnkFyxkVZMCiPoqXduURNvpOX/QRK
146 | pUpnNDlxnrp2VC+kZhMg7KIsOGjkStGZhLA1Ib5AJdizjXMgDZs278Br+19FXwXtOc+V4AGqvwABrTDO
147 | oFZAvSDENU0KlSwbVosNZzW1zjOnz3zyWVLj5dVr9fOGprNwaAvw8eVsxAZyEbu0ETH/I4j1bMBidw5i
148 | PnrvzQL8mfBo1uGH23Ow5yeFUPxhK2bM38aifSPmO3Jxq+NRzNs45sYZJS7ZH0Gfai30soNoNtoglrBv
149 | 8fIMo9FUWkzmTvqb9Ut0V2XCV7kBPjVRRVTmfIrZ8Cqz4vQTndIsWE6vh0tKDsmz0SXfgK5ynvTs+RS9
150 | xG7aY5U8i3ajHrV1umunTp3OSjhQWdXn8Xajv9eDgV4v0YfB3h4M9fkx3N+L8bFhXL86jsDUDYSCAczN
151 | cgwizDEUjD9znA1MYWryOqYmruPq2ChGB/vi+zk7nL0Bf8LuJX8vrNbOD/PyNhfEHSg+XlwmlcpmRaKy
152 | iEgkSbBUEiktYyNlEjYiYWURlq2IsNKKiLRCEamoUCaoUEXoyI6P9DvMkebDtC7MsvKwhJWGy8RsmOyE
153 | yV64RCQOi4ilpZyOqGf58rTMuAM8uGvzy+Z/Axjmb16JL+4sqeK+AAAAAElFTkSuQmCC
154 |
155 |
156 |
--------------------------------------------------------------------------------
/src/flash-multi/Eeprom/AtmegaEepromUtils.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Diagnostics;
25 | using System.IO;
26 |
27 | ///
28 | /// Functions for working with the EEPROM of an Atmega328p-based MULTI-Module.
29 | ///
30 | internal class AtmegaEepromUtils
31 | {
32 | ///
33 | /// EEPROM page size; 1024 bytes on the STM32F103.
34 | ///
35 | private const int EepromSize = 0x400;
36 |
37 | ///
38 | /// Extract the EEPROM data from an EEPROM backup file.
39 | ///
40 | /// The name of the backup file to parse.
41 | /// The EEPROM data.
42 | internal static byte[] GetEepromDataFromBackup(string filename)
43 | {
44 | byte[] eepromData;
45 |
46 | // Get the file size
47 | long length = new System.IO.FileInfo(filename).Length;
48 |
49 | // File is not the right size to contain EEPROM data
50 | if (length != 1024)
51 | {
52 | return null;
53 | }
54 |
55 | // Read the binary file
56 | using (BinaryReader b = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
57 | {
58 | eepromData = b.ReadBytes(EepromSize);
59 | }
60 |
61 | return eepromData;
62 | }
63 |
64 | ///
65 | /// Read a single address from the EEPROM data and retun the value.
66 | ///
67 | /// The virtual address to read.
68 | /// A byte array containing the EEPROM data.
69 | /// The variable value or -1 if the address was not found.
70 | internal static int ReadEepromVariable(int address, byte[] eepromData)
71 | {
72 | if (address >= 0 && address < EepromSize)
73 | {
74 | return eepromData[address];
75 | }
76 | else
77 | {
78 | return -1;
79 | }
80 | }
81 |
82 | ///
83 | /// Retrieves the Global ID from the EEPROM data.
84 | ///
85 | /// A byte array containing the EEPROM data.
86 | /// The Global ID.
87 | internal static uint ReadGlobalId(byte[] eepromData)
88 | {
89 | uint id = 0;
90 |
91 | // Read the four EEPROM variables containing the Global ID
92 | for (int i = 3; i >= 0; i--)
93 | {
94 | // Get the variable data
95 | int var = ReadEepromVariable(10 + i, eepromData);
96 | if (var < 0)
97 | {
98 | return 0;
99 | }
100 |
101 | // Shift the ID left 8 bits for the next value
102 | id <<= 8;
103 |
104 | // OR the variables together
105 | id |= (uint)var;
106 | }
107 |
108 | return id;
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/flash-multi/Eeprom/Stm32EepromUtils.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Diagnostics;
25 | using System.IO;
26 | using System.Linq;
27 |
28 | ///
29 | /// Functions for working with the emulated EEPROM of the STM32F103.
30 | ///
31 | internal class Stm32EepromUtils
32 | {
33 | ///
34 | /// EEPROM page size; 1024 bytes on the STM32F103.
35 | ///
36 | private const int PageSize = 0x400;
37 |
38 | ///
39 | /// Base address of EEPROM page 0.
40 | ///
41 | private const int PageBase0 = 0;
42 |
43 | ///
44 | /// Base address of EEPROM page 1.
45 | ///
46 | private const int PageBase1 = 0x400;
47 |
48 | ///
49 | /// Page header of an erased EEPROM page.
50 | ///
51 | private const int EepromPageErased = 0xFFFF;
52 |
53 | ///
54 | /// Page header of a valid EEPROM page.
55 | ///
56 | private const int EepromPageValid = 0x0000;
57 |
58 | ///
59 | /// Extract the EEPROM data from a backup file.
60 | /// The EEPROM data is the last 2048 bytes of the file.
61 | ///
62 | /// The name of the backup file to parse.
63 | /// The EEPROM data.
64 | internal static byte[] GetEepromDataFromBackup(string filename)
65 | {
66 | byte[] eepromData;
67 |
68 | // Get the file size
69 | long length = new System.IO.FileInfo(filename).Length;
70 |
71 | // File is too small to contain EEPROM data
72 | if (length < 2048)
73 | {
74 | return null;
75 | }
76 |
77 | // Read the last 2048 bytes of the binary file
78 | using (BinaryReader b = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
79 | {
80 | long offset = new System.IO.FileInfo(filename).Length - 2048;
81 |
82 | // Seek to our required position.
83 | b.BaseStream.Seek(offset, SeekOrigin.Begin);
84 |
85 | // Read the next 2048 bytes.
86 | eepromData = b.ReadBytes(2048);
87 | }
88 |
89 | return eepromData;
90 | }
91 |
92 | ///
93 | /// Find the valid page in the EEPROM data.
94 | ///
95 | /// A byte array containing the EEPROM data.
96 | /// The start address of the valid page.
97 | internal static int FindValidPage(byte[] eepromData)
98 | {
99 | if (eepromData != null)
100 | {
101 | // Get the status page bytes
102 | byte[] status0Bytes = { eepromData[PageBase0 + 1], eepromData[PageBase0] };
103 | byte[] status1Bytes = { eepromData[PageBase1 + 1], eepromData[PageBase1] };
104 |
105 | // Convert the bytes to integers
106 | int status0 = System.Convert.ToInt32(BitConverter.ToString(status0Bytes).Replace("-", string.Empty), 16);
107 | int status1 = System.Convert.ToInt32(BitConverter.ToString(status1Bytes).Replace("-", string.Empty), 16);
108 |
109 | // Compare the page status values to determine the valid page
110 | if (status0 == EepromPageValid && status1 == EepromPageErased)
111 | {
112 | return PageBase0;
113 | }
114 |
115 | if (status0 == EepromPageErased && status1 == EepromPageValid)
116 | {
117 | return PageBase1;
118 | }
119 | }
120 |
121 | Debug.WriteLine($"No valid EEPROM page found!");
122 | return -1;
123 | }
124 |
125 | ///
126 | /// Read a single address from the EEPROM data and retun the value.
127 | ///
128 | /// The virtual address to read.
129 | /// A byte array containing the EEPROM data.
130 | /// The variable value or -1 if the address was not found.
131 | internal static int ReadEepromVariable(int address, byte[] eepromData)
132 | {
133 | int pageBase = FindValidPage(eepromData);
134 |
135 | if (pageBase < 0)
136 | {
137 | return -1;
138 | }
139 |
140 | int pageEnd = pageBase + PageSize - 2;
141 |
142 | for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
143 | {
144 | byte[] addressBytes = { eepromData[pageEnd + 1], eepromData[pageEnd] };
145 | int addressValue = System.Convert.ToInt32(BitConverter.ToString(addressBytes).Replace("-", string.Empty), 16);
146 |
147 | if (addressValue == address)
148 | {
149 | byte[] dataBytes = { eepromData[pageEnd - 1], eepromData[pageEnd - 2] };
150 | int dataValue = System.Convert.ToInt32(BitConverter.ToString(dataBytes).Replace("-", string.Empty), 16);
151 | return dataValue;
152 | }
153 | }
154 |
155 | return -1;
156 | }
157 |
158 | ///
159 | /// Retrieves the Global ID from the EEPROM data.
160 | ///
161 | /// A byte array containing the EEPROM data.
162 | /// The Global ID.
163 | internal static uint ReadGlobalId(byte[] eepromData)
164 | {
165 | uint id = 0;
166 |
167 | // Read the four EEPROM variables containing the Global ID
168 | for (int i = 3; i >= 0; i--)
169 | {
170 | // Get the variable data
171 | int var = ReadEepromVariable(10 + i, eepromData);
172 | if (var < 0)
173 | {
174 | return 0;
175 | }
176 |
177 | // Shift the ID left 8 bits for the next value
178 | id <<= 8;
179 |
180 | // OR the variables together
181 | id |= (uint)var;
182 | }
183 |
184 | return id;
185 | }
186 |
187 | ///
188 | /// Check if the firmware section of the flash memory is empty (contains all 0xFF).
189 | ///
190 | /// The name of the firmware backup file to evaluate.
191 | /// A boolean indicating whether or not the firmware data is empty.
192 | internal static bool FirmwareIsEmpty(string filename)
193 | {
194 | long filesize = new System.IO.FileInfo(filename).Length;
195 | using (BinaryReader b = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
196 | {
197 | // Read the file, excluding the EEPROM data
198 | b.BaseStream.Seek(0, SeekOrigin.Begin);
199 | byte[] data = b.ReadBytes((int)filesize - 2048);
200 |
201 | return data.Distinct().Count() == 1 && data.Distinct().FirstOrDefault() == 255;
202 | }
203 | }
204 |
205 | ///
206 | /// Check if the EEPROM section of the flash memory is empty (contains all 0xFF).
207 | ///
208 | /// The name of the firmware backup file to evaluate.
209 | /// A boolean indicating whether or not the EEPROM data is empty.
210 | internal static bool EepromIsEmpty(string filename)
211 | {
212 | byte[] data = GetEepromDataFromBackup(filename);
213 | if (data != null)
214 | {
215 | return data.Distinct().Count() == 1 && data.Distinct().FirstOrDefault() == 255;
216 | }
217 | else
218 | {
219 | return true;
220 | }
221 | }
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/src/flash-multi/Program.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Windows.Forms;
25 |
26 | ///
27 | /// The main class.
28 | ///
29 | public static class Program
30 | {
31 | ///
32 | /// The main entry point for the application.
33 | ///
34 | [STAThread]
35 | private static void Main()
36 | {
37 | Application.EnableVisualStyles();
38 | Application.SetCompatibleTextRenderingDefault(false);
39 | Application.Run(new FlashMulti());
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/flash-multi/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | using System.Reflection;
22 | using System.Runtime.InteropServices;
23 |
24 | // General Information about an assembly is controlled through the following
25 | // set of attributes. Change these attribute values to modify the information
26 | // associated with an assembly.
27 | [assembly: AssemblyTitle("flash-multi")]
28 | [assembly: AssemblyDescription("MULTI-Module firmware updater")]
29 | [assembly: AssemblyConfiguration("")]
30 | [assembly: AssemblyCompany("Ben Lye")]
31 | [assembly: AssemblyProduct("flash-multi")]
32 | [assembly: AssemblyCopyright("Copyright © 2020")]
33 | [assembly: AssemblyTrademark("")]
34 | [assembly: AssemblyCulture("")]
35 |
36 | // Setting ComVisible to false makes the types in this assembly not visible
37 | // to COM components. If you need to access a type in this assembly from
38 | // COM, set the ComVisible attribute to true on that type.
39 | [assembly: ComVisible(false)]
40 |
41 | // The following GUID is for the ID of the typelib if this project is exposed to COM
42 | [assembly: Guid("72d5a55c-cc93-422c-a12f-cce99e1c7300")]
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("0.6.2")]
55 | [assembly: AssemblyFileVersion("0.6.2")]
56 |
--------------------------------------------------------------------------------
/src/flash-multi/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Flash_Multi.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Flash_Multi.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/flash-multi/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/src/flash-multi/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Flash_Multi.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("-1, -1")]
29 | public global::System.Drawing.Point WindowLocation {
30 | get {
31 | return ((global::System.Drawing.Point)(this["WindowLocation"]));
32 | }
33 | set {
34 | this["WindowLocation"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
41 | public bool CheckForUpdates {
42 | get {
43 | return ((bool)(this["CheckForUpdates"]));
44 | }
45 | set {
46 | this["CheckForUpdates"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("115200")]
53 | public int SerialBaudRate {
54 | get {
55 | return ((int)(this["SerialBaudRate"]));
56 | }
57 | set {
58 | this["SerialBaudRate"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("-1, -1")]
65 | public global::System.Drawing.Point SerialMonitorWindowLocation {
66 | get {
67 | return ((global::System.Drawing.Point)(this["SerialMonitorWindowLocation"]));
68 | }
69 | set {
70 | this["SerialMonitorWindowLocation"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("en-US")]
77 | public string Language {
78 | get {
79 | return ((string)(this["Language"]));
80 | }
81 | set {
82 | this["Language"] = value;
83 | }
84 | }
85 |
86 | [global::System.Configuration.UserScopedSettingAttribute()]
87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
88 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
89 | public bool RunAfterUpload {
90 | get {
91 | return ((bool)(this["RunAfterUpload"]));
92 | }
93 | set {
94 | this["RunAfterUpload"] = value;
95 | }
96 | }
97 |
98 | [global::System.Configuration.UserScopedSettingAttribute()]
99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
100 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
101 | public bool EnableDeviceDetection {
102 | get {
103 | return ((bool)(this["EnableDeviceDetection"]));
104 | }
105 | set {
106 | this["EnableDeviceDetection"] = value;
107 | }
108 | }
109 |
110 | [global::System.Configuration.UserScopedSettingAttribute()]
111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
112 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
113 | public bool ErrorIfNoUSB {
114 | get {
115 | return ((bool)(this["ErrorIfNoUSB"]));
116 | }
117 | set {
118 | this["ErrorIfNoUSB"] = value;
119 | }
120 | }
121 |
122 | [global::System.Configuration.UserScopedSettingAttribute()]
123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
124 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
125 | public bool WarnIfNoUSB {
126 | get {
127 | return ((bool)(this["WarnIfNoUSB"]));
128 | }
129 | set {
130 | this["WarnIfNoUSB"] = value;
131 | }
132 | }
133 |
134 | [global::System.Configuration.UserScopedSettingAttribute()]
135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
136 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
137 | public bool DisableFlashVerification {
138 | get {
139 | return ((bool)(this["DisableFlashVerification"]));
140 | }
141 | set {
142 | this["DisableFlashVerification"] = value;
143 | }
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/flash-multi/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | -1, -1
7 |
8 |
9 | True
10 |
11 |
12 | 115200
13 |
14 |
15 | -1, -1
16 |
17 |
18 | en-US
19 |
20 |
21 | False
22 |
23 |
24 | True
25 |
26 |
27 | False
28 |
29 |
30 | True
31 |
32 |
33 | False
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/flash-multi/README.txt:
--------------------------------------------------------------------------------
1 |
2 | Flash Multi Readme
3 | ==============================
4 |
5 | 1. MULTI-Module Drivers
6 |
7 | The Flash Multi installer only installs USB and DFU mode drivers for
8 | the native 'Maple' serial port (if they are selected).
9 |
10 | If your version of Windows requires additional serial port drivers
11 | for your MULTI-Module, you will need to install those manually.
12 |
13 | See the Flash Multi documentation for more information.
14 | https://github.com/benlye/flash-multi/
15 |
--------------------------------------------------------------------------------
/src/flash-multi/RunCommand.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System.Diagnostics;
24 | using System.IO;
25 |
26 | ///
27 | /// Class for running commands.
28 | ///
29 | internal class RunCommand
30 | {
31 | ///
32 | /// Runs a command with arguments.
33 | ///
34 | /// An instance of the class.
35 | /// The command to run.
36 | /// Arguments for the command.
37 | /// The exit code returned by the command.
38 | public static int Run(FlashMulti flashMulti, string command, string args)
39 | {
40 | Debug.WriteLine("\n" + command + " " + args + "\n");
41 | flashMulti.AppendVerbose(command + " " + args + "\r\n");
42 |
43 | // Check if the file exists
44 | if (!File.Exists(command))
45 | {
46 | flashMulti.AppendVerbose(string.Format("{0} does not exist", command));
47 | return -1;
48 | }
49 |
50 | Process myProcess = new Process();
51 |
52 | // Process process = new Process();
53 | myProcess.StartInfo.FileName = command;
54 | myProcess.StartInfo.Arguments = args;
55 | myProcess.StartInfo.UseShellExecute = false;
56 | myProcess.StartInfo.RedirectStandardOutput = true;
57 | myProcess.StartInfo.RedirectStandardError = true;
58 | myProcess.StartInfo.CreateNoWindow = true;
59 |
60 | // avrdude sends all output to stderr, so reverse the sync/async processing
61 | if (command.EndsWith("avrdude.exe"))
62 | {
63 | // Handle standard output asynchronously
64 | myProcess.OutputDataReceived += new DataReceivedEventHandler(flashMulti.OutputHandler);
65 |
66 | // Start process and handlers
67 | myProcess.Start();
68 |
69 | // Read the standard output asynchronously, handle it by line
70 | myProcess.BeginOutputReadLine();
71 |
72 | // Read the error output synchronously, handle it character-by-character
73 | while (!myProcess.StandardError.EndOfStream)
74 | {
75 | var data = myProcess.StandardError.Read();
76 | flashMulti.CharOutputHandler((char)data);
77 | }
78 | }
79 | else
80 | {
81 | // Hande error output asynchronously
82 | myProcess.ErrorDataReceived += new DataReceivedEventHandler(flashMulti.OutputHandler);
83 |
84 | // Start process and handlers
85 | myProcess.Start();
86 |
87 | // Read the error output asynchronously, handle it by line
88 | myProcess.BeginErrorReadLine();
89 |
90 | // Read the standard output synchronously, handle it character-by-character
91 | while (!myProcess.StandardOutput.EndOfStream)
92 | {
93 | var data = myProcess.StandardOutput.Read();
94 | flashMulti.CharOutputHandler((char)data);
95 | }
96 | }
97 |
98 | // Loop until the process finishes
99 | myProcess.WaitForExit();
100 |
101 | int returnCode = myProcess.ExitCode;
102 | myProcess.Dispose();
103 |
104 | // Return the exit code from the process
105 | return returnCode;
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/flash-multi/UpdateCheck.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Diagnostics;
25 | using System.IO;
26 | using System.Net;
27 | using System.Text.RegularExpressions;
28 | using System.Threading.Tasks;
29 | using System.Windows.Forms;
30 |
31 | ///
32 | /// Class for performing application update checks.
33 | ///
34 | internal class UpdateCheck
35 | {
36 | ///
37 | /// Gets a value indicating whether or not the Github version check succeeded.
38 | ///
39 | public bool CheckSuccess { get; private set; }
40 |
41 | ///
42 | /// Gets a containing the version of the latest release.
43 | ///
44 | public Version LatestVersion { get; private set; }
45 |
46 | ///
47 | /// Gets a string containing the URL of the latest release.
48 | ///
49 | public string ReleaseUrl { get; private set; }
50 |
51 | ///
52 | /// Prompt the user if a newer version is available.
53 | ///
54 | /// An instance of the class.
55 | /// Indicate whether or not to show a message if there is no update.
56 | public static async void DoCheck(FlashMulti flashMulti, bool showNoUpdate = false)
57 | {
58 | // Get check for the latest version on Github
59 | UpdateCheck check = new UpdateCheck();
60 | await Task.Run(() => { check = GetLatestVersion(); });
61 |
62 | // If the check completed successfully
63 | if (check.CheckSuccess)
64 | {
65 | // Get the current version
66 | Version currentVersion = Version.Parse(Application.ProductVersion);
67 |
68 | // Get the version available on Github
69 | Version latestVersion = check.LatestVersion;
70 |
71 | // Check if the current version is older than the latest Github release version
72 | if (currentVersion.CompareTo(latestVersion) == -1)
73 | {
74 | // A newer version is available to show the user a prompt
75 | Debug.WriteLine($"App version is older than latest version: {currentVersion} < {latestVersion}");
76 |
77 | DialogResult showUpdate;
78 | using (new CenterWinDialog(flashMulti))
79 | {
80 | showUpdate = MessageBox.Show(
81 | $"{Strings.updatePromptPart1} v{currentVersion} {Strings.updatePromptPart2} v{latestVersion} {Strings.updatePromptPart3}",
82 | Strings.dialogTitleUpdateCheck,
83 | MessageBoxButtons.YesNo,
84 | MessageBoxIcon.Information);
85 | }
86 |
87 | // Show the Github release page for the new version if the user clicked Yes
88 | if (showUpdate == DialogResult.Yes)
89 | {
90 | flashMulti.OpenLink(check.ReleaseUrl);
91 | }
92 | }
93 | else
94 | {
95 | if (showNoUpdate)
96 | {
97 | using (new CenterWinDialog(flashMulti))
98 | {
99 | MessageBox.Show(Strings.updateNoUpdate, Strings.dialogTitleUpdateCheck, MessageBoxButtons.OK);
100 | }
101 | }
102 | }
103 | }
104 | else
105 | {
106 | if (showNoUpdate)
107 | {
108 | using (new CenterWinDialog(flashMulti))
109 | {
110 | MessageBox.Show(Strings.updateCheckFailed, Strings.dialogTitleUpdateCheck, MessageBoxButtons.OK);
111 | }
112 | }
113 | }
114 | }
115 |
116 | ///
117 | /// Gets the latest release tag from Github.
118 | ///
119 | /// Returns an .
120 | private static UpdateCheck GetLatestVersion()
121 | {
122 | // Somewhere to store the results
123 | UpdateCheck results = new UpdateCheck
124 | {
125 | CheckSuccess = false,
126 | };
127 |
128 | try
129 | {
130 | // The API URL to check for the latest release
131 | // Returns a JSON payload containing all the details of the latest release
132 | string releasesUrl = "https://api.github.com/repos/benlye/flash-multi/releases/latest";
133 |
134 | // Set TLS1.2, as required by the Github API
135 | System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
136 |
137 | // Create the WebRequest
138 | HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(releasesUrl);
139 |
140 | // Set the UserAgent, as required by the Github API
141 | webRequest.UserAgent = $"flash-multi-{Application.ProductVersion}";
142 |
143 | // Disable keepalive so we don't hold a connection open
144 | webRequest.KeepAlive = false;
145 |
146 | // Get the response and read it
147 | using (WebResponse myResponse = webRequest.GetResponse())
148 | using (StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8))
149 | {
150 | // Read all of the output from the StreamReader
151 | string result = sr.ReadToEnd();
152 |
153 | // Parse the release tag out of the JSON
154 | // This contains the version string
155 | int tagStart = result.IndexOf("\"tag_name\":");
156 | int tagEnd = result.IndexOf(",", tagStart);
157 | string tagLine = result.Substring(tagStart, tagEnd - tagStart);
158 | string tag = tagLine.Split('"')[3];
159 |
160 | // Add the release tag to the results
161 | results.LatestVersion = Version.Parse(tag);
162 |
163 | // Parse the release URL out of the JSON
164 | // This is the URL of the Github page containing details of the latest release
165 | int urlStart = result.IndexOf("\"html_url\":");
166 | int urlEnd = result.IndexOf(",", urlStart);
167 | string urlLine = result.Substring(urlStart, urlEnd - urlStart);
168 | string url = urlLine.Split('"')[3];
169 |
170 | // Add the release URL to the results
171 | results.ReleaseUrl = url;
172 | }
173 |
174 | // Define a regular expression to test the version number looks how we expect it to
175 | Regex versionRegex = new Regex(@"\d+\.\d+\.\d+");
176 |
177 | // Check that the URL and version number are as we expect
178 | if (results.ReleaseUrl.StartsWith("https://github.com/benlye/flash-multi/releases/") && versionRegex.Match(results.LatestVersion.ToString()).Success)
179 | {
180 | // All looks good; the check succeeded
181 | Debug.WriteLine($"Update check succeeded. Latest version is {results.LatestVersion}");
182 | results.CheckSuccess = true;
183 | }
184 | }
185 | catch (Exception ex)
186 | {
187 | Debug.WriteLine($"Error getting latest version: {ex.Message}");
188 | }
189 |
190 | // Return the results
191 | return results;
192 | }
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/src/flash-multi/UsbDeviceInfo.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System.Collections.Generic;
24 | using System.Management;
25 |
26 | ///
27 | /// Class for retrieving information about connected USB devices.
28 | ///
29 | internal class UsbDeviceInfo
30 | {
31 | ///
32 | /// Initializes a new instance of the class.
33 | ///
34 | /// The USB device ID.
35 | /// The PNP Device ID.
36 | /// Description of the device.
37 | /// Device manufacturer.
38 | /// Device name.
39 | /// Device status.
40 | public UsbDeviceInfo(string deviceID, string pnpDeviceID, string description, string manufacturer, string name, string status)
41 | {
42 | this.DeviceID = deviceID;
43 | this.PnpDeviceID = pnpDeviceID;
44 | this.Description = description;
45 | this.Manufacturer = manufacturer;
46 | this.Name = name;
47 | this.Status = status;
48 | }
49 |
50 | ///
51 | /// Gets the device ID.
52 | ///
53 | public string DeviceID { get; private set; }
54 |
55 | ///
56 | /// Gets the PnP device ID.
57 | ///
58 | public string PnpDeviceID { get; private set; }
59 |
60 | ///
61 | /// Gets the device description.
62 | ///
63 | public string Description { get; private set; }
64 |
65 | ///
66 | /// Gets the device manufacturer.
67 | ///
68 | public string Manufacturer { get; private set; }
69 |
70 | ///
71 | /// Gets the device name.
72 | ///
73 | public string Name { get; private set; }
74 |
75 | ///
76 | /// Gets the device status.
77 | ///
78 | public string Status { get; private set; }
79 |
80 | ///
81 | /// Gets a list of devices matching the Maple DeviceID.
82 | ///
83 | /// Returns a list of devices.
84 | public static List GetUSBDevices()
85 | {
86 | // Create a list to store the output
87 | List devices = new List();
88 |
89 | // Use WMI to find all the Maple devices
90 | ManagementObjectCollection collection;
91 | using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity WHERE DeviceID like '%VID_1EAF&%' OR DeviceID like '%VID_16C0%'"))
92 | using (collection = searcher.Get())
93 | {
94 | foreach (var device in collection)
95 | {
96 | devices.Add(new UsbDeviceInfo(
97 | (string)device.GetPropertyValue("DeviceID"),
98 | (string)device.GetPropertyValue("PNPDeviceID"),
99 | (string)device.GetPropertyValue("Description"),
100 | (string)device.GetPropertyValue("Manufacturer"),
101 | (string)device.GetPropertyValue("Name"),
102 | (string)device.GetPropertyValue("Status")));
103 | }
104 | }
105 |
106 | // Return the list of devices
107 | return devices;
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/flash-multi/UsbNotification.cs:
--------------------------------------------------------------------------------
1 | // -------------------------------------------------------------------------------
2 | //
3 | // Copyright 2020 Ben Lye
4 | //
5 | // This file is part of Flash Multi.
6 | //
7 | // Flash Multi is free software: you can redistribute it and/or modify it under
8 | // the terms of the GNU General Public License as published by the Free Software
9 | // Foundation, either version 3 of the License, or(at your option) any later
10 | // version.
11 | //
12 | // Flash Multi is distributed in the hope that it will be useful, but WITHOUT
13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 | // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along with
17 | // Flash Multi. If not, see http://www.gnu.org/licenses/.
18 | //
19 | // -------------------------------------------------------------------------------
20 |
21 | namespace Flash_Multi
22 | {
23 | using System;
24 | using System.Runtime.InteropServices;
25 |
26 | ///
27 | /// Class for handling USB devices being plugged / unplugged.
28 | ///
29 | internal static class UsbNotification
30 | {
31 | ///
32 | /// Constant indicating a new device.
33 | ///
34 | public const int DbtDevicearrival = 0x8000; // system detected a new device
35 |
36 | ///
37 | /// Constant indicating a device has been removed.
38 | ///
39 | public const int DbtDeviceremovecomplete = 0x8004;
40 |
41 | ///
42 | /// Constant indicating a device change event.
43 | ///
44 | public const int WmDevicechange = 0x0219;
45 |
46 | ///
47 | /// Device type.
48 | ///
49 | private const int DbtDevtypDeviceinterface = 5;
50 |
51 | ///
52 | /// GUID for USB devices.
53 | ///
54 | private static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");
55 | private static IntPtr notificationHandle;
56 |
57 | ///
58 | /// Registers a window to receive notifications when USB devices are plugged or unplugged.
59 | ///
60 | /// Handle to the window receiving notifications.
61 | public static void RegisterUsbDeviceNotification(IntPtr windowHandle)
62 | {
63 | DevBroadcastDeviceinterface dbi = new DevBroadcastDeviceinterface
64 | {
65 | DeviceType = DbtDevtypDeviceinterface,
66 | Reserved = 0,
67 | ClassGuid = GuidDevinterfaceUSBDevice,
68 | Name = 0,
69 | };
70 |
71 | dbi.Size = Marshal.SizeOf(dbi);
72 | IntPtr buffer = Marshal.AllocHGlobal(dbi.Size);
73 | Marshal.StructureToPtr(dbi, buffer, true);
74 |
75 | notificationHandle = RegisterDeviceNotification(windowHandle, buffer, 0);
76 | }
77 |
78 | ///
79 | /// Unregisters the window for USB device notifications.
80 | ///
81 | public static void UnregisterUsbDeviceNotification()
82 | {
83 | UnregisterDeviceNotification(notificationHandle);
84 | }
85 |
86 | [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
87 | private static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags);
88 |
89 | [DllImport("user32.dll")]
90 | private static extern bool UnregisterDeviceNotification(IntPtr handle);
91 |
92 | [StructLayout(LayoutKind.Sequential)]
93 | private struct DevBroadcastDeviceinterface
94 | {
95 | internal int Size;
96 | internal int DeviceType;
97 | internal int Reserved;
98 | internal Guid ClassGuid;
99 | internal short Name;
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/flash-multi/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | -1, -1
12 |
13 |
14 | True
15 |
16 |
17 | 115200
18 |
19 |
20 | -1, -1
21 |
22 |
23 | en-US
24 |
25 |
26 | False
27 |
28 |
29 | True
30 |
31 |
32 | False
33 |
34 |
35 | True
36 |
37 |
38 | False
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/flash-multi/flash-multi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {72D5A55C-CC93-422C-A12F-CCE99E1C7300}
8 | WinExe
9 | Flash_Multi
10 | flash-multi
11 | v4.5
12 | 512
13 | true
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 |
37 |
38 | icon.ico
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Form
57 |
58 |
59 | UsbSupportErrorDialog.cs
60 |
61 |
62 | Form
63 |
64 |
65 | UsbSupportWarningDialog.cs
66 |
67 |
68 |
69 |
70 | Form
71 |
72 |
73 | DfuRecoveryDialog.cs
74 |
75 |
76 |
77 |
78 | Form
79 |
80 |
81 | FlashMulti.cs
82 |
83 |
84 |
85 |
86 |
87 | True
88 | True
89 | Resources.resx
90 |
91 |
92 |
93 |
94 | Form
95 |
96 |
97 | SerialMonitor.cs
98 |
99 |
100 | True
101 | True
102 | Strings.resx
103 |
104 |
105 |
106 |
107 |
108 |
109 | DfuRecoveryDialog.cs
110 |
111 |
112 | SerialMonitor.cs
113 |
114 |
115 | UsbSupportErrorDialog.cs
116 |
117 |
118 | UsbSupportWarningDialog.cs
119 |
120 |
121 | FlashMulti.cs
122 |
123 |
124 | FlashMulti.cs
125 |
126 |
127 | SerialMonitor.cs
128 |
129 |
130 | ResXFileCodeGenerator
131 | Strings.Designer.cs
132 | Flash_Multi
133 |
134 |
135 | ResXFileCodeGenerator
136 | Resources.Designer.cs
137 |
138 |
139 |
140 |
141 | SettingsSingleFileGenerator
142 | Settings.Designer.cs
143 |
144 |
145 | True
146 | Settings.settings
147 | True
148 |
149 |
150 |
151 |
152 |
153 | Always
154 |
155 |
156 |
157 | Always
158 |
159 |
160 | Always
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | XCOPY "$(SolutionDir)tools\*.*" "$(TargetDir)" /S /Y
171 |
172 |
--------------------------------------------------------------------------------
/src/flash-multi/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/flash-multi/icon.ico
--------------------------------------------------------------------------------
/src/flash-multi/license.txt:
--------------------------------------------------------------------------------
1 | Copyright 2019 Ben Lye
2 |
3 | Flash Multi is free software: you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation, either version 3 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with Flash Multi. If not, see .
15 |
--------------------------------------------------------------------------------
/src/flash-multi/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/flash-multi/stylecop.json:
--------------------------------------------------------------------------------
1 | {
2 | // ACTION REQUIRED: This file was automatically added to your project, but it
3 | // will not take effect until additional steps are taken to enable it. See the
4 | // following page for additional information:
5 | //
6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
7 |
8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
9 | "settings": {
10 | "documentationRules": {
11 | "companyName": "Ben Lye",
12 | "copyrightText": "Copyright 2020 Ben Lye\n\nThis file is part of Flash Multi.\n\nFlash Multi is free software: you can redistribute it and/or modify it under\nthe terms of the GNU General Public License as published by the Free Software\nFoundation, either version 3 of the License, or(at your option) any later\nversion.\n\nFlash Multi is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with\nFlash Multi. If not, see http://www.gnu.org/licenses/.",
13 | "headerDecoration": "-------------------------------------------------------------------------------"
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/make_release.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Import the Visual Studio command line build environment, remembering the current working directory
4 | PUSHD %cd%
5 | IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsMSBuildCmd.bat" (
6 | CALL "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat"
7 | POPD
8 | GOTO BUILD
9 | )
10 | IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Professional\Common7\Tools\VsMSBuildCmd.bat" (
11 | CALL "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Professional\Common7\Tools\VsMSBuildCmd.bat"
12 | POPD
13 | GOTO BUILD
14 | )
15 |
16 | ECHO Couldn't find Visual Studio tools
17 | GOTO :EOF
18 |
19 | :BUILD
20 | REM Delete any existing build output
21 | rmdir /s /q .\flash-multi\bin
22 |
23 | REM Run the build command
24 | msbuild /t:Clean /p:Configuration=Release
25 | msbuild /t:Build /p:Configuration=Release
26 |
27 | REM Get the version
28 | FOR /F "USEBACKQ" %%F IN (`powershell -NoLogo -NoProfile -Command ^(Get-Item ".\flash-multi\bin\Release\flash-multi.exe"^).VersionInfo.FileVersion`) DO (SET fileVersion=%%F)
29 | echo File version: %fileVersion%
30 |
31 | REM Create the zip archive
32 | "C:\Program Files\7-Zip\7z.exe" a -r -x!*.pdb .\flash-multi\bin\flash-multi-%fileVersion%.zip .\flash-multi\bin\Release
33 |
34 | REM Rename the root folder in the zip
35 | "C:\Program Files\7-Zip\7z.exe" rn .\flash-multi\bin\flash-multi-%fileVersion%.zip Release\ flash-multi-%fileVersion%\
36 |
37 | REM Create the installer package
38 | REM "C:\Program Files (x86)\Inno Setup 6\iscc.exe" /Qp /DMyAppVersion=%fileVersion% flash-multi.iss
39 | REM "C:\Program Files (x86)\NSIS\Bin\makensis.exe" /DVERSION=%fileVersion% flash-multi.nsi
40 |
41 | REM Get the SH256 hashes from the files
42 | ECHO.
43 | FOR /F "USEBACKQ" %%F IN (`powershell -NoLogo -NoProfile -Command ^(Get-FileHash ".\flash-multi\bin\flash-multi-%fileVersion%.zip"^).Hash`) DO (SET fileHash=%%F)
44 | ECHO flash-multi-%fileVersion%.zip: %fileHash%
45 |
46 | REM FOR /F "USEBACKQ" %%F IN (`powershell -NoLogo -NoProfile -Command ^(Get-FileHash ".\flash-multi\bin\flash-multi-%fileVersion%.exe"^).Hash`) DO (SET fileHash=%%F)
47 | REM ECHO flash-multi-%fileVersion%.exe: %fileHash%
48 |
--------------------------------------------------------------------------------
/src/make_release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | VERSION=$(grep "^VERSION=[0-9].[0-9].[0-9]" "../linux/flash-multi" | awk -F = '{ print $2 }')
4 |
5 | echo
6 | echo "Version: $VERSION"
7 | echo "Creating archive 'flash-multi-$VERSION.tar.gz'"
8 | tar -czf /tmp/flash-multi-$VERSION.tar.gz --transform s/linux/flash-multi-$VERSION/ ../linux/*
9 | sleep 1s
10 |
11 | SHA=`(sha256sum /tmp/flash-multi-$VERSION.tar.gz | awk -v N=1 '{print $N}')`
12 |
13 | echo
14 | echo "Package: flash-multi-$VERSION.tar.gz"
15 | echo "SHA256: ${SHA^^}"
16 | echo "Size: `(ls -al /tmp/flash-multi-$VERSION.tar.gz | awk -v N=5 '{print $N}')`"
17 | echo
18 |
--------------------------------------------------------------------------------
/src/tools/bootloaders/AtmegaMultiBoot.hex:
--------------------------------------------------------------------------------
1 | :107E0000112484B714BE9FEF9BB99CE395B991E010
2 | :107E100098B98370A9F08AEF80938500109284004E
3 | :107E200085E08093810096BBB09BFECF10928100CD
4 | :107E300093B186B181709C73892B8D3109F0B3D0D9
5 | :107E400082E08093C00088E18093C10086E0809347
6 | :107E5000C20081E28093C400259AC0E0D0E093E0A4
7 | :107E6000F92EEE24E39425E0D22E31E1C32EA9D0E1
8 | :107E7000813481F4A6D08EBBABD08EB3823811F49E
9 | :107E800085E006C08EB3813811F484E001C083E040
10 | :107E900091D086C0823411F484E103C0853419F492
11 | :107EA00085E09DD07DC0853541F48BD0C82F89D029
12 | :107EB000D0E0D82BCC0FDD1F72C0863521F484E0D2
13 | :107EC0008ED080E0E5CF843609F03DC07AD079D0FD
14 | :107ED000B82E77D0C11520E7D20718F000E011E0E6
15 | :107EE00004C0FE01F7BEE895F9CF6BD0F80181938D
16 | :107EF0008F01BE12FACFCE01905781159E4018F423
17 | :107F0000FE01F7BEE89564D0C115FEE7DF0708F073
18 | :107F100047C007B600FCFDCFFE01A0E0B1E08D91A7
19 | :107F20009D910C01E7BEE89511243296A03821E01E
20 | :107F3000B207A9F7FE01D7BEE89507B600FCFDCF52
21 | :107F4000C7BEE8952DC08437B1F43BD03AD0B82EE7
22 | :107F500038D03ED0FE01AC2EAB0C8F010F5F1F4F0F
23 | :107F6000849128D0A01205C02196BA94CB0DD11DC2
24 | :107F700017C0F801F2CF853739F42AD08EE11AD034
25 | :107F800085E918D08FE084CF813549F421D080E194
26 | :107F900011D08091C00086FFFCCF05D001C018D061
27 | :107FA00080E108D064CFE0E0F0E084918F3F09F0F9
28 | :107FB000099408959091C00095FFFCCF8093C6006E
29 | :107FC00008958091C00087FFFCCF8091C60008957E
30 | :107FD000F8DF803211F085E1EDDF84E1EBCFCF9364
31 | :107FE000C82FEFDFC150E9F7CF91F2CFA8950895E0
32 | :0C7FF000E0E6F0E098E1908380830895C3
33 | :0400000300007E007B
34 | :00000001FF
35 |
--------------------------------------------------------------------------------
/src/tools/bootloaders/StmMulti4in1_Legacy.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/bootloaders/StmMulti4in1_Legacy.bin
--------------------------------------------------------------------------------
/src/tools/bootloaders/StmMulti4in1_StickyDfu.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/bootloaders/StmMulti4in1_StickyDfu.bin
--------------------------------------------------------------------------------
/src/tools/drivers/install_drivers.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | echo Installing MULTI-Module DFU Bootloader Driver...
4 | "%~dp0wdi-simple" --vid 0x1EAF --pid 0x0003 --type 2 --name "MULTI-Module DFU Bootloader" --dest "%~dp0MULTI-DFU-Bootloader" -b
5 | echo.
6 |
7 | echo Installing MULTI-Module USB Serial Driver...
8 | "%~dp0wdi-simple" --vid 0x1EAF --pid 0x0004 --type 3 --name "MULTI-Module USB Serial" --dest "%~dp0MULTI-USB-Serial" -b
9 | echo.
10 |
--------------------------------------------------------------------------------
/src/tools/drivers/wdi-simple.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/drivers/wdi-simple.exe
--------------------------------------------------------------------------------
/src/tools/tools/BootReloader_Legacy.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/BootReloader_Legacy.bin
--------------------------------------------------------------------------------
/src/tools/tools/BootReloader_StickyDfu.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/BootReloader_StickyDfu.bin
--------------------------------------------------------------------------------
/src/tools/tools/avrdude.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/avrdude.exe
--------------------------------------------------------------------------------
/src/tools/tools/dfu-util-multi.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/dfu-util-multi.exe
--------------------------------------------------------------------------------
/src/tools/tools/erase1.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/erase1.bin
--------------------------------------------------------------------------------
/src/tools/tools/erase118.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/erase118.bin
--------------------------------------------------------------------------------
/src/tools/tools/erase120.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/erase120.bin
--------------------------------------------------------------------------------
/src/tools/tools/erase32.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/erase32.bin
--------------------------------------------------------------------------------
/src/tools/tools/libusb-1.0.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/libusb-1.0.dll
--------------------------------------------------------------------------------
/src/tools/tools/libusb0.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/libusb0.dll
--------------------------------------------------------------------------------
/src/tools/tools/maple-reset.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/maple-reset.exe
--------------------------------------------------------------------------------
/src/tools/tools/stm32flash.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benlye/flash-multi/5baf34d055c91859dfa03f79b8408d7714492f8b/src/tools/tools/stm32flash.exe
--------------------------------------------------------------------------------