Skip to content

Commit

Permalink
add script to generate rst from hwdef
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbarker committed May 21, 2024
1 parent 24e54da commit 100a0cc
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 0 deletions.
109 changes: 109 additions & 0 deletions Tools/scripts/generate_board_page.py
Original file line number Diff line number Diff line change
@@ -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()
9 changes: 9 additions & 0 deletions libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6X/hwdef.dat
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 44 additions & 0 deletions libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 100a0cc

Please sign in to comment.