@@ -71,6 +71,9 @@ def displayName(self):
71
71
if "0000:0000" in self .port [2 ]:
72
72
return "%s (Maybe TinyFPGA Bx Prototype)" % self .port [0 ]
73
73
74
+ def get_file_extensions (self ):
75
+ return ('.hex' , '.bin' )
76
+
74
77
def program (self , filename , progress ):
75
78
global max_progress
76
79
@@ -90,29 +93,30 @@ def program(self, filename, progress):
90
93
91
94
92
95
def checkPortStatus (self , update_button_state ):
93
- global serial_port_ready
94
96
try :
95
97
with serial .Serial (self .port [0 ], 10000000 , timeout = 0.1 , writeTimeout = 0.1 ) as ser :
96
98
fpga = TinyFPGAB (ser )
97
99
100
+ fpga .wake ()
101
+ fpga .read (0 , 16 )
98
102
fpga .wake ()
99
103
devid = fpga .read_id ()
100
104
101
105
expected_devid = [0x1F , 0x84 , 0x01 ]
102
106
if devid == expected_devid :
103
107
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
105
109
else :
106
110
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
108
112
109
113
except serial .SerialTimeoutException :
110
114
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
112
116
113
117
except :
114
118
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
116
120
117
121
def exitBootloader (self ):
118
122
with serial .Serial (self .port [0 ], 10000000 , timeout = 0.1 , writeTimeout = 0.1 ) as ser :
@@ -135,6 +139,9 @@ def canProgram(port):
135
139
def displayName (self ):
136
140
return "%s (TinyFPGA Ax)" % self .port [0 ]
137
141
142
+ def get_file_extensions (self ):
143
+ return ('.jed' )
144
+
138
145
def program (self , filename , progress ):
139
146
global max_progress
140
147
@@ -157,30 +164,35 @@ def program(self, filename, progress):
157
164
self .reset ()
158
165
traceback .print_exc ()
159
166
160
-
167
+ port_success = False
161
168
def checkPortStatus (self , update_button_state ):
169
+ global port_success
162
170
with serial .Serial (self .port [0 ], 12000000 , timeout = .5 , writeTimeout = 0.1 ) as ser :
163
171
async_serial = tinyfpgaa .SyncSerial (ser )
164
172
pins = tinyfpgaa .JtagTinyFpgaProgrammer (async_serial )
165
173
jtag = tinyfpgaa .Jtag (pins )
166
174
programmer = tinyfpgaa .JtagCustomProgrammer (jtag )
175
+ port_success = False
167
176
168
177
def status_callback (status ):
178
+ global port_success
179
+
169
180
if status == [0x43 , 0x80 , 0x2B , 0x01 ]:
170
181
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
172
183
173
184
elif status == [0x43 , 0xA0 , 0x2B , 0x01 ]:
174
185
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
176
187
177
188
else :
178
189
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
180
191
181
192
### read idcode
182
193
programmer .write_ir (8 , 0xE0 )
183
194
programmer .read_dr (32 , status_callback , blocking = True )
195
+ return port_success
184
196
185
197
def exitBootloader (self ):
186
198
pass
@@ -208,33 +220,26 @@ def exitBootloader(self):
208
220
program_in_progress = False
209
221
program_failure = False
210
222
211
- boot_fpga_b = Button (r , text = "Exit Bootloader" )
212
223
program_fpga_b = Button (r , text = "Program FPGA" )
213
224
program_progress_pb = Progressbar (r , orient = "horizontal" , length = 400 , mode = "determinate" )
214
225
226
+ boot_fpga_b = Button (r , text = "Exit Bootloader" )
227
+
215
228
program_status_sv = StringVar (r )
216
229
217
230
serial_port_ready = False
218
231
bitstream_file_ready = False
219
- has_bootloader = False
220
232
file_mtime = 0
221
233
222
- def update_button_state (new_serial_port_ready = None , new_has_bootloader = None ):
234
+ def update_button_state (new_serial_port_ready = None ):
223
235
global serial_port_ready
224
236
global bitstream_file_ready
225
- global has_bootloader
226
237
227
238
if new_serial_port_ready is not None :
228
239
serial_port_ready = new_serial_port_ready
229
240
230
- if new_has_bootloader is not None :
231
- has_bootloader = new_has_bootloader
232
-
233
241
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 )
238
243
239
244
if bitstream_file_ready :
240
245
program_fpga_b .config (state = NORMAL )
@@ -282,6 +287,10 @@ def update_serial_port_list_task():
282
287
if new_tinyfpga_ports != tinyfpga_ports :
283
288
if com_port_sv .get () == "" and len (new_tinyfpga_ports ) > 0 :
284
289
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
+
285
294
menu = select_port_om ["menu" ]
286
295
menu .delete (0 , "end" )
287
296
for string in new_tinyfpga_ports :
@@ -291,32 +300,25 @@ def update_serial_port_list_task():
291
300
tinyfpga_ports = new_tinyfpga_ports
292
301
tinyfpga_adapters = new_tinyfpga_adapters
293
302
294
- r .after (1000 , update_serial_port_list_task )
303
+ r .after (500 , update_serial_port_list_task )
295
304
296
305
update_serial_port_list_task ()
297
306
298
307
def check_port_status_task ():
299
308
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 ()
301
316
try :
302
- adapter = tinyfpga_adapters [com_port_sv .get ()]
303
- adapter .checkPortStatus (update_button_state )
317
+ adapter .reset ()
304
318
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 )
307
319
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
317
321
318
- check_port_status_task ()
319
- #update_button_state(new_serial_port_ready = True)
320
322
321
323
322
324
########################################
@@ -326,10 +328,18 @@ def check_port_status_task():
326
328
filename_sv = StringVar (r )
327
329
328
330
def 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
+
329
339
filename = tkFileDialog .askopenfilename (
330
340
title = "Select file" ,
331
341
filetypes = [
332
- ('FPGA Bitstream Files' , ( '.hex' , '.jed' ) ),
342
+ ('FPGA Bitstream Files' , file_extensions ),
333
343
('all files' , '.*' )
334
344
]
335
345
)
@@ -447,26 +457,16 @@ def update_progress_task():
447
457
update_progress_task ()
448
458
449
459
def 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 ()
455
466
456
467
program_fpga_b .configure (command = program_fpga_cmd )
457
468
program_fpga_b .grid (column = 0 , row = 2 , sticky = W + E , padx = 10 , pady = 8 )
458
469
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 ()
470
470
471
471
472
472
########################################
0 commit comments