From 1818f04c46beaaebf27dc2c4af4818d8d1dab03a Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Sun, 30 Aug 2020 11:29:36 +0200 Subject: [PATCH 1/2] Adapt to new modm-devices pinout format The pinout information is now stored in a separate list instead of being part of the GPIO table. --- Makefile | 4 ++-- chip_db.py | 37 ++++++------------------------------- chip_stm.py | 46 ++++++++++++++++++++++++++-------------------- stm_layout.py | 2 +- 4 files changed, 35 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index c6fe6cc..ce3ee73 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ tgcurses: modm-devices: - @git clone -b develop_with_gpio_xml https://github.com/tgree/modm-devices + @git clone -b feature/pinout https://github.com/salkinium/modm-devices .xml: modm-devices @@ -19,7 +19,7 @@ modm-devices: modm_devices: modm-devices - @ln -s modm-devices/tools/device/modm_devices + @ln -s modm-devices/modm_devices clean: diff --git a/chip_db.py b/chip_db.py index 376ec97..a6e57c5 100644 --- a/chip_db.py +++ b/chip_db.py @@ -34,38 +34,13 @@ def find(name): def pin_count(dev): # Unfortunately, sometimes R means 64 and sometimes it means 68. So, we # just count the pins. For some reason, counting the pins goes slower. - # Maybe modm-devices does some deferred loading? - return len(set(p['position'] for p in dev.properties['pin'])) - #return {'a' : 169, - # 'b' : 208, - # 'c' : 48, - # 'k' : 32, - # 'i' : 176, - # 'm' : 80.5, - # 'q' : 100, - # 'r' : 64, - # 'v' : 100, - # 'x' : 240, - # 'z' : 144, - # }[dev.identifier.pin] + # Maybe modm-devices does some deferred loading? Yes it does. -Niklas + return len(set(p['position'] for p in dev.get_driver("gpio")["package"][0]["pin"])) def package(dev): try: - return {'e' : 'EWLCSP', - 'f' : 'WLCSP', - 'h' : 'TFBGA', - 'i' : 'UFBGA', # 0.5 mm - 'j' : 'UFBGA', - 'k' : 'UFBGA', # 0.65 mm - 'm' : 'SO8N', - 'p' : 'TSSOP', - 'q' : 'UFBGA', - 't' : 'LQFP', - 'u' : 'UFQFPN', - 'v' : 'VFQFPN', - 'y' : 'WLCSP', - }[dev.identifier.package] + return dev.get_driver("gpio")["package"][0]["name"] except: pass raise Exception("Device %s has unknown package '%s'." @@ -75,7 +50,7 @@ def package(dev): def make_package(dev): p = package(dev) n = pin_count(dev) - if p in ('TFBGA', 'UFBGA', 'WLCSP', 'EWLCSP'): + if any(name in p for name in ('TFBGA', 'UFBGA', 'WLCSP', 'EWLCSP')): if n == 240: dim = 17 # 240+25 elif n == 176: @@ -83,10 +58,10 @@ def make_package(dev): else: dim = int(math.ceil(math.sqrt(float(n)))) return chip_package.BGA(dim, dim) - elif p in ('LQFP', 'UFQFPN', 'VFQFPN'): + elif any(name in p for name in ('LQFP', 'UFQFPN', 'VFQFPN')): dim = int(math.ceil(float(n)/4.)) return chip_package.LQFP(dim, dim) - elif p in ('TSSOP', 'SO8N'): + elif any(name in p for name in ('TSSOP', 'SO8N')): dim = int(math.ceil(float(n)/2.)) return chip_package.TSSOP(dim) raise KeyError diff --git a/chip_stm.py b/chip_stm.py index e06d843..ff63fb1 100644 --- a/chip_stm.py +++ b/chip_stm.py @@ -165,7 +165,7 @@ def serialize_settings(self): continue if not hasattr(p, '_gpio'): continue - + port = p._gpio n = p._gpionum mask_1[port] &= ~(0x1 << n) @@ -207,15 +207,24 @@ def serialize_settings(self): def make_chip(part): pkg = chip_db.make_package(part) - pin_map = {} - for p in part.properties['pin']: - name = p['name'].split('-')[0] - name = name.split(' ')[0] - prefix = name.split('_')[0] - p['shortname'] = name - pin_map[p['position']] = p gpios = part.get_driver('gpio') + pinout = [] + for pin in gpios["package"][0]["pin"]: + name = shortname = pin["name"] + ptype = pin.get("type", "i/o").upper() + if "I/O" in ptype: + shortname = name[:4] + if len(shortname) > 3 and not shortname[3].isdigit(): + shortname = shortname[:3] + pinout.append({ + "short": shortname, + "position": pin["position"], + "name": pin["name"], + "type": ptype, + "remap": pin.get("variant", "") == "remap", + }) + pins = {} for gpio in gpios['gpio']: name = 'P%c%u' % (gpio['port'].upper(), int(gpio['pin'], 10)) @@ -239,17 +248,14 @@ def make_chip(part): # usually always just PA0 and then you select the alternate or # analog function for that pin - i.e. it's another level of # multiplexing to squash more functionality into a small pin - # count. For these types of devices, there will be multiple - # GPIOs that have the same 'position' field and when we populate - # pins[key] we will only hold the last one there. - key = gpio['position'] - pin = pin_map[key] - name = pin['shortname'] - fname = pin['name'] - pins[key] = GPIO(name, key, alt_fns, add_fns, fname, part) - - for p in part.properties['pin']: - key = p['position'] + # count. For these types of devices, there will only show the + # default configuration, i.e. the non-remapped pin. + pin = next(p for p in pinout if p["short"] == name and not p["remap"]) + key = pin['position'] + pins[key] = GPIO(name, key, alt_fns, add_fns, pin['name'], part) + + for pin in pinout: + key = pin['position'] if key not in pins: - pins[key] = Pin(p['name'], key, [], [], p['name']) + pins[key] = Pin(pin["short"], key, [], [], pin['name']) return Chip(part, pkg, pins) diff --git a/stm_layout.py b/stm_layout.py index 552cb82..7e7d4c4 100755 --- a/stm_layout.py +++ b/stm_layout.py @@ -362,7 +362,7 @@ def main(screen, chip): parts = chip_db.find(rv.chip) if len(parts) > 1: for p in parts: - print('%s - %s%s' % (p, chip_db.package(p), chip_db.pin_count(p))) + print('%s - %s' % (p, chip_db.package(p))) else: chip = chip_stm.make_chip(parts[0]) tgcurses.wrapper(main, chip) From 94253cedf6fdb30e1282fb302102462c5f1e5933 Mon Sep 17 00:00:00 2001 From: Terry Greeniaus Date: Sun, 20 Sep 2020 00:42:18 -0600 Subject: [PATCH 2/2] chip_stm.py: Rework parsing so that "similar" pins like PC2 and PC2_C on the same device are handled properly. --- chip_stm.py | 88 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 38 deletions(-) diff --git a/chip_stm.py b/chip_stm.py index ff63fb1..6805f2b 100644 --- a/chip_stm.py +++ b/chip_stm.py @@ -206,28 +206,52 @@ def serialize_settings(self): def make_chip(part): - pkg = chip_db.make_package(part) - - gpios = part.get_driver('gpio') - pinout = [] - for pin in gpios["package"][0]["pin"]: - name = shortname = pin["name"] - ptype = pin.get("type", "i/o").upper() - if "I/O" in ptype: - shortname = name[:4] - if len(shortname) > 3 and not shortname[3].isdigit(): - shortname = shortname[:3] - pinout.append({ - "short": shortname, - "position": pin["position"], - "name": pin["name"], - "type": ptype, - "remap": pin.get("variant", "") == "remap", - }) - - pins = {} - for gpio in gpios['gpio']: - name = 'P%c%u' % (gpio['port'].upper(), int(gpio['pin'], 10)) + gpio_driver = part.get_driver('gpio') + + gpios = {} + for gpio in gpio_driver['gpio']: + gpios['P%s%s' % (gpio['port'].upper(), gpio['pin'])] = gpio + + pins = {} + for p in gpio_driver['package'][0]['pin']: + # TODO: Some small devices have multiplexed pins where the SYSCFG + # device can be used to select if the physical pin should be PA0 + # or PA1 or... This is different from a normal pin which is + # usually always just PA0 and then you select the alternate or + # analog function for that pin - i.e. it's another level of + # multiplexing to squash more functionality into a small pin + # count. For these types of devices, we will only show the + # default configuration, i.e. the non-remapped pin. + if p.get('variant', '') == 'remap': + continue + + full_name = p['name'] + key = p['position'] + + # GPIO pins don't have a type and non-GPIOs have nothing to extract, + # so assign them directly. + if 'type' in p: + pins[key] = Pin(full_name, key, [], [], full_name) + continue + + # Extract the short name and the GPIO key from the full name. Sample + # full names: + # + # PA0 + # PA11 [PA9] + # PC14-OSC32_IN (PC14) + # PC2_C + # + # The short name is the initial prefix except in the case of an "_C" + # suffix, in which case the short name includes the suffix. The GPIO + # key is always strictly the prefix. + short_name = full_name.split('-')[0] + short_name = short_name.split(' ')[0] + gpio_key = short_name.split('_')[0] + + # Extract the alternate (digital) functions and additional (analog) + # functions. + gpio = gpios[gpio_key] alt_fns = ['-']*16 add_fns = [] for s in gpio.get('signal', []): @@ -242,20 +266,8 @@ def make_chip(part): else: add_fns.append(f) - # TODO: Some small devices have multiplexed pins where the SYSCFG - # device can be used to select if the physical pin should be PA0 - # or PA1 or... This is different from a normal pin which is - # usually always just PA0 and then you select the alternate or - # analog function for that pin - i.e. it's another level of - # multiplexing to squash more functionality into a small pin - # count. For these types of devices, there will only show the - # default configuration, i.e. the non-remapped pin. - pin = next(p for p in pinout if p["short"] == name and not p["remap"]) - key = pin['position'] - pins[key] = GPIO(name, key, alt_fns, add_fns, pin['name'], part) - - for pin in pinout: - key = pin['position'] - if key not in pins: - pins[key] = Pin(pin["short"], key, [], [], pin['name']) + # Assign the final pin. + pins[key] = GPIO(short_name, key, alt_fns, add_fns, full_name, part) + + pkg = chip_db.make_package(part) return Chip(part, pkg, pins)