diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ebf92dd9..0167a259 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,13 @@ jobs: TARGET: x86_64-unknown-linux-gnu TRAVIS_OS_NAME: linux + # Use nightly for architectures which don't support stable + - rust: nightly + experimental: true + VENDOR: Espressif + TARGET: x86_64-unknown-linux-gnu + TRAVIS_OS_NAME: linux + # OSX - rust: stable TARGET: x86_64-apple-darwin diff --git a/ci/script.sh b/ci/script.sh old mode 100644 new mode 100755 index ccb1f55f..b9c4ed03 --- a/ci/script.sh +++ b/ci/script.sh @@ -692,6 +692,17 @@ main() { # OK test_svd M061 ;; + + Espressif) + echo '[dependencies.bare-metal]' >> $td/Cargo.toml + echo 'version = "0.2.0"' >> $td/Cargo.toml + + echo '[dependencies.xtensa-lx6-rt]' >> $td/Cargo.toml + echo 'git = "https://github.com/esp-rs/xtensa-lx6-rt.git"' >> $td/Cargo.toml + + test_svd_for_target esp32 https://raw.githubusercontent.com/arjanmels/esp32/add-output-svd/svd/esp32.svd + ;; + esac rm -rf $td diff --git a/ci/svd2rust-regress/README.md b/ci/svd2rust-regress/README.md index 2491265c..7c423973 100644 --- a/ci/svd2rust-regress/README.md +++ b/ci/svd2rust-regress/README.md @@ -60,8 +60,7 @@ FLAGS: OPTIONS: -a, --architecture - Filter by architecture, case sensitive, may be combined with other filters Options are: "CortexM", "RiscV", - and "Msp430" + Filter by architecture, case sensitive, may be combined with other filters Options are: "CortexM", "RiscV", "Msp430" and "ESP32" -p, --svd2rust-path Path to an `svd2rust` binary, relative or absolute. Defaults to `target/release/svd2rust[.exe]` of this repository (which must be already built) diff --git a/ci/svd2rust-regress/src/svd_test.rs b/ci/svd2rust-regress/src/svd_test.rs index 90d81730..f5b0bc7c 100644 --- a/ci/svd2rust-regress/src/svd_test.rs +++ b/ci/svd2rust-regress/src/svd_test.rs @@ -10,6 +10,8 @@ static CRATES_ALL: &[&str] = &["bare-metal = \"0.2.0\"", "vcell = \"0.1.0\""]; static CRATES_MSP430: &[&str] = &["msp430 = \"0.1.0\""]; static CRATES_CORTEX_M: &[&str] = &["cortex-m = \"0.5.0\"", "cortex-m-rt = \"0.5.0\""]; static CRATES_RISCV: &[&str] = &["riscv = \"0.4.0\"", "riscv-rt = \"0.4.0\""]; +static CRATES_ESP32: &[&str] = + &["xtensa-lx6-rt = {git=\"https://github.com/esp-rs/xtensa-lx6-rt\"}"]; static PROFILE_ALL: &[&str] = &["[profile.dev]", "incremental = false"]; static FEATURES_ALL: &[&str] = &["[features]"]; static FEATURES_CORTEX_M: &[&str] = @@ -133,6 +135,7 @@ pub fn test( CortexM => CRATES_CORTEX_M.iter(), RiscV => CRATES_RISCV.iter(), Msp430 => CRATES_MSP430.iter(), + ESP32 => CRATES_ESP32.iter(), }) .chain(PROFILE_ALL.iter()) .chain(FEATURES_ALL.iter()) @@ -165,6 +168,7 @@ pub fn test( CortexM => "cortex-m", Msp430 => "msp430", RiscV => "riscv", + ESP32 => "esp32", }; let mut svd2rust_bin = Command::new(bin_path); if nightly { @@ -180,14 +184,15 @@ pub fn test( output.capture_outputs( true, "svd2rust", - Some(&lib_rs_file).filter(|_| (t.arch != CortexM) && (t.arch != Msp430)), + Some(&lib_rs_file) + .filter(|_| (t.arch != CortexM) && (t.arch != Msp430) && (t.arch != ESP32)), Some(&svd2rust_err_file), &[], )?; process_stderr_paths.push(svd2rust_err_file); match t.arch { - CortexM | Msp430 => { + CortexM | Msp430 | ESP32 => { // TODO: Give error the path to stderr fs::rename(path_helper_base(&chip_dir, &["lib.rs"]), &lib_rs_file) .chain_err(|| "While moving lib.rs file")? diff --git a/ci/svd2rust-regress/src/tests.rs b/ci/svd2rust-regress/src/tests.rs index cd170942..f018db02 100644 --- a/ci/svd2rust-regress/src/tests.rs +++ b/ci/svd2rust-regress/src/tests.rs @@ -7,6 +7,7 @@ pub enum Architecture { CortexM, Msp430, RiscV, + ESP32, } #[derive(Debug)] @@ -24,6 +25,7 @@ pub enum Manufacturer { Toshiba, SiFive, TexasInstruments, + Espressif, } #[derive(Debug)] @@ -4226,4 +4228,14 @@ pub const TESTS: &[&TestCase] = &[ should_pass: true, run_when: Always, }, + &TestCase { + arch: ESP32, + mfgr: Espressif, + chip: "esp32", + svd_url: Some( + "https://raw.githubusercontent.com/arjanmels/esp32/add-output-svd/svd/esp32.svd", + ), + should_pass: true, + run_when: Always, + }, ]; diff --git a/src/generate/device.rs b/src/generate/device.rs index e4dd4ae4..c67a51af 100644 --- a/src/generate/device.rs +++ b/src/generate/device.rs @@ -97,6 +97,11 @@ pub fn render( extern crate riscv_rt; }); } + Target::ESP32 => { + out.extend(quote! { + extern crate xtensa_lx6_rt; + }); + } Target::None => {} } @@ -226,6 +231,7 @@ pub fn render( Target::CortexM => Some(Ident::new("cortex_m", span)), Target::Msp430 => Some(Ident::new("msp430", span)), Target::RISCV => Some(Ident::new("riscv", span)), + Target::ESP32 => Some(Ident::new("xtensa_lx6_rt", span)), Target::None => None, } .map(|krate| { diff --git a/src/generate/interrupt.rs b/src/generate/interrupt.rs index 56be1826..bf036008 100644 --- a/src/generate/interrupt.rs +++ b/src/generate/interrupt.rs @@ -125,6 +125,30 @@ pub fn render( }); } Target::RISCV => {} + Target::ESP32 => { + for name in &names { + writeln!(device_x, "PROVIDE({} = DefaultHandler);", name)?; + } + + root.extend(quote! { + #[cfg(feature = "rt")] + extern "C" { + #(fn #names();)* + } + + #[doc(hidden)] + pub union Vector { + pub _handler: unsafe extern "C" fn(), + _reserved: u32, + } + + #[cfg(feature = "rt")] + #[doc(hidden)] + pub static __INTERRUPTS: [Vector; #n] = [ + #elements + ]; + }); + } Target::None => {} } @@ -137,7 +161,7 @@ pub fn render( let interrupt_enum = quote! { ///Enumeration of all the interrupts - #[derive(Copy, Clone, Debug)] + #[derive(Copy, Clone, Debug, PartialEq, Eq)] #enum_repr pub enum Interrupt { #variants @@ -178,7 +202,7 @@ pub fn render( _ => "C", }; - if target != Target::CortexM && target != Target::Msp430 { + if target != Target::CortexM && target != Target::Msp430 && target != Target::ESP32 { mod_items.extend(quote! { #[cfg(feature = "rt")] #[macro_export] diff --git a/src/lib.rs b/src/lib.rs index d3b0250a..854eb39b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,9 +18,9 @@ //! //! # Usage //! -//! `svd2rust` supports Cortex-M, MSP430 and RISCV microcontrollers. The generated crate can be -//! tailored for either architecture using the `--target` flag. The flag accepts "cortex-m", -//! "msp430", "riscv" and "none" as values. "none" can be used to generate a crate that's +//! `svd2rust` supports Cortex-M, MSP430, RISCV and ESP32 microcontrollers. The generated crate can +//! be tailored for either architecture using the `--target` flag. The flag accepts "cortex-m", +//! "msp430", "riscv", "esp32" and "none" as values. "none" can be used to generate a crate that's //! architecture agnostic and that should work for architectures that `svd2rust` doesn't currently //! know about like the Cortex-A architecture. //! diff --git a/src/main.rs b/src/main.rs index b0afc532..e74e28d8 100755 --- a/src/main.rs +++ b/src/main.rs @@ -103,7 +103,7 @@ fn run() -> Result<()> { file.write_all(data.as_ref()) .expect("Could not write code to lib.rs"); - if target == Target::CortexM || target == Target::Msp430 { + if target == Target::CortexM || target == Target::Msp430 || target == Target::ESP32 { writeln!(File::create("device.x")?, "{}", device_x)?; writeln!(File::create("build.rs")?, "{}", build_rs())?; } diff --git a/src/util.rs b/src/util.rs index 638cd92a..d5716583 100644 --- a/src/util.rs +++ b/src/util.rs @@ -18,6 +18,7 @@ pub enum Target { CortexM, Msp430, RISCV, + ESP32, None, } @@ -27,6 +28,7 @@ impl Target { "cortex-m" => Target::CortexM, "msp430" => Target::Msp430, "riscv" => Target::RISCV, + "esp32" => Target::ESP32, "none" => Target::None, _ => bail!("unknown target {}", s), })