1#!/usr/bin/python3 2# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. 3# SPDX-License-Identifier: Apache-2.0 4 5import os 6import sys 7import yaml 8import argparse 9from pathlib import Path 10from datetime import datetime 11 12current_year = datetime.now().year 13 14file_out_head = f'''/* 15 * Copyright (c) {current_year} Espressif Systems (Shanghai) Co., Ltd. 16 * 17 * SPDX-License-Identifier: Apache-2.0 18 * 19 * NOTE: Autogenerated file using esp_genpinctrl.py 20 */ 21 22#ifndef INC_DT_BINDS_PINCTRL_''' + '''{SOC}''' + '''_PINCTRL_HAL_H_ 23#define INC_DT_BINDS_PINCTRL_''' + '''{SOC}''' + '''_PINCTRL_HAL_H_ 24 25''' 26 27file_out_tail = ''' 28#endif /* INC_DT_BINDS_PINCTRL_{SOC}_PINCTRL_HAL_H_ */ 29''' 30 31file_out_path = 'include/zephyr/dt-bindings/pinctrl/' 32file_out_temp = '{SOC}-pinctrl-temp.h' 33file_out_name = '{SOC}-pinctrl.h' 34file_tmp_abs = '' 35 36line_comment = '' 37 38 39def err(source, msg): 40 global file_tmp_abs 41 os.remove(file_tmp_abs) 42 sys.exit('ERR(' + source + '):' + msg) 43 44 45def get_pin_ios(pins): 46 ios = [] 47 for io in pins: 48 if type(io) is int: 49 ios.append(io) 50 elif type(io) is list and io.__len__() == 2: 51 for io_num in range(io[0], 1 + io[1]): 52 ios.append(io_num) 53 else: 54 err('gpio', 'bad type / wrong list size') 55 56 return ios 57 58 59def get_gpios(pin_info): 60 if 'gpio' in pin_info: 61 return get_pin_ios(pin_info.get('gpio')) 62 else: 63 err('gpio', 'missing property') 64 65 66def get_pin_sigi(pin_info): 67 sigi = 'ESP_' 68 if 'sigi' in pin_info: 69 sigi = sigi + pin_info['sigi'].upper() 70 else: 71 sigi = sigi + 'NOSIG' 72 73 return sigi 74 75 76def get_pin_sigo(pin_info): 77 sigo = 'ESP_' 78 if 'sigo' in pin_info: 79 sigo = sigo + pin_info['sigo'].upper() 80 else: 81 sigo = sigo + 'NOSIG' 82 83 return sigo 84 85 86def get_pinmux(dev_name, pin_name, pin_info, io): 87 sigi = get_pin_sigi(pin_info) 88 sigo = get_pin_sigo(pin_info) 89 global line_comment 90 91 pinmux = dev_name.upper() + '_' + pin_name.upper() + '_GPIO' + str(io) 92 define_str = '#define ' + pinmux 93 macro_str = 'ESP32_PINMUX(' + str(io) + ', ' + sigi + ', ' + sigo + ')' 94 95 if len(define_str + ' ' + macro_str) > 100: 96 # print in two lines 97 pinmux = define_str + ' \\\n\t' + macro_str + '\n\n' 98 else: 99 pinmux = define_str + ' ' + macro_str + '\n\n' 100 101 if bool(line_comment): 102 pinmux = line_comment + pinmux 103 line_comment = '' 104 105 return pinmux 106 107 108def main(pcfg_in): 109 zephyr_base = os.getenv('ZEPHYR_BASE') 110 111 if zephyr_base is None: 112 print("Missing ZEPHYR_BASE environment variable") 113 exit() 114 115 print("Zephyr Base: ", zephyr_base) 116 117 stream = open(pcfg_in, 'r') 118 pcfg_data = yaml.load(stream, Loader=yaml.FullLoader) 119 soc = os.path.basename(pcfg_in).replace('.yml', '') 120 121 file_out_abs = Path(zephyr_base, file_out_path + soc + '-pinctrl.h') 122 global file_tmp_abs 123 file_tmp_abs = Path(zephyr_base, file_out_path + soc + '-pinctrl-temp.h') 124 125 # sorts by dev name, which keeps git 126 # diffs minimal and easily trackable 127 all_data = sorted(pcfg_data.items()) 128 129 f = open(file_tmp_abs, 'w') 130 f.write(file_out_head.replace('{SOC}', soc.upper())) 131 132 for (dev_name, dev_info) in all_data: 133 134 # sorts by pin name, which keeps git 135 # diffs minimal and easily trackable 136 dev_info = sorted(dev_info.items()) 137 138 for (pin_name, pin_info) in dev_info: 139 global line_comment 140 line_comment = '/* ' + dev_name.upper() + '_' + pin_name.upper() + ' */\n' 141 ios = get_gpios(pin_info) 142 for io in ios: 143 pinmux = get_pinmux(dev_name, pin_name, pin_info, io) 144 f.write(pinmux) 145 146 f.write(file_out_tail.replace('{SOC}', soc.upper())) 147 f.close() 148 149 if os.path.exists(file_out_abs): 150 os.remove(file_out_abs) 151 152 os.rename(file_tmp_abs, file_out_abs) 153 154 print("Output file: ", file_out_abs) 155 156 157if __name__ == '__main__': 158 parser = argparse.ArgumentParser() 159 parser.add_argument( 160 '-p', 161 '--path', 162 type=Path, 163 required=True, 164 help='Path to target file', 165 ) 166 args = parser.parse_args() 167 168 main(args.path) 169