Skip to content

Commit 088bd78

Browse files
author
tinyfpga
committed
fixes for TinyFPGA Programmer on MacOS
1 parent a404f24 commit 088bd78

File tree

2 files changed

+101
-68
lines changed

2 files changed

+101
-68
lines changed

tinyfpga-programmer-gui.py

Lines changed: 100 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import serial
1212
import array
1313
import time
14-
from intelhex import IntelHex
14+
#from intelhex import IntelHex
1515
from Tkinter import *
1616
from ttk import *
1717
import tkFileDialog
@@ -28,8 +28,9 @@
2828
## Programmer Hardware Adapters
2929
########################################
3030
class ProgrammerHardwareAdapter(object):
31-
def __init__(self):
32-
pass
31+
def __init__(self, port):
32+
self.port = port
33+
self.bus, self.portnum = [int(x) for x in self.port[2].split('=')[-1].split('-')]
3334

3435
@staticmethod
3536
def canProgram(port):
@@ -44,10 +45,18 @@ def checkPortStatus(self):
4445
def exitBootloader(self):
4546
pass
4647

48+
def reset(self):
49+
try:
50+
import usb
51+
device = usb.core.find(custom_match = lambda d: d.bus == self.bus and d.port_number == self.portnum)
52+
device.reset()
53+
except:
54+
traceback.print_exc()
55+
4756

4857
class TinyFPGABSeries(ProgrammerHardwareAdapter):
4958
def __init__(self, port):
50-
self.port = port
59+
super(TinyFPGABSeries, self).__init__(port)
5160

5261
@staticmethod
5362
def canProgram(port):
@@ -74,33 +83,34 @@ def program(self, filename, progress):
7483
fpga.program_bitstream(addr, bitstream)
7584
except:
7685
program_failure = True
86+
traceback.print_exc()
87+
7788

7889

7990
def checkPortStatus(self, update_button_state):
8091
global serial_port_ready
81-
if not program_in_progress:
82-
try:
83-
with serial.Serial(self.port[0], 10000000, timeout=0.1, writeTimeout=0.1) as ser:
84-
fpga = TinyFPGAB(ser)
92+
try:
93+
with serial.Serial(self.port[0], 10000000, timeout=0.1, writeTimeout=0.1) as ser:
94+
fpga = TinyFPGAB(ser)
8595

86-
fpga.wake()
87-
devid = fpga.read_id()
96+
fpga.wake()
97+
devid = fpga.read_id()
8898

89-
expected_devid = [0x1F, 0x84, 0x01]
90-
if devid == expected_devid:
91-
com_port_status_sv.set("Connected to TinyFPGA B2. Ready to program.")
92-
update_button_state(new_serial_port_ready = True, new_has_bootloader = True)
93-
else:
94-
com_port_status_sv.set("Unable to communicate with TinyFPGA. Reconnect and reset TinyFPGA before programming.")
95-
update_button_state(new_serial_port_ready = False, new_has_bootloader = True)
99+
expected_devid = [0x1F, 0x84, 0x01]
100+
if devid == expected_devid:
101+
com_port_status_sv.set("Connected to TinyFPGA B2. Ready to program.")
102+
update_button_state(new_serial_port_ready = True, new_has_bootloader = True)
103+
else:
104+
com_port_status_sv.set("Unable to communicate with TinyFPGA. Reconnect and reset TinyFPGA before programming.")
105+
update_button_state(new_serial_port_ready = False, new_has_bootloader = True)
96106

97-
except serial.SerialTimeoutException:
98-
com_port_status_sv.set("Hmm...try pressing the reset button on TinyFPGA again.")
99-
update_button_state(new_serial_port_ready = False, new_has_bootloader = True)
107+
except serial.SerialTimeoutException:
108+
com_port_status_sv.set("Hmm...try pressing the reset button on TinyFPGA again.")
109+
update_button_state(new_serial_port_ready = False, new_has_bootloader = True)
100110

101-
except:
102-
com_port_status_sv.set("Bootloader not active. Press reset button on TinyFPGA before programming.")
103-
update_button_state(new_serial_port_ready = False, new_has_bootloader = True)
111+
except:
112+
com_port_status_sv.set("Bootloader not active. Press reset button on TinyFPGA before programming.")
113+
update_button_state(new_serial_port_ready = False, new_has_bootloader = True)
104114

105115
def exitBootloader(self):
106116
with serial.Serial(self.port[0], 10000000, timeout=0.1, writeTimeout=0.1) as ser:
@@ -114,7 +124,7 @@ def exitBootloader(self):
114124

115125
class TinyFPGAASeries(ProgrammerHardwareAdapter):
116126
def __init__(self, port):
117-
self.port = port
127+
super(TinyFPGAASeries, self).__init__(port)
118128

119129
@staticmethod
120130
def canProgram(port):
@@ -126,8 +136,8 @@ def displayName(self):
126136
def program(self, filename, progress):
127137
global max_progress
128138

129-
with serial.Serial(self.port[0], 12000000, timeout=2.0, writeTimeout=20) as ser:
130-
async_serial = tinyfpgaa.AsyncSerial(ser)
139+
with serial.Serial(self.port[0], 12000000, timeout=10, writeTimeout=5) as ser:
140+
async_serial = tinyfpgaa.SyncSerial(ser)
131141
pins = tinyfpgaa.JtagTinyFpgaProgrammer(async_serial)
132142
jtag = tinyfpgaa.Jtag(pins)
133143
programmer = tinyfpgaa.JtagCustomProgrammer(jtag)
@@ -137,17 +147,18 @@ def program(self, filename, progress):
137147

138148
max_progress = jedec_file.numRows() * 3
139149

140-
programmer.program(jedec_file, progress)
141-
142-
143150
try:
144-
fpga.program_bitstream(addr, bitstream)
151+
programmer.program(jedec_file, progress)
152+
145153
except:
146154
program_failure = True
155+
self.reset()
156+
traceback.print_exc()
157+
147158

148159
def checkPortStatus(self, update_button_state):
149160
with serial.Serial(self.port[0], 12000000, timeout=.5, writeTimeout=0.1) as ser:
150-
async_serial = tinyfpgaa.AsyncSerial(ser)
161+
async_serial = tinyfpgaa.SyncSerial(ser)
151162
pins = tinyfpgaa.JtagTinyFpgaProgrammer(async_serial)
152163
jtag = tinyfpgaa.Jtag(pins)
153164
programmer = tinyfpgaa.JtagCustomProgrammer(jtag)
@@ -186,6 +197,8 @@ def exitBootloader(self):
186197
################################################################################
187198
################################################################################
188199

200+
communication_lock = threading.Lock()
201+
189202
r = Tk()
190203
r.title("TinyFPGA Programmer")
191204
r.resizable(width=False, height=False)
@@ -199,8 +212,9 @@ def exitBootloader(self):
199212

200213
program_status_sv = StringVar(r)
201214

202-
serial_port_ready = False;
203-
bitstream_file_ready = False;
215+
serial_port_ready = False
216+
bitstream_file_ready = False
217+
has_bootloader = False
204218
file_mtime = 0
205219

206220
def update_button_state(new_serial_port_ready = None, new_has_bootloader = None):
@@ -260,8 +274,8 @@ def update_serial_port_list_task():
260274
global tinyfpga_adapters
261275

262276
if not program_in_progress:
263-
tinyfpga_adapters = dict((adapter.displayName(), adapter) for adapter in [getProgrammerHardwareAdapter(port) for port in comports()] if adapter is not None)
264-
new_tinyfpga_ports = [key for key, value in tinyfpga_adapters.iteritems()]
277+
new_tinyfpga_adapters = dict((adapter.displayName(), adapter) for adapter in [getProgrammerHardwareAdapter(port) for port in comports()] if adapter is not None)
278+
new_tinyfpga_ports = [key for key, value in new_tinyfpga_adapters.iteritems()]
265279

266280
if new_tinyfpga_ports != tinyfpga_ports:
267281
if com_port_sv.get() == "" and len(new_tinyfpga_ports) > 0:
@@ -273,25 +287,34 @@ def update_serial_port_list_task():
273287
label=string,
274288
command=lambda value=string: com_port_sv.set(value))
275289
tinyfpga_ports = new_tinyfpga_ports
290+
tinyfpga_adapters = new_tinyfpga_adapters
276291

277292
r.after(1000, update_serial_port_list_task)
278293

279294
update_serial_port_list_task()
280295

281296
def check_port_status_task():
282-
if not program_in_progress:
297+
global adapter
298+
if communication_lock.acquire(False):
283299
try:
284300
adapter = tinyfpga_adapters[com_port_sv.get()]
285301
adapter.checkPortStatus(update_button_state)
286302
except:
287303
com_port_status_sv.set("Unable to communicate with TinyFPGA. Reset your TinyFPGA and check your connections.")
288304
update_button_state(new_serial_port_ready = False)
305+
traceback.print_exc()
306+
try:
307+
adapter.reset()
308+
except:
309+
pass
310+
finally:
311+
communication_lock.release()
289312

290-
291-
r.after(500, check_port_status_task)
313+
r.after(100, check_port_status_task)
292314

293315

294316
check_port_status_task()
317+
#update_button_state(new_serial_port_ready = True)
295318

296319

297320
########################################
@@ -365,37 +388,39 @@ def check_bitstream_file_status_cb(*args):
365388
program_progress_pb.grid(column=1, row=2, sticky=W+E, padx=10, pady=8)
366389

367390
def program_fpga_thread():
368-
global program_in_progress
369-
global program_failure
370-
program_failure = False
371-
372-
try:
373-
global current_progress
374-
global max_progress
375-
global progress_lock
376-
with progress_lock:
377-
current_progress = 0
391+
with communication_lock:
392+
global program_failure
393+
global program_in_progress
394+
program_failure = False
378395

379-
def progress(v):
396+
try:
397+
global current_progress
398+
global max_progress
380399
global progress_lock
381400
with progress_lock:
382-
if isinstance(v, int) or isinstance(v, long):
383-
global current_progress
384-
current_progress += v
385-
elif isinstance(v, str):
386-
program_status_sv.set(v)
401+
current_progress = 0
387402

388-
adapter = tinyfpga_adapters[com_port_sv.get()]
389-
adapter.program(filename_sv.get(), progress)
403+
def progress(v):
404+
global progress_lock
405+
with progress_lock:
406+
if isinstance(v, int) or isinstance(v, long):
407+
global current_progress
408+
current_progress += v
409+
elif isinstance(v, str):
410+
program_status_sv.set(v)
390411

391-
program_in_progress = False
412+
adapter = tinyfpga_adapters[com_port_sv.get()]
413+
adapter.program(filename_sv.get(), progress)
392414

393-
except:
394-
program_failure = True
395-
traceback.print_exc()
396415

397-
finally:
398-
program_in_progress = False
416+
except:
417+
program_failure = True
418+
traceback.print_exc()
419+
420+
finally:
421+
program_in_progress = False
422+
pass
423+
399424

400425
current_progress = 0
401426
max_progress = 0
@@ -406,11 +431,17 @@ def update_progress_task():
406431
global max_progress
407432
global progress_lock
408433

409-
with progress_lock:
410-
if isinstance(current_progress, (int, long)):
411-
program_progress_pb["value"] = current_progress
412-
program_progress_pb["maximum"] = max_progress
413-
r.after(10, update_progress_task)
434+
if progress_lock.acquire(False):
435+
try:
436+
if isinstance(current_progress, (int, long)):
437+
program_progress_pb["value"] = current_progress
438+
program_progress_pb["maximum"] = max_progress
439+
except:
440+
traceback.print_exc()
441+
finally:
442+
progress_lock.release()
443+
444+
r.after(100, update_progress_task)
414445

415446
update_progress_task()
416447

@@ -426,7 +457,9 @@ def program_fpga_cmd():
426457

427458
def program_failure_task():
428459
global program_failure
460+
global adapter
429461
if program_failure:
462+
adapter.reset()
430463
program_status_sv.set("Programming failed! Reset TinyFPGA and try again.")
431464
program_failure = False
432465

0 commit comments

Comments
 (0)