diff --git a/examples/atmega328p/.cargo/config.toml b/.cargo/config.toml similarity index 100% rename from examples/atmega328p/.cargo/config.toml rename to .cargo/config.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d81ac61..944dc80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,44 +21,13 @@ jobs: toolchain: stable # Rust Dependencies - - name: Cache Cargo installed binaries - uses: actions/cache@v4 - id: cache-cargo - with: - path: ~/cargo-bin - key: rust-tools-20250106-001 - - name: Install svd2rust - if: steps.cache-cargo.outputs.cache-hit != 'true' - run: cargo install svd2rust --version 0.28.0 --locked - - name: Install cargo-form - if: steps.cache-cargo.outputs.cache-hit != 'true' - run: cargo install form --version 0.8.0 --locked - - name: Install atdf2svd - if: steps.cache-cargo.outputs.cache-hit != 'true' - run: cargo install atdf2svd --version 0.5.0 --locked - - name: Install svdtools - if: steps.cache-cargo.outputs.cache-hit != 'true' - run: cargo install svdtools --version 0.4.0 --locked - - name: Copy tools to cache directory - if: steps.cache-cargo.outputs.cache-hit != 'true' - run: | - mkdir ~/cargo-bin - cp ~/.cargo/bin/svd2rust ~/cargo-bin - cp ~/.cargo/bin/form ~/cargo-bin - cp ~/.cargo/bin/atdf2svd ~/cargo-bin - cp ~/.cargo/bin/svdtools ~/cargo-bin - - name: Put new cargo binary directory into path - run: echo "$HOME/cargo-bin" >> $GITHUB_PATH - - name: Install Nightly Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: nightly-2023-08-08 - components: rustfmt + toolchain: nightly-2025-01-08 + components: rust-src,rustfmt # Actual test run - - name: Generate chip description sources - run: make RUSTUP_TOOLCHAIN=nightly-2023-08-08 - name: Test-compile the crate run: cargo check --all-features @@ -73,7 +42,7 @@ jobs: with: name: avr-device path: | - svd/ + target/avr-atmega328p/debug/build/avr-device-*/out/svd/ target/package/avr-device-*.crate macros/target/package/avr-device-macros-*.crate @@ -86,11 +55,9 @@ jobs: - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: nightly-2023-12-28 + toolchain: nightly-2025-01-08 components: rust-src,rustfmt - name: Install AVR gcc, binutils, and libc run: sudo apt-get install -y avr-libc binutils-avr gcc-avr - name: Build ATmega328P example - run: cd examples/atmega328p && cargo build - - name: Check ATmega328P formatting - run: cd examples/atmega328p && cargo fmt --check + run: cargo build --example atmega328p --features atmega328p,rt diff --git a/.gitignore b/.gitignore index fede716..6aa1064 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,3 @@ /target/ -/macros/target/ **/*.rs.bk Cargo.lock - -svd/ -.deps/ -src/devices/*/* -src/generic.rs -__pycache__/ diff --git a/Cargo.toml b/Cargo.toml index 08b0bc1..9c7d1bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,10 +12,14 @@ keywords = ["avr", "arduino"] categories = ["no-std", "embedded", "hardware-support"] include = [ - "/src/**/*.rs", "/LICENSE-*", "/README.md", "/build.rs", + "/patch/**/*.yaml", + "/src/**/*.rs", + "/vendor/*.atdf", + "/vendor/LICENSE", + "/examples/**/src/*.rs" ] [package.metadata.docs.rs] @@ -74,14 +78,66 @@ attiny88 = ["device-selected"] attiny1614 = ["device-selected"] avr64du32 = ["device-selected"] avr64du28 = ["device-selected"] -rt = ["avr-device-macros"] +rt = ["avr-device-macros", "critical-section"] +critical-section = ["critical-section-impl"] critical-section-impl = ["critical-section/restore-state-u8"] -# Unfortunately, we can only build documentation for a subset of the supported -# MCUs on docs.rs. If you think a very popular chip is missing from the list, -# feel free to add it here. -docsrs = ["rt", "ufmt", "atmega328p", "atmega32u4", "atmega2560", "attiny85", "atmega4809"] +docsrs = [ + "rt", + "ufmt", + "at90usb1286", + "atmega1280", + "atmega1284p", + "atmega128a", + "atmega128rfa1", + "atmega16", + "atmega16u2", + "atmega164pa", + "atmega168", + "atmega2560", + "atmega8", + "atmega8u2", + "atmega324pa", + "atmega328p", + "atmega328pb", + "atmega3208", + "atmega3209", + "atmega4808", + "atmega4809", + "atmega48p", + "atmega32a", + "atmega32u2", + "atmega32u4", + "atmega64", + "atmega644", + "atmega88p", + "attiny13a", + "attiny167", + "attiny202", + "attiny212", + "attiny214", + "attiny2313", + "attiny2313a", + "attiny26", + "attiny402", + "attiny404", + "attiny412", + "attiny414", + "attiny416", + "attiny44a", + "attiny816", + "attiny828", + "attiny84", + "attiny841", + "attiny84a", + "attiny85", + "attiny861", + "attiny88", + "attiny1614", + "avr64du32", + "avr64du28", +] [dependencies] bare-metal = "1.0.0" @@ -94,3 +150,32 @@ critical-section = { version = "1.1.1", optional = true } path = "macros/" version = "=0.7.0" optional = true + +[build-dependencies] +svd2rust = "0.35.0" +svdtools = "0.4.0" +atdf2svd = "0.4.0" +prettyplease = "0.2" +syn = { version = "2", default-features = false, features = ["full", "parsing"] } + +[dev-dependencies] +nb = "0.1.2" +embedded-hal = "0.2.3" + +[[example]] +name = "atmega328p" +path = "examples/atmega328p/src/main.rs" +required-features = ["atmega328p", "rt"] + +[profile.dev] +panic = "abort" +codegen-units = 1 +debug = true +lto = true +opt-level = "s" + +[profile.release] +panic = "abort" +codegen-units = 1 +lto = true +opt-level = "s" diff --git a/Makefile b/Makefile deleted file mode 100644 index ebb4956..0000000 --- a/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -all: deps chips - -CHIPS := at90usb1286 atmega1280 atmega1284p atmega128a atmega128rfa1 atmega16 atmega164pa atmega168 atmega16u2 atmega2560 atmega8 atmega8u2 atmega324pa atmega328p atmega328pb atmega32a atmega32u2 atmega32u4 atmega3208 atmega3209 atmega4808 atmega4809 atmega48p atmega64 atmega644 atmega88p attiny13a attiny202 attiny212 attiny214 attiny2313 attiny2313a attiny26 attiny402 attiny404 attiny412 attiny414 attiny416 attiny44a attiny84 attiny85 attiny88 attiny816 attiny828 attiny841 attiny84a attiny861 attiny167 attiny1614 avr64du32 avr64du28 - -RUSTUP_TOOLCHAIN ?= nightly - -PATCHES := $(foreach chip, $(CHIPS), $(wildcard patch/$(chip).yaml)) -DEPS := $(foreach patch, $(PATCHES), $(patsubst patch/%.yaml, .deps/%.d, $(patch))) - -.PHONY: chips deps $(CHIPS) vector all clean -chips: $(CHIPS) -deps: $(DEPS) -vector: macros/src/vector.rs - -$(foreach chip, $(CHIPS), $(eval $(chip): src/devices/$(chip)/mod.rs)) - -.SECONDARY: -svd/%.svd: vendor/%.atdf - @mkdir -p svd - @echo -e "\tATDF2SVD\t$*" - @atdf2svd $< $@ 2>/dev/null - -svd/%.svd.patched: svd/%.svd .deps/%.d patch/%.yaml - @if [ -f patch/$*.yaml ] ; then \ - echo -e "\tPATCH\t\t$*"; \ - svdtools patch patch/$*.yaml; \ - test -e $@; \ - else \ - echo -e "\t - No patches found for $*"; \ - cp $< $@; \ - fi - -src/devices/%/mod.full.rs: svd/%.svd.patched - @mkdir -p $(@D) - @echo -e "\tSVD2RUST\t$*" - @cd $(@D); svd2rust --generic_mod --make_mod --target none -i $(realpath $<) - @mv $(@D)/mod.rs $@ - @mv $(@D)/generic.rs $(@D)/../../generic.rs - -src/devices/%/mod.rs: src/devices/%/mod.full.rs - @echo -e "\tFORM\t\t$*" - @RUST_LOG=WARN form -i $< -o $(@D) >/dev/null - @rm $< - @mv $(@D)/lib.rs $@ - @RUSTUP_TOOLCHAIN=$(RUSTUP_TOOLCHAIN) rustfmt $@ - @# Remove the `extern crate` lines - @sed -i'' -e "/^extern crate/d" $@ - @# Remove DEVICE_PERIPHERALS declaration and replace it with a reference - @# to the global version - @patch --no-backup-if-mismatch --quiet $@ patch/modrs.patch - @# Fixup the take() implementation - @sed -i'' -e '/#\[cfg(feature = "critical-section")]/d' $@ - @sed -i'' -e 's/critical_section::with/crate::interrupt::free/' $@ - @echo -e "\tGEN-VECTOR\t>macros/src/vector.rs" - @./gen-intr-lut.sh svd/*.patched >macros/src/vector.rs - -macros/src/vector.rs: svd/*.patched - @echo -e "\tGEN-VECTOR\t>macros/src/vector.rs" - @./gen-intr-lut.sh $^ >$@ - -clean: - @echo -e "\tCLEAN\t\t./svd/" - @rm -rf svd/ - @echo -e "\tCLEAN\t\t./src/devices" - @rm -rf src/devices/at* - @echo -e "\tCLEAN\t\t./src/generic.rs" - @rm -f src/generic.rs - @echo -e "\tCLEAN\t\t./.deps/" - @rm -rf .deps/ - @echo -e "\tCLEAN\t\t./macros/src/vector.rs" - @rm -rf macros/src/vector.rs - -# Patch dependencies -patch/%.yaml: .deps/%.d -.deps/%.d: patch/%.yaml - @mkdir -p .deps - @echo -e "\tMAKEDEPS\t$*" - @svdtools makedeps $< $@ - --include $(DEPS) diff --git a/README.md b/README.md index 64f036a..67f797b 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,11 @@ Add the following to `Cargo.toml`: ```toml [dependencies.avr-device] version = "0.7.0" -features = ["atmega32u4"] +features = ["atmega32u4", "rt"] ``` -Via the feature you can select which chip you want the register specifications for. The following list is what is currently supported: +Via the features you can select which chip you want the register specifications +for. The following list is what is currently supported: | ATmega | ATmega USB | ATmega 0,1 Series | AT90 | ATtiny | | :-------------: | :----------: | :---------------: | :-----------: | :-----------: | @@ -37,56 +38,80 @@ Via the feature you can select which chip you want the register specifications f | | | | | `attiny2313` | | | | | | `attiny2313a` | -## Build Instructions -The version on `crates.io` is pre-built. The following is only necessary when trying to build this crate from source. - -You need to have [atdf2svd][] (= 0.5.0), [svd2rust][] (= 0.28), [form][] (>= 0.8), [rustfmt][](for the *nightly* toolchain) and [svdtools][] (= 0.4.0) installed: -```bash -cargo install atdf2svd --version 0.5.0 --locked -cargo install svd2rust --version 0.28.0 --locked -cargo install form -rustup component add --toolchain nightly rustfmt -cargo install svdtools --version 0.4.0 --locked -``` - -[atdf2svd]: https://github.com/Rahix/atdf2svd -[svd2rust]: https://github.com/rust-embedded/svd2rust -[form]: https://github.com/djmcgill/form -[rustfmt]: https://github.com/rust-lang/rustfmt -[svdtools]: https://github.com/stm32-rs/svdtools +The `rt` feature, while optional, provides some minimal +startup/interrupt-handling code most projects will benefit from. It also enables +the `critical-section` feature, without which all peripheral access is +considered `unsafe` and the API becomes more limited. -Next, clone this repo and build the device definitions: -```bash -git clone https://github.com/Rahix/avr-device -cd avr-device -make -# You can build for just one specific chip using -# make atmega32u4 -# I suggest building documentation as well -cargo +nightly doc --features --open -``` - -## Internals -*avr-device* is generated using [`atdf2svd`](https://github.com/Rahix/atdf2svd) and [`svd2rust`](https://github.com/rust-embedded/svd2rust). The vendor-provided *atdf* files can be found in `vendor/`. The intermediate svd files are patched by `svdpatch.py` (Adapted from [`svdpatch.py`](https://github.com/stm32-rs/stm32-rs/blob/master/scripts/svdpatch.py) in [stm32-rs](https://github.com/stm32-rs/stm32-rs)) with device-dependent patches in `patch/`, mainly to improve undescriptive names and missing descriptions. +## Build Instructions +The PACs (Peripheral Access Crates, or really modules, in our case) **are not** +checked into git. Rather, we generate them at build time, via an automated +process implemented in [`build.rs`](./build.rs). It takes the ATDF files +Microchip (former Atmel) provides plus some patches of our own making as inputs, +and outputs a module generated from those device descriptions. These inputs +**are** checked-in. The process is similar to what the `*bindgen` crates +provide, just has more steps. So, in short, building should be a matter of +selecting the features and running cargo. ### Adding a new Chip -To add a new chip, download the *atdf* from (or [avr-mcu/packs/](https://github.com/avr-rust/avr-mcu/tree/master/packs)) and place it in `vendor/` ***note: file name may need to be modified***. Be sure to name it like the Rust module that should be generated. Next, you need to integrate it into the base crate and build system. Follow what was done in commit [290613454fbd ("Add basic support for ATmega64")](https://github.com/Rahix/avr-device/commit/290613454fbdc5e4ac98e53deccaf74dafc88963). Please adhere to the alphabetical sorting that is present so far. - -Next, you **must** create a `.yaml` in `patch/` which has at least the following content: -```yaml -_svd: ../svd/.svd -``` - -If more patches need to be applied (most likely!), they should be added into this file as well. The patching format is documented in the [`svdtools` README](https://github.com/stm32-rs/svdtools#device-and-peripheral-yaml-format). Ideally, try to reuse the exisiting patches in `patch/common/` or `patch/timer/`. - -Finally, try building the crate for your MCU with `make `. +To add a new chip: + +1. Download the ATDF from and place it in + `vendor/`. Be sure to name it like the Rust module that should be generated. +2. Add a feature of the same name to `Cargo.toml` (it should enable + `device-selected`); +3. Add any needed patches to a yaml file with the same name under the `patch` + directory, ideally by including some of the snippets present in + `patch/common` and `patch/timer`; The format is decribed + [here](https://github.com/rust-embedded/svdtools#device-and-peripheral-yaml-format), + but it should not include the top-level `_svd` key, as that's handled by the + build system; If patching is unneeded (most likely it is!), the file can be + ommited. +4. Include the module into the tree, in [`devices.rs`](./src/devices.rs), + following the format used by other modules in that file; +5. Finally, try building the crate for your MCU with + `cargo build --features ,rt`. +6. Also check the built documentation for inconsistencies, via + `cargo doc --features ,rt --open` (it will pop up in your browser). + +## Internals +Since the vendor does not provide SVDs we can pass to [`svd2rust`][], we +generate one via [`atdf2svd`][]. The sequence is as follows: + +1. Check which MCUs are known to the crate + ([build.rs:get_available_mcus](./build.rs#L21-L40)); +2. Select which to build for by checking enabled features + ([build.rs:select_mcu](./build.rs#L42-L62)); +3. Generate the Rust module ([build.rs:build_mcu_module](./build.rs#L64-L148)); + + Substeps are: + 1. Register inputs with cargo; + 2. Get a temporary directory; + 3. Apply `atdf2svd`; + 4. If a yaml patch exists, use it via [`svdtools`][] and read the new content + / else, read the content of the unpatched file to continue; + 5. Get the output directory; + 6. Apply `svd2rust`; + 7. Run [`rustfmt`][] on the module to make it readable in [`docs.rs`][]; +4. It will be included from `$OUT_DIR/pac/.rs` into the path + `avr_device::devices::` (private), and re-exported as + `avr_device::` (public). + +[`atdf2svd`]: https://github.com/Rahix/atdf2svd +[`svd2rust`]: https://github.com/rust-embedded/svd2rust +[`svdtools`]: https://github.com/rust-embedded/svdtools +[`rustfmt`]: https://github.com/rust-lang/rustfmt +[`docs.rs`]: https://docs.rs/avr-device/latest/avr_device ## License *avr-device* is licensed under either of - * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) at your option. -The vendored *atdf* files are licensed under the Apache License, Version 2.0 ([LICENSE-VENDOR](vendor/LICENSE)). +The vendored *atdf* files are licensed under the Apache License, Version 2.0 +([LICENSE-VENDOR](vendor/LICENSE)). diff --git a/examples/atmega328p/avr-specs/avr-atmega328p.json b/avr-specs/avr-atmega328p.json similarity index 58% rename from examples/atmega328p/avr-specs/avr-atmega328p.json rename to avr-specs/avr-atmega328p.json index 7d7d82c..f8d539b 100644 --- a/examples/atmega328p/avr-specs/avr-atmega328p.json +++ b/avr-specs/avr-atmega328p.json @@ -2,20 +2,33 @@ "arch": "avr", "atomic-cas": false, "cpu": "atmega328p", + "crt-objects-fallback": "false", "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8", "eh-frame-header": false, "exe-suffix": ".elf", "late-link-args": { - "gcc": [ + "gnu-cc": [ + "-lgcc" + ], + "gnu-lld-cc": [ "-lgcc" ] }, "linker": "avr-gcc", + "linker-flavor": "gnu-cc", "llvm-target": "avr-unknown-unknown", - "max-atomic-width": 8, - "no-default-libraries": false, + "max-atomic-width": 16, + "metadata": { + "description": null, + "host_tools": null, + "std": null, + "tier": null + }, "pre-link-args": { - "gcc": [ + "gnu-cc": [ + "-mmcu=atmega328p" + ], + "gnu-lld-cc": [ "-mmcu=atmega328p" ] }, diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..1fc15be --- /dev/null +++ b/build.rs @@ -0,0 +1,244 @@ +#![feature(io_error_more)] +#![feature(exit_status_error)] + +use atdf2svd::{atdf, svd}; +use std::{ + collections::{BTreeSet, HashSet}, + env, + fs::{self, File}, + io::{self, Write}, + path::{Path, PathBuf}, +}; +use svdtools::patch; +use syn::Item; + +fn main() { + println!("cargo::rustc-check-cfg=cfg(single_mcu)"); + + let available_mcus = get_available_mcus(); + let mcus = select_mcus(available_mcus); + if mcus.len() == 1 { + println!("cargo::rustc-cfg=single_mcu"); + } + for mcu in &mcus { + build_mcu_module(mcu); + } + generate_vector_macro(mcus); +} + +fn get_available_mcus() -> BTreeSet { + let crate_root = env::var_os("CARGO_MANIFEST_DIR").unwrap(); + let packs_dir = Path::new(&crate_root).join("vendor"); + fs::read_dir(&packs_dir) + .unwrap() + .filter_map(|f| f.ok()) + .filter_map(|entry| { + entry + .file_name() + .to_str() + .and_then(|fstr| fstr.strip_suffix(".atdf")) + .map(|mcu| mcu.to_owned()) + }) + .collect() +} + +fn select_mcus(mcus: BTreeSet) -> BTreeSet { + let pack_names = mcus + .iter() + .filter_map(|mcu| { + env::var(format!("CARGO_FEATURE_{}", mcu.to_uppercase())) + .and_then(|_| Ok(mcu.clone())) + .ok() + }) + .collect::>(); + + if pack_names.is_empty() { + panic!( + "No MCU feature selected! \ + The avr-device crate requires one to be enabled in order to \ + know your target's peripherals. Currently available are:\n\ + {}", + mcus.into_iter().collect::>().join("\n"), + ) + } + + pack_names +} + +fn build_mcu_module(mcu: &str) { + // Register our inputs with Cargo. + let crate_root = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let atdf_file = crate_root.join("vendor").join(format!("{}.atdf", mcu)); + println!("cargo::rerun-if-changed={}", atdf_file.display()); + let patch_dir = crate_root.join("patch"); + let patch_file = patch_dir.join(format!("{}.yaml", mcu)); + println!("cargo::rerun-if-changed={}", patch_file.display()); + + let out_dir = env::var("OUT_DIR").unwrap(); + // Get a temporary directory to work inside. + let svd_dir = Path::new(&out_dir).join("svd"); + ensure_directory(&svd_dir); + let svd_unpatched_dir = svd_dir.join("unpatched"); + ensure_directory(&svd_unpatched_dir); + let svd_patched_dir = svd_dir.join("patched"); + ensure_directory(&svd_patched_dir); + + // Apply atdf2svd. + let atdf_parsed = get_atdf_parsed(mcu); + let svd_file = svd_unpatched_dir.join(mcu).with_extension("svd"); + let svd_writer = File::create(&svd_file).unwrap(); + if let Err(what) = svd::generate(&atdf_parsed, svd_writer) { + let _ = what.format(&mut io::stdout()); + panic!("Failed to generate \"{}\"!", svd_file.display()); + } + + let svd_content; + if let Ok(true) = patch_file.try_exists() { + // Point the patch file to our generated svd and apply the patch. + let includer_content = format!( + r#"_svd: {} + +_include: +- {} +"#, + svd_file.display(), + patch_file.display() + ); + let includer_file = svd_dir.join("patch.yaml"); + fs::write(&includer_file, &includer_content).unwrap(); + let svd_patched_file = svd_patched_dir.join(mcu).with_extension("svd"); + patch::process_file( + &includer_file, + Some(&svd_patched_file), + None, + &Default::default(), + ) + .unwrap(); + + // Read the contents after patching. + svd_content = fs::read_to_string(&svd_patched_file).unwrap(); + } else { + // No patching needed, just read the svd. + svd_content = fs::read_to_string(&svd_file).unwrap(); + } + + // Apply svd2rust. + let pac_dir = Path::new(&out_dir).join("pac"); + ensure_directory(&pac_dir); + let mut svd2rust_config = svd2rust::Config::default(); + svd2rust_config.target = svd2rust::Target::None; + svd2rust_config.generic_mod = true; + svd2rust_config.make_mod = true; + svd2rust_config.skip_crate_attributes = true; + svd2rust_config.strict = true; + svd2rust_config.output_dir = Some(pac_dir.to_owned()); + svd2rust_config.interrupt_link_section = Some(".text.vector".to_owned()); + let generated = svd2rust::generate(&svd_content, &svd2rust_config).unwrap(); + + let mut syntax_tree = syn::parse_file(&generated.lib_rs).unwrap(); + for item in syntax_tree.items.iter_mut().rev() { + { + let Item::Static(statik) = item else { continue }; + if &statik.ident.to_string() != "DEVICE_PERIPHERALS" { + continue; + } + } + *item = syn::parse_quote! {use super::DEVICE_PERIPHERALS;}; + } + let formatted = prettyplease::unparse(&syntax_tree); + let module_file = pac_dir.join(mcu).with_extension("rs"); + fs::write(&module_file, &formatted).unwrap(); +} + +fn ensure_directory(dir: &Path) { + if dir.is_dir() { + return; + } else if dir.try_exists().unwrap() { + println!( + "cargo::warning=A non-directory exists in \"{0}\", it will be moved to \"{0}.before\" and a directory created in its place.", + dir.display() + ); + fs::rename(&dir, dir.with_extension("before")).unwrap(); + } + + fs::create_dir(dir).unwrap(); +} + +fn get_atdf_parsed(mcu: &str) -> atdf2svd::chip::Chip { + let crate_root = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let atdf_file = crate_root.join("vendor").join(format!("{}.atdf", mcu)); + + let atdf_reader = File::open(&atdf_file).unwrap(); + let atdf_parsed = match atdf::parse(atdf_reader, &HashSet::::new()) { + Ok(chip) => chip, + Err(what) => { + let _ = what.format(&mut io::stdout()); + panic!("Failed to parse \"{}\"!", atdf_file.display()); + } + }; + + atdf_parsed +} + +fn generate_vector_macro(mcus: BTreeSet) { + let specific_matchers = mcus + .iter() + .flat_map(|mcu| { + get_atdf_parsed(mcu) + .interrupts + .into_iter() + .map(move |(_, value)| { + format!( + r#" + (@{0}, {1}, $it:item) => {{ + #[export_name = "__vector_{2}"] + $it + }};"#, + mcu, value.name, value.index + ) + }) + }) + .collect::>(); + let single_expansion = if mcus.len() == 1 { + &format!( + "$crate::__avr_device_trampoline!(@{}, $name, $it);", + mcus.first().unwrap(), + ) + } else { + "compile_error!(\"More than one MCU feature selected. \ + To use interrupts like this, you must call #[interrupt(chip)] with the \ + chip argument as your MCU, using default is not allowed. \ + Note this is rarely what you want, you should probably enable only one \ + MCU.\");" + }; + + let mut file_handle = File::create( + Path::new(&env::var("OUT_DIR").unwrap()) + .join("pac") + .join("vector.rs"), + ) + .unwrap(); + writeln!( + file_handle, + r#"#[doc(hidden)] +#[macro_export] +macro_rules! __avr_device_trampoline {{ + {} + (@$mcu:ident, $name:ident, $it:item) => {{ + compile_error!(concat!("Couldn't find interrupt ", stringify!($name), ", for MCU ", stringify!($mcu), ".")); + }} +}} + +#[doc(hidden)] +#[macro_export] +macro_rules! __avr_device_trampoline_single {{ + (@$name:ident, $it:item) => {{ + {} + }}; +}} +"#, + specific_matchers.concat(), + single_expansion, + ) + .unwrap(); +} diff --git a/examples/atmega328p/.gitignore b/examples/atmega328p/.gitignore deleted file mode 100644 index 2f7896d..0000000 --- a/examples/atmega328p/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target/ diff --git a/examples/atmega328p/Cargo.toml b/examples/atmega328p/Cargo.toml.example similarity index 76% rename from examples/atmega328p/Cargo.toml rename to examples/atmega328p/Cargo.toml.example index b9a532e..420a077 100644 --- a/examples/atmega328p/Cargo.toml +++ b/examples/atmega328p/Cargo.toml.example @@ -10,7 +10,6 @@ name = "mega328-test" test = false bench = false - [dependencies] ufmt = "0.2.0" nb = "0.1.2" @@ -19,20 +18,18 @@ embedded-hal = "0.2.3" [dependencies.avr-device] version = "0.5.3" -# To use the local version of avr-device instead, uncomment the following line: -# NB: make sure to build this crate first by running `make` at the root of the project -# path = "../.." features = ["atmega328p", "rt"] # Configure the build for minimal size - AVRs have very little program memory [profile.dev] panic = "abort" +codegen-units = 1 +debug = true lto = true opt-level = "s" [profile.release] panic = "abort" codegen-units = 1 -debug = true lto = true opt-level = "s" diff --git a/examples/atmega328p/README.md b/examples/atmega328p/README.md index 29f8cad..91d5bee 100644 --- a/examples/atmega328p/README.md +++ b/examples/atmega328p/README.md @@ -4,6 +4,12 @@ This example showcases a minimal Rust program that solely utilizes bare register writes without relying on a Hardware Abstraction Layer. If you want to use a HAL, you can use [`avr-hal`], which uses `avr-device` under the hood. +Also note that to use this directory as a template for new crates, +`Cargo.toml.example` must be renamed to `Cargo.toml`. The `.example` is there +because examples of a crate shouldn't be crates themselves. You may also need +files from the crate root, namely `.cargo/config.toml`, and a nightly toolchain, +since the AVR target and the `-Zbuild-std=core` flag are unstable. + [`avr-hal`]: https://github.com/Rahix/avr-hal ## Demonstrated Features @@ -52,22 +58,16 @@ a panic is raised and our custom panic handler is called. ## Trying it out 1. First of all, check the README of the [`avr-hal`][avr-hal-readme] crate for an overview of required build dependencies. -2. Change into the example directory: - ```bash - cd examples/atmega328p/ - ``` -3. Build the program: +2. Build the program: ```bash - cargo build + cargo build --example atmega328p --features=atmega328p,rt ``` -4. If you want to run the example on an Arduino Uno board, you can use - [`ravedude`] to flash the microcontroller. The project is preconfigured for +3. If you want to run the example on an Arduino Uno board, you can use + [`ravedude`] to flash the microcontroller. The project is preconfigured for this, so all you need to do is: ```bash - cargo run + cargo run --example atmega328p --features=atmega328p,rt ``` - You can configure a different ATmega328P board by editing the - `.cargo/config.toml` file. [avr-hal-readme]: https://github.com/Rahix/avr-hal#quickstart [`ravedude`]: https://github.com/Rahix/avr-hal/tree/main/ravedude diff --git a/examples/atmega328p/rust-toolchain.toml b/examples/atmega328p/rust-toolchain.toml deleted file mode 100644 index 5e363e2..0000000 --- a/examples/atmega328p/rust-toolchain.toml +++ /dev/null @@ -1,4 +0,0 @@ -[toolchain] -channel = "nightly-2023-12-28" -components = ["rust-src"] -profile = "minimal" diff --git a/examples/atmega328p/src/main.rs b/examples/atmega328p/src/main.rs index 147b7e7..791bef3 100644 --- a/examples/atmega328p/src/main.rs +++ b/examples/atmega328p/src/main.rs @@ -4,7 +4,10 @@ use core::cell::Cell; -use avr_device::interrupt::{self, Mutex}; +use avr_device::{ + atmega328p::Peripherals, + interrupt::{self, Mutex}, +}; static LED_STATE: Mutex> = Mutex::new(Cell::new(true)); @@ -22,17 +25,17 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { // SAFETY: Because main() already has references to the peripherals this is an unsafe // operation - but because no other code can run after the panic handler was called, // we know it is okay. - let dp = unsafe { avr_device::atmega328p::Peripherals::steal() }; + let dp = unsafe { Peripherals::steal() }; loop { avr_device::asm::delay_cycles(1_000_000); - dp.PORTD.portd.write(|w| w.pd3().set_bit()); + dp.portd.portd().write(|w| w.pd3().set_bit()); avr_device::asm::delay_cycles(1_000_000); - dp.PORTD.portd.write(|w| w.pd3().clear_bit()); + dp.portd.portd().write(|w| w.pd3().clear_bit()); } } -#[avr_device::interrupt(atmega328p)] +#[avr_device::interrupt] fn TIMER0_OVF() { // This interrupt should raise every (1024*255)/16MHz s ≈ 0.01s // We then count 61 times to approximate 1s. @@ -53,20 +56,20 @@ fn TIMER0_OVF() { #[avr_device::entry] fn main() -> ! { - let dp = avr_device::atmega328p::Peripherals::take().unwrap(); + let dp = Peripherals::take().unwrap(); // As you can see, we use .write() instead of .modify(), so the register // will be written value + the modified bits // Divide by 1024 -> 16MHz/1024 = 15.6kHz - dp.TC0.tccr0b.write(|w| w.cs0().prescale_1024()); + dp.tc0.tccr0b().write(|w| w.cs0().prescale_1024()); // Enable overflow interrupts - dp.TC0.timsk0.write(|w| w.toie0().set_bit()); + dp.tc0.timsk0().write(|w| w.toie0().set_bit()); // Make pd2 and pd3 outputs // We use .modify() in order not to change the other bits - dp.PORTD.ddrd.modify(|_, w| w.pd2().set_bit()); - dp.PORTD.ddrd.modify(|_, w| w.pd3().set_bit()); + dp.portd.ddrd().modify(|_, w| w.pd2().set_bit()); + dp.portd.ddrd().modify(|_, w| w.pd3().set_bit()); // SAFETY: We can enable the interrupts here as we are not inside // a critical section. @@ -82,7 +85,7 @@ fn main() -> ! { led_state = LED_STATE.borrow(cs).get(); }); - dp.PORTD.portd.modify(|_, w| w.pd2().bit(led_state)); + dp.portd.portd().modify(|_, w| w.pd2().bit(led_state)); // We want to make the program crash after 9 blinks if previous_state != led_state { diff --git a/gen-intr-lut.sh b/gen-intr-lut.sh deleted file mode 100755 index a343fc1..0000000 --- a/gen-intr-lut.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -# Generate a lookup table function for interrupts of all supported chips -set -e - -echo "// Autogenerated. Do not edit." -echo "pub fn lookup_vector(chip: &str, intr: &str) -> Option {" -echo " match chip {" - -for intr_path in "$@"; do - chip="$(basename "${intr_path%.svd.patched}")" - echo " \"$chip\" => match intr {" - # toupper() to be compliant with svd2rust interrupts name - svdtools interrupts --no-gaps $intr_path | awk '{print " \""toupper(substr($2, 1, length($2)-1))"\"" " => Some(" $1"),"}' - echo " _ => None," - echo " }," -done - -echo " _ => None," -echo " }" -echo "}" diff --git a/macros/src/.gitignore b/macros/src/.gitignore deleted file mode 100644 index 9a74c56..0000000 --- a/macros/src/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/vector.rs diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 1139cec..cb324bd 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,10 +1,14 @@ -// Adapted from https://github.com/rust-embedded/cortex-m-rt/blob/master/macros/src/lib.rs +//! Adapted from +//! +//! Do not use this crate directly. extern crate proc_macro; -mod vector; - -use syn::spanned::Spanned; +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::quote; +use std::iter; +use syn::{parse, spanned::Spanned, Attribute, FnArg, Ident, ItemFn, ReturnType, Type, Visibility}; #[proc_macro_attribute] pub fn entry( @@ -15,19 +19,19 @@ pub fn entry( // check the function signature let valid_signature = f.sig.constness.is_none() - && f.vis == syn::Visibility::Inherited + && f.vis == Visibility::Inherited && f.sig.abi.is_none() && f.sig.inputs.is_empty() && f.sig.generics.params.is_empty() && f.sig.generics.where_clause.is_none() && f.sig.variadic.is_none() && match f.sig.output { - syn::ReturnType::Default => false, - syn::ReturnType::Type(_, ref ty) => matches!(**ty, syn::Type::Never(_)), + ReturnType::Default => false, + ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)), }; if !valid_signature { - return syn::parse::Error::new( + return parse::Error::new( f.span(), "`#[entry]` function must have signature `[unsafe] fn() -> !`", ) @@ -36,12 +40,9 @@ pub fn entry( } if !args.is_empty() { - return syn::parse::Error::new( - proc_macro2::Span::call_site(), - "This attribute accepts no arguments", - ) - .to_compile_error() - .into(); + return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") + .to_compile_error() + .into(); } let (statics, stmts) = match extract_static_muts(f.block.stmts) { @@ -50,10 +51,7 @@ pub fn entry( }; // Rename the function so it is not callable - f.sig.ident = syn::Ident::new( - &format!("__avr_device_rt_{}", f.sig.ident), - proc_macro2::Span::call_site(), - ); + f.sig.ident = Ident::new(&format!("__avr_device_{}", f.sig.ident), Span::call_site()); f.sig.inputs.extend(statics.iter().map(|statik| { let ident = &statik.ident; let ty = &statik.ty; @@ -68,10 +66,7 @@ pub fn entry( })); f.block.stmts = stmts; - let tramp_ident = syn::Ident::new( - &format!("{}_trampoline", f.sig.ident), - proc_macro2::Span::call_site(), - ); + let tramp_ident = Ident::new(&format!("{}_trampoline", f.sig.ident), Span::call_site()); let ident = &f.sig.ident; let resource_args = statics @@ -81,9 +76,9 @@ pub fn entry( let ident = &statik.ident; let ty = &statik.ty; let expr = &statik.expr; - quote::quote! { + quote! { #(#cfgs)* - { + unsafe { #(#attrs)* static mut #ident: #ty = #expr; &mut #ident @@ -92,7 +87,13 @@ pub fn entry( }) .collect::>(); - quote::quote! ( + if let Err(error) = check_attr_whitelist(&f.attrs, WhiteListCaller::Entry) { + return error; + } + + let (ref cfgs, ref attrs) = extract_cfgs(f.attrs.clone()); + + quote! ( #[cfg(not(any(doc, target_arch = "avr")))] compile_error!( "Ensure that you are using an AVR target! You may need to change \ @@ -100,71 +101,52 @@ pub fn entry( https://github.com/Rahix/avr-device/pull/41 for more details." ); + #(#cfgs)* + #(#attrs)* #[doc(hidden)] #[export_name = "main"] pub unsafe extern "C" fn #tramp_ident() { + #[allow(static_mut_refs)] #ident( #(#resource_args),* ) } - #[doc(hidden)] #f ) .into() } #[proc_macro_attribute] -pub fn interrupt( - args: proc_macro::TokenStream, - input: proc_macro::TokenStream, -) -> proc_macro::TokenStream { - let mut f: syn::ItemFn = - syn::parse(input).expect("`#[interrupt]` must be applied to a function"); - let args: Vec<_> = args.into_iter().collect(); - - let fspan = f.span(); - let ident = f.sig.ident.clone(); - let ident_s = ident.to_string(); +pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream { + let mut f: ItemFn = syn::parse(input).expect("`#[interrupt]` must be applied to a function"); - let chip = if let Some(tree) = args.get(0) { - if let proc_macro::TokenTree::Ident(ident) = tree { - ident.to_string() - } else { - return syn::parse::Error::new( - proc_macro2::Span::call_site(), - "#[interrupt(chip)]: chip must be an ident", - ) - .to_compile_error() - .into(); - } + let chip: Option = if args.is_empty() { + None } else { - return syn::parse::Error::new( - proc_macro2::Span::call_site(), - "#[interrupt(chip)] needs a chip argument", - ) - .to_compile_error() - .into(); + syn::parse(args).expect("#[interrupt(chip)]: chip must be an ident") }; + let fspan = f.span(); + let valid_signature = f.sig.constness.is_none() - && f.vis == syn::Visibility::Inherited + && f.vis == Visibility::Inherited && f.sig.abi.is_none() && f.sig.inputs.is_empty() && f.sig.generics.params.is_empty() && f.sig.generics.where_clause.is_none() && f.sig.variadic.is_none() && match f.sig.output { - syn::ReturnType::Default => true, - syn::ReturnType::Type(_, ref ty) => match **ty { - syn::Type::Tuple(ref tuple) => tuple.elems.is_empty(), - syn::Type::Never(..) => true, + ReturnType::Default => true, + ReturnType::Type(_, ref ty) => match **ty { + Type::Tuple(ref tuple) => tuple.elems.is_empty(), + Type::Never(..) => true, _ => false, }, }; if !valid_signature { - return syn::parse::Error::new( + return parse::Error::new( fspan, "`#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`", ) @@ -177,26 +159,32 @@ pub fn interrupt( Ok(x) => x, }; - f.sig.ident = syn::Ident::new( - &format!("__avr_device_rt_{}", f.sig.ident), - proc_macro2::Span::call_site(), - ); + let cased_ident = f.sig.ident.clone(); + let uncased_ident = Ident::new(&f.sig.ident.to_string().to_lowercase(), Span::call_site()); + f.sig.ident = Ident::new(&format!("__avr_device_{}", uncased_ident), Span::call_site()); f.sig.inputs.extend(statics.iter().map(|statik| { let ident = &statik.ident; let ty = &statik.ty; let attrs = &statik.attrs; - syn::parse::( - quote::quote!(#[allow(non_snake_case)] #(#attrs)* #ident: &mut #ty).into(), - ) - .unwrap() + syn::parse::(quote!(#[allow(non_snake_case)] #(#attrs)* #ident: &mut #ty).into()) + .unwrap() })); - f.block.stmts = stmts; - - let tramp_ident = syn::Ident::new( - &format!("{}_trampoline", f.sig.ident), - proc_macro2::Span::call_site(), - ); - let ident = &f.sig.ident; + f.block.stmts = iter::once( + syn::parse2(if let Some(ref mcu) = chip { + quote! {{ + // Check that this interrupt actually exists + ::avr_device::#mcu::Interrupt::#cased_ident; + }} + } else { + quote! {{ + // If the chip argument was not given, expect it to be at the root + ::avr_device::Interrupt::#cased_ident; + }} + }) + .unwrap(), + ) + .chain(stmts) + .collect(); let resource_args = statics .iter() @@ -205,9 +193,9 @@ pub fn interrupt( let ident = &statik.ident; let ty = &statik.ty; let expr = &statik.expr; - quote::quote! { + quote! { #(#cfgs)* - { + unsafe { #(#attrs)* static mut #ident: #ty = #expr; &mut #ident @@ -216,32 +204,41 @@ pub fn interrupt( }) .collect::>(); - let vect = if let Some(v) = vector::lookup_vector(&chip, &ident_s) { - v - } else { - return syn::parse::Error::new( - proc_macro2::Span::call_site(), - &format!("Chip `{}` or interrupt `{}` unknown", chip, ident_s), - ) - .to_compile_error() - .into(); - }; - let vector = format!("__vector_{}", vect); - let vector_ident = syn::Ident::new(&vector, proc_macro2::Span::call_site()); - let vector_ident_s = vector_ident.to_string(); + if let Err(error) = check_attr_whitelist(&f.attrs, WhiteListCaller::Interrupt) { + return error; + } - quote::quote! ( - #[doc(hidden)] - #[export_name = #vector_ident_s] - pub unsafe extern "avr-interrupt" fn #tramp_ident() { - #ident( - #(#resource_args),* - ) + let (ref cfgs, ref attrs) = extract_cfgs(f.attrs.clone()); + let interrupt_ident = &f.sig.ident; + let trampoline_ident = Ident::new(&format!("{}_trampoline", interrupt_ident), Span::call_site()); + + if let Some(ref mcu) = chip { + quote! { + #(#cfgs)* + #(#attrs)* + ::avr_device::__avr_device_trampoline!(@#mcu, #cased_ident, pub extern "avr-interrupt" fn #trampoline_ident() { + #[allow(static_mut_refs)] + #interrupt_ident( + #(#resource_args),* + ) + }); + + #f } - - #[doc(hidden)] - #f - ) + } else { + quote! { + #(#cfgs)* + #(#attrs)* + ::avr_device::__avr_device_trampoline_single!(@#cased_ident, pub extern "avr-interrupt" fn #trampoline_ident() { + #[allow(static_mut_refs)] + #interrupt_ident( + #(#resource_args),* + ) + }); + + #f + } + } .into() } @@ -298,6 +295,46 @@ fn extract_cfgs(attrs: Vec) -> (Vec, Vec Result<(), TokenStream> { + let whitelist = &[ + "doc", + "link_section", + "cfg", + "allow", + "warn", + "deny", + "forbid", + "cold", + "naked", + ]; + + 'o: for attr in attrs { + for val in whitelist { + if eq(attr, val) { + continue 'o; + } + } + + let err_str = match caller { + WhiteListCaller::Entry => "this attribute is not allowed on an avr-device entry point", + WhiteListCaller::Interrupt => { + "this attribute is not allowed on an interrupt handler controlled by avr-device" + } + }; + + return Err(parse::Error::new(attr.span(), err_str) + .to_compile_error() + .into()); + } + + Ok(()) +} + /// Returns `true` if `attr.path` matches `name` fn eq(attr: &syn::Attribute, name: &str) -> bool { attr.style == syn::AttrStyle::Outer && attr.path.is_ident(name) diff --git a/patch/at90usb1286.yaml b/patch/at90usb1286.yaml index 7ca8b0f..2666ea7 100644 --- a/patch/at90usb1286.yaml +++ b/patch/at90usb1286.yaml @@ -1,8 +1,6 @@ -_svd: ../svd/at90usb1286.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/twi.yaml" diff --git a/patch/atmega1280.yaml b/patch/atmega1280.yaml index d66b208..e2a7b4c 100644 --- a/patch/atmega1280.yaml +++ b/patch/atmega1280.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega1280.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega1280-2560.yaml" diff --git a/patch/atmega1284p.yaml b/patch/atmega1284p.yaml index fea3f1f..9a61f4d 100644 --- a/patch/atmega1284p.yaml +++ b/patch/atmega1284p.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega1284p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega1284p.yaml" diff --git a/patch/atmega128a.yaml b/patch/atmega128a.yaml index 396a7c7..0a4dc6b 100644 --- a/patch/atmega128a.yaml +++ b/patch/atmega128a.yaml @@ -1,17 +1,19 @@ -_svd: ../svd/atmega128a.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" + - "common/wdt.yaml" + - "common/wdt-more-cycles.yaml" + - "timer/atmega128a.yaml" USART?: UCSR?C: _modify: UMSEL?: - bitRange: "[7:6]" + bitOffset: 6 + bitWidth: 2 # Patches for the Two-Wire-Interface peripheral (i2c) # @@ -34,24 +36,6 @@ TWI*: PRESCALER_16: [2, "Prescaler Value 16"] PRESCALER_64: [3, "Prescaler Value 64"] -WDT: - WDTCR: - _delete: - - WDP - _add: - WDPL: - description: "Watchdog Timer Prescaler - Low Bits" - bitRange: "[2:0]" - WDPL: - CYCLES_16K: [0, "- 16K (16,384) cycles, ~14ms"] - CYCLES_32K: [1, "- 32K (32,768) cycles, ~28ms"] - CYCLES_64K: [2, "- 64K (65,536) cycles, ~56ms"] - CYCLES_128K: [3, "- 128K (131,072) cycles, ~0.11s"] - CYCLES_256K: [4, "- 256K (262,144) cycles, ~0.22s"] - CYCLES_512K: [5, "- 512K (524,288) cycles, ~0.45s"] - CYCLES_1024K: [6, "- 1024K (1,048,576) cycles, ~0.9s"] - CYCLES_2048K: [7, "- 2048K (2,097,152) cycles, ~1.8s"] - ADC: ADMUX: MUX: diff --git a/patch/atmega128rfa1.yaml b/patch/atmega128rfa1.yaml index c976d43..099f7cc 100644 --- a/patch/atmega128rfa1.yaml +++ b/patch/atmega128rfa1.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega128rfa1.svd - # this isn't complete, but the MAN_ID_0 field is broken into bits, and has an # associated 8-bit wide enum which is associated with bit 0 rather than the # entire register. many other registers within the TRX24 are incorrectly split @@ -14,7 +12,7 @@ _include: - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega128rfa1.yaml" diff --git a/patch/atmega16.yaml b/patch/atmega16.yaml index e355e29..79d4962 100644 --- a/patch/atmega16.yaml +++ b/patch/atmega16.yaml @@ -1,10 +1,10 @@ -_svd: ../svd/atmega16.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - + - "common/wdt.yaml" + - "common/wdt-more-cycles.yaml" + - "timer/atmega16.yaml" ADC: @@ -61,24 +61,6 @@ TWI: PRESCALER_16: [2, "Prescaler Value 16"] PRESCALER_64: [3, "Prescaler Value 64"] -WDT: - WDTCR: - _delete: - - WDP - _add: - WDPL: - description: "Watchdog Timer Prescaler - Low Bits" - bitRange: "[2:0]" - WDPL: - CYCLES_16K: [0, "- 16K (16384) cycles, ~16ms"] - CYCLES_32K: [1, "- 32K (32768) cycles, ~32ms"] - CYCLES_64K: [2, "- 64K (65536) cycles, ~65ms"] - CYCLES_128K: [3, "- 128K (131072) cycles, ~0.13s"] - CYCLES_256K: [4, "- 256K (262144) cycles, ~0.26s"] - CYCLES_512K: [5, "- 512K (524288) cycles, ~0.52s"] - CYCLES_1024K: [6, "- 1024K (1048576) cycles, ~1.0s"] - CYCLES_2048K: [7, "- 2048K (2097152) cycles, ~2.1s"] - USART: UCSRA: _modify: diff --git a/patch/atmega164pa.yaml b/patch/atmega164pa.yaml index 8f144db..8c63534 100644 --- a/patch/atmega164pa.yaml +++ b/patch/atmega164pa.yaml @@ -1,9 +1,7 @@ -_svd: ../svd/atmega164pa.svd - _include: - "common/adc.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" EEPROM: diff --git a/patch/atmega168.yaml b/patch/atmega168.yaml index ef8f6a6..08f671d 100644 --- a/patch/atmega168.yaml +++ b/patch/atmega168.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega168.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega328p.yaml" diff --git a/patch/atmega16u2.yaml b/patch/atmega16u2.yaml index 909ac37..d80bf7a 100644 --- a/patch/atmega16u2.yaml +++ b/patch/atmega16u2.yaml @@ -1,10 +1,8 @@ -_svd: ../svd/atmega16u2.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" - "common/spi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega8u2.yaml" @@ -13,4 +11,4 @@ PLL: PLLCSR: _modify: PLOCK: - access: read-only \ No newline at end of file + access: read-only diff --git a/patch/atmega2560.yaml b/patch/atmega2560.yaml index d10b31d..e2a7b4c 100644 --- a/patch/atmega2560.yaml +++ b/patch/atmega2560.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega2560.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega1280-2560.yaml" diff --git a/patch/atmega3208.yaml b/patch/atmega3208.yaml index 519e2ab..fe0f1cc 100644 --- a/patch/atmega3208.yaml +++ b/patch/atmega3208.yaml @@ -1,4 +1,2 @@ -_svd: ../svd/atmega3208.svd - _include: - - "common/mega0/port.yaml" \ No newline at end of file + - "common/mega0/port.yaml" diff --git a/patch/atmega3209.yaml b/patch/atmega3209.yaml index 1de62ab..fe0f1cc 100644 --- a/patch/atmega3209.yaml +++ b/patch/atmega3209.yaml @@ -1,4 +1,2 @@ -_svd: ../svd/atmega3209.svd - _include: - - "common/mega0/port.yaml" \ No newline at end of file + - "common/mega0/port.yaml" diff --git a/patch/atmega324pa.yaml b/patch/atmega324pa.yaml index 7e14d14..dd99dc3 100644 --- a/patch/atmega324pa.yaml +++ b/patch/atmega324pa.yaml @@ -1,10 +1,8 @@ -_svd: ../svd/atmega324pa.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega324pa.yaml" diff --git a/patch/atmega328p.yaml b/patch/atmega328p.yaml index 9ae1eff..6efacab 100644 --- a/patch/atmega328p.yaml +++ b/patch/atmega328p.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega328p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega328p.yaml" diff --git a/patch/atmega328pb.yaml b/patch/atmega328pb.yaml index db9c1d2..2548f66 100644 --- a/patch/atmega328pb.yaml +++ b/patch/atmega328pb.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega328pb.svd - # Remove index suffix from all registers and fields SPI0: _strip_end: @@ -47,7 +45,7 @@ AC: _include: - "common/adc.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/spi.yaml" - "common/twi.yaml" - "common/wdt.yaml" diff --git a/patch/atmega32a.yaml b/patch/atmega32a.yaml index 5ea17c1..294d752 100644 --- a/patch/atmega32a.yaml +++ b/patch/atmega32a.yaml @@ -1,9 +1,9 @@ -_svd: ../svd/atmega32a.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" + - "common/wdt.yaml" + - "common/wdt-more-cycles.yaml" ADC: ADMUX: @@ -64,22 +64,6 @@ WDT: _modify: WDTOE: name: WDCE - _delete: - - WDP - _add: - WDPL: - description: "Watchdog Timer Prescaler - Low Bits" - bitRange: "[2:0]" - WDPL: - CYCLES_16K: [0, "- 16K (16384) cycles, ~16ms"] - CYCLES_32K: [1, "- 32K (32768) cycles, ~32ms"] - CYCLES_64K: [2, "- 64K (65536) cycles, ~65ms"] - CYCLES_128K: [3, "- 128K (131072) cycles, ~0.13s"] - CYCLES_256K: [4, "- 256K (262144) cycles, ~0.26s"] - CYCLES_512K: [5, "- 512K (524288) cycles, ~0.52s"] - CYCLES_1024K: [6, "- 1024K (1048576) cycles, ~1.0s"] - CYCLES_2048K: [7, "- 2048K (2097152) cycles, ~2.1s"] - USART: UCSRA: @@ -124,4 +108,4 @@ USART: UCPOL: _replace_enum: RISING_EDGE: [0, "Transmit on Rising XCK Edge, Receive on Falling XCK Edge"] - FALLING_EDGE: [1, "Transmit on Falling XCK Edge, Receive on Rising XCK Edge"] \ No newline at end of file + FALLING_EDGE: [1, "Transmit on Falling XCK Edge, Receive on Rising XCK Edge"] diff --git a/patch/atmega32u2.yaml b/patch/atmega32u2.yaml index 77cd2c2..d80bf7a 100644 --- a/patch/atmega32u2.yaml +++ b/patch/atmega32u2.yaml @@ -1,10 +1,8 @@ -_svd: ../svd/atmega32u2.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" - "common/spi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega8u2.yaml" @@ -13,4 +11,4 @@ PLL: PLLCSR: _modify: PLOCK: - access: read-only \ No newline at end of file + access: read-only diff --git a/patch/atmega32u4.yaml b/patch/atmega32u4.yaml index 33fed85..afa8865 100644 --- a/patch/atmega32u4.yaml +++ b/patch/atmega32u4.yaml @@ -1,12 +1,10 @@ -_svd: ../svd/atmega32u4.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/pll.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega32u4.yaml" @@ -17,17 +15,20 @@ PORTF: _add: PF7: description: "Pin F7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PINF: _add: PF7: description: "Pin F7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTF: _add: PF7: description: "Pin F7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write diff --git a/patch/atmega4808.yaml b/patch/atmega4808.yaml index f85d3cf..fe0f1cc 100644 --- a/patch/atmega4808.yaml +++ b/patch/atmega4808.yaml @@ -1,4 +1,2 @@ -_svd: ../svd/atmega4808.svd - _include: - - "common/mega0/port.yaml" \ No newline at end of file + - "common/mega0/port.yaml" diff --git a/patch/atmega4809.yaml b/patch/atmega4809.yaml index 4c02e38..fe0f1cc 100644 --- a/patch/atmega4809.yaml +++ b/patch/atmega4809.yaml @@ -1,4 +1,2 @@ -_svd: ../svd/atmega4809.svd - _include: - "common/mega0/port.yaml" diff --git a/patch/atmega48p.yaml b/patch/atmega48p.yaml index 3159302..08f671d 100644 --- a/patch/atmega48p.yaml +++ b/patch/atmega48p.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega48p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega328p.yaml" diff --git a/patch/atmega64.yaml b/patch/atmega64.yaml index f010c54..08350b0 100644 --- a/patch/atmega64.yaml +++ b/patch/atmega64.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega64.svd - _include: - "common/ac.yaml" - "common/adc.yaml" @@ -10,4 +8,5 @@ USART?: UCSR?C: _modify: UMSEL?: - bitRange: "[7:6]" + bitOffset: 6 + bitWidth: 1 diff --git a/patch/atmega644.yaml b/patch/atmega644.yaml index 84843bc..08f671d 100644 --- a/patch/atmega644.yaml +++ b/patch/atmega644.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega644.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega328p.yaml" diff --git a/patch/atmega8.yaml b/patch/atmega8.yaml index 6d04778..cb5bf6b 100644 --- a/patch/atmega8.yaml +++ b/patch/atmega8.yaml @@ -1,9 +1,9 @@ -_svd: ../svd/atmega8.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" + - "common/wdt.yaml" + - "common/wdt-more-cycles.yaml" - "timer/atmega8.yaml" @@ -82,21 +82,3 @@ USART: _replace_enum: RISING_EDGE: [0, "Transmit on Rising XCK Edge, Receive on Falling XCK Edge"] FALLING_EDGE: [1, "Transmit on Falling XCK Edge, Receive on Rising XCK Edge"] - -WDT: - WDTCR: - _delete: - - WDP - _add: - WDPL: - description: "Watchdog Timer Prescaler - Low Bits" - bitRange: "[2:0]" - WDPL: - CYCLES_16K: [0, "- 16K (16384) cycles, ~16ms"] - CYCLES_32K: [1, "- 32K (32768) cycles, ~32ms"] - CYCLES_64K: [2, "- 64K (65536) cycles, ~65ms"] - CYCLES_128K: [3, "- 128K (131072) cycles, ~0.13s"] - CYCLES_256K: [4, "- 256K (262144) cycles, ~0.26s"] - CYCLES_512K: [5, "- 512K (524288) cycles, ~0.52s"] - CYCLES_1024K: [6, "- 1024K (1048576) cycles, ~1.0s"] - CYCLES_2048K: [7, "- 2048K (2097152) cycles, ~2.1s"] diff --git a/patch/atmega88p.yaml b/patch/atmega88p.yaml index b0ed252..08f671d 100644 --- a/patch/atmega88p.yaml +++ b/patch/atmega88p.yaml @@ -1,11 +1,9 @@ -_svd: ../svd/atmega88p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" - "common/spi.yaml" - "common/twi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega328p.yaml" diff --git a/patch/atmega8u2.yaml b/patch/atmega8u2.yaml index 7209b7f..a57e127 100644 --- a/patch/atmega8u2.yaml +++ b/patch/atmega8u2.yaml @@ -1,10 +1,8 @@ -_svd: ../svd/atmega8u2.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" - "common/spi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/atmega8u2.yaml" diff --git a/patch/attiny13a.yaml b/patch/attiny13a.yaml index fed06be..e6b7df0 100644 --- a/patch/attiny13a.yaml +++ b/patch/attiny13a.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny13a.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" @@ -66,7 +64,7 @@ CPU: PRESCALER_256: [8, "Prescaler Value 256"] MCUCR: _delete: - - ISC? + - "ISC?" _add: BODS: description: "BOD Sleep (available on some devices)" diff --git a/patch/attiny1614.yaml b/patch/attiny1614.yaml deleted file mode 100644 index 6a5f01f..0000000 --- a/patch/attiny1614.yaml +++ /dev/null @@ -1 +0,0 @@ -_svd: ../svd/attiny1614.svd diff --git a/patch/attiny167.yaml b/patch/attiny167.yaml index ef72841..2905320 100644 --- a/patch/attiny167.yaml +++ b/patch/attiny167.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny167.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" @@ -87,103 +85,127 @@ PORTA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PA3: description: "Pin A3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PA4: description: "Pin A4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PA5: description: "Pin A5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PA6: description: "Pin A6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PA7: description: "Pin A7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PINA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PA3: description: "Pin A3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PA4: description: "Pin A4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PA5: description: "Pin A5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PA6: description: "Pin A6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PA7: description: "Pin A7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PA3: description: "Pin A3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PA4: description: "Pin A4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PA5: description: "Pin A5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PA6: description: "Pin A6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PA7: description: "Pin A7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTB: @@ -191,101 +213,125 @@ PORTB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PB4: description: "Pin B4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PB5: description: "Pin B5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PB6: description: "Pin B6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PB7: description: "Pin B7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PINB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PB4: description: "Pin B4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PB5: description: "Pin B5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PB6: description: "Pin B6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PB7: description: "Pin B7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PB4: description: "Pin B4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PB5: description: "Pin B5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PB6: description: "Pin B6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PB7: description: "Pin B7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write diff --git a/patch/attiny202.yaml b/patch/attiny202.yaml index ef99254..964980f 100644 --- a/patch/attiny202.yaml +++ b/patch/attiny202.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny202.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/0-series.yaml diff --git a/patch/attiny212.yaml b/patch/attiny212.yaml index 3a6f5b6..780dcf6 100644 --- a/patch/attiny212.yaml +++ b/patch/attiny212.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny212.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/1-series.yaml diff --git a/patch/attiny214.yaml b/patch/attiny214.yaml index 3f6d7ab..780dcf6 100644 --- a/patch/attiny214.yaml +++ b/patch/attiny214.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny214.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/1-series.yaml diff --git a/patch/attiny2313-common.yaml b/patch/attiny2313-common.yaml index d2092c5..0ae7db3 100644 --- a/patch/attiny2313-common.yaml +++ b/patch/attiny2313-common.yaml @@ -32,43 +32,52 @@ PORTA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PINA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PORTA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PORTB: @@ -76,103 +85,127 @@ PORTB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PB4: description: "Pin B4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PB5: description: "Pin B5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PB6: description: "Pin B6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PB7: description: "Pin B7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PINB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PB4: description: "Pin B4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PB5: description: "Pin B5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PB6: description: "Pin B6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PB7: description: "Pin B7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PB4: description: "Pin B4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PB5: description: "Pin B5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PB6: description: "Pin B6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PB7: description: "Pin B7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTD: @@ -180,89 +213,110 @@ PORTD: _add: PD0: description: "Pin D0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PD1: description: "Pin D1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PD2: description: "Pin D2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PD3: description: "Pin D3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PD4: description: "Pin D4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PD5: description: "Pin D5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PD6: description: "Pin D6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PIND: _add: PD0: description: "Pin D0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PD1: description: "Pin D1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PD2: description: "Pin D2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PD3: description: "Pin D3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PD4: description: "Pin D4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PD5: description: "Pin D5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PD6: description: "Pin D6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PORTD: _add: PD0: description: "Pin D0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PD1: description: "Pin D1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PD2: description: "Pin D2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PD3: description: "Pin D3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PD4: description: "Pin D4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PD5: description: "Pin D5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PD6: description: "Pin D6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write diff --git a/patch/attiny2313.yaml b/patch/attiny2313.yaml index 4fa3c69..4977809 100644 --- a/patch/attiny2313.yaml +++ b/patch/attiny2313.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny2313.svd - _include: - "attiny2313-common.yaml" - - "common/usart-single-attiny2313.yaml" + - "common/usart-single.yaml" diff --git a/patch/attiny2313a.yaml b/patch/attiny2313a.yaml index e5f545f..0e7bcbd 100644 --- a/patch/attiny2313a.yaml +++ b/patch/attiny2313a.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny2313a.svd - _include: - "attiny2313-common.yaml" - - "common/usart-single-attiny2313a.yaml" + - "common/usart-single-spi.yaml" diff --git a/patch/attiny26.yaml b/patch/attiny26.yaml index 8182aeb..9267270 100644 --- a/patch/attiny26.yaml +++ b/patch/attiny26.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny26.svd - _include: - "common/ac.yaml" - "common/wdt.yaml" diff --git a/patch/attiny402.yaml b/patch/attiny402.yaml index da41f3f..964980f 100644 --- a/patch/attiny402.yaml +++ b/patch/attiny402.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny402.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/0-series.yaml diff --git a/patch/attiny404.yaml b/patch/attiny404.yaml index 1152d2c..964980f 100644 --- a/patch/attiny404.yaml +++ b/patch/attiny404.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny404.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/0-series.yaml diff --git a/patch/attiny412.yaml b/patch/attiny412.yaml index 981a8af..780dcf6 100644 --- a/patch/attiny412.yaml +++ b/patch/attiny412.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny412.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/1-series.yaml diff --git a/patch/attiny414.yaml b/patch/attiny414.yaml index ce14d3d..780dcf6 100644 --- a/patch/attiny414.yaml +++ b/patch/attiny414.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny414.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/1-series.yaml diff --git a/patch/attiny416.yaml b/patch/attiny416.yaml index 85aac3a..780dcf6 100644 --- a/patch/attiny416.yaml +++ b/patch/attiny416.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny416.svd - _include: - common/attiny-xmega/common.yaml - common/attiny-xmega/1-series.yaml diff --git a/patch/attiny44a.yaml b/patch/attiny44a.yaml deleted file mode 100644 index 67d92ba..0000000 --- a/patch/attiny44a.yaml +++ /dev/null @@ -1 +0,0 @@ -_svd: ../svd/attiny44a.svd diff --git a/patch/attiny816.yaml b/patch/attiny816.yaml index f1c3e2f..7658a24 100644 --- a/patch/attiny816.yaml +++ b/patch/attiny816.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny816.svd - CRCSCAN: CTRLB: SRC: diff --git a/patch/attiny828.yaml b/patch/attiny828.yaml index c814854..d7fb59a 100644 --- a/patch/attiny828.yaml +++ b/patch/attiny828.yaml @@ -1,10 +1,9 @@ -_svd: ../svd/attiny828.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" - "common/spi.yaml" - "common/wdt.yaml" + - "common/usart-single-spi.yaml" - "timer/attiny828.yaml" @@ -78,29 +77,23 @@ USART: _modify: RXB8: access: read-only - UCSRC: - UMSEL: - _replace_enum: - USART_ASYNC: [0, "Asynchronous USART"] - USART_SYNC: [1, "Synchronous USART"] - # The following option is missing from atdf file, but it's present in the datasheet - SPI_MASTER: [3, "Master SPI (MSPIM)"] - UPM: - _replace_enum: - DISABLED: [0, "Disabled"] - PARITY_EVEN: [2, "Enabled, Even Parity"] - PARITY_ODD: [3, "Enabled, Odd Parity"] - USBS: - _replace_enum: - STOP1: [0, "1-bit"] - STOP2: [1, "2-bit"] - UCSZ: - _replace_enum: - CHR5: [0, "Character Size: 5 bit"] - CHR6: [1, "Character Size: 6 bit"] - CHR7: [2, "Character Size: 7 bit"] - CHR8: [3, "Character Size: 8 bit"] - UCPOL: - _replace_enum: - RISING_EDGE: [0, "Transmit on Rising XCKn Edge, Receive on Falling XCKn Edge"] - FALLING_EDGE: [1, "Transmit on Falling XCKn Edge, Receive on Rising XCKn Edge"] + # UCSRC: + # UPM: + # _replace_enum: + # DISABLED: [0, "Disabled"] + # PARITY_EVEN: [2, "Enabled, Even Parity"] + # PARITY_ODD: [3, "Enabled, Odd Parity"] + # USBS: + # _replace_enum: + # STOP1: [0, "1-bit"] + # STOP2: [1, "2-bit"] + # UCSZ: + # _replace_enum: + # CHR5: [0, "Character Size: 5 bit"] + # CHR6: [1, "Character Size: 6 bit"] + # CHR7: [2, "Character Size: 7 bit"] + # CHR8: [3, "Character Size: 8 bit"] + # UCPOL: + # _replace_enum: + # RISING_EDGE: [0, "Transmit on Rising XCKn Edge, Receive on Falling XCKn Edge"] + # FALLING_EDGE: [1, "Transmit on Falling XCKn Edge, Receive on Rising XCKn Edge"] diff --git a/patch/attiny84.yaml b/patch/attiny84.yaml index d48b8ea..6528f32 100644 --- a/patch/attiny84.yaml +++ b/patch/attiny84.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny84.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" @@ -168,103 +166,127 @@ PORTA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PA3: description: "Pin A3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PA4: description: "Pin A4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PA5: description: "Pin A5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PA6: description: "Pin A6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PA7: description: "Pin A7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PINA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PA3: description: "Pin A3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PA4: description: "Pin A4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PA5: description: "Pin A5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PA6: description: "Pin A6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PA7: description: "Pin A7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTA: _add: PA0: description: "Pin A0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PA1: description: "Pin A1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PA2: description: "Pin A2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PA3: description: "Pin A3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PA4: description: "Pin A4" - bitRange: "[4:4]" + bitOffset: 4 + bitWidth: 1 access: read-write PA5: description: "Pin A5" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 access: read-write PA6: description: "Pin A6" - bitRange: "[6:6]" + bitOffset: 6 + bitWidth: 1 access: read-write PA7: description: "Pin A7" - bitRange: "[7:7]" + bitOffset: 7 + bitWidth: 1 access: read-write PORTB: @@ -272,53 +294,65 @@ PORTB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PINB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write PORTB: _add: PB0: description: "Pin B0" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write PB1: description: "Pin B1" - bitRange: "[1:1]" + bitOffset: 1 + bitWidth: 1 access: read-write PB2: description: "Pin B2" - bitRange: "[2:2]" + bitOffset: 2 + bitWidth: 1 access: read-write PB3: description: "Pin B3" - bitRange: "[3:3]" + bitOffset: 3 + bitWidth: 1 access: read-write diff --git a/patch/attiny841.yaml b/patch/attiny841.yaml index 7029367..e51ca44 100644 --- a/patch/attiny841.yaml +++ b/patch/attiny841.yaml @@ -1,9 +1,7 @@ -_svd: ../svd/attiny841.svd - _include: - "common/ac.yaml" - "common/spi.yaml" - - "common/usart.yaml" + - "common/usart-spi.yaml" - "common/wdt.yaml" - "timer/attiny841.yaml" diff --git a/patch/attiny84a.yaml b/patch/attiny84a.yaml index d9caea2..7116a92 100644 --- a/patch/attiny84a.yaml +++ b/patch/attiny84a.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny84a.svd - _include: - "common/eeprom.yaml" diff --git a/patch/attiny85.yaml b/patch/attiny85.yaml index f3e27c1..5951fbc 100644 --- a/patch/attiny85.yaml +++ b/patch/attiny85.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny85.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" @@ -82,7 +80,7 @@ CPU: PRESCALER_256: [8, "Prescaler Value 256"] MCUCR: _delete: - - ISC? + - "ISC?" _add: BODS: description: "BOD Sleep (available on some devices)" diff --git a/patch/attiny861.yaml b/patch/attiny861.yaml index f44ad52..cba99e3 100644 --- a/patch/attiny861.yaml +++ b/patch/attiny861.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny861.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/attiny88.yaml b/patch/attiny88.yaml index 46c777b..5faf28e 100644 --- a/patch/attiny88.yaml +++ b/patch/attiny88.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny88.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" diff --git a/patch/avr64du28.yaml b/patch/avr64du28.yaml deleted file mode 100644 index 83f7573..0000000 --- a/patch/avr64du28.yaml +++ /dev/null @@ -1 +0,0 @@ -_svd: ../svd/avr64du28.svd diff --git a/patch/avr64du32.yaml b/patch/avr64du32.yaml deleted file mode 100644 index 65d70cb..0000000 --- a/patch/avr64du32.yaml +++ /dev/null @@ -1 +0,0 @@ -_svd: ../svd/avr64du32.svd diff --git a/patch/common/attiny-xmega/common.yaml b/patch/common/attiny-xmega/common.yaml index e7739b5..d6d39ae 100644 --- a/patch/common/attiny-xmega/common.yaml +++ b/patch/common/attiny-xmega/common.yaml @@ -15,11 +15,13 @@ TWI0: # FIXME: Make this so we don't need 'unsafe' ADDR: description: "Client Address" - bitRange: "[7:1]" + bitOffset: 1 + bitWidth: 7 access: read-write GCE: description: "General Call Recognition Enable Bit" - bitRange: "[0:0]" + bitOffset: 0 + bitWidth: 1 access: read-write USERROW: diff --git a/patch/common/tiny/exint.yaml b/patch/common/tiny/exint.yaml index f5322b0..8ecc997 100644 --- a/patch/common/tiny/exint.yaml +++ b/patch/common/tiny/exint.yaml @@ -1,7 +1,7 @@ EXINT: MCUCR: _delete: - - ISC?? + - "ISC??" _add: ISC0: description: "Interrupt Sense Control 0 bits" diff --git a/patch/common/usart-single-attiny2313a.yaml b/patch/common/usart-single-spi.yaml similarity index 100% rename from patch/common/usart-single-attiny2313a.yaml rename to patch/common/usart-single-spi.yaml diff --git a/patch/common/usart-single-attiny2313.yaml b/patch/common/usart-single.yaml similarity index 100% rename from patch/common/usart-single-attiny2313.yaml rename to patch/common/usart-single.yaml diff --git a/patch/common/usart-spi.yaml b/patch/common/usart-spi.yaml new file mode 100644 index 0000000..ed4ebee --- /dev/null +++ b/patch/common/usart-spi.yaml @@ -0,0 +1,44 @@ +USART?: + UCSR?A: + _modify: + UPE?: + access: read-only + DOR?: + access: read-only + FE?: + access: read-only + UDRE?: + access: read-only + TXC?: + description: "USART Transmit Complete" + RXC?: + access: read-only + UCSR?B: + _modify: + RXB8?: + access: read-only + UCSR?C: + UMSEL?: + _replace_enum: + USART_ASYNC: [0, "Asynchronous USART"] + USART_SYNC: [1, "Synchronous USART"] + SPI_MASTER: [3, "Master SPI (MSPIM)"] + UPM?: + _replace_enum: + DISABLED: [0, "Disabled"] + PARITY_EVEN: [2, "Enabled, Even Parity"] + PARITY_ODD: [3, "Enabled, Odd Parity"] + USBS?: + _replace_enum: + STOP1: [0, "1-bit"] + STOP2: [1, "2-bit"] + UCSZ?: + _replace_enum: + CHR5: [0, "Character Size: 5 bit"] + CHR6: [1, "Character Size: 6 bit"] + CHR7: [2, "Character Size: 7 bit"] + CHR8: [3, "Character Size: 8 bit"] + UCPOL?: + _replace_enum: + RISING_EDGE: [0, "Transmit on Rising XCKn Edge, Receive on Falling XCKn Edge"] + FALLING_EDGE: [1, "Transmit on Falling XCKn Edge, Receive on Rising XCKn Edge"] diff --git a/patch/common/usart.yaml b/patch/common/usart.yaml index ed4ebee..1e083bc 100644 --- a/patch/common/usart.yaml +++ b/patch/common/usart.yaml @@ -22,7 +22,6 @@ USART?: _replace_enum: USART_ASYNC: [0, "Asynchronous USART"] USART_SYNC: [1, "Synchronous USART"] - SPI_MASTER: [3, "Master SPI (MSPIM)"] UPM?: _replace_enum: DISABLED: [0, "Disabled"] diff --git a/patch/common/wdt-more-cycles.yaml b/patch/common/wdt-more-cycles.yaml new file mode 100644 index 0000000..623b425 --- /dev/null +++ b/patch/common/wdt-more-cycles.yaml @@ -0,0 +1,13 @@ + +WDT: + WDTCSR,WDTCR: + WDPL: + _replace_enum: + CYCLES_16K: [0, "- 16K (16,384) cycles, ~14ms"] + CYCLES_32K: [1, "- 32K (32,768) cycles, ~28ms"] + CYCLES_64K: [2, "- 64K (65,536) cycles, ~56ms"] + CYCLES_128K: [3, "- 128K (131,072) cycles, ~0.11s"] + CYCLES_256K: [4, "- 256K (262,144) cycles, ~0.22s"] + CYCLES_512K: [5, "- 512K (524,288) cycles, ~0.45s"] + CYCLES_1024K: [6, "- 1024K (1,048,576) cycles, ~0.9s"] + CYCLES_2048K: [7, "- 2048K (2,097,152) cycles, ~1.8s"] diff --git a/patch/common/wdt.yaml b/patch/common/wdt.yaml index 578b0a4..62c59fb 100644 --- a/patch/common/wdt.yaml +++ b/patch/common/wdt.yaml @@ -5,7 +5,8 @@ # # - Remove the overlapping WDP (Prescaler) field and replace # it with two separate fields. -# - TODO: See if svd2rust would support some kind of mask? +# - TODO(@LuigiPiucco): When svdtools+svd2rust support dont-cares, merge the +# field again and mark unowned bits with those. WDT: WDTCSR,WDTCR: _delete: @@ -13,10 +14,12 @@ WDT: _add: WDPL: description: "Watchdog Timer Prescaler - Low Bits" - bitRange: "[2:0]" + bitOffset: 0 + bitWidth: 3 WDPH: description: "Watchdog Timer Prescaler - High Bit" - bitRange: "[5:5]" + bitOffset: 5 + bitWidth: 1 WDPL: CYCLES_2K_512K: [0, "- 2048 cycles, ~16ms/512K (524288) cycles, ~4s if WDPH is set"] CYCLES_4K_1024K: [1, "- 4096 cycles, ~32ms/1024K (1048576) cycles, ~8s if WDPH is set"] diff --git a/patch/modrs.patch b/patch/modrs.patch deleted file mode 100644 index e165b70..0000000 --- a/patch/modrs.patch +++ /dev/null @@ -1,5 +0,0 @@ -1337,1338c1337 -< #[no_mangle] -< static mut DEVICE_PERIPHERALS: bool = false; ---- -> use crate::devices::DEVICE_PERIPHERALS; diff --git a/patch/timer/atmega16.yaml b/patch/timer/atmega16.yaml index d1571d1..319538d 100644 --- a/patch/timer/atmega16.yaml +++ b/patch/timer/atmega16.yaml @@ -1,14 +1,6 @@ TC0: TCCR0: - _delete: - - CS00 - - CS01 - - CS02 - _add: - CS: - description: "Clock Select" - bitRange: "[2:0]" - CS: + CS0: _replace_enum: NO_CLOCK: [0, "No clock source (Timer/Counter stopped)"] DIRECT: [1, "Running, No Prescaling"] @@ -22,15 +14,7 @@ TC1: # TCCR1A is too complex for me to implement right now, because it has 3 different # modes depending on bits which are set elsewhere. TCCR1B: # ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10 - _delete: - - CS10 - - CS11 - - CS12 - _add: - CS: - description: "Clock Select" - bitRange: "[2:0]" - CS: + CS1: _replace_enum: NO_CLOCK: [0, "No clock source (Timer/Counter stopped)"] DIRECT: [1, "Running, No Prescaling"] @@ -42,15 +26,7 @@ TC1: EXT_RISING: [7, "Running, ExtClk T1 Rising Edge"] TC2: TCCR2: - _delete: - - CS20 - - CS21 - - CS22 - _add: - CS: - description: "Clock Select" - bitRange: "[2:0]" - CS: + CS2: _replace_enum: NO_CLOCK: [0, "No clock source (Timer/Counter stopped)"] DIRECT: [1, "Running, No Prescaling"] diff --git a/patch/timer/dev/8bit-mega8.yaml b/patch/timer/dev/8bit-mega8.yaml index 4ae971e..96978fc 100644 --- a/patch/timer/dev/8bit-mega8.yaml +++ b/patch/timer/dev/8bit-mega8.yaml @@ -6,7 +6,8 @@ TCCR?: _add: CS0: description: "Clock Select 0" - bitRange: "[2:0]" + bitOffset: 0 + bitWidth: 3 CS0: _replace_enum: NO_CLOCK: [0, "No clock source (Timer/Counter stopped)"] diff --git a/src/devices/mod.rs b/src/devices.rs similarity index 54% rename from src/devices/mod.rs rename to src/devices.rs index 6d5b538..c8c26d3 100644 --- a/src/devices/mod.rs +++ b/src/devices.rs @@ -1,208 +1,308 @@ -#[allow(renamed_and_removed_lints)] -#[allow(private_no_mangle_statics)] #[no_mangle] -pub(crate) static mut DEVICE_PERIPHERALS: bool = false; +static mut DEVICE_PERIPHERALS: bool = false; /// [AT90USB1286](https://www.microchip.com/wwwproducts/en/AT90USB1286) #[cfg(feature = "at90usb1286")] -pub mod at90usb1286; +pub mod at90usb1286 { + include!(concat!(env!("OUT_DIR"), "/pac/at90usb1286.rs")); +} /// [ATmega1280](https://www.microchip.com/wwwproducts/en/ATmega1280) #[cfg(feature = "atmega1280")] -pub mod atmega1280; +pub mod atmega1280 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega1280.rs")); +} /// [ATmega1284P](https://www.microchip.com/en-us/product/ATmega1284P) #[cfg(feature = "atmega1284p")] -pub mod atmega1284p; +pub mod atmega1284p { + include!(concat!(env!("OUT_DIR"), "/pac/atmega1284p.rs")); +} /// [ATmega128A](https://www.microchip.com/wwwproducts/en/ATmega128A) #[cfg(feature = "atmega128a")] -pub mod atmega128a; +pub mod atmega128a { + include!(concat!(env!("OUT_DIR"), "/pac/atmega128a.rs")); +} /// [ATmega128RFA1](https://www.microchip.com/en-us/product/ATmega128RFA1) #[cfg(feature = "atmega128rfa1")] -pub mod atmega128rfa1; +pub mod atmega128rfa1 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega128rfa1.rs")); +} /// [ATmega16](https://www.microchip.com/wwwproducts/en/ATmega16) #[cfg(feature = "atmega16")] -pub mod atmega16; +pub mod atmega16 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega16.rs")); +} /// [ATmega164PA](https://www.microchip.com/en-us/product/ATmega164PA) #[cfg(feature = "atmega164pa")] -pub mod atmega164pa; +pub mod atmega164pa { + include!(concat!(env!("OUT_DIR"), "/pac/atmega164pa.rs")); +} /// [ATmega168](https://www.microchip.com/wwwproducts/en/ATmega168) #[cfg(feature = "atmega168")] -pub mod atmega168; +pub mod atmega168 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega168.rs")); +} /// [ATmega16u2](https://www.microchip.com/wwwproducts/en/ATmega16u2) #[cfg(feature = "atmega16u2")] -pub mod atmega16u2; +pub mod atmega16u2 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega16u2.rs")); +} /// [ATmega2560](https://www.microchip.com/wwwproducts/en/ATmega2560) #[cfg(feature = "atmega2560")] -pub mod atmega2560; +pub mod atmega2560 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega2560.rs")); +} /// [ATmega324PA](https://www.microchip.com/wwwproducts/en/ATmega324PA) #[cfg(feature = "atmega324pa")] -pub mod atmega324pa; +pub mod atmega324pa { + include!(concat!(env!("OUT_DIR"), "/pac/atmega324pa.rs")); +} /// [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P) #[cfg(feature = "atmega328p")] -pub mod atmega328p; +pub mod atmega328p { + include!(concat!(env!("OUT_DIR"), "/pac/atmega328p.rs")); +} /// [ATmega328PB](https://www.microchip.com/wwwproducts/en/ATmega328PB) #[cfg(feature = "atmega328pb")] -pub mod atmega328pb; +pub mod atmega328pb { + include!(concat!(env!("OUT_DIR"), "/pac/atmega328pb.rs")); +} /// [ATmega32A](https://www.microchip.com/wwwproducts/en/ATmega32A) #[cfg(feature = "atmega32a")] -pub mod atmega32a; +pub mod atmega32a { + include!(concat!(env!("OUT_DIR"), "/pac/atmega32a.rs")); +} /// [ATmega32u2](https://www.microchip.com/wwwproducts/en/ATmega32u2) #[cfg(feature = "atmega32u2")] -pub mod atmega32u2; +pub mod atmega32u2 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega32u2.rs")); +} /// [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) #[cfg(feature = "atmega32u4")] -pub mod atmega32u4; +pub mod atmega32u4 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega32u4.rs")); +} /// [ATmega3208](https://www.microchip.com/wwwproducts/en/ATmega3208) #[cfg(feature = "atmega3208")] -pub mod atmega3208; +pub mod atmega3208 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega3208.rs")); +} /// [ATmega3209](https://www.microchip.com/wwwproducts/en/ATmega3209) #[cfg(feature = "atmega3209")] -pub mod atmega3209; +pub mod atmega3209 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega3209.rs")); +} /// [ATmega4808](https://www.microchip.com/wwwproducts/en/ATmega4808) #[cfg(feature = "atmega4808")] -pub mod atmega4808; +pub mod atmega4808 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega4808.rs")); +} /// [ATmega4809](https://www.microchip.com/wwwproducts/en/ATmega4809) #[cfg(feature = "atmega4809")] -pub mod atmega4809; +pub mod atmega4809 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega4809.rs")); +} /// [ATmega48P](https://www.microchip.com/wwwproducts/en/ATmega48P) #[cfg(feature = "atmega48p")] -pub mod atmega48p; +pub mod atmega48p { + include!(concat!(env!("OUT_DIR"), "/pac/atmega48p.rs")); +} /// [ATmega8](https://www.microchip.com/wwwproducts/en/ATmega8) #[cfg(feature = "atmega8")] -pub mod atmega8; +pub mod atmega8 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega8.rs")); +} /// [ATmega8u2](https://www.microchip.com/wwwproducts/en/ATmega8u2) #[cfg(feature = "atmega8u2")] -pub mod atmega8u2; +pub mod atmega8u2 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega8u2.rs")); +} /// [ATmega64](https://www.microchip.com/wwwproducts/en/ATmega64) #[cfg(feature = "atmega64")] -pub mod atmega64; +pub mod atmega64 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega64.rs")); +} /// [ATmega644](https://www.microchip.com/wwwproducts/en/ATmega644) #[cfg(feature = "atmega644")] -pub mod atmega644; +pub mod atmega644 { + include!(concat!(env!("OUT_DIR"), "/pac/atmega644.rs")); +} /// [ATmega88P](https://www.microchip.com/wwwproducts/en/ATmega88P) #[cfg(feature = "atmega88p")] -pub mod atmega88p; +pub mod atmega88p { + include!(concat!(env!("OUT_DIR"), "/pac/atmega88p.rs")); +} /// [ATtiny13A](https://www.microchip.com/wwwproducts/en/ATtiny13A) #[cfg(feature = "attiny13a")] -pub mod attiny13a; +pub mod attiny13a { + include!(concat!(env!("OUT_DIR"), "/pac/attiny13a.rs")); +} /// [ATtiny167](https://www.microchip.com/wwwproducts/en/ATtiny167) #[cfg(feature = "attiny167")] -pub mod attiny167; +pub mod attiny167 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny167.rs")); +} /// [ATtiny1614](https://www.microchip.com/wwwproducts/en/ATtiny1614) #[cfg(feature = "attiny1614")] -pub mod attiny1614; +pub mod attiny1614 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny1614.rs")); +} /// [ATtiny202](https://www.microchip.com/wwwproducts/en/ATtiny202) #[cfg(feature = "attiny202")] -pub mod attiny202; +pub mod attiny202 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny202.rs")); +} /// [ATtiny212](https://www.microchip.com/wwwproducts/en/ATtiny212) #[cfg(feature = "attiny212")] -pub mod attiny212; +pub mod attiny212 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny212.rs")); +} /// [ATtiny214](https://www.microchip.com/wwwproducts/en/ATtiny214) #[cfg(feature = "attiny214")] -pub mod attiny214; +pub mod attiny214 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny214.rs")); +} /// [ATtiny2313](https://www.microchip.com/wwwproducts/en/ATtiny2313) #[cfg(feature = "attiny2313")] -pub mod attiny2313; +pub mod attiny2313 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny2313.rs")); +} /// [ATtiny2313A](https://www.microchip.com/wwwproducts/en/ATtiny2313A) #[cfg(feature = "attiny2313a")] -pub mod attiny2313a; +pub mod attiny2313a { + include!(concat!(env!("OUT_DIR"), "/pac/attiny2313a.rs")); +} /// [ATtiny26](https://www.microchip.com/wwwproducts/en/ATtiny26) #[cfg(feature = "attiny26")] -pub mod attiny26; +pub mod attiny26 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny26.rs")); +} /// [ATtiny402](https://www.microchip.com/en-us/product/ATTINY402) #[cfg(feature = "attiny402")] -pub mod attiny402; +pub mod attiny402 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny402.rs")); +} /// [ATtiny404](https://www.microchip.com/en-us/product/ATTINY404) #[cfg(feature = "attiny404")] -pub mod attiny404; +pub mod attiny404 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny404.rs")); +} /// [ATtiny412](https://www.microchip.com/wwwproducts/en/ATtiny412) #[cfg(feature = "attiny412")] -pub mod attiny412; +pub mod attiny412 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny412.rs")); +} /// [ATtiny414](https://www.microchip.com/wwwproducts/en/ATtiny414) #[cfg(feature = "attiny414")] -pub mod attiny414; +pub mod attiny414 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny414.rs")); +} /// [ATtiny416](https://www.microchip.com/wwwproducts/en/ATtiny416) #[cfg(feature = "attiny416")] -pub mod attiny416; +pub mod attiny416 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny416.rs")); +} /// [ATtiny44a](https://www.microchip.com/en-us/product/ATtiny44a) #[cfg(feature = "attiny44a")] -pub mod attiny44a; +pub mod attiny44a { + include!(concat!(env!("OUT_DIR"), "/pac/attiny44a.rs")); +} /// [ATtiny816](https://www.microchip.com/wwwproducts/en/ATtiny816) #[cfg(feature = "attiny816")] -pub mod attiny816; +pub mod attiny816 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny816.rs")); +} /// [ATtiny828](https://www.microchip.com/wwwproducts/en/ATtiny828) #[cfg(feature = "attiny828")] -pub mod attiny828; +pub mod attiny828 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny828.rs")); +} /// [ATtiny84](https://www.microchip.com/wwwproducts/en/ATtiny84) #[cfg(feature = "attiny84")] -pub mod attiny84; +pub mod attiny84 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny84.rs")); +} /// [ATtiny841](https://www.microchip.com/wwwproducts/en/ATtiny841) #[cfg(feature = "attiny841")] -pub mod attiny841; +pub mod attiny841 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny841.rs")); +} /// [ATtiny84a](https://www.microchip.com/en-us/product/ATtiny84a) #[cfg(feature = "attiny84a")] -pub mod attiny84a; +pub mod attiny84a { + include!(concat!(env!("OUT_DIR"), "/pac/attiny84a.rs")); +} /// [ATtiny85](https://www.microchip.com/wwwproducts/en/ATtiny85) #[cfg(feature = "attiny85")] -pub mod attiny85; +pub mod attiny85 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny85.rs")); +} /// [ATtiny861](https://www.microchip.com/wwwproducts/en/ATtiny861) #[cfg(feature = "attiny861")] -pub mod attiny861; +pub mod attiny861 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny861.rs")); +} /// [ATtiny88](https://www.microchip.com/wwwproducts/en/ATtiny88) #[cfg(feature = "attiny88")] -pub mod attiny88; +pub mod attiny88 { + include!(concat!(env!("OUT_DIR"), "/pac/attiny88.rs")); +} /// [AVR64DU32](https://www.microchip.com/wwwproducts/en/AVR64DU32) #[cfg(feature = "avr64du32")] -pub mod avr64du32; +pub mod avr64du32 { + include!(concat!(env!("OUT_DIR"), "/pac/avr64du32.rs")); +} /// [AVR64DU28](https://www.microchip.com/wwwproducts/en/AVR64DU28) #[cfg(feature = "avr64du28")] -pub mod avr64du28; +pub mod avr64du28 { + include!(concat!(env!("OUT_DIR"), "/pac/avr64du28.rs")); +} diff --git a/src/lib.rs b/src/lib.rs index 7db14ec..9c2dd18 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,7 +55,7 @@ //! #![cfg_attr( feature = "docsrs", - doc = "**Warning**: The doc-build here on docs.rs is only for a subset of supported chips. Please build documentation locally if your MCU's registers are not documented here.\n\n" + doc = "**Warning**: The doc-build here on docs.rs is for all of the supported chips. In practice, you'd only select the MCU you're using as a feature, and that'll be the only module available.\n\n" )] //! Which chips the crate is built for depends on the feature flag used. //! The following chips are available (using feature flags of the same name): @@ -143,19 +143,19 @@ //! //! ```ignore //! // Configure bit 5 of port B as output: -//! dp.PORTB.ddrb.write(|w| w.pb5().set_bit()); +//! dp.portb.ddrb().write(|w| w.pb5().set_bit()); //! // Clear bit 5 of port B: -//! dp.PORTB.portb.write(|w| w.pb5().clear_bit()); +//! dp.portb.portb().write(|w| w.pb5().clear_bit()); //! // Set bit 5 of port B: -//! dp.PORTB.portb.write(|w| w.pb5().set_bit()); +//! dp.portb.portb().write(|w| w.pb5().set_bit()); //! //! // Configure bit 6 of port B as input with pullup: -//! dp.PORTB.ddrb.write(|w| w.pb6().clear_bit()); -//! dp.PORTB.portb.write(|w| w.pb6().set_bit()); +//! dp.portb.ddrb().write(|w| w.pb6().clear_bit()); +//! dp.portb.portb().write(|w| w.pb6().set_bit()); //! // Read bit 6 of pin B: -//! let _mybit = dp.PORTB.pinb.read().pb6().bit_is_set(); +//! let _mybit = dp.portb.pinb().read().pb6().bit_is_set(); //! // Read bit 6 and write to bit 5 of port B: -//! dp.PORTB.portb.modify(|r, w| w.pb6().bit(r.pb5().bit_is_set())) +//! dp.portb.portb().modify(|r, w| w.pb6().bit(r.pb5().bit_is_set())) //! ``` //! //! ## Example: Other peripheral register access @@ -168,7 +168,7 @@ //! //! ```ignore //! // Set SPE in SPCR (Enable SPI): -//! dp.SPI.spcr.write(|w| w.spe().set_bit()); +//! dp.spi.spcr().write(|w| w.spe().set_bit()); //! ``` //! //! # Crate feature flags @@ -184,28 +184,35 @@ pub mod asm; pub mod interrupt; -#[allow(unused_imports)] -use generic::*; +pub(crate) use generic::*; #[doc = r"Common register and bit access and modify traits"] -pub mod generic; +pub mod generic { + include!(concat!(env!("OUT_DIR"), "/pac/generic.rs")); +} /// Attribute to declare an interrupt service routine /// /// ``` -/// #[avr_device::interrupt(atmega32u4)] +/// #[avr_device::interrupt] /// fn INT6() { /// // ... /// } /// ``` /// /// # Constraints -/// - The name of the function must be the name of an interrupt. Each chip's +/// - The name of the function must be the name of an interrupt. Each chip's /// module has a `Interrupt` enum defining the available names. -/// - The attribute needs the chip-name to correctly map the interrupt to its -/// vector. This is an unfortunate requirement of the current crate -/// architecture and might change in the future. +/// - Any function-local persistent data (such as any inner `static`s it may +/// have) must come in the beginning, as the macro performs special processing +/// on those to make them safer. /// - The function must have a signature of `[unsafe] fn() [-> !]`. /// - This macro requires the avr-device `rt` crate feature. +/// - The function will not be callable in any way other than as an interrupt +/// routine. It would be unsound to call it anyway, and we need to perform +/// some renaming to conform to the linker's expectations, which prevents that +/// fully. +/// - If more than one MCUs have been selected, the macro must take as an +/// argument which one you mean to attach the interrupt for. #[cfg(feature = "rt")] pub use avr_device_macros::interrupt; @@ -225,6 +232,10 @@ pub use avr_device_macros::interrupt; /// # Constraints /// - The entry function must have a signature of `[unsafe] fn() -> !`. /// - This macro requires the avr-device `rt` crate feature. +/// - The function will not be callable in any way other than as the entrypoint. +/// It would be unsound to call it again anyway, and we need to perform some +/// renaming to conform to the linker's expectations, which prevents that +/// fully. #[cfg(feature = "rt")] pub use avr_device_macros::entry; @@ -288,6 +299,8 @@ compile_error!( #[allow(non_camel_case_types, unused_attributes, unreachable_patterns)] mod devices; +include!(concat!(env!("OUT_DIR"), "/pac/vector.rs")); + #[cfg(feature = "at90usb1286")] pub use crate::devices::at90usb1286; #[cfg(feature = "atmega1280")] @@ -308,6 +321,10 @@ pub use crate::devices::atmega168; pub use crate::devices::atmega16u2; #[cfg(feature = "atmega2560")] pub use crate::devices::atmega2560; +#[cfg(feature = "atmega3208")] +pub use crate::devices::atmega3208; +#[cfg(feature = "atmega3209")] +pub use crate::devices::atmega3209; #[cfg(feature = "atmega324pa")] pub use crate::devices::atmega324pa; #[cfg(feature = "atmega328p")] @@ -320,10 +337,6 @@ pub use crate::devices::atmega32a; pub use crate::devices::atmega32u2; #[cfg(feature = "atmega32u4")] pub use crate::devices::atmega32u4; -#[cfg(feature = "atmega3208")] -pub use crate::devices::atmega3208; -#[cfg(feature = "atmega3209")] -pub use crate::devices::atmega3209; #[cfg(feature = "atmega4808")] pub use crate::devices::atmega4808; #[cfg(feature = "atmega4809")] @@ -390,3 +403,105 @@ pub use crate::devices::attiny88; pub use crate::devices::avr64du28; #[cfg(feature = "avr64du32")] pub use crate::devices::avr64du32; +#[cfg(all(feature = "at90usb1286", single_mcu))] +pub use at90usb1286::Interrupt; +#[cfg(all(feature = "atmega1280", single_mcu))] +pub use atmega1280::Interrupt; +#[cfg(all(feature = "atmega1284p", single_mcu))] +pub use atmega1284p::Interrupt; +#[cfg(all(feature = "atmega128a", single_mcu))] +pub use atmega128a::Interrupt; +#[cfg(all(feature = "atmega128rfa1", single_mcu))] +pub use atmega128rfa1::Interrupt; +#[cfg(all(feature = "atmega16", single_mcu))] +pub use atmega16::Interrupt; +#[cfg(all(feature = "atmega164pa", single_mcu))] +pub use atmega164pa::Interrupt; +#[cfg(all(feature = "atmega168", single_mcu))] +pub use atmega168::Interrupt; +#[cfg(all(feature = "atmega16u2", single_mcu))] +pub use atmega16u2::Interrupt; +#[cfg(all(feature = "atmega2560", single_mcu))] +pub use atmega2560::Interrupt; +#[cfg(all(feature = "atmega3208", single_mcu))] +pub use atmega3208::Interrupt; +#[cfg(all(feature = "atmega3209", single_mcu))] +pub use atmega3209::Interrupt; +#[cfg(all(feature = "atmega324pa", single_mcu))] +pub use atmega324pa::Interrupt; +#[cfg(all(feature = "atmega328p", single_mcu))] +pub use atmega328p::Interrupt; +#[cfg(all(feature = "atmega328pb", single_mcu))] +pub use atmega328pb::Interrupt; +#[cfg(all(feature = "atmega32a", single_mcu))] +pub use atmega32a::Interrupt; +#[cfg(all(feature = "atmega32u2", single_mcu))] +pub use atmega32u2::Interrupt; +#[cfg(all(feature = "atmega32u4", single_mcu))] +pub use atmega32u4::Interrupt; +#[cfg(all(feature = "atmega4808", single_mcu))] +pub use atmega4808::Interrupt; +#[cfg(all(feature = "atmega4809", single_mcu))] +pub use atmega4809::Interrupt; +#[cfg(all(feature = "atmega48p", single_mcu))] +pub use atmega48p::Interrupt; +#[cfg(all(feature = "atmega64", single_mcu))] +pub use atmega64::Interrupt; +#[cfg(all(feature = "atmega644", single_mcu))] +pub use atmega644::Interrupt; +#[cfg(all(feature = "atmega8", single_mcu))] +pub use atmega8::Interrupt; +#[cfg(all(feature = "atmega88p", single_mcu))] +pub use atmega88p::Interrupt; +#[cfg(all(feature = "atmega8u2", single_mcu))] +pub use atmega8u2::Interrupt; +#[cfg(all(feature = "attiny13a", single_mcu))] +pub use attiny13a::Interrupt; +#[cfg(all(feature = "attiny1614", single_mcu))] +pub use attiny1614::Interrupt; +#[cfg(all(feature = "attiny167", single_mcu))] +pub use attiny167::Interrupt; +#[cfg(all(feature = "attiny202", single_mcu))] +pub use attiny202::Interrupt; +#[cfg(all(feature = "attiny212", single_mcu))] +pub use attiny212::Interrupt; +#[cfg(all(feature = "attiny214", single_mcu))] +pub use attiny214::Interrupt; +#[cfg(all(feature = "attiny2313", single_mcu))] +pub use attiny2313::Interrupt; +#[cfg(all(feature = "attiny2313a", single_mcu))] +pub use attiny2313a::Interrupt; +#[cfg(all(feature = "attiny26", single_mcu))] +pub use attiny26::Interrupt; +#[cfg(all(feature = "attiny402", single_mcu))] +pub use attiny402::Interrupt; +#[cfg(all(feature = "attiny404", single_mcu))] +pub use attiny404::Interrupt; +#[cfg(all(feature = "attiny412", single_mcu))] +pub use attiny412::Interrupt; +#[cfg(all(feature = "attiny414", single_mcu))] +pub use attiny414::Interrupt; +#[cfg(all(feature = "attiny416", single_mcu))] +pub use attiny416::Interrupt; +#[cfg(all(feature = "attiny44a", single_mcu))] +pub use attiny44a::Interrupt; +#[cfg(all(feature = "attiny816", single_mcu))] +pub use attiny816::Interrupt; +#[cfg(all(feature = "attiny828", single_mcu))] +pub use attiny828::Interrupt; +#[cfg(all(feature = "attiny84", single_mcu))] +pub use attiny84::Interrupt; +#[cfg(all(feature = "attiny841", single_mcu))] +pub use attiny841::Interrupt; +#[cfg(all(feature = "attiny84a", single_mcu))] +pub use attiny84a::Interrupt; +#[cfg(all(feature = "attiny85", single_mcu))] +pub use attiny85::Interrupt; +#[cfg(all(feature = "attiny861", single_mcu))] +pub use attiny861::Interrupt; +#[cfg(all(feature = "attiny88", single_mcu))] +pub use attiny88::Interrupt; +#[cfg(all(feature = "avr64du28", single_mcu))] +pub use avr64du28::Interrupt; +#[cfg(all(feature = "avr64du32", single_mcu))] +pub use avr64du32::Interrupt;