@@ -71,6 +71,9 @@ def displayName(self):
7171 if "0000:0000" in self .port [2 ]:
7272 return "%s (Maybe TinyFPGA Bx Prototype)" % self .port [0 ]
7373
74+ def get_file_extensions (self ):
75+ return ('.hex' , '.bin' )
76+
7477 def program (self , filename , progress ):
7578 global max_progress
7679
@@ -90,29 +93,30 @@ def program(self, filename, progress):
9093
9194
9295 def checkPortStatus (self , update_button_state ):
93- global serial_port_ready
9496 try :
9597 with serial .Serial (self .port [0 ], 10000000 , timeout = 0.1 , writeTimeout = 0.1 ) as ser :
9698 fpga = TinyFPGAB (ser )
9799
100+ fpga .wake ()
101+ fpga .read (0 , 16 )
98102 fpga .wake ()
99103 devid = fpga .read_id ()
100104
101105 expected_devid = [0x1F , 0x84 , 0x01 ]
102106 if devid == expected_devid :
103107 com_port_status_sv .set ("Connected to TinyFPGA B2. Ready to program." )
104- update_button_state ( new_serial_port_ready = True , new_has_bootloader = True )
108+ return True
105109 else :
106110 com_port_status_sv .set ("Unable to communicate with TinyFPGA. Reconnect and reset TinyFPGA before programming." )
107- update_button_state ( new_serial_port_ready = False , new_has_bootloader = True )
111+ return False
108112
109113 except serial .SerialTimeoutException :
110114 com_port_status_sv .set ("Hmm...try pressing the reset button on TinyFPGA again." )
111- update_button_state ( new_serial_port_ready = False , new_has_bootloader = True )
115+ return False
112116
113117 except :
114118 com_port_status_sv .set ("Bootloader not active. Press reset button on TinyFPGA before programming." )
115- update_button_state ( new_serial_port_ready = False , new_has_bootloader = True )
119+ return False
116120
117121 def exitBootloader (self ):
118122 with serial .Serial (self .port [0 ], 10000000 , timeout = 0.1 , writeTimeout = 0.1 ) as ser :
@@ -135,6 +139,9 @@ def canProgram(port):
135139 def displayName (self ):
136140 return "%s (TinyFPGA Ax)" % self .port [0 ]
137141
142+ def get_file_extensions (self ):
143+ return ('.jed' )
144+
138145 def program (self , filename , progress ):
139146 global max_progress
140147
@@ -157,30 +164,35 @@ def program(self, filename, progress):
157164 self .reset ()
158165 traceback .print_exc ()
159166
160-
167+ port_success = False
161168 def checkPortStatus (self , update_button_state ):
169+ global port_success
162170 with serial .Serial (self .port [0 ], 12000000 , timeout = .5 , writeTimeout = 0.1 ) as ser :
163171 async_serial = tinyfpgaa .SyncSerial (ser )
164172 pins = tinyfpgaa .JtagTinyFpgaProgrammer (async_serial )
165173 jtag = tinyfpgaa .Jtag (pins )
166174 programmer = tinyfpgaa .JtagCustomProgrammer (jtag )
175+ port_success = False
167176
168177 def status_callback (status ):
178+ global port_success
179+
169180 if status == [0x43 , 0x80 , 0x2B , 0x01 ]:
170181 com_port_status_sv .set ("Connected to TinyFPGA A1. Ready to program." )
171- update_button_state ( new_serial_port_ready = True , new_has_bootloader = False )
182+ port_success = True
172183
173184 elif status == [0x43 , 0xA0 , 0x2B , 0x01 ]:
174185 com_port_status_sv .set ("Connected to TinyFPGA A2. Ready to program." )
175- update_button_state ( new_serial_port_ready = True , new_has_bootloader = False )
186+ port_success = True
176187
177188 else :
178189 com_port_status_sv .set ("Cannot identify FPGA. Please ensure proper FPGA power and JTAG connection." )
179- update_button_state ( new_serial_port_ready = False , new_has_bootloader = False )
190+ port_success = False
180191
181192 ### read idcode
182193 programmer .write_ir (8 , 0xE0 )
183194 programmer .read_dr (32 , status_callback , blocking = True )
195+ return port_success
184196
185197 def exitBootloader (self ):
186198 pass
@@ -208,33 +220,26 @@ def exitBootloader(self):
208220program_in_progress = False
209221program_failure = False
210222
211- boot_fpga_b = Button (r , text = "Exit Bootloader" )
212223program_fpga_b = Button (r , text = "Program FPGA" )
213224program_progress_pb = Progressbar (r , orient = "horizontal" , length = 400 , mode = "determinate" )
214225
226+ boot_fpga_b = Button (r , text = "Exit Bootloader" )
227+
215228program_status_sv = StringVar (r )
216229
217230serial_port_ready = False
218231bitstream_file_ready = False
219- has_bootloader = False
220232file_mtime = 0
221233
222- def update_button_state (new_serial_port_ready = None , new_has_bootloader = None ):
234+ def update_button_state (new_serial_port_ready = None ):
223235 global serial_port_ready
224236 global bitstream_file_ready
225- global has_bootloader
226237
227238 if new_serial_port_ready is not None :
228239 serial_port_ready = new_serial_port_ready
229240
230- if new_has_bootloader is not None :
231- has_bootloader = new_has_bootloader
232-
233241 if serial_port_ready and not program_in_progress :
234- if has_bootloader :
235- boot_fpga_b .config (state = NORMAL )
236- else :
237- boot_fpga_b .config (state = DISABLED )
242+ boot_fpga_b .config (state = NORMAL )
238243
239244 if bitstream_file_ready :
240245 program_fpga_b .config (state = NORMAL )
@@ -282,6 +287,10 @@ def update_serial_port_list_task():
282287 if new_tinyfpga_ports != tinyfpga_ports :
283288 if com_port_sv .get () == "" and len (new_tinyfpga_ports ) > 0 :
284289 com_port_sv .set (new_tinyfpga_ports [0 ])
290+ update_button_state (new_serial_port_ready = True )
291+
292+ update_button_state (new_serial_port_ready = com_port_sv .get () in new_tinyfpga_ports )
293+
285294 menu = select_port_om ["menu" ]
286295 menu .delete (0 , "end" )
287296 for string in new_tinyfpga_ports :
@@ -291,32 +300,25 @@ def update_serial_port_list_task():
291300 tinyfpga_ports = new_tinyfpga_ports
292301 tinyfpga_adapters = new_tinyfpga_adapters
293302
294- r .after (1000 , update_serial_port_list_task )
303+ r .after (500 , update_serial_port_list_task )
295304
296305update_serial_port_list_task ()
297306
298307def check_port_status_task ():
299308 global adapter
300- if communication_lock .acquire (False ):
309+ try :
310+ adapter = tinyfpga_adapters [com_port_sv .get ()]
311+ return adapter .checkPortStatus (update_button_state )
312+
313+ except :
314+ com_port_status_sv .set ("Unable to communicate with TinyFPGA. Reset your TinyFPGA and check your connections." )
315+ traceback .print_exc ()
301316 try :
302- adapter = tinyfpga_adapters [com_port_sv .get ()]
303- adapter .checkPortStatus (update_button_state )
317+ adapter .reset ()
304318 except :
305- com_port_status_sv .set ("Unable to communicate with TinyFPGA. Reset your TinyFPGA and check your connections." )
306- update_button_state (new_serial_port_ready = False )
307319 traceback .print_exc ()
308- try :
309- adapter .reset ()
310- except :
311- traceback .print_exc ()
312- finally :
313- communication_lock .release ()
314-
315- r .after (100 , check_port_status_task )
316-
320+ return False
317321
318- check_port_status_task ()
319- #update_button_state(new_serial_port_ready = True)
320322
321323
322324########################################
@@ -326,10 +328,18 @@ def check_port_status_task():
326328filename_sv = StringVar (r )
327329
328330def select_bitstream_file_cmd ():
331+ file_extensions = ('FPGA Bitstream Files' , ('.hex' , '.bin' , '.jed' ))
332+
333+ try :
334+ adapter = tinyfpga_adapters [com_port_sv .get ()]
335+ file_extensions = adapter .get_file_extensions ()
336+ except :
337+ pass
338+
329339 filename = tkFileDialog .askopenfilename (
330340 title = "Select file" ,
331341 filetypes = [
332- ('FPGA Bitstream Files' , ( '.hex' , '.jed' ) ),
342+ ('FPGA Bitstream Files' , file_extensions ),
333343 ('all files' , '.*' )
334344 ]
335345 )
@@ -447,26 +457,16 @@ def update_progress_task():
447457update_progress_task ()
448458
449459def program_fpga_cmd ():
450- global program_in_progress
451- program_in_progress = True
452- update_button_state ()
453- t = threading .Thread (target = program_fpga_thread )
454- t .start ()
460+ if check_port_status_task ():
461+ global program_in_progress
462+ program_in_progress = True
463+ update_button_state ()
464+ t = threading .Thread (target = program_fpga_thread )
465+ t .start ()
455466
456467program_fpga_b .configure (command = program_fpga_cmd )
457468program_fpga_b .grid (column = 0 , row = 2 , sticky = W + E , padx = 10 , pady = 8 )
458469
459- def program_failure_task ():
460- global program_failure
461- global adapter
462- if program_failure :
463- adapter .reset ()
464- program_status_sv .set ("Programming failed! Reset TinyFPGA and try again." )
465- program_failure = False
466-
467- r .after (100 , program_failure_task )
468-
469- program_failure_task ()
470470
471471
472472########################################
0 commit comments