1+ import io
2+ import time
3+ import os
4+ import subprocess
5+ import utils
6+ import shutil
7+ import zipfile
8+
9+ import requests
10+
11+
12+ JLINK_PATH = "C:\Program Files (x86)\SEGGER\JLink\JLink.exe"
13+ assert os .path .exists ("bootloader.bin" )
14+ assert os .path .exists ("firmware.uf2" )
15+
16+ ROOT_DIR = os .path .abspath (os .path .join (os .path .dirname (__file__ ), ".." ))
17+ FIRMWARE_DIR = os .path .join (ROOT_DIR , "firmware" )
18+ LIB_DIR = os .path .join (FIRMWARE_DIR , "lib" )
19+ EXAMPLES_DIR = os .path .join (ROOT_DIR , "examples" )
20+
21+ FILES_TO_DEPLOY = {
22+ "https://raw.githubusercontent.com/theacodes/Winterbloom_VoltageIO/master/winterbloom_voltageio.py" : "lib" ,
23+ os .path .join (FIRMWARE_DIR , "winterbloom_bhb" ): "lib" ,
24+ os .path .join (ROOT_DIR , "samples" ): "." ,
25+ os .path .join (ROOT_DIR , "examples" ): "." ,
26+ os .path .join (FIRMWARE_DIR , "LICENSE" ): "." ,
27+ os .path .join (FIRMWARE_DIR , "README.HTM" ): "." ,
28+ os .path .join (ROOT_DIR , "examples/default.py" ): "code.py" ,
29+ }
30+
31+
32+ def program_bootloader ():
33+ print ("========== PROGRAMMING BOOTLOADER ==========" )
34+ subprocess .check_call (
35+ [JLINK_PATH , "-device" , "ATSAMD21G18" , "-autoconnect" , "1" , "-if" , "SWD" , "-speed" , "4000" , "-CommanderScript" , "flash-bootloader.jlink" ]
36+ )
37+
38+
39+ def program_circuitpython ():
40+ print ("========== PROGRAMMING CIRCUITPYTHON ==========" )
41+ input ("Connect usb cable, press enter." )
42+ bootloader_drive = utils .find_drive_by_name ("HONKBOOT" )
43+ utils .copyfile ("firmware.uf2" , os .path .join (bootloader_drive , "NEW.uf2" ))
44+
45+
46+ def deploy_circuitpython_code ():
47+ print ("========== DEPLOYING CODE ==========" )
48+ # Wait for the circuitpython drive to show up.
49+ time .sleep (5 )
50+ cpy_drive = utils .find_drive_by_name ("CIRCUITPY" )
51+
52+ utils .clean_pycache (FIRMWARE_DIR )
53+ utils .clean_pycache (EXAMPLES_DIR )
54+
55+ os .makedirs (os .path .join (cpy_drive , "lib" ), exist_ok = True )
56+
57+ for src , dst in FILES_TO_DEPLOY .items ():
58+ if src .startswith ("https://" ):
59+ if '.zip' in src :
60+ http_src , zip_path = src .rsplit (':' , 1 )
61+
62+ zip_data = io .BytesIO (requests .get (http_src ).content )
63+
64+ with zipfile .ZipFile (zip_data , "r" ) as zipfh :
65+ file_data = zipfh .read (zip_path )
66+
67+ dst = os .path .join (dst , os .path .basename (zip_path ))
68+ with open (os .path .join (cpy_drive , dst ), "wb" ) as fh :
69+ fh .write (file_data )
70+
71+ else :
72+ file_data = requests .get (src ).content
73+ _ , file_name = src .rsplit ('/' , 1 )
74+ dst = os .path .join (dst , file_name )
75+ with open (os .path .join (cpy_drive , dst ), "wb" ) as fh :
76+ fh .write (file_data )
77+
78+ else :
79+ if os .path .isdir (src ):
80+ dst = os .path .join (cpy_drive , dst , os .path .basename (src ))
81+ if os .path .exists (dst ):
82+ shutil .rmtree (dst )
83+ shutil .copytree (src , dst )
84+ else :
85+ shutil .copy (src , os .path .join (cpy_drive , dst ))
86+
87+ print (f"Copied { src } to { dst } " )
88+
89+ utils .flush (cpy_drive )
90+
91+
92+ def main ():
93+ try :
94+ bootloader_drive = utils .find_drive_by_name ("HONKBOOT" )
95+ except :
96+ bootloader_drive = None
97+
98+ try :
99+ circuitpython_drive = utils .find_drive_by_name ("CIRCUITPY" )
100+ except :
101+ circuitpython_drive = None
102+
103+ if not circuitpython_drive and not bootloader_drive :
104+ program_bootloader ()
105+
106+ if not circuitpython_drive :
107+ program_circuitpython ()
108+
109+ if circuitpython_drive and os .path .exists (os .path .join (circuitpython_drive , "code.py" )):
110+ if input ("redeploy code? y/n: " ).strip () == "y" :
111+ deploy_circuitpython_code ()
112+ else :
113+ deploy_circuitpython_code ()
114+
115+
116+ if __name__ == "__main__" :
117+ main ()
0 commit comments