add quick instructions on how to run pinouts.py to get some debug info
[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 from openpower.util import log
7 from nmigen.build.dsl import Resource, Subsignal, Pins
8
9
10 def _byteify(data, ignore_dicts = False):
11 # if this is a unicode string, return its string representation
12 try:
13 if isinstance(data, unicode):
14 return data.encode('utf-8')
15 except NameError:
16 return data
17 # if this is a list of values, return list of byteified values
18 if isinstance(data, list):
19 return [ _byteify(item, ignore_dicts=True) for item in data ]
20 # if this is a dictionary, return dictionary of byteified keys and values
21 # but only if we haven't already byteified it
22 if isinstance(data, dict) and not ignore_dicts:
23 return OrderedDict((_byteify(key, ignore_dicts=True),
24 _byteify(value, ignore_dicts=True))
25 for key, value in data.iteritems())
26 # if it's anything else, return it in its original form
27 return data
28
29
30 def get_pinspec_resources(chipname=None, subset=None, conn=None):
31 """get_pinspec_resources - returns an auto-generated list of resources
32 """
33 chip = load_pinouts(chipname)
34 pinmap = chip['pins.map']
35 specs = []
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 io = []
41 for pin in bus:
42 pin = pin.lower()
43 pin, pin_dir = pin[:-1], pin[-1] # split pin+ into pin, +
44 pname = '%s_%s' % (name, pin)
45 if pname in pinmap:
46 newpin = pinmap[pname][2:]
47 newpin = '_'.join(newpin.split("_")[1:])
48 # turn direction into nmigen Pins direction format
49 dirn = {'-': 'i', '+': 'o', '*': 'io'}[pin_dir]
50 # TODO: make assert_width not have to be 1
51 p = Pins(newpin, dir=dirn, conn=conn, assert_width=1)
52 io.append(Subsignal(pin, p))
53 spec = Resource.family(name, num, default_name=name, ios=io)
54 log("pinspec", name, repr(spec))
55 specs.append(spec)
56 return specs
57
58
59 def get_pinspecs(chipname=None, subset=None):
60 """get_pinspecs - returns a dictionary of lists of pins for an IO function
61 example: {'uart': ['tx+', 'rx-'],
62 'i2c': ['sda*', 'scl+']}
63 """
64 chip = load_pinouts(chipname)
65 pinmap = chip['pins.map']
66 specs = OrderedDict() # preserve order
67 for k, bus in chip['pins.specs'].items():
68 k, num = k.lower().split(":")
69 name = '%s%s' % (k, num)
70 if subset is None or name in subset:
71 pins = []
72 for pin in bus:
73 pin = pin.lower()
74 pname = '%s_%s' % (name, pin[:-1])
75 if pname in pinmap:
76 newpin = pinmap[pname][2:]
77 newpin = '_'.join(newpin.split("_")[1:])
78 pin = newpin + pin[-1]
79 pins.append(pin)
80 specs['%s%s' % (k, num)] = pins
81 return specs
82
83
84 def load_pinouts(chipname=None):
85 """load_pinouts - loads the JSON-formatted dictionary of a chip spec
86
87 note: this works only when pinmux is a correctly-initialised git submodule
88 and when the spec has been actually generated. see Makefile "make mkpinmux"
89 """
90
91 # default pinouts for now: ls180
92 if chipname is None:
93 chipname = 'ls180'
94
95 # load JSON-formatted pad info from pinmux
96 pth = os.path.abspath(__file__)
97 pth = os.path.split(pth)[0]
98
99 # path is relative to this filename, in the pinmux submodule
100 pinmux = os.getenv("PINMUX", "%s/../../../pinmux" % pth)
101 fname = "%s/%s/litex_pinpads.json" % (pinmux, chipname)
102 with open(fname) as f:
103 txt = f.read()
104
105 # decode the json, strip unicode formatting (has to be recursive)
106 chip = json.loads(txt, object_hook=_byteify)
107 chip = _byteify(chip, ignore_dicts=True)
108
109 return chip
110
111 if __name__ == '__main__':
112 # run this with:
113 # git submodule update --init --remote --recursive
114 # make mkpinmux
115 # python3 soc/config/pinouts.py ngi_pointer (or ls180, or other)
116 # it will print out a stack of debug stuff
117 if len(sys.argv) == 2:
118 chipname = sys.argv[1]
119 else:
120 chipname = None
121 chip = load_pinouts(chipname)
122 for k, v in chip.items():
123 print ("\n****", k, "****")
124 pprint(v)
125 print ("chipname pinspec resources", sys.argv, chipname)
126 specs = get_pinspec_resources(chipname, subset=None)