code-comment for get_pinspecs()
[soc.git] / src / soc / config / pinouts.py
1 import os
2 import sys
3 import json
4 from pprint import pprint
5 from collections import OrderedDict
6
7
8 def _byteify(data, ignore_dicts = False):
9 # if this is a unicode string, return its string representation
10 try:
11 if isinstance(data, unicode):
12 return data.encode('utf-8')
13 except NameError:
14 return data
15 # if this is a list of values, return list of byteified values
16 if isinstance(data, list):
17 return [ _byteify(item, ignore_dicts=True) for item in data ]
18 # if this is a dictionary, return dictionary of byteified keys and values
19 # but only if we haven't already byteified it
20 if isinstance(data, dict) and not ignore_dicts:
21 return OrderedDict((_byteify(key, ignore_dicts=True),
22 _byteify(value, ignore_dicts=True))
23 for key, value in data.iteritems())
24 # if it's anything else, return it in its original form
25 return data
26
27
28 def get_pinspecs(chipname=None, subset=None):
29 """get_pinspecs - returns a dictionary of lists of pins for an IO function
30 example: {'uart': ['tx+', 'rx-'],
31 'i2c': ['sda*', 'scl+']}
32 """
33 chip = load_pinouts(chipname)
34 pinmap = chip['pins.map']
35 specs = OrderedDict() # preserve order
36 for k, bus in chip['pins.specs'].items():
37 k, num = k.lower().split(":")
38 name = '%s%s' % (k, num)
39 if subset is None or name in subset:
40 pins = []
41 for pin in bus:
42 pin = pin.lower()
43 pname = '%s_%s' % (name, pin[:-1])
44 if pname in pinmap:
45 newpin = pinmap[pname][2:]
46 newpin = '_'.join(newpin.split("_")[1:])
47 pin = newpin + pin[-1]
48 pins.append(pin)
49 specs['%s%s' % (k, num)] = pins
50 return specs
51
52
53 def load_pinouts(chipname=None):
54 """load_pinouts - loads the JSON-formatted dictionary of a chip spec
55
56 note: this works only when pinmux is a correctly-initialised git submodule
57 and when the spec has been actually generated. see Makefile "make mkpinmux"
58 """
59
60 # default pinouts for now: ls180
61 if chipname is None:
62 chipname = 'ls180'
63
64 # load JSON-formatted pad info from pinmux
65 pth = os.path.abspath(__file__)
66 pth = os.path.split(pth)[0]
67
68 # path is relative to this filename, in the pinmux submodule
69 pinmux = os.getenv("PINMUX", "%s/../../../pinmux" % pth)
70 fname = "%s/%s/litex_pinpads.json" % (pinmux, chipname)
71 with open(fname) as f:
72 txt = f.read()
73
74 # decode the json, strip unicode formatting (has to be recursive)
75 chip = json.loads(txt, object_hook=_byteify)
76 chip = _byteify(chip, ignore_dicts=True)
77
78 return chip
79
80 if __name__ == '__main__':
81 if sys.argv == 2:
82 chipname = sys.argv[1]
83 else:
84 chipname = None
85 chip = load_pinouts(chipname)
86 for k, v in chip.items():
87 print ("\n****", k, "****")
88 pprint(v)