1111CMD_GET = const (0x00 ) # Gets the version and the allowed commands
1212CMD_GET_VERSION = const (0x01 ) # Gets the protocol version
1313CMD_GET_ID = const (0x02 ) # Get chip ID
14+ CMD_ERASE = const (0x44 ) # Erase memory
15+ CMD_GO = const (0x21 ) # Jumps to user application code located in the internal flash memory
16+ CMD_WRITE = const (0x32 ) # Write memory
1417
1518# Define I2C pins and initialize I2C
16- i2c = I2C (0 , freq = 100000 , timeout = 50000 * 2 )
19+ i2c = I2C (0 , freq = 100000 )
1720
1821def send_reset (address ):
1922 """
@@ -23,25 +26,23 @@ def send_reset(address):
2326 :return: 0 if the reset command was sent successfully, otherwise -1.
2427 """
2528 buffer = b'DIE'
26- # Pad buffer to 40 bytes
27- buffer += b'\x00 ' * (40 - len (buffer ))
29+ buffer += b'\x00 ' * (8 - len (buffer )) # Pad buffer to 8 bytes
2830
2931 try :
3032 print (f"Sending reset command to address { hex (address )} " )
3133 i2c .writeto (address , buffer , True )
32- return False
33- except OSError as e :
34- # pass
35- time .sleep (0.25 )
34+ print ("Reset command sent successfully" )
35+ time .sleep (0.25 ) # Wait for the device to reset
3636 return True
37-
38- # time.sleep(0.25)
39- # devices = i2c.scan()
40-
41- # if address in devices:
42- # return False
43- # elif BOOTLOADER_I2C_ADDRESS in devices:
44- # return True
37+ except OSError as e :
38+ # ENODEV can be thrown if either the device reset while writing out the buffer or if the device
39+ # was already in bootloader mode in which case there is no device at the original address
40+ if e .errno == 19 :
41+ time .sleep (0.25 ) # Wait for the device to reset
42+ return True
43+ else :
44+ print (f"Error sending reset command: { e } " )
45+ return False
4546
4647def wait_for_ack ():
4748 """
@@ -98,7 +99,7 @@ def execute_command(opcode, command_data, response_length = 0, verbose=True):
9899
99100 return data [1 : amount_of_bytes + 1 ]
100101
101- def flash_firmware (firmware , length , verbose = True ):
102+ def flash_firmware (firmware , verbose = True ):
102103 """
103104 Flash the firmware to the I2C device.
104105
@@ -127,32 +128,27 @@ def flash_firmware(firmware, length, verbose=True):
127128
128129 return True # Debug. Remove when done
129130
130- if verbose :
131- print ("Mass erase" )
132- erase_buffer = bytearray ([0xFF , 0xFF , 0x0 ])
133- if execute_command (0x44 , erase_buffer , 3 , None , 0 , verbose ) < 0 :
134- print ("Failed to mass erase" )
135- return False
131+ print ("Erasing memory..." )
132+ erase_buffer = bytearray ([0xFF , 0xFF , 0x0 ]) # Mass erase flash
133+ execute_command (CMD_ERASE , erase_buffer , 0 , verbose )
136134
137- for i in range (0 , length , 128 ):
135+ for i in range (0 , len ( firmware ) , 128 ):
138136 progress_bar (i , length )
139137 write_buffer = bytearray ([8 , 0 , i // 256 , i % 256 ])
140- if write_firmware_page (0x32 , write_buffer , 5 , firmware [i :i + 128 ], 128 , verbose ) < 0 :
138+ if write_firmware_page (write_buffer , 5 , firmware [i :i + 128 ], 128 , verbose ) < 0 :
141139 print (f"Failed to write page { hex (i )} " )
142140 return False
143141 time .sleep (0.01 )
144142
145143 progress_bar (length , length ) # Complete the progress bar
146144
147145 print ("Starting firmware" )
148- jump_buffer = bytearray ([0x8 , 0x00 , 0x00 , 0x00 , 0x8 ])
149- if execute_command (0x21 , jump_buffer , 5 , None , 0 , verbose ) < 0 :
150- print ("Failed to start firmware" )
151- return False
146+ go_params = bytearray ([0x8 , 0x00 , 0x00 , 0x00 , 0x8 ])
147+ execute_command (CMD_GO , go_params , 0 , verbose ) # Jump to the application
152148
153149 return True
154150
155- def write_firmware_page (opcode , command_buffer , command_length , firmware_buffer , firmware_length , verbose = True ):
151+ def write_firmware_page (command_buffer , command_length , firmware_buffer , firmware_length , verbose = True ):
156152 """
157153 Write a page of the firmware to the I2C device.
158154
@@ -164,7 +160,7 @@ def write_firmware_page(opcode, command_buffer, command_length, firmware_buffer,
164160 :param verbose: Whether to print debug information.
165161 :return: The number of bytes written, or -1 if an error occurred.
166162 """
167- cmd = bytes ([opcode , 0xFF ^ opcode ])
163+ cmd = bytes ([CMD_WRITE , 0xFF ^ CMD_WRITE ])
168164 i2c .writeto (100 , cmd )
169165
170166 if command_length > 0 :
@@ -273,10 +269,10 @@ def setup():
273269 with open (bin_file , 'rb' ) as file :
274270 firmware = file .read ()
275271
276- if flash_firmware (firmware , len ( firmware ) ):
277- print ("PASS " )
272+ if flash_firmware (firmware ):
273+ print ("Firmware flashed successfully " )
278274 else :
279- print ("FAIL " )
275+ print ("Failed to flash firmware " )
280276
281277# Start the setup
282278setup ()
0 commit comments