1
+ """
2
+ This script is a firmware updater for the Modulino devices.
3
+
4
+ It uses the I2C bootloader to flash the firmware to the device.
5
+ The script finds all .bin files in the root directory and prompts the user to select a file to flash.
6
+ It then scans the I2C bus for devices and prompts the user to select a device to flash.
7
+ You must either know the I2C address of the device to be flashed or make sure that only one device is connected.
8
+ The script sends a reset command to the device, erases the memory, and writes the firmware to the device in chunks.
9
+ Finally, it starts the new firmware on the device.
10
+
11
+ Initial author: Sebastian Romero ([email protected] )
12
+ """
13
+
1
14
import os
2
15
import sys
3
16
from machine import I2C , Pin
@@ -34,7 +47,7 @@ def send_reset(address):
34
47
try :
35
48
print (f"🔄 Resetting device at address { hex (address )} " )
36
49
i2c .writeto (address , buffer , True )
37
- print ("✅ Reset command sent successfully " )
50
+ print ("📤 Reset command sent" )
38
51
time .sleep (0.25 ) # Wait for the device to reset
39
52
return True
40
53
except OSError as e :
@@ -204,7 +217,7 @@ def progress_bar(current, total, bar_length=40):
204
217
:param bar_length: The length of the progress bar in characters.
205
218
"""
206
219
percent = float (current ) / total
207
- arrow = '- ' * int (round (percent * bar_length ))
220
+ arrow = '= ' * int (round (percent * bar_length ))
208
221
spaces = ' ' * (bar_length - len (arrow ))
209
222
sys .stdout .write (f"\r Progress: [{ arrow } { spaces } ] { int (round (percent * 100 ))} %" )
210
223
if current == total :
@@ -225,20 +238,24 @@ def select_file(bin_files):
225
238
:param bin_files: A list of .bin file names.
226
239
:return: The selected .bin file name.
227
240
"""
241
+ if len (bin_files ) == 0 :
242
+ print ("❌ No .bin files found in the root directory." )
243
+ return None
244
+
228
245
if len (bin_files ) == 1 :
229
- confirm = input (f"👀 Found one bin file: { bin_files [0 ]} . Do you want to flash it? (yes/no) " )
246
+ confirm = input (f"📄 Found one biary file: { bin_files [0 ]} . Do you want to flash it? (yes/no) " )
230
247
if confirm .lower () == 'yes' :
231
248
return bin_files [0 ]
232
249
else :
233
250
return None
234
- else :
235
- print ("👀 Found bin files:" )
236
- for index , file in enumerate (bin_files ):
237
- print (f"{ index + 1 } . { file } " )
238
- choice = int (input ("Select the file to flash (number): " ))
239
- if choice < 1 or choice > len (bin_files ):
240
- return None
241
- return bin_files [choice - 1 ]
251
+
252
+ print ("📄 Found binary files:" )
253
+ for index , file in enumerate (bin_files ):
254
+ print (f"{ index + 1 } . { file } " )
255
+ choice = int (input ("Select the file to flash (number): " ))
256
+ if choice < 1 or choice > len (bin_files ):
257
+ return None
258
+ return bin_files [choice - 1 ]
242
259
243
260
def select_i2c_device ():
244
261
"""
@@ -247,7 +264,19 @@ def select_i2c_device():
247
264
:return: The selected I2C device address.
248
265
"""
249
266
devices = i2c .scan ()
250
- print ("👀 I2C devices found:" )
267
+
268
+ if len (devices ) == 0 :
269
+ print ("❌ No I2C devices found" )
270
+ return None
271
+
272
+ if len (devices ) == 1 :
273
+ confirm = input (f"🔌 Found one I2C device at address { hex (devices [0 ])} . Do you want to flash it? (yes/no) " )
274
+ if confirm .lower () == 'yes' :
275
+ return devices [0 ]
276
+ else :
277
+ return None
278
+
279
+ print ("🔌 I2C devices found:" )
251
280
for index , device in enumerate (devices ):
252
281
print (f"{ index + 1 } . Address: { hex (device )} " )
253
282
choice = int (input ("Select the I2C device to flash (number): " ))
0 commit comments