tinyusb-sys 0.1.1

Bindings to the tinyusb library
#!/usr/bin/env python3
import fileinput
import re
import sys

# Usage: ./generate_features.py features
# Usage: ./generate_features.py tusb_config.rs

#####################################################################

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':
            # typical keyboard + mouse device can have 3-4 HID interfaces
            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':
            # // hub typically has 4 ports
            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")