blob: cd47c103807e63750a0acc4d5ee1047d34ab329b [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2018-2020 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import os
class Style:
BOLD = 1
DEFAULT = 39
RED = 31
GREEN = 32
YELLOW = 33
BLUE = 34
MAGENTA = 35
CYAN = 36
DARK_GRAY = 90
class Kind:
GND, POWER, I2C, UART, GPIO, SAI, SPI, PWM = range(8)
KINDS = {
Kind.GND: (Style.DARK_GRAY, 'GND', 'Ground'),
Kind.POWER: (Style.RED, 'POWER', 'Power: +5V or +3.3V'),
Kind.I2C: (Style.GREEN, 'I2C', 'Inter-Integrated Circuit [/dev/i2c-N]'),
Kind.UART: (Style.MAGENTA, 'UART', 'Serial Port [/dev/ttySN]'),
Kind.GPIO: (Style.DEFAULT, 'GPIO', 'General Purpose Input Output [/sys/class/gpio/gpioN]'),
Kind.SAI: (Style.CYAN, 'SAI', 'Synchronous Audio Interface'),
Kind.SPI: (Style.BLUE, 'SPI', 'Serial Peripheral Interface [/dev/spidevN.N]'),
Kind.PWM: (Style.YELLOW, 'PWM', 'Pulse Width Modulation [/sys/class/pwm/pwmchipN/pwm0]'),
}
I2C_DEVICES = {
'I2C1': '1100a000.i2c',
'I2C2': '1100b000.i2c',
}
def lookup_i2c_bus(device_tree_name):
sysfs_directory = '/sys/devices/platform/soc/{}'.format(device_tree_name)
return [x for x in os.listdir(sysfs_directory) if x.startswith('i2c-')][0]
PINS = {
1: ('3.3.V', Kind.POWER), 2: ('5V', Kind.POWER),
3: ('I2C1_SDA ({})'.format(lookup_i2c_bus(I2C_DEVICES['I2C1'])), Kind.I2C),
4: ('5V', Kind.POWER),
5: ('I2C1_SCL ({})'.format(lookup_i2c_bus(I2C_DEVICES['I2C1'])), Kind.I2C),
6: ('GND', Kind.GND),
7: ('GPIO (gpio409)', Kind.GPIO), 8: ('UART0_TX (ttyS0)', Kind.UART),
9: ('GND', Kind.GND), 10: ('UART0_RX (ttyS0)', Kind.UART),
11: ('GPIO (gpio396)', Kind.GPIO), 12: ('GPIO (gpio423) / I2S_BCK', Kind.SAI),
13: ('GPIO (gpio397)', Kind.GPIO), 14: ('GND', Kind.GND),
15: ('PWM (pwmchip0.2)', Kind.PWM), 16: ('GPIO (gpio387)', Kind.GPIO),
17: ('3.3V', Kind.POWER), 18: ('GPIO (gpio399)', Kind.GPIO),
19: ('SPI_MOSI (spidev0)', Kind.SPI), 20: ('GND', Kind.GND),
21: ('SPI_MISO (spidev0)', Kind.SPI), 22: ('GPIO (gpio394)', Kind.GPIO),
23: ('SPI_SCLK (spidev0)', Kind.SPI), 24: ('SPI_CSB (spidev0.0)', Kind.SPI),
25: ('GND', Kind.GND), 26: ('GPIO (gpio395)', Kind.GPIO),
27: ('I2C2_SDA ({})'.format(lookup_i2c_bus(I2C_DEVICES['I2C2'])), Kind.I2C),
28: ('I2C2_SCL ({})'.format(lookup_i2c_bus(I2C_DEVICES['I2C2'])), Kind.I2C),
29: ('UART1_TX (ttyS1)', Kind.UART), 30: ('GND', Kind.GND),
31: ('UART1_RX (ttyS1)', Kind.UART), 32: ('PWM (pwmchip0.0)', Kind.PWM),
33: ('PWM (pwmchip0.1)', Kind.PWM), 34: ('GND', Kind.GND),
35: ('GPIO (gpio424) / I2S_LRCK', Kind.SAI), 36: ('GPIO (gpio400)', Kind.GPIO),
37: ('GPIO (gpio432)', Kind.GPIO), 38: ('GPIO (gpio425) / I2S_DO', Kind.SAI),
39: ('GND', Kind.GND), 40: ('GPIO (gpio426) / I2S_MCK', Kind.SAI)
}
assert(len(PINS) % 2 == 0)
assert(set(PINS.keys()) == set(range(1, len(PINS) + 1)))
def pins():
for i in range(len(PINS) // 2):
yield (2 * i + 1, 2 * i + 2)
def pin_desc(pin):
text, _ = PINS[pin]
return text
def pin_kind(pin):
_, kind = PINS[pin]
return kind
def stylize(text, style, esc='\033['):
return '%s%dm%s%s0m' % (esc, style, text, esc)
def stylize_pin(text, pin):
style, _, _ = KINDS[pin_kind(pin)]
return stylize(text, style)
def print_pinout(color):
max_len = max(len(pin_desc(l)) for l, _ in pins())
for l, r in pins():
l_pin, r_pin = str(l).ljust(2), str(r).rjust(2)
l_txt, r_txt = pin_desc(l).rjust(max_len), pin_desc(r)
if color:
l_pin = stylize(l_pin, Style.BOLD)
r_pin = stylize(r_pin, Style.BOLD)
l_txt, r_txt = stylize_pin(l_txt, l), stylize_pin(r_txt, r)
print('%s -> %s %s <- %s' % (l_txt, l_pin, r_pin, r_txt))
def print_legend(color):
max_len = max(len(name) for _, (_, name, _) in KINDS.items())
for kind, (style, name, desc) in KINDS.items():
txt = name.ljust(max_len)
if color:
txt = stylize(txt, style)
print('%s - %s' % (txt, desc))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--nocolor', dest='color', action='store_false',
default=True, help='Do not output in color.')
parser.add_argument('--nolegend', dest='legend', action='store_false',
default=True, help='Do not output legend.')
args = parser.parse_args()
print_pinout(args.color)
if args.legend:
print()
print_legend(args.color)
if __name__ == '__main__':
main()