import fileinput
import re
import sys
mcus = []
host_features = []
device_features = []
for line in open("tinyusb/src/tusb_option.h", "r"):
line = line.strip()
m = re.match("#define OPT_MCU_([^ ]+) ", line)
if m is not None:
mcu = m.groups()[0].lower()
mcus.append(mcu)
m = re.match("#define CFG_TUH_([^ ]+) +0", line)
if m is not None:
cls = m.groups()[0].lower()
host_features.append(cls)
m = re.match("#define CFG_TUD_([^ ]+) +0", line)
if m is not None:
cls = m.groups()[0].lower()
device_features.append(cls)
mcus = [v for v in mcus if v != 'none']
host_features = [v for v in host_features
if v not in ['device_max', 'enumeration_bufsize']]
device_features = [v for v in device_features
if v not in ['endpoint0_size', 'enumeration_bufsize']]
cmd = sys.argv[1] if len(sys.argv) == 2 else None
if cmd == "features":
print("# Auto-generated by generate_features.py")
print("host = []")
print("device = []")
for mcu in mcus:
print(f"{mcu} = []")
for f in set(host_features + device_features):
print(f"{f} = []")
elif cmd == "tusb_config.rs":
cfg = []
cfg.append('#[cfg(all(feature = "host", feature = "device"))]')
cfg.append('compile_error!("choose only host or device");')
cfg.append('#[cfg(not(any(feature = "host", feature ="device")))]')
cfg.append('compile_error!("select mode host or device");')
for mcu in mcus:
cfg.append(f'#[cfg(feature = "{mcu}")]')
cfg.append(f'cfg.push_str("#define CFG_TUSB_MCU OPT_MCU_{mcu.upper()}\\n");')
for feature in host_features:
n = 1
if feature == 'hid':
n = 4
cfg.append(f'#[cfg(all(feature = "host", feature = "{feature}"))]')
cfg.append(f'cfg.push_str("#define CFG_TUH_{feature.upper()} {n}\\n");')
if feature == 'hub':
cfg.append(f'#[cfg(all(feature = "host", feature = "{feature}"))]')
cfg.append(f'cfg.push_str("#define CFG_TUH_DEVICE_MAX 4\\n");')
for feature in device_features:
cfg.append(f'#[cfg(all(feature = "device", feature = "{feature}"))]')
cfg.append(f'cfg.push_str("#define CFG_TUD_{feature.upper()} 1\\n");')
cfg = '\n'.join(cfg)
print(f"""
// Auto-generated by generate_features.py
pub fn generate_cfg() -> String {{
let mut cfg = String::new();
cfg.push_str("#ifndef _TUSB_CONFIG_H_\\n");
cfg.push_str("#define _TUSB_CONFIG_H_\\n");
#[cfg(feature = "host")]
cfg.push_str("#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST\\n");
#[cfg(feature = "device")]
cfg.push_str("#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE\\n");
cfg.push_str("#define CFG_TUSB_OS OPT_OS_NONE\\n");
cfg.push_str("#define CFG_TUSB_MEM_SECTION __attribute__((section(\\\".data.usb\\\")))\\n");
{cfg}
cfg.push_str("#endif\\n");
cfg
}}
""")
else:
print(f"Usage: {sys.argv[0]} features|tusb_config.rs")