-
Notifications
You must be signed in to change notification settings - Fork 167
/
quartushpsdriver.py
78 lines (66 loc) · 2.62 KB
/
quartushpsdriver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# pylint: disable=no-member
import subprocess
import re
import attr
from ..factory import target_factory
from ..resource.remote import NetworkAlteraUSBBlaster
from ..resource.udev import AlteraUSBBlaster
from ..step import step
from .common import Driver
from .exception import ExecutionError
from ..util.managedfile import ManagedFile
@target_factory.reg_driver
@attr.s(cmp=False)
class QuartusHPSDriver(Driver):
bindings = {
"interface": {AlteraUSBBlaster, NetworkAlteraUSBBlaster},
}
image = attr.ib(
default=None,
validator=attr.validators.optional(attr.validators.instance_of(str))
)
def __attrs_post_init__(self):
super().__attrs_post_init__()
# FIXME make sure we always have an environment or config
if self.target.env:
self.tool = self.target.env.config.get_tool('quartus_hps') or 'quartus_hps'
else:
self.tool = 'quartus_hps'
def _get_cable_number(self):
"""Returns the JTAG cable numer for the USB path of the device"""
# FIXME make sure we always have an environment or config
if self.target.env:
jtagconfig_tool = self.target.env.config.get_tool('jtagconfig') or 'jtagconfig'
else:
jtagconfig_tool = 'jtagconfig'
cmd = self.interface.command_prefix + [jtagconfig_tool]
jtagconfig_process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE
)
stdout, _ = jtagconfig_process.communicate()
regex = re.compile(r".*(\d+)\) .* \[(.*)\]")
for line in stdout.decode("utf-8").split("\n"):
jtag_mapping = regex.match(line)
if jtag_mapping:
cable_number, usb_path = jtag_mapping.groups()
if usb_path == self.interface.path:
return int(cable_number)
raise ExecutionError("Could not get cable number for USB path {}"
.format(self.interface.path))
@Driver.check_active
@step(args=['filename', 'address'])
def flash(self, filename=None, address=0x0):
if filename is None and self.image is not None:
filename = self.target.env.config.get_image_path(self.image)
mf = ManagedFile(filename, self.interface)
mf.sync_to_resource()
assert isinstance(address, int)
cable_number = self._get_cable_number()
cmd = self.interface.command_prefix + [self.tool]
cmd += [
"--cable={}".format(cable_number),
"--addr=0x{:X}".format(address),
"--operation=P {}".format(mf.get_remote_path()),
]
subprocess.check_call(cmd)