esp-generate 1.3.0

Template generation tool to create no_std applications targeting Espressif's chips
Documentation
1
pub static TEMPLATE_FILES : & [(& str , & str)] = & [("src/lib.rs" , "#![no_std]") , ("src/bin/async_main.rs" , "//INCLUDEFILE option(\"embassy\")\n//INCLUDE_AS src/bin/main.rs\n#![no_std]\n#![no_main]\n#![deny(\n    clippy::mem_forget,\n    reason = \"mem::forget is generally not safe to do with esp_hal types, especially those \\\n    holding buffers for the duration of a data transfer.\"\n)]\n#![deny(clippy::large_stack_frames)]\n\nuse esp_hal::clock::CpuClock;\nuse esp_hal::timer::timg::TimerGroup;\n\n//IF option(\"ble-trouble\") || option(\"ble-bleps\")\nuse esp_radio::ble::controller::BleConnector;\n//ENDIF\n//IF option(\"ble-trouble\")\nuse bt_hci::controller::ExternalController;\nuse trouble_host::prelude::*;\n//ENDIF\n\nuse embassy_executor::Spawner;\nuse embassy_time::{Duration, Timer};\n\n//IF option(\"defmt\")\n//IF !option(\"probe-rs\")\n//+use esp_println as _;\n//ENDIF\n//+use defmt::info;\n//IF !option(\"panic-handler\")\n//+use defmt::error;\n//ENDIF !option(\"panic-handler\")\n//ELIF option(\"log\")\nuse log::info;\n//IF !option(\"panic-handler\")\nuse log::error;\n//ENDIF !option(\"panic-handler\")\n//ELIF option(\"probe-rs\") // without defmt\n//+use rtt_target::rprintln;\n//ENDIF !defmt\n\n//IF !option(\"panic-handler\")\n//IF option(\"defmt\") || option(\"log\")\n//+#[panic_handler]\n//+fn panic(panic_info: &core::panic::PanicInfo) -> ! {\n//+    error!(\"{}\", panic_info);\n//+    loop {}\n//+}\n//ELIF option(\"probe-rs\")\n//+#[panic_handler]\n//+fn panic(panic_info: &core::panic::PanicInfo) -> ! {\n//+    rprintln!(\"{}\", panic_info);\n//+    loop {}\n//+}\n//ELSE\n#[panic_handler]\nfn panic(_: &core::panic::PanicInfo) -> ! {\n    loop {}\n}\n//ENDIF\n//ELIF option(\"esp-backtrace\")\n//+use esp_backtrace as _;\n//ELIF option(\"panic-rtt-target\")\n//+use panic_rtt_target as _;\n//ENDIF\n\n//IF option(\"alloc\")\nextern crate alloc;\n//ENDIF\n\n//IF option(\"ble-trouble\")\nconst CONNECTIONS_MAX: usize = 1;\nconst L2CAP_CHANNELS_MAX: usize = 1;\n//ENDIF\n\n// This creates a default app-descriptor required by the esp-idf bootloader.\n// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>\nesp_bootloader_esp_idf::esp_app_desc!();\n\n#[allow(\n    clippy::large_stack_frames,\n    reason = \"it's not unusual to allocate larger buffers etc. in main\"\n)]\n#[esp_rtos::main]\nasync fn main(spawner: Spawner) -> ! {\n    //REPLACE generate-version generate-version\n    // generator version: generate-version\n    //REPLACE generate-parameters generate-parameters\n    // generator parameters: generate-parameters\n\n    //IF option(\"probe-rs\")\n    //IF option(\"defmt\")\n    rtt_target::rtt_init_defmt!();\n    //ELSE\n    rtt_target::rtt_init_print!();\n    //ENDIF\n    //ELIF option(\"log\")\n    esp_println::logger::init_logger_from_env();\n    //ENDIF\n\n    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());\n    let peripherals = esp_hal::init(config);\n\n    //REPLACE __RESERVED_GPIO_CODE__; reserved_gpio_code\n    __RESERVED_GPIO_CODE__;\n\n    //IF option(\"alloc\")\n    //REPLACE 65536 max-dram2-uninit\n    esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 65536);\n    //IF option(\"wifi\") && (option(\"ble-bleps\") || option(\"ble-trouble\"))\n    // COEX needs more RAM - so we've added some more\n    esp_alloc::heap_allocator!(size: 64 * 1024);\n    //ENDIF\n    //ENDIF alloc\n\n    let timg0 = TimerGroup::new(peripherals.TIMG0);\n    let sw_interrupt =\n        esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);\n    esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);\n\n    //IF option(\"defmt\") || option(\"log\")\n    info!(\"Embassy initialized!\");\n    //ELIF option(\"probe-rs\") // without defmt\n    rprintln!(\"Embassy initialized!\");\n    //ENDIF\n\n    //IF option(\"wifi\")\n    let (mut _wifi_controller, _interfaces) =\n        esp_radio::wifi::new(peripherals.WIFI, Default::default())\n            .expect(\"Failed to initialize Wi-Fi controller\");\n    //ENDIF\n    //IF option(\"ble-trouble\")\n    // find more examples https://github.com/embassy-rs/trouble/tree/main/examples/esp32\n    let transport = BleConnector::new(peripherals.BT, Default::default()).unwrap();\n    let ble_controller = ExternalController::<_, 1>::new(transport);\n    let mut resources: HostResources<DefaultPacketPool, CONNECTIONS_MAX, L2CAP_CHANNELS_MAX> =\n        HostResources::new();\n    let _stack = trouble_host::new(ble_controller, &mut resources);\n    //ELIF option(\"ble-bleps\")\n    let _connector = BleConnector::new(peripherals.BT, Default::default());\n    //ENDIF\n\n    // TODO: Spawn some tasks\n    let _ = spawner;\n\n    loop {\n        //IF option(\"defmt\") || option(\"log\")\n        info!(\"Hello world!\");\n        //ELIF option(\"probe-rs\") // without defmt\n        rprintln!(\"Hello world!\");\n        //ENDIF\n        Timer::after(Duration::from_secs(1)).await;\n    }\n\n    //REPLACE {current-version} esp-hal-version-full\n    // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v{current-version}/examples\n}\n") , ("src/bin/main.rs" , "//INCLUDEFILE !option(\"embassy\")\n#![no_std]\n#![no_main]\n#![deny(\n    clippy::mem_forget,\n    reason = \"mem::forget is generally not safe to do with esp_hal types, especially those \\\n    holding buffers for the duration of a data transfer.\"\n)]\n#![deny(clippy::large_stack_frames)]\n\nuse esp_hal::{\n    clock::CpuClock,\n    main,\n    time::{Duration, Instant},\n};\n//IF option(\"wifi\") || option(\"ble-bleps\")\nuse esp_hal::timer::timg::TimerGroup;\n//ENDIF\n//IF option(\"ble-bleps\")\nuse esp_radio::ble::controller::BleConnector;\n//ENDIF\n\n//IF option(\"defmt\")\n//IF !option(\"probe-rs\")\n//+use esp_println as _;\n//ENDIF\n//+use defmt::info;\n//IF !option(\"panic-handler\")\n//+use defmt::error;\n//ENDIF !option(\"panic-handler\")\n//ELIF option(\"log\")\nuse log::info;\n//IF !option(\"panic-handler\")\nuse log::error;\n//ENDIF !option(\"panic-handler\")\n//ELIF option(\"probe-rs\") // without defmt\n//+use rtt_target::rprintln;\n//ENDIF !defmt\n\n//IF !option(\"panic-handler\")\n//IF option(\"defmt\") || option(\"log\")\n//+#[panic_handler]\n//+fn panic(panic_info: &core::panic::PanicInfo) -> ! {\n//+    error!(\"{}\", panic_info);\n//+    loop {}\n//+}\n//ELIF option(\"probe-rs\")\n//+#[panic_handler]\n//+fn panic(panic_info: &core::panic::PanicInfo) -> ! {\n//+    rprintln!(\"{}\", panic_info);\n//+    loop {}\n//+}\n//ELSE\n#[panic_handler]\nfn panic(_: &core::panic::PanicInfo) -> ! {\n    loop {}\n}\n//ENDIF\n//ELIF option(\"esp-backtrace\")\n//+use esp_backtrace as _;\n//ELIF option(\"panic-rtt-target\")\n//+use panic_rtt_target as _;\n//ENDIF\n\n//IF option(\"alloc\")\nextern crate alloc;\n//ENDIF\n\n// This creates a default app-descriptor required by the esp-idf bootloader.\n// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>\nesp_bootloader_esp_idf::esp_app_desc!();\n\n#[allow(\n    clippy::large_stack_frames,\n    reason = \"it's not unusual to allocate larger buffers etc. in main\"\n)]\n#[main]\nfn main() -> ! {\n    //REPLACE generate-version generate-version\n    // generator version: generate-version\n    //REPLACE generate-parameters generate-parameters\n    // generator parameters: generate-parameters\n\n    //IF option(\"probe-rs\")\n    //IF option(\"defmt\")\n    rtt_target::rtt_init_defmt!();\n    //ELSE\n    rtt_target::rtt_init_print!();\n    //ENDIF\n    //ELIF option(\"log\")\n    esp_println::logger::init_logger_from_env();\n    //ENDIF\n\n    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());\n    //IF option(\"wifi\") || option(\"ble-bleps\") || option(\"module-selected\")\n    let peripherals = esp_hal::init(config);\n    //ELSE\n    //+let _peripherals = esp_hal::init(config);\n    //ENDIF\n\n    //REPLACE __RESERVED_GPIO_CODE__; reserved_gpio_code\n    __RESERVED_GPIO_CODE__;\n\n    //IF option(\"alloc\")\n    //REPLACE 65536 max-dram2-uninit\n    esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 65536);\n    //IF option(\"wifi\") && (option(\"ble-bleps\") || option(\"ble-trouble\"))\n    // COEX needs more RAM - so we've added some more\n    esp_alloc::heap_allocator!(size: 64 * 1024);\n    //ENDIF\n    //ENDIF alloc\n\n    //IF option(\"wifi\") || option(\"ble-bleps\")\n    let timg0 = TimerGroup::new(peripherals.TIMG0);\n    let sw_interrupt =\n        esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);\n    esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);\n    //ENDIF\n    //IF option(\"wifi\")\n    let (mut _wifi_controller, _interfaces) =\n        esp_radio::wifi::new(peripherals.WIFI, Default::default())\n            .expect(\"Failed to initialize Wi-Fi controller\");\n    //ENDIF\n    //IF option(\"ble-bleps\")\n    let _connector = BleConnector::new(peripherals.BT, Default::default());\n    //ENDIF\n\n    loop {\n        //IF option(\"defmt\") || option(\"log\")\n        info!(\"Hello world!\");\n        //ELIF option(\"probe-rs\") // without defmt\n        rprintln!(\"Hello world!\");\n        //ENDIF\n        let delay_start = Instant::now();\n        while delay_start.elapsed() < Duration::from_millis(500) {}\n    }\n\n    //REPLACE {current-version} esp-hal-version-full\n    // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v{current-version}/examples\n}\n") , (".github/workflows/rust_ci.yml" , "#INCLUDEFILE option(\"ci\")\nname: Continuous Integration\n\non:\n  push:\n    branches:\n      - main\n    paths-ignore:\n      - \"**/README.md\"\n  pull_request:\n  workflow_dispatch:\n\nenv:\n  CARGO_TERM_COLOR: always\n#IF option(\"xtensa\")\n  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n#ENDIF\n\njobs:\n  rust-checks:\n    name: Rust Checks\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        action:\n          - command: build\n            args: --release\n          - command: fmt\n            args: --all -- --check\n          - command: clippy\n            args: --all-features --workspace -- -D warnings\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n      - name: Setup Rust\n#IF option(\"riscv\")\n        uses: dtolnay/rust-toolchain@v1\n        with:\n#REPLACE riscv32imac-unknown-none-elf rust_target\n          target: riscv32imac-unknown-none-elf\n          toolchain: stable\n          components: rust-src, rustfmt, clippy\n#ELIF option(\"xtensa\")\n#+        uses: esp-rs/xtensa-toolchain@v1.5\n#+        with:\n#+          default: true\n#REPLACE esp32 mcu\n#+          buildtargets: esp32\n#+          ldproxy: false\n#ENDIF\n      - name: Enable caching\n        uses: Swatinem/rust-cache@v2\n      - name: Run command\n        run: cargo ${{ matrix.action.command }} ${{ matrix.action.args }}") , ("build.rs" , "fn main() {\n    linker_be_nice();\n    //IF option(\"embedded-test\")\n    println!(\"cargo:rustc-link-arg-tests=-Tembedded-test.x\");\n    //ENDIF\n    //IF option(\"defmt\")\n    println!(\"cargo:rustc-link-arg=-Tdefmt.x\");\n    //ENDIF\n    // make sure linkall.x is the last linker script (otherwise might cause problems with flip-link)\n    println!(\"cargo:rustc-link-arg=-Tlinkall.x\");\n}\n\nfn linker_be_nice() {\n    let args: Vec<String> = std::env::args().collect();\n    if args.len() > 1 {\n        let kind = &args[1];\n        let what = &args[2];\n\n        match kind.as_str() {\n            \"undefined-symbol\" => match what.as_str() {\n                what if what.starts_with(\"_defmt_\") => {\n                    eprintln!();\n                    eprintln!(\n                        \"💡 `defmt` not found - make sure `defmt.x` is added as a linker script and you have included `use defmt_rtt as _;`\"\n                    );\n                    eprintln!();\n                }\n                \"_stack_start\" => {\n                    eprintln!();\n                    eprintln!(\"💡 Is the linker script `linkall.x` missing?\");\n                    eprintln!();\n                }\n                what if what.starts_with(\"esp_rtos_\") => {\n                    eprintln!();\n                    eprintln!(\n                        \"💡 `esp-radio` has no scheduler enabled. Make sure you have initialized `esp-rtos` or provided an external scheduler.\"\n                    );\n                    eprintln!();\n                }\n                \"embedded_test_linker_file_not_added_to_rustflags\" => {\n                    eprintln!();\n                    eprintln!(\n                        \"💡 `embedded-test` not found - make sure `embedded-test.x` is added as a linker script for tests\"\n                    );\n                    eprintln!();\n                }\n                \"free\"\n                | \"malloc\"\n                | \"calloc\"\n                | \"get_free_internal_heap_size\"\n                | \"malloc_internal\"\n                | \"realloc_internal\"\n                | \"calloc_internal\"\n                | \"free_internal\" => {\n                    eprintln!();\n                    eprintln!(\n                        \"💡 Did you forget the `esp-alloc` dependency or didn't enable the `compat` feature on it?\"\n                    );\n                    eprintln!();\n                }\n                _ => (),\n            },\n            // we don't have anything helpful for \"missing-lib\" yet\n            _ => {\n                std::process::exit(1);\n            }\n        }\n\n        std::process::exit(0);\n    }\n\n    //IF option(\"xtensa\")\n    println!(\n        \"cargo:rustc-link-arg=-Wl,--error-handling-script={}\",\n        std::env::current_exe().unwrap().display()\n    );\n    //ELIF option(\"riscv\")\n    println!(\n        \"cargo:rustc-link-arg=--error-handling-script={}\",\n        std::env::current_exe().unwrap().display()\n    );\n    //ENDIF\n}\n") , ("tests/async_hello_test.rs" , "//INCLUDEFILE option(\"embassy\") && option(\"embedded-test\")\n//INCLUDE_AS tests/hello_test.rs\n//! Demo test suite using embedded-test\n//!\n//! You can run this using `cargo test` as usual.\n\n#![no_std]\n#![no_main]\n\nesp_bootloader_esp_idf::esp_app_desc!();\n\n#[cfg(test)]\n#[embedded_test::tests(executor = esp_rtos::embassy::Executor::new())]\nmod tests {\n    //IF option(\"defmt\")\n    use defmt::assert_eq;\n    //ENDIF\n\n    #[init]\n    fn init() {\n        let peripherals = esp_hal::init(esp_hal::Config::default());\n\n        let timg0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0);\n        let sw_interrupt =\n            esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);\n        esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);\n\n        //IF option(\"defmt\")\n        rtt_target::rtt_init_defmt!();\n        //ENDIF\n    }\n\n    #[test]\n    async fn hello_test() {\n        //IF option(\"defmt\")\n        defmt::info!(\"Running test!\");\n        //ENDIF\n\n        embassy_time::Timer::after(embassy_time::Duration::from_millis(100)).await;\n        assert_eq!(1 + 1, 2);\n    }\n}\n") , ("tests/hello_test.rs" , "//INCLUDEFILE !option(\"embassy\") && option(\"embedded-test\")\n//! Demo test suite using embedded-test\n//!\n//! You can run this using `cargo test` as usual.\n\n#![no_std]\n#![no_main]\n\nesp_bootloader_esp_idf::esp_app_desc!();\n\n#[cfg(test)]\n#[embedded_test::tests]\nmod tests {\n    //IF option(\"defmt\")\n    use defmt::assert_eq;\n    //ENDIF\n    use esp_hal as _;\n\n    #[init]\n    fn init() {\n        let _ = esp_hal::init(esp_hal::Config::default());\n\n        //IF option(\"defmt\")\n        rtt_target::rtt_init_defmt!();\n        //ENDIF\n    }\n\n    #[test]\n    fn hello_test() {\n        //IF option(\"defmt\")\n        defmt::info!(\"Running test!\");\n        //ENDIF\n\n        assert_eq!(1 + 1, 2);\n    }\n}\n") , (".cargo/config.toml" , "#REPLACE riscv32imac-unknown-none-elf rust_target\n[target.riscv32imac-unknown-none-elf]\n#IF option(\"probe-rs\")\n#REPLACE esp32c6 mcu\nrunner = \"probe-rs run --chip=esp32c6 --preverify --always-print-stacktrace --no-location\"\n#ELIF option(\"defmt\")\n#REPLACE esp32c6 mcu\n#+runner = \"espflash flash --monitor --chip esp32c6 --log-format defmt\"\n#ELSE\n#REPLACE esp32c6 mcu\n#+runner = \"espflash flash --monitor --chip esp32c6\"\n#ENDIF\n\n[env]\n#IF option(\"defmt\")\nDEFMT_LOG=\"info\"\n#ELIF option(\"log\")\nESP_LOG=\"info\"\n#ENDIF\n\n[build]\nrustflags = [\n#IF option(\"xtensa\")\n  \"-C\", \"link-arg=-nostartfiles\",\n#ELIF option(\"riscv\")\n  # Required to obtain backtraces (e.g. when using the \"esp-backtrace\" crate.)\n  # NOTE: May negatively impact performance of produced code\n  \"-C\", \"force-frame-pointers\",\n#ENDIF\n#IF option(\"stack-smashing-protection\")\n  \"-Z\", \"stack-protector=all\",\n#ENDIF\n]\n\n#REPLACE riscv32imac-unknown-none-elf rust_target\ntarget = \"riscv32imac-unknown-none-elf\"\n\n[unstable]\n#IF option(\"alloc\")\nbuild-std = [\"alloc\", \"core\"]\n#ELSE\n#+build-std = [\"core\"]\n#ENDIF\n") , ("template.yaml" , "#INCLUDEFILE false\noptions:\n  - !Category\n    name: module\n    display_name: Module/Board selection\n    help: Select your specific ESP32 module. This selection is optional, but it will generate code to help you avoid using reserved GPIOs.\n    options:\n      - !Option\n        name: PLACEHOLDER\n        display_name: \"<dynamic - will be replaced at runtime>\"\n        selection_group: module\n\n  - !Option\n    name: unstable-hal\n    display_name: Enable unstable HAL features.\n    help: \"This configuration enables unstable esp-hal features.\n      These come with no stability guarantees, and could be changed or removed at any time.\"\n\n  - !Option\n    name: alloc\n    display_name: Enable allocations via the esp-alloc crate.\n    help: esp-alloc comes with no stability guarantees at this time.\n\n  - !Option\n    name: wifi\n    display_name: Enable Wi-Fi via the esp-radio crate.\n    help: esp-radio comes with no stability guarantees at this time.\n    requires:\n      - alloc\n      - unstable-hal\n    chips:\n      - esp32\n      - esp32c2\n      - esp32c3\n      - esp32c5\n      - esp32c6\n      - esp32c61\n      - esp32s2\n      - esp32s3\n\n  - !Option\n    name: ble-bleps\n    display_name: Enable BLE via the esp-radio crate (bleps).\n    help: esp-radio comes with no stability guarantees at this time.\n    selection_group: ble-lib\n    requires:\n      - alloc\n      - unstable-hal\n    chips:\n      - esp32\n      - esp32c2\n      - esp32c3\n      - esp32c5\n      - esp32c6\n      - esp32c61\n      - esp32h2\n      - esp32s3\n\n  - !Option\n    name: ble-trouble\n    display_name: Enable BLE via the esp-radio crate (embassy-trouble).\n    help: esp-radio comes with no stability guarantees at this time.\n    selection_group: ble-lib\n    requires:\n      - alloc\n      - unstable-hal\n      - embassy\n    chips:\n      - esp32\n      - esp32c2\n      - esp32c3\n      - esp32c5\n      - esp32c6\n      - esp32c61\n      - esp32h2\n      - esp32s3\n\n  - !Option\n    name: embassy\n    display_name: Add embassy framework support.\n    help: esp-rtos module responsible for embassy support comes with no stability guarantees at this time.\n    selection_group: base-template\n    requires:\n      - unstable-hal\n\n  - !Option\n    name: stack-smashing-protection\n    display_name: Enable stack smashing protection.\n    help: Requires nightly Rust. Note that this option generates additional checks in most functions\n      and will slow down your code.\n\n  - !Option\n    name: probe-rs\n    display_name: Use probe-rs to flash and monitor instead of espflash.\n    help: probe-rs is a debugger that connects to the chips over JTAG. It can be used to flash and\n      monitor, and it can also be used to interactively debug an application, or run tests on the\n      hardware. Semihosting or RTT-based technologies like defmt-rtt require probe-rs.\n    chips:\n      - esp32c5\n      - esp32c6\n      - esp32c61\n      - esp32h2\n      - esp32s3\n\n  - !Option\n    name: probe-rs\n    display_name: Use probe-rs to flash and monitor instead of espflash.\n    help: probe-rs is a debugger that connects to the chips over JTAG. It can be used to flash and\n      monitor, and it can also be used to interactively debug an application, or run tests on the\n      hardware. Semihosting or RTT-based technologies like defmt-rtt require probe-rs.\n\n      probe-rs requires a debug probe like esp-prog, and will not work with USB-UART adapters that\n      often come on development boards.\n    chips:\n      - esp32\n      - esp32s2\n      - esp32c2\n      - esp32c3\n\n  - !Category\n    name: flashing-probe-rs\n    display_name: Flashing, logging and debugging (probe-rs)\n    requires:\n      - probe-rs\n    options:\n      - !Option\n        name: defmt\n        display_name: Use defmt to print messages.\n        selection_group: log-frontend\n      - !Option\n        name: panic-rtt-target\n        display_name: Use panic-rtt-target as the panic handler.\n        selection_group: panic-handler\n        requires:\n          - probe-rs\n      - !Option\n        name: embedded-test\n        display_name: Enable embedded-test support.\n        requires:\n          - probe-rs\n\n  - !Category\n    name: flashing-espflash\n    display_name: Flashing, logging and debugging (espflash)\n    requires:\n      - \"!probe-rs\"\n    options:\n      - !Option\n        name: log\n        display_name: Use the log crate to print messages.\n        selection_group: log-frontend\n        requires:\n          - \"!probe-rs\"\n      - !Option\n        name: defmt\n        display_name: Use defmt to print messages.\n        selection_group: log-frontend\n      - !Option\n        name: esp-backtrace\n        display_name: Use esp-backtrace as the panic handler.\n        selection_group: panic-handler\n        requires:\n          - \"!probe-rs\"\n\n  - !Category\n    name: optional\n    display_name: Options\n    options:\n      - !Option\n        name: wokwi\n        display_name: Add support for Wokwi simulation using VS Code Wokwi extension.\n        chips:\n          - esp32\n          - esp32c3\n          - esp32c6\n          - esp32h2\n          - esp32s2\n          - esp32s3\n\n      - !Option\n        name: ci\n        display_name: Add GitHub Actions support with some basic checks.\n\n  - !Category\n    name: editor\n    display_name: Optional editor integration\n    options:\n      - !Option\n        name: helix\n        display_name: Add settings for Helix Editor\n\n      - !Option\n        name: neovim\n        display_name: Add settings for Neovim\n\n      - !Option\n        name: vscode\n        display_name: Add settings for Visual Studio Code\n\n      - !Option\n        name: zed\n        display_name: Add settings for Zed\n\n  - !Category\n    name: toolchain\n    display_name: Rust toolchain\n    options:\n      - !Option\n        name:\n        display_name: \"Scanning installed toolchains...\"\n        selection_group: toolchain\n") , ("rust-toolchain.toml" , "[toolchain]\n#IF option(\"riscv\")\n#IF option(\"stack-smashing-protection\")\n#+channel    = \"nightly\"\n#ELSE\n#REPLACE stable rust_toolchain\nchannel    = \"stable\"\n#ENDIF\ncomponents = [\"rust-src\"]\n#REPLACE riscv32imac-unknown-none-elf rust_target\ntargets = [\"riscv32imac-unknown-none-elf\"]\n#ELIF option(\"xtensa\")\n#REPLACE esp rust_toolchain\n#+channel = \"esp\"\n#ENDIF\n") , (".clippy.toml" , "stack-size-threshold = 1024\n") , ("wokwi.toml" , "#INCLUDEFILE option(\"wokwi\")\n[wokwi]\nversion = 1\ngdbServerPort = 3333\n#REPLACE project-name project-name && rust_target rust_target\nelf = \"target/rust_target/debug/project-name\"\n#REPLACE project-name project-name && rust_target rust_target\nfirmware = \"target/rust_target/debug/project-name\"\n") , (".gitignore" , "# will have compiled files and executables\ndebug/\ntarget/\n\n# Editor configuration\n.vscode/\n.zed/\n.helix/\n.nvim.lua\n\n# These are backup files generated by rustfmt\n**/*.rs.bk\n\n# MSVC Windows builds of rustc generate these, which store debugging information\n*.pdb\n\n# RustRover\n#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can\n#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore\n#  and can be added to the global gitignore or merged into this file.  For a more nuclear\n#  option (not recommended) you can uncomment the following to ignore the entire idea folder.\n#.idea/\n\n\n# Ignore .DS_Store file in mac\n**/.DS_Store") , (".helix/languages.toml" , "#INCLUDEFILE option(\"helix\")\n[[language]]\nname = \"rust\"\n\n#IF option(\"xtensa\")\n[language-server.rust-analyzer]\nenvironment.RUSTUP_TOOLCHAIN = \"stable\"\n\n#ENDIF\n[language-server.rust-analyzer.config]\ncargo.allTargets = false\n#REPLACE riscv32imac-unknown-none-elf rust_target\ncargo.target = \"riscv32imac-unknown-none-elf\"\n#IF option(\"xtensa\")\n#REPLACE esp rust_toolchain\ncargo.extraEnv.RUSTUP_TOOLCHAIN = \"esp\"\n#ENDIF\n") , (".vscode/settings.json" , "//INCLUDEFILE option(\"vscode\")\n{\n  \"rust-analyzer.cargo.allTargets\": false,\n  //REPLACE riscv32imac-unknown-none-elf rust_target\n  \"rust-analyzer.cargo.target\": \"riscv32imac-unknown-none-elf\",\n  //IF option(\"xtensa\")\n  \"rust-analyzer.server.extraEnv\": {\n    \"RUSTUP_TOOLCHAIN\": \"stable\"\n  },\n  \"rust-analyzer.cargo.extraEnv\": {\n    //REPLACE esp rust_toolchain\n    \"RUSTUP_TOOLCHAIN\": \"esp\"\n  },\n  //ENDIF\n}\n") , (".vscode/launch.json" , "//INCLUDEFILE option(\"vscode\")\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        //IF option(\"probe-rs\")\n        {\n            \"type\": \"probe-rs-debug\",\n            \"request\": \"launch\",\n            \"name\": \"Launch\",\n            \"cwd\": \"${workspaceFolder}\",\n            \"preLaunchTask\": \"build-debug\",\n            //REPLACE esp32c3 mcu\n            \"chip\": \"esp32c3\",\n            \"flashingConfig\": {\n                \"flashingEnabled\": true,\n                \"haltAfterReset\": true,\n                \"verifyBeforeFlashing\": true,\n                \"formatOptions\": {\n                    \"binaryFormat\": \"idf\"\n                }\n            },\n            \"coreConfigs\": [\n                {\n                    \"coreIndex\": 0,\n                    //REPLACE riscv32imc-unknown-none-elf rust_target\n                    \"programBinary\": \"target/riscv32imc-unknown-none-elf/debug/${workspaceFolderBasename}\",\n                    \"rttEnabled\": true,\n                    //IF option(\"defmt\")\n                    \"rttChannelFormats\": [\n                        {\n                            \"channelNumber\": 0,\n                            \"dataFormat\": \"Defmt\",\n                        }\n                    ],\n                    //ENDIF\n                }\n            ]\n        },\n        {\n            \"type\": \"probe-rs-debug\",\n            \"request\": \"attach\",\n            \"name\": \"Attach\",\n            \"cwd\": \"${workspaceFolder}\",\n            //REPLACE esp32c3 mcu\n            \"chip\": \"esp32c3\",\n            \"coreConfigs\": [\n                {\n                    \"coreIndex\": 0,\n                    //REPLACE riscv32imc-unknown-none-elf rust_target\n                    \"programBinary\": \"target/riscv32imc-unknown-none-elf/debug/${workspaceFolderBasename}\",\n                    \"rttEnabled\": true,\n                    //IF option(\"defmt\")\n                    \"rttChannelFormats\": [\n                        {\n                            \"channelNumber\": 0,\n                            \"dataFormat\": \"Defmt\",\n                        }\n                    ],\n                    //ENDIF\n                }\n            ]\n        }\n        //ENDIF\n    ]\n}\n") , (".vscode/extensions.json" , "//INCLUDEFILE option(\"vscode\")\n{\n    \"recommendations\": [\n        \"rust-lang.rust-analyzer\",\n        \"tamasfe.even-better-toml\",\n        //IF option(\"wokwi\")\n        \"Wokwi.wokwi-vscode\",\n        //ENDIF\n        //IF option(\"probe-rs\")\n        \"probe-rs.probe-rs-debugger\",\n        //ENDIF\n        \"fill-labs.dependi\"\n    ]\n}") , (".vscode/tasks.json" , "//INCLUDEFILE option(\"vscode\")\n{\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"label\": \"build-debug\",\n            \"command\": \"cargo build\",\n            \"type\": \"shell\",\n        }\n    ]\n}") , (".zed/settings.json" , "//INCLUDEFILE option(\"zed\")\n{\n    \"lsp\": {\n        \"rust-analyzer\": {\n            \"initialization_options\": {\n                \"cargo\": {\n                    \"allTargets\": false,\n                    //REPLACE riscv32imac-unknown-none-elf rust_target\n                    \"target\": \"riscv32imac-unknown-none-elf\",\n                    //IF option(\"xtensa\")\n                    \"extraEnv\": {\n                        //REPLACE esp rust_toolchain\n                        \"RUSTUP_TOOLCHAIN\": \"esp\"\n                    }\n                    //ENDIF\n                },\n                //IF option(\"xtensa\")\n                \"server\": {\n                    \"extraEnv\": {\n                        \"RUSTUP_TOOLCHAIN\": \"stable\"\n                    }\n                },\n                //ENDIF\n            }\n        }\n    }\n}\n") , (".nvim.lua" , "--INCLUDEFILE option(\"neovim\")\n-- You must enable the exrc setting in neovim for this config file to be used.\nlocal rust_analyzer = {\n    cargo = {\n        --REPLACE riscv32imac-unknown-none-elf rust_target\n        target = \"riscv32imac-unknown-none-elf\",\n        allTargets = false,\n    },\n}\n--IF option(\"xtensa\")\n--REPLACE esp rust_toolchain\nrust_analyzer.cargo.extraEnv = { RUST_TOOLCHAIN = \"esp\" }\nrust_analyzer.server = { extraEnv = { RUST_TOOLCHAIN = \"stable\" } }\n--ENDIF\n\n-- Note the neovim name of the language server is rust_analyzer with an underscore.\nvim.lsp.config(\"rust_analyzer\", {\n    settings = {\n        [\"rust-analyzer\"] = rust_analyzer,\n    },\n})\n") , ("Cargo.toml" , "[package]\n#REPLACE project-name project-name\nname = \"project-name\"\nversion = \"0.1.0\"\nedition = \"2024\"\nrust-version = \"1.88\"\n\n[[bin]]\n#REPLACE project-name project-name\nname = \"project-name\"\npath = \"./src/bin/main.rs\"\n#IF option(\"embedded-test\")\ntest = false\n\n[[test]]\nname    = \"hello_test\"\nharness = false\n\n[lib]\ntest = false\n#ENDIF\n\n[dependencies]\nesp-hal = { version = \"~1.1.0\", features = [\n    #REPLACE esp32c6 mcu\n    \"esp32c6\",\n    #IF option(\"unstable-hal\")\n    \"unstable\",\n    #ENDIF\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log-04\",\n    #ENDIF\n] }\n\n#IF option(\"embassy\") || option(\"wifi\") || option(\"ble-bleps\") || option(\"ble-trouble\")\nesp-rtos = { version = \"0.3.0\", features = [\n    #IF option(\"wifi\") || option(\"ble-bleps\") || option(\"ble-trouble\")\n    \"esp-radio\",\n    #ENDIF\n    #IF option(\"alloc\")\n    \"esp-alloc\",\n    #ENDIF\n    #IF option(\"embassy\")\n    \"embassy\",\n    #ENDIF\n    #REPLACE esp32c6 mcu\n    \"esp32c6\",\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log-04\",\n    #ENDIF\n]}\n#ENDIF\n\nesp-bootloader-esp-idf = { version = \"0.5.0\", features = [\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log-04\",\n    #ENDIF\n    #REPLACE esp32c6 mcu\n    \"esp32c6\",\n] }\n#IF option(\"defmt\")\n#+defmt = \"1.0.1\"\n#ELIF option(\"log\")\nlog = \"0.4.27\"\n#ENDIF\n\n#IF option(\"log-frontend\") || option(\"panic-handler\") || option(\"probe-rs\")\n#IF option(\"probe-rs\")\n#IF option(\"defmt\")\nrtt-target = { version = \"0.6.2\", features = [\"defmt\"] }\n#ELSE\n#+rtt-target = \"0.6.2\"\n#ENDIF defmt\n#ELSE probe-rs\nesp-println = { version = \"0.17.0\", features = [\n    #REPLACE esp32c6 mcu\n    \"esp32c6\",\n    #IF option(\"defmt\")\n    #+\"defmt-espflash\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log-04\",\n    #ENDIF\n] }\n#ENDIF probe-rs\n#ENDIF log-frontend || panic-handler || probe-rs\n#IF option(\"esp-backtrace\")\nesp-backtrace = { version = \"0.19.0\", features = [\n    #REPLACE esp32c6 mcu\n    \"esp32c6\",\n    \"panic-handler\",\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ELSE\n    \"println\",\n    #ENDIF\n] }\n#ELIF option(\"panic-rtt-target\")\n#IF option(\"defmt\")\n#+panic-rtt-target = { version = \"0.2.0\", features = [\"defmt\"] }\n#ELSE\npanic-rtt-target = \"0.2.0\"\n#ENDIF defmt\n#ENDIF esp-backtrace\n#IF option(\"alloc\")\n#IF option(\"defmt\")\n#+esp-alloc = { version = \"0.10.0\", features = [\"defmt\"] }\n#ELSE\nesp-alloc = \"0.10.0\"\n#ENDIF defmt\n#ENDIF alloc\n#IF option(\"wifi\") || option(\"ble-bleps\") || option(\"ble-trouble\")\n#IF option(\"defmt\")\n#+embedded-io = { version = \"0.7.1\", features = [\"defmt\"] }\n#ELSE\nembedded-io = \"0.7.1\"\n#ENDIF defmt\n#IF option(\"embassy\")\n#IF option(\"defmt\")\n#+embedded-io-async = { version = \"0.7.0\", features = [\"defmt\"] }\n#ELSE\nembedded-io-async = \"0.7.0\"\n#ENDIF defmt\n#IF option(\"wifi\")\nembassy-net = { version = \"0.9.1\", features = [\n    \"tcp\",\n    \"udp\",\n    \"dhcpv4\",\n    \"medium-ethernet\",\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log\",\n    #ENDIF\n] }\n# for more networking protocol support see https://crates.io/crates/edge-net\n#ENDIF wifi\n#ENDIF embassy\n#IF option(\"wifi\")\nsmoltcp = { version = \"0.13.0\", default-features = false, features = [\n    \"medium-ethernet\",\n    \"multicast\",\n    \"proto-dhcpv4\",\n    \"proto-dns\",\n    \"proto-ipv4\",\n    \"socket-dns\",\n    \"socket-raw\",\n    \"socket-tcp\",\n    \"socket-udp\",\n    \"socket-icmp\",\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log\",\n    #ENDIF\n] }\n#ENDIF wifi\nesp-radio = { version = \"0.18.0\", features = [\n    #REPLACE esp32c6 mcu\n    \"esp32c6\",\n    #IF option(\"wifi\")\n    \"wifi\",\n    #ENDIF\n    #IF option(\"ble-bleps\") || option(\"ble-trouble\")\n    \"ble\",\n    #ENDIF\n    #IF option(\"wifi\") && (option(\"ble-bleps\") || option(\"ble-trouble\"))\n    \"coex\",\n    #ENDIF\n    #IF option(\"alloc\")\n    \"esp-alloc\",\n    #ENDIF\n    \"unstable\",\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log-04\",\n    #ENDIF\n] }\n#IF option(\"ble-bleps\")\n#+bleps = { git = \"https://github.com/bjoernQ/bleps\", package = \"bleps\", rev = \"a5148d8ae679e021b78f53fd33afb8bb35d0b62e\", features = [ \"macros\", \"async\"] }\n#ENDIF\n#IF option(\"ble-trouble\")\n#+trouble-host = { version = \"0.6.0\", features = [\"gatt\"] }\n#+bt-hci = \"0.8.0\"\n#ENDIF\n#ENDIF wifi || ble || ble-trouble\n#IF option(\"embassy\")\nembassy-executor = { version = \"0.10.0\", features = [\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log\",\n    #ENDIF\n] }\n#IF option(\"defmt\")\n#+embassy-time     = { version = \"0.5.0\", features = [\"defmt\"] }\n#ENDIF\n#IF option(\"log\")\nembassy-time = { version = \"0.5.0\", features = [\"log\"] }\n#ENDIF\n#IF !option(\"defmt\") && !option(\"log\")\n#+embassy-time     = \"0.5.0\"\n#ENDIF\n\nstatic_cell = \"2.1.1\"\n#ENDIF\ncritical-section = \"1.2.0\"\n\n#IF option(\"embedded-test\")\n[dev-dependencies]\nembedded-test = { version = \"0.7.1\", features = [\n    #IF option(\"xtensa\")\n    \"xtensa-semihosting\",\n    #ENDIF\n    #IF option(\"embassy\")\n    \"embassy-010\",\n    \"external-executor\",\n    #ENDIF\n    #IF option(\"defmt\")\n    #+\"defmt\",\n    #ENDIF\n    #IF option(\"log\")\n    \"log-04\",\n    #ENDIF\n] }\n#ENDIF embedded-test\n\n# For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html\n[profile.dev]\n# The default debug profile is too slow and too big for resource-constrained devices.\n# Always build with some optimizations enabled.\nopt-level = \"s\"\n\n[profile.release]\ncodegen-units = 1       # LLVM can perform better optimizations using a single thread\ndebug = 2               # prefer slower builds but better debugging experience\nlto = 'fat'\nopt-level = 's'\n") , ("diagram.json" , "//INCLUDEFILE option(\"wokwi\")\n{\n    \"version\": 1,\n    \"editor\": \"wokwi\",\n    \"parts\": [\n        {\n            //REPLACE wokwi-board wokwi-board\n            \"type\": \"wokwi-board\",\n            \"id\": \"esp\",\n            \"top\": 0.59,\n            \"left\": 0.67,\n            \"attrs\": {\n                \"flashSize\": \"16\"\n            }\n        }\n    ],\n    \"connections\": [\n        [\n            \"esp:TX\",\n            \"$serialMonitor:RX\",\n            \"\",\n            []\n        ],\n        [\n            \"esp:RX\",\n            \"$serialMonitor:TX\",\n            \"\",\n            []\n        ]\n    ],\n    \"serialMonitor\": {\n        \"display\": \"terminal\",\n        \"convertEol\": true\n    }\n}")] ;