Parse MSP messages from the backpack while TX is in mavlink mode (#2883)
[ExpressLRS.git] / src / python / binary_flash.py
bloba884a0ecee39af95d86f344ef151eecb724b4a09
1 #!/usr/bin/python
3 from enum import Enum
4 import shutil
5 import os
7 from elrs_helpers import ElrsUploadResult
8 import BFinitPassthrough
9 import ETXinitPassthrough
10 import serials_find
11 import UARTupload
12 import upload_via_esp8266_backpack
13 from firmware import DeviceType, FirmwareOptions, MCUType
15 import sys
16 from os.path import dirname
17 sys.path.append(dirname(__file__) + '/external/esptool')
19 from external.esptool import esptool
20 sys.path.append(dirname(__file__) + "/external")
22 import external.pystlink
24 class UploadMethod(Enum):
25 wifi = 'wifi'
26 uart = 'uart'
27 betaflight = 'bf'
28 edgetx = 'etx'
29 stlink = 'stlink'
30 stock = 'stock'
31 dir = 'dir'
33 def __str__(self):
34 return self.value
36 def upload_wifi(args, options, upload_addr, isstm: bool):
37 wifi_mode = 'upload'
38 if args.force == True:
39 wifi_mode = 'uploadforce'
40 elif args.confirm == True:
41 wifi_mode = 'uploadconfirm'
42 if args.port:
43 upload_addr = [args.port]
44 if options.mcuType == MCUType.ESP8266:
45 return upload_via_esp8266_backpack.do_upload('firmware.bin.gz', wifi_mode, upload_addr, isstm, {})
46 else:
47 return upload_via_esp8266_backpack.do_upload(args.file.name, wifi_mode, upload_addr, isstm, {})
49 def upload_stm32_uart(args, options):
50 if args.port == None:
51 args.port = serials_find.get_serial_port()
52 return UARTupload.uart_upload(args.port, args.file.name, args.baud, target=options.firmware.upper(), accept=args.accept, ignore_incorrect_target=args.force)
54 def upload_stm32_stlink(args, options: FirmwareOptions):
55 stlink = external.pystlink.PyStlink(verbosity=1)
57 flash_start = app_start = 0x08000000
58 if "0x" in options.offset:
59 offset = int(options.offset, 16)
60 else:
61 offset = int(options.offset, 10)
62 app_start = flash_start + offset
64 if options.bootloader is not None:
65 bootloader_dir = '' if args.fdir is None else args.fdir + '/'
66 stlink.program_flash(bootloader_dir + 'bootloader/' + options.bootloader, flash_start, erase=True, verify=True, initialize_comms=True)
68 stlink.program_flash(args.file.name, app_start, erase=True, verify=True, initialize_comms=True)
70 return ElrsUploadResult.Success
72 def upload_esp8266_uart(args):
73 if args.port == None:
74 args.port = serials_find.get_serial_port()
75 try:
76 cmd = ['--chip', 'esp8266', '--port', args.port, '--baud', str(args.baud), '--after', 'soft_reset', 'write_flash']
77 if args.erase: cmd.append('--erase-all')
78 cmd.extend(['0x0000', args.file.name])
79 esptool.main(cmd)
80 except:
81 return ElrsUploadResult.ErrorGeneral
82 return ElrsUploadResult.Success
84 def upload_esp8266_bf(args, options):
85 if args.port == None:
86 args.port = serials_find.get_serial_port()
87 mode = 'upload'
88 if args.force == True:
89 mode = 'uploadforce'
90 retval = BFinitPassthrough.main(['-p', args.port, '-b', str(args.baud), '-r', options.firmware, '-a', mode, '--accept', args.accept])
91 if retval != ElrsUploadResult.Success:
92 return retval
93 try:
94 cmd = ['--passthrough', '--chip', 'esp8266', '--port', args.port, '--baud', str(args.baud), '--before', 'no_reset', '--after', 'soft_reset', '--no-stub', 'write_flash']
95 if args.erase: cmd.append('--erase-all')
96 cmd.extend(['0x0000', args.file.name])
97 esptool.main(cmd)
98 except:
99 return ElrsUploadResult.ErrorGeneral
100 return ElrsUploadResult.Success
102 def upload_esp32_uart(args):
103 if args.port == None:
104 args.port = serials_find.get_serial_port()
105 try:
106 dir = os.path.dirname(args.file.name)
107 cmd = ['--chip', args.platform.replace('-', ''), '--port', args.port, '--baud', str(args.baud), '--after', 'hard_reset', 'write_flash']
108 if args.erase: cmd.append('--erase-all')
109 start_addr = '0x0000' if args.platform.startswith('esp32-') else '0x1000'
110 cmd.extend(['-z', '--flash_mode', 'dio', '--flash_freq', '40m', '--flash_size', 'detect', start_addr, os.path.join(dir, 'bootloader.bin'), '0x8000', os.path.join(dir, 'partitions.bin'), '0xe000', os.path.join(dir, 'boot_app0.bin'), '0x10000', args.file.name])
111 esptool.main(cmd)
112 except:
113 return ElrsUploadResult.ErrorGeneral
114 return ElrsUploadResult.Success
116 def upload_esp32_etx(args):
117 if args.port == None:
118 args.port = serials_find.get_serial_port()
119 ETXinitPassthrough.etx_passthrough_init(args.port, args.baud)
120 try:
121 dir = os.path.dirname(args.file.name)
122 cmd = ['--chip', args.platform.replace('-', ''), '--port', args.port, '--baud', str(args.baud), '--before', 'no_reset', '--after', 'hard_reset', 'write_flash']
123 if args.erase: cmd.append('--erase-all')
124 start_addr = '0x0000' if args.platform.startswith('esp32-') else '0x1000'
125 cmd.extend(['-z', '--flash_mode', 'dio', '--flash_freq', '40m', '--flash_size', 'detect', start_addr, os.path.join(dir, 'bootloader.bin'), '0x8000', os.path.join(dir, 'partitions.bin'), '0xe000', os.path.join(dir, 'boot_app0.bin'), '0x10000', args.file.name])
126 esptool.main(cmd)
127 except:
128 return ElrsUploadResult.ErrorGeneral
129 return ElrsUploadResult.Success
131 def upload_esp32_bf(args, options):
132 if args.port == None:
133 args.port = serials_find.get_serial_port()
134 mode = 'upload'
135 if args.force == True:
136 mode = 'uploadforce'
137 retval = BFinitPassthrough.main(['-p', args.port, '-b', str(args.baud), '-r', options.firmware, '-a', mode])
138 if retval != ElrsUploadResult.Success:
139 return retval
140 try:
141 esptool.main(['--passthrough', '--chip', args.platform.replace('-', ''), '--port', args.port, '--baud', str(args.baud), '--before', 'no_reset', '--after', 'hard_reset', 'write_flash', '-z', '--flash_mode', 'dio', '--flash_freq', '40m', '--flash_size', 'detect', '0x10000', args.file.name])
142 except:
143 return ElrsUploadResult.ErrorGeneral
144 return ElrsUploadResult.Success
146 def upload_dir(mcuType, args):
147 if mcuType == MCUType.STM32:
148 if args.flash == UploadMethod.stock:
149 shutil.copy2(args.file.name, os.path.join(args.out, 'firmware.elrs'))
150 else:
151 shutil.copy2(args.file.name, args.out)
152 if mcuType == MCUType.ESP8266:
153 shutil.copy2('firmware.bin.gz', os.path.join(args.out, 'firmware.bin.gz'))
154 elif mcuType == MCUType.ESP32:
155 shutil.copy2(args.file.name, args.out)
157 def upload(options: FirmwareOptions, args):
158 if args.baud == 0:
159 args.baud = 460800
160 if args.flash == UploadMethod.betaflight:
161 args.baud = 420000
163 if args.flash == UploadMethod.dir or args.flash == UploadMethod.stock:
164 return upload_dir(options.mcuType, args)
165 elif options.deviceType == DeviceType.RX:
166 if options.mcuType == MCUType.ESP8266:
167 if args.flash == UploadMethod.betaflight:
168 return upload_esp8266_bf(args, options)
169 elif args.flash == UploadMethod.uart:
170 return upload_esp8266_uart(args)
171 elif args.flash == UploadMethod.wifi:
172 return upload_wifi(args, options, ['elrs_rx', 'elrs_rx.local'], False)
173 elif options.mcuType == MCUType.ESP32:
174 if args.flash == UploadMethod.betaflight:
175 return upload_esp32_bf(args, options)
176 elif args.flash == UploadMethod.uart:
177 return upload_esp32_uart(args)
178 elif args.flash == UploadMethod.wifi:
179 return upload_wifi(args, options, ['elrs_rx', 'elrs_rx.local'], False)
180 elif options.mcuType == MCUType.STM32:
181 if args.flash == UploadMethod.betaflight or args.flash == UploadMethod.uart:
182 return upload_stm32_uart(args, options)
183 elif args.flash == UploadMethod.stlink: # untested
184 return upload_stm32_stlink(args, options)
185 else:
186 if options.mcuType == MCUType.ESP8266:
187 if args.flash == UploadMethod.uart:
188 return upload_esp8266_uart(args)
189 elif args.flash == UploadMethod.wifi:
190 return upload_wifi(args, options, ['elrs_tx', 'elrs_tx.local'], False)
191 elif options.mcuType == MCUType.ESP32:
192 if args.flash == UploadMethod.edgetx:
193 return upload_esp32_etx(args)
194 elif args.flash == UploadMethod.uart:
195 return upload_esp32_uart(args)
196 elif args.flash == UploadMethod.wifi:
197 return upload_wifi(args, options, ['elrs_tx', 'elrs_tx.local'], False)
198 elif options.mcuType == MCUType.STM32:
199 if args.flash == UploadMethod.stlink: # test
200 return upload_stm32_stlink(args, options)
201 elif args.flash == UploadMethod.wifi:
202 return upload_wifi(args, options, ['elrs_txbp', 'elrs_txbp.local'], True)
203 print("Invalid upload method for firmware")
204 return ElrsUploadResult.ErrorGeneral