Refactor uart (#13585)
[betaflight.git] / src / utils / gen-serial-j2.py
blobdaefa9654d0393562928f6c4783bdd092c6cc629
1 from jinja2 import Environment, FileSystemLoader
2 import jinja2
3 import os
4 from datetime import datetime
5 import pprint
7 # generate normalization preprocessor file for serial ports
9 # configuration for template generation
10 serials = {
11 "UART": {"ids": [i + 1 for i in range(10)],
12 "inverter": True,
14 "LPUART": {"ids": [1],
15 "depends": {"UART"},
16 # "inverter": True, # TODO: old code compatibility only, disabled
18 "SOFTSERIAL": {"ids": [i + 1 for i in range(2)],
19 "use_enables_all": True,
20 "force_continuous": True,
22 "VCP": {"singleton": True,
23 "no_pins": True}
26 def flatten_config(data):
27 flattened_list = []
28 for key, value in data.items():
29 flattened_dict = {'typ': key}
30 # Update this new dictionary with the inner dictionary's items
31 flattened_dict.update(value)
32 flattened_list.append(flattened_dict)
33 return flattened_list
35 def pprint_filter(value, indent=4):
36 return pprint.pformat(value, indent=indent)
38 def rdepends_filter(cfg, typ):
39 return list(set([ c['typ'] for c in cfg if typ in c['depends'] ]))
41 def main():
42 # Setup Jinja2 environment
43 current_dir = os.path.dirname(os.path.abspath(__file__))
44 # Set the template directory relative to the current script
45 template_dir = os.path.join(current_dir, 'templates')
46 env = Environment(loader=FileSystemLoader(template_dir),
47 autoescape=True,
48 undefined=jinja2.StrictUndefined, # Throws an error on undefined variables
49 trim_blocks = True,
51 env.filters['pprint'] = pprint_filter
52 env.filters['zip'] = zip
53 env.filters['rdepends'] = rdepends_filter
54 template = env.get_template('serial_post.h')
56 # Read license file
57 license_path = 'DEFAULT_LICENSE.md'
58 with open(license_path, 'r') as file:
59 t_license = file.read()
61 context = {}
62 context['license'] = t_license
63 context['date_generated'] = datetime.now().strftime('%Y-%m-%d')
64 context['user_config'] = serials
65 config = flatten_config(serials)
66 context['config'] = config
68 for cfg in config:
69 singleton = cfg.setdefault('singleton', False)
70 no_pins = cfg.setdefault('no_pins', False)
71 inverter = cfg.setdefault('inverter', False)
72 cfg.setdefault("use_enables_all", False)
73 cfg.setdefault("force_continuous", False)
74 cfg.setdefault("depends", {})
75 typ = cfg['typ']
76 if singleton:
77 cfg['ports']= [ f"{typ}" ]
78 else:
79 cfg['ports'] = [ f"{typ}{i}" for i in cfg["ids"] ]
81 # Render the template with the license content
82 output = template.render(**context)
84 if False:
85 # Output or save to a file
86 output_path = './src/main/target/serial_post.h'
87 with open(output_path, 'w') as file:
88 file.write(output)
89 print(f"Generated file saved to {output_path}")
90 else:
91 print(output)
93 if __name__ == '__main__':
94 main()