| 
					
				 | 
			
			
				@@ -18,6 +18,8 @@ from greaseweazle import usb as USB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Updates the Greaseweazle firmware using the specified Update File. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def update_firmware(usb, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    req_type = b'BL' if args.bootloader else b'GW' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     filename = args.file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if filename == "auto": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Get the absolute path to the root Greaseweazle folder. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -35,7 +37,8 @@ def update_firmware(usb, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Search the catalogue for a match on our Weazle's hardware type. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while dat: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         upd_len, hw_type = struct.unpack("<2H", dat[:4]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if hw_type == usb.hw_type: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        upd_type, = struct.unpack("2s", dat[upd_len-4:upd_len-2]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if hw_type == usb.hw_type and upd_type == req_type: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             # Match: Pull out the embedded update file. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dat = dat[4:upd_len+4] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -48,7 +51,7 @@ def update_firmware(usb, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Check the matching update file's footer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sig, maj, min, hw_type = struct.unpack("<2s2BH", dat[-8:-2]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if len(dat) & 3 != 0 or sig != b'GW' or hw_type != usb.hw_type: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if len(dat) & 3 != 0 or sig != req_type or hw_type != usb.hw_type: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         print("%s: Bad update file" % (filename)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     crc16 = crcmod.predefined.Crc('crc-ccitt-false') 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -58,17 +61,27 @@ def update_firmware(usb, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Perform the update. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("Updating to v%u.%u..." % (maj, min)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ack = usb.update_firmware(dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if ack != 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print("** UPDATE FAILED: Please retry!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("Done.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if usb.hw_type == 7: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        util.usb_reopen(usb, is_update=False) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print("Updating %s to v%u.%u..." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          % ("Bootloader" if args.bootloader else "Main Firmware", maj, min)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if args.bootloader: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ack = usb.update_bootloader(dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ack != 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            print("""\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+** UPDATE FAILED: Please retry immediately or your Weazle may need 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        full reflashing via a suitable programming adapter!""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print("Done.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print("** Disconnect Greaseweazle and remove the Programming Jumper.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ack = usb.update_firmware(dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ack != 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            print("** UPDATE FAILED: Please retry!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print("Done.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if usb.hw_type == 7: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            util.usb_reopen(usb, is_update=False) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            print("** Disconnect Greaseweazle and remove the Programming Jumper.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def main(argv): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -79,10 +92,12 @@ def main(argv): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         help="update filename") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     parser.add_argument("device", nargs="?", default="auto", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         help="serial device") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    parser.add_argument("--bootloader", action="store_true", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        help="update the bootloader (WARNING: Use with caution!)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     parser.prog += ' ' + argv[1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     args = parser.parse_args(argv[2:]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    usb = util.usb_open(args.device, is_update=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    usb = util.usb_open(args.device, is_update=not args.bootloader) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         update_firmware(usb, args) 
			 |