diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d81ac61..4ce8111 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,50 +15,18 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + # Rust Dependencies - name: Install Stable Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: 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-18 + 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 +41,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,7 +54,7 @@ jobs: - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: nightly-2023-12-28 + toolchain: nightly-2025-01-18 components: rust-src,rustfmt - name: Install AVR gcc, binutils, and libc run: sudo apt-get install -y avr-libc binutils-avr gcc-avr diff --git a/.gitignore b/.gitignore index fede716..0565bba 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,3 @@ /macros/target/ **/*.rs.bk Cargo.lock - -svd/ -.deps/ -src/devices/*/* -src/generic.rs -__pycache__/ diff --git a/Cargo.toml b/Cargo.toml index 08b0bc1..c0d7646 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,10 @@ include = [ "/LICENSE-*", "/README.md", "/build.rs", + "/patch/**/*.yaml", + "/vendor/*.atdf", + "/vendor/LICENSE", + "/examples/**/src/*.rs" ] [package.metadata.docs.rs] @@ -94,3 +98,10 @@ 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"] } 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..d6b736a 100644 --- a/README.md +++ b/README.md @@ -38,48 +38,64 @@ Via the feature you can select which chip you want the register specifications f | | | | | `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 - -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. +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 (it's almost always needed!), the file + can be omitted. +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 [`prettyplease`][] 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 +[`prettyplease`]: https://github.com/dtolnay/prettyplease +[`docs.rs`]: https://docs.rs/avr-device/latest/avr_device ## License *avr-device* is licensed under either of diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..f94921f --- /dev/null +++ b/build.rs @@ -0,0 +1,341 @@ +use std::{ + collections::{BTreeMap, HashSet}, + env, + ffi::OsString, + fs::{self, File}, + io::Write, + path::{Path, PathBuf}, +}; + +#[derive(Clone)] +struct McuInputs { + pub atdf_path: PathBuf, + pub patch_path: PathBuf, +} + +struct GenerationDirs { + pub unpatched_svd: PathBuf, + pub patched_svd: PathBuf, + pub patch: PathBuf, + pub module: PathBuf, +} + +fn main() { + let gen_dirs = match get_create_gen_dirs() { + Ok(d) => d, + Err(e) => { + println!("cargo::error={}", e); + return; + } + }; + + let available_mcus = match setup() { + Ok(d) => d, + Err(e) => { + println!("cargo::error={}", e); + return; + } + }; + + let all_mcus = available_mcus + .keys() + .map(|s| s.to_owned()) + .collect::>(); + let selected_mcus = available_mcus + .into_iter() + .filter(|(mcu, _)| env::var_os(format!("CARGO_FEATURE_{}", mcu.to_uppercase())).is_some()) + .collect::>(); + if selected_mcus.is_empty() { + println!( + "cargo::error=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\ + {}", + all_mcus.join("\n"), + ); + return; + } + + let Ok(generated_mcus) = build_mcu_modules(&gen_dirs, &selected_mcus) else { + return; + }; + + let _ = generate_vector_macro(&gen_dirs, &generated_mcus); +} + +fn get_create_gen_dirs() -> Result { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let svd_dir = out_dir.join("svd"); + let unpatched_svd = svd_dir.join("unpatched"); + let patched_svd = svd_dir.join("patched"); + let patch = out_dir.join("patch"); + let module = out_dir.join("pac"); + + for dir in [&unpatched_svd, &patched_svd, &patch, &module] { + if !dir.is_dir() { + fs::create_dir_all(dir)?; + } + } + + Ok(GenerationDirs { + unpatched_svd, + patched_svd, + patch, + module, + }) +} + +fn track_dir(dir: &Path) -> Result<(), std::io::Error> { + let contents = fs::read_dir(dir)?; + for result in contents { + let entry: std::fs::DirEntry = result?; + let ty = entry.file_type()?; + let path = entry.path(); + if ty.is_file() { + println!("cargo::rerun-if-changed={}", path.display()); + } else if ty.is_dir() { + track_dir(&entry.path())?; + } + } + Ok(()) +} + +fn setup() -> Result, std::io::Error> { + let crate_root = env::var_os("CARGO_MANIFEST_DIR").unwrap(); + let packs_dir = Path::new(&crate_root).join("vendor"); + let patches_dir = Path::new(&crate_root).join("patch"); + + track_dir(&patches_dir)?; + + let pack_files = fs::read_dir(&packs_dir)?; + + let mut map = BTreeMap::new(); + for result in pack_files { + let entry = result?; + let atdf_path = entry.path(); + if atdf_path.extension() != Some(&OsString::from("atdf")) { + continue; + } + let mcu_name = atdf_path + .file_stem() + .and_then(|f| f.to_str()) + .expect("ATDF file must be named after its MCU and str-compatible!") + .to_owned(); + let patch_path = patches_dir.join(&mcu_name).with_extension("yaml"); + println!("cargo::rerun-if-changed={}", atdf_path.display()); + map.insert( + mcu_name, + McuInputs { + atdf_path, + patch_path, + }, + ); + } + Ok(map) +} + +fn build_mcu_modules( + gen_dirs: &GenerationDirs, + mcus: &BTreeMap, +) -> Result, ()> { + let mut map = BTreeMap::new(); + for (mcu, inputs) in mcus { + let unpatched_svd_path = gen_dirs.unpatched_svd.join(mcu).with_extension("svd"); + let patched_svd_path = gen_dirs.patched_svd.join(mcu).with_extension("svd"); + let includer_path = gen_dirs.patch.join(mcu).with_extension("yaml"); + let module_path = gen_dirs.module.join(mcu).with_extension("rs"); + + let atdf_reader = File::open(&inputs.atdf_path).unwrap(); + let Ok(atdf_parsed) = atdf2svd::atdf::parse(atdf_reader, &mut HashSet::new()) else { + println!("cargo::error=Failed to parse ATDF for {}!", mcu); + return Err(()); + }; + let unpatched_writer = match File::create(&unpatched_svd_path) { + Ok(w) => w, + Err(e) => { + println!( + "cargo::error=Failed to open unpatched SVD file for {}!\n{}", + mcu, e + ); + return Err(()); + } + }; + match atdf2svd::svd::generate(&atdf_parsed, unpatched_writer) { + Ok(()) => {} + Err(_) => { + println!( + "cargo::error=Failed to generate unpatched SVD file for {}!", + mcu + ); + return Err(()); + } + }; + + // Apply svdtools' patches. + let svd_content; + match inputs.patch_path.try_exists() { + Ok(true) => { + // Point the patch file to our generated svd and apply the patch. + let includer_content = format!( + r#"_svd: {} + +_include: +- {} +"#, + unpatched_svd_path.display(), + inputs.patch_path.display() + ); + let Ok(()) = fs::write(&includer_path, &includer_content) else { + println!("cargo::error=Failed to write includer file for {}!", mcu); + return Err(()); + }; + let Ok(()) = svdtools::patch::process_file( + &includer_path, + Some(&patched_svd_path), + None, + &Default::default(), + ) else { + println!("cargo::error=Failed to patch svd for {}!", mcu); + return Err(()); + }; + + svd_content = fs::read_to_string(&patched_svd_path); + map.insert(mcu.to_owned(), patched_svd_path); + } + Ok(false) => { + // No patching needed, just continue with unpatched. + svd_content = fs::read_to_string(&unpatched_svd_path); + map.insert(mcu.to_owned(), unpatched_svd_path); + } + Err(e) => { + println!( + "cargo::error=Failed to check patch existence for {}!\n{}", + mcu, e + ); + return Err(()); + } + } + let svd_content = match svd_content { + Ok(c) => c, + Err(e) => { + println!( + "cargo::error=Failed to read patched SVD back for {}!\n{}", + mcu, e + ); + return Err(()); + } + }; + // Apply svd2rust. + 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.strict = true; + svd2rust_config.output_dir = Some(gen_dirs.module.clone()); + svd2rust_config.skip_crate_attributes = true; + let generated = match svd2rust::generate(&svd_content, &svd2rust_config) { + Ok(g) => g, + Err(e) => { + println!( + "cargo::error=Failed to generate rust code for {}!\n{}", + mcu, e + ); + return Err(()); + } + }; + + let mut syntax_tree: syn::File = match syn::parse_str(&generated.lib_rs) { + Ok(s) => s, + Err(e) => { + println!("cargo::error=Failed to parse rust code for {}! {}", mcu, e); + return Err(()); + } + }; + syntax_tree.attrs.clear(); + for item in syntax_tree.items.iter_mut() { + { + let syn::Item::Static(statik) = item else { + continue; + }; + if &statik.ident.to_string() != "DEVICE_PERIPHERALS" { + continue; + } + } + *item = syn::parse_quote! {use super::DEVICE_PERIPHERALS;}; + break; + } + + let formatted = prettyplease::unparse(&syntax_tree); + if let Err(e) = fs::write(&module_path, &formatted) { + println!( + "cargo::error=Failed to write module file for {}!\n{}", + mcu, e + ); + return Err(()); + } + } + + Ok(map) +} + +fn generate_vector_macro( + gen_dirs: &GenerationDirs, + mcus: &BTreeMap, +) -> Result<(), ()> { + let mut devices = BTreeMap::new(); + for (mcu, patched_path) in mcus { + let d = match svdtools::common::svd_reader::device(&patched_path) { + Ok(d) => d, + Err(e) => { + println!( + "cargo::error=Failed to parse SVD device for {}!\n{}", + mcu, e + ); + return Err(()); + } + }; + devices.insert(mcu.to_owned(), d); + } + let mut specific_matchers = Vec::new(); + for (mcu, device) in devices { + for p in device.peripherals { + for i in &p.interrupt { + specific_matchers.push(format!( + r#" + (@{0}, {1}, $it:item) => {{ + #[export_name = "__vector_{2}"] + $it + }};"#, + mcu, i.name, i.value, + )); + } + } + } + + let mut file_handle = match File::create(&gen_dirs.module.join("vector.rs")) { + Ok(h) => h, + Err(e) => { + println!("cargo::error=Failed to create vector file!\n{}", e); + return Err(()); + } + }; + match 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), ".")); + }} +}} +"#, + specific_matchers.concat(), + ) { + Ok(()) => Ok(()), + Err(e) => { + println!("cargo::error=Failed to write vector file!\n{}", e); + Err(()) + } + } +} diff --git a/examples/atmega328p/Cargo.toml b/examples/atmega328p/Cargo.toml index b9a532e..5380f85 100644 --- a/examples/atmega328p/Cargo.toml +++ b/examples/atmega328p/Cargo.toml @@ -18,11 +18,11 @@ embedded-hal = "0.2.3" [dependencies.avr-device] -version = "0.5.3" +version = "0.7.0" # 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"] +path = "../.." +features = ["atmega328p", "rt", "critical-section-impl"] # Configure the build for minimal size - AVRs have very little program memory [profile.dev] diff --git a/examples/atmega328p/src/main.rs b/examples/atmega328p/src/main.rs index 147b7e7..8bc8472 100644 --- a/examples/atmega328p/src/main.rs +++ b/examples/atmega328p/src/main.rs @@ -26,9 +26,9 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { 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()); } } @@ -59,14 +59,14 @@ fn main() -> ! { // 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 +82,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..80167e9 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,9 +1,9 @@ -// 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; #[proc_macro_attribute] @@ -83,7 +83,7 @@ pub fn entry( let expr = &statik.expr; quote::quote! { #(#cfgs)* - { + unsafe { #(#attrs)* static mut #ident: #ty = #expr; &mut #ident @@ -92,6 +92,12 @@ pub fn entry( }) .collect::>(); + if let Err(error) = check_attr_whitelist(&f.attrs, WhiteListCaller::Entry) { + return error; + } + + let (ref cfgs, ref attrs) = extract_cfgs(f.attrs.clone()); + quote::quote! ( #[cfg(not(any(doc, target_arch = "avr")))] compile_error!( @@ -100,6 +106,8 @@ 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() { @@ -125,11 +133,10 @@ pub fn interrupt( let fspan = f.span(); let ident = f.sig.ident.clone(); - let ident_s = ident.to_string(); let chip = if let Some(tree) = args.get(0) { if let proc_macro::TokenTree::Ident(ident) = tree { - ident.to_string() + syn::Ident::new(&ident.to_string(), fspan) } else { return syn::parse::Error::new( proc_macro2::Span::call_site(), @@ -192,12 +199,6 @@ pub fn interrupt( })); 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; - let resource_args = statics .iter() .map(|statik| { @@ -207,7 +208,7 @@ pub fn interrupt( let expr = &statik.expr; quote::quote! { #(#cfgs)* - { + unsafe { #(#attrs)* static mut #ident: #ty = #expr; &mut #ident @@ -216,32 +217,30 @@ 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( + let (ref cfgs, ref attrs) = extract_cfgs(f.attrs.clone()); + + let tramp_ident = syn::Ident::new( + &format!("{}_trampoline", f.sig.ident), + proc_macro2::Span::call_site(), + ); + let interrupt_ident = &f.sig.ident; + + quote::quote! { + #(#cfgs)* + #(#attrs)* + ::avr_device::__avr_device_trampoline!(@#chip, #ident, pub extern "avr-interrupt" fn #tramp_ident() { + #[allow(static_mut_refs)] + #interrupt_ident( #(#resource_args),* ) - } + }); - #[doc(hidden)] #f - ) + } .into() } @@ -298,6 +297,46 @@ fn extract_cfgs(attrs: Vec) -> (Vec, Vec Result<(), proc_macro::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(syn::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..8a0a923 100644 --- a/patch/at90usb1286.yaml +++ b/patch/at90usb1286.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/at90usb1286.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega1280.yaml b/patch/atmega1280.yaml index d66b208..9c6cafa 100644 --- a/patch/atmega1280.yaml +++ b/patch/atmega1280.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega1280.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega1284p.yaml b/patch/atmega1284p.yaml index fea3f1f..5f44c5b 100644 --- a/patch/atmega1284p.yaml +++ b/patch/atmega1284p.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega1284p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega128a.yaml b/patch/atmega128a.yaml index 396a7c7..1693f4b 100644 --- a/patch/atmega128a.yaml +++ b/patch/atmega128a.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega128a.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega128rfa1.yaml b/patch/atmega128rfa1.yaml index c976d43..204b7a2 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 diff --git a/patch/atmega16.yaml b/patch/atmega16.yaml index e355e29..c417a0e 100644 --- a/patch/atmega16.yaml +++ b/patch/atmega16.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega16.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega164pa.yaml b/patch/atmega164pa.yaml index 8f144db..e056269 100644 --- a/patch/atmega164pa.yaml +++ b/patch/atmega164pa.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega164pa.svd - _include: - "common/adc.yaml" - "common/twi.yaml" diff --git a/patch/atmega168.yaml b/patch/atmega168.yaml index ef8f6a6..5dca314 100644 --- a/patch/atmega168.yaml +++ b/patch/atmega168.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega168.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega16u2.yaml b/patch/atmega16u2.yaml index 909ac37..522c3d9 100644 --- a/patch/atmega16u2.yaml +++ b/patch/atmega16u2.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega16u2.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" diff --git a/patch/atmega2560.yaml b/patch/atmega2560.yaml index d10b31d..9c6cafa 100644 --- a/patch/atmega2560.yaml +++ b/patch/atmega2560.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega2560.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega3208.yaml b/patch/atmega3208.yaml index 519e2ab..38516f0 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 diff --git a/patch/atmega3209.yaml b/patch/atmega3209.yaml index 1de62ab..38516f0 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 diff --git a/patch/atmega324pa.yaml b/patch/atmega324pa.yaml index 7e14d14..e86b941 100644 --- a/patch/atmega324pa.yaml +++ b/patch/atmega324pa.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega324pa.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega328p.yaml b/patch/atmega328p.yaml index 9ae1eff..1f9930e 100644 --- a/patch/atmega328p.yaml +++ b/patch/atmega328p.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega328p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega328pb.yaml b/patch/atmega328pb.yaml index db9c1d2..dfddec3 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: diff --git a/patch/atmega32a.yaml b/patch/atmega32a.yaml index 5ea17c1..6b2be31 100644 --- a/patch/atmega32a.yaml +++ b/patch/atmega32a.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega32a.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega32u2.yaml b/patch/atmega32u2.yaml index 77cd2c2..522c3d9 100644 --- a/patch/atmega32u2.yaml +++ b/patch/atmega32u2.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega32u2.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" diff --git a/patch/atmega32u4.yaml b/patch/atmega32u4.yaml index 33fed85..533d1f5 100644 --- a/patch/atmega32u4.yaml +++ b/patch/atmega32u4.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega32u4.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega4808.yaml b/patch/atmega4808.yaml index f85d3cf..38516f0 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 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..5dca314 100644 --- a/patch/atmega48p.yaml +++ b/patch/atmega48p.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega48p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega64.yaml b/patch/atmega64.yaml index f010c54..38f73fa 100644 --- a/patch/atmega64.yaml +++ b/patch/atmega64.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega64.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega644.yaml b/patch/atmega644.yaml index 84843bc..5dca314 100644 --- a/patch/atmega644.yaml +++ b/patch/atmega644.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega644.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega8.yaml b/patch/atmega8.yaml index 6d04778..7ef3bc5 100644 --- a/patch/atmega8.yaml +++ b/patch/atmega8.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega8.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega88p.yaml b/patch/atmega88p.yaml index b0ed252..5dca314 100644 --- a/patch/atmega88p.yaml +++ b/patch/atmega88p.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega88p.svd - _include: - "common/ac.yaml" - "common/adc.yaml" diff --git a/patch/atmega8u2.yaml b/patch/atmega8u2.yaml index 7209b7f..ea8cdad 100644 --- a/patch/atmega8u2.yaml +++ b/patch/atmega8u2.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/atmega8u2.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" diff --git a/patch/attiny13a.yaml b/patch/attiny13a.yaml index fed06be..a6231f9 100644 --- a/patch/attiny13a.yaml +++ b/patch/attiny13a.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny13a.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" 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..5490df0 100644 --- a/patch/attiny167.yaml +++ b/patch/attiny167.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny167.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" 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.yaml b/patch/attiny2313.yaml index 4fa3c69..6845164 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" diff --git a/patch/attiny2313a.yaml b/patch/attiny2313a.yaml index e5f545f..3c13fe6 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" 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..479155f 100644 --- a/patch/attiny828.yaml +++ b/patch/attiny828.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny828.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" diff --git a/patch/attiny84.yaml b/patch/attiny84.yaml index d48b8ea..8f99413 100644 --- a/patch/attiny84.yaml +++ b/patch/attiny84.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny84.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" diff --git a/patch/attiny841.yaml b/patch/attiny841.yaml index 7029367..0be7d70 100644 --- a/patch/attiny841.yaml +++ b/patch/attiny841.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny841.svd - _include: - "common/ac.yaml" - "common/spi.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..7d689de 100644 --- a/patch/attiny85.yaml +++ b/patch/attiny85.yaml @@ -1,5 +1,3 @@ -_svd: ../svd/attiny85.svd - _include: - "common/ac.yaml" - "common/eeprom.yaml" 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/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/src/devices/mod.rs b/src/devices.rs similarity index 55% rename from src/devices/mod.rs rename to src/devices.rs index 6d5b538..089069a 100644 --- a/src/devices/mod.rs +++ b/src/devices.rs @@ -5,204 +5,306 @@ pub(crate) 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..d5585b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -184,10 +184,11 @@ 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 /// @@ -288,6 +289,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")]