diff --git a/Tools/scripts/generate_board_page.py b/Tools/scripts/generate_board_page.py new file mode 100755 index 0000000000000..82510cd1756ce --- /dev/null +++ b/Tools/scripts/generate_board_page.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 + +import os +import pathlib +import shutil +import sys + +# modify our search path: +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../libraries/AP_HAL_ChibiOS/hwdef/scripts')) +import chibios_hwdef # noqa + + +class GenerateBoardPage(): + '''an object that will create many html files into a directory, one + for each hwdef board''' + + def __init__(self): + self.hwdef_dir = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "..", "..", "libraries", "AP_HAL_ChibiOS", "hwdef") + self.outdir = "/tmp/some_html" + + def generate_UART_mapping(self, hwdef): + uart_order = hwdef.get_config('SERIAL_ORDER', required=False, aslist=True) + if uart_order is None: + return None + serial_purpose = hwdef.get_serial_purpose() + count = 0 + ret = "" + for uart in uart_order: + purpose = serial_purpose.get(count, "") + if purpose != "": + purpose = f" ({purpose})" + rtsctsnote = "" + if hwdef.serial_has_cts_rts(count): + rtsctsnote = " (RTS/CTS pins)" + ret += f"SERIAL{count} -> {uart}{purpose}{rtsctsnote}\n" + count += 1 + + return ret + + def generate_Specifications(self, hwdef): + ret = "" + + # baro_list contains all possible baros, not the onnes you + # might actually find on a board... + return None + + dev_counts = {} + for baro in hwdef.baro_list: + dev = baro[0] + if dev not in dev_counts.keys(): + dev_counts[dev] = 0 + dev_counts[dev] += 1 + for dev in dev_counts.keys(): + ret += f" - {dev}" + if dev_counts[dev] > 1: + ret += f" * {dev_counts[dev]}" + ret += "\n" + + return ret + + def content_section(self, section_name, content): + if content is None: + return "bob" + return f""" +{"=" * len(section_name)} +{section_name} +{"=" * len(section_name)} + +{content} +""" + + def generate_content_for_hwdef(self, filepath): + hwdef = chibios_hwdef.ChibiOSHWDef(quiet=True, hwdef=None) + hwdef.process_file(filepath) + + content = "" + + content += self.content_section("UART Mapping", self.generate_UART_mapping(hwdef)) + content += self.content_section("Specifications", self.generate_Specifications(hwdef)) + + return content + + def run(self): + try: + shutil.rmtree(self.outdir) + except FileNotFoundError: + pass + pathlib.Path(self.outdir).mkdir(parents=True, exist_ok=True) + + for adir in os.listdir(self.hwdef_dir): + if adir is None: + continue + if adir != "Pixhawk6X": + continue + board_dirpath = os.path.join(self.hwdef_dir, adir) + filepath = os.path.join(board_dirpath, "hwdef.dat") + if not os.path.exists(filepath): + continue + + output = self.generate_content_for_hwdef(filepath) + + outfile = os.path.join(self.outdir, f"{adir}.rst") + pathlib.Path(outfile).write_text(output) + + +gbp = GenerateBoardPage() +gbp.run() diff --git a/libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6X/hwdef.dat b/libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6X/hwdef.dat index a53e62d65d4bd..1c140e09c2b96 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6X/hwdef.dat +++ b/libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6X/hwdef.dat @@ -30,6 +30,15 @@ env OPTIMIZE -O2 # order of UARTs (and USB) SERIAL_ORDER OTG1 UART7 UART5 USART1 UART8 USART2 UART4 USART3 OTG2 +SERIAL_PURPOSE 0 USB +SERIAL_PURPOSE 1 Telem1 +SERIAL_PURPOSE 2 Telem2 +SERIAL_PURPOSE 3 GPS1 +SERIAL_PURPOSE 4 GPS2 +SERIAL_PURPOSE 5 Telem3 +SERIAL_PURPOSE 6 User +SERIAL_PURPOSE 7 Debug +SERIAL_PURPOSE 8 USB; MAVLink, can be used for SLCAN with protocol change # default to all pins low to avoid ESD issues DEFAULTGPIO OUTPUT LOW PULLDOWN diff --git a/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py b/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py index 4e1e04a75563e..eb19f61b9bb5a 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py +++ b/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py @@ -128,6 +128,9 @@ def __init__(self, quiet=False, bootloader=False, signed_fw=False, outdir=None, # list of shared up timers self.shared_up = [] + # a map from a serial number (0 being USB) to the usual use of that port (e.g. Telem1) + self.serial_purpose = {} + def is_int(self, str): '''check if a string is an integer''' try: @@ -1801,6 +1804,28 @@ def get_extra_bylabel(self, label, name, default=None): return default return p.extra_value(name, type=str, default=default) + def get_UART_ORDER(self): + '''get UART_ORDER from SERIAL_ORDER option''' + if self.get_config('UART_ORDER', required=False, aslist=True) is not None: + self.error('Please convert UART_ORDER to SERIAL_ORDER') + serial_order = self.get_config('SERIAL_ORDER', required=False, aslist=True) + if serial_order is None: + return None + if self.is_bootloader_fw(): + # in bootloader SERIAL_ORDER is treated the same as UART_ORDER + return serial_order + map = [0, 3, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12] + while len(serial_order) < 4: + serial_order += ['EMPTY'] + uart_order = [] + for i in range(len(serial_order)): + uart_order.append(serial_order[map[i]]) + return uart_order + + def get_serial_purpose(self): + '''returns a dict mapping from serial number (0 is USB) to textual description of purpose''' + return self.serial_purpose + def write_UART_config(self, f): '''write UART config defines''' serial_list = self.get_config('SERIAL_ORDER', required=False, aslist=True) @@ -2446,6 +2471,23 @@ def setup_apj_IDs(self): (USB_VID, USB_PID) = self.get_USB_IDs() self.env_vars['USBID'] = '0x%04x/0x%04x' % (USB_VID, USB_PID) + def serial_has_cts_rts(self, serial): + '''returns true if serial "serial" has CTS/RTS pins associated''' + uart_order = self.get_config('SERIAL_ORDER', required=True, aslist=True) + uart_name = uart_order[serial] + have_cts = False + have_rts = False + + for t in self.bytype.values(): + for pin in t: + if pin.label == f"{uart_name}_CTS": + have_cts = True + elif pin.label == f"{uart_name}_RTS": + have_rts = True + if have_rts and have_cts: + return True + return False + def write_peripheral_enable(self, f): '''write peripheral enable lines''' f.write('// peripherals enabled\n') @@ -3058,6 +3100,8 @@ def process_line(self, line, depth): # raise ValueError(msg) self.intdefines[name] = intvalue + elif a[0] == "SERIAL_PURPOSE": + self.serial_purpose[int(a[1])] = ' '.join(a[2:]) def progress(self, message): if self.quiet: