diff --git a/Cargo.toml b/Cargo.toml index 9babd2a7c4a771cb72b4e15897120d4d5aa2a170..33da0ba72ad3e940ed3ee03df21f763774ef6d28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,12 @@ edition = "2021" base-address = "0.0.0" volatile-register = "0.2.1" embedded-hal = "1.0.0-alpha.10" + +[dev-dependencies] +panic-halt = "0.2.0" + +[dev-dependencies.bl-rom-rt] +git = "https://gitee.com/rustsbi/bl-rom-rt" +branch = "main" +default-features = false +features = ["bl808-d0"] diff --git a/build.rs b/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..3509edb78b16f69c40351e7e21ee482e492753bc --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rustc-link-arg=-Tbl-rom-rt.ld"); +} diff --git a/examples/jtag-bl808-d0.rs b/examples/jtag-bl808-d0.rs new file mode 100644 index 0000000000000000000000000000000000000000..c70da9d3b6e5e72a6224bd8428c16a20d27b053a --- /dev/null +++ b/examples/jtag-bl808-d0.rs @@ -0,0 +1,34 @@ +// Build this example with: +// rustup target install riscv64imac-unknown-none-elf +// cargo build --example jtag-bl808-d0 --target riscv64imac-unknown-none-elf --release + +#![no_std] +#![no_main] + +use base_address::Static; +use bl_rom_rt::entry; +use bl_soc::gpio::Pins; +use embedded_hal::digital::OutputPin; +use panic_halt as _; + +#[entry] +fn main() -> ! { + let gpio: Pins> = unsafe { core::mem::transmute(()) }; + // enable jtag + gpio.io0.into_jtag_d0(); + gpio.io1.into_jtag_d0(); + gpio.io2.into_jtag_d0(); + gpio.io3.into_jtag_d0(); + + let mut led = gpio.io8.into_floating_output(); + loop { + led.set_low().ok(); + for _ in 0..100_000 { + unsafe { core::arch::asm!("nop") } + } + led.set_high().ok(); + for _ in 0..100_000 { + unsafe { core::arch::asm!("nop") } + } + } +} diff --git a/src/glb.rs b/src/glb.rs index e02598079b0c1dd1bbef92f99d67ac616ef4753f..53708f922eba7ab043015bd863380e28a70eec04 100644 --- a/src/glb.rs +++ b/src/glb.rs @@ -253,6 +253,8 @@ impl GpioConfig { pub const fn set_pull(self, val: Pull) -> Self { Self((self.0 & !Self::PULL) | ((val as u32) << 4)) } + /// Reset value of GPIO_CONFIG register. + pub(crate) const RESET_VALUE: Self = Self(0x0040_0b02); } /// Pin drive strength. diff --git a/src/gpio.rs b/src/gpio.rs index 01b1a79a2314f01a20cdbf878efdc7e6fd3d815c..c1ccea8cf23b16f7966790ddd17f41c55ef50f47 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -9,8 +9,8 @@ use embedded_hal::digital::{ErrorType, InputPin, OutputPin}; /// Individual GPIO pin. pub struct Pin { - base: GLB, - _mode: PhantomData, + pub(crate) base: GLB, + pub(crate) _mode: PhantomData, } /// Alternate type state. @@ -249,7 +249,18 @@ impl Pin { /// Available GPIO pins. pub struct Pins { + // GPIO I/O 0. + pub io0: Pin, + // GPIO I/O 1. + pub io1: Pin, + // GPIO I/O 2. + pub io2: Pin, + // GPIO I/O 3. + pub io3: Pin, + // GPIO I/O 8. pub io8: Pin, + // GPIO I/O 22. pub io22: Pin, + // GPIO I/O 23. pub io23: Pin, } diff --git a/src/jtag.rs b/src/jtag.rs new file mode 100644 index 0000000000000000000000000000000000000000..2a6c242cfa62c9a5037388f2dfc7eb49539ca50d --- /dev/null +++ b/src/jtag.rs @@ -0,0 +1,70 @@ +//! JTAG interface feature support. + +use crate::{ + glb::{Drive, Function, GpioConfig, Pull}, + gpio::{Alternate, Pin}, +}; +use base_address::BaseAddress; +use core::marker::PhantomData; + +/// D0 core JTAG mode (type state). +pub struct JtagD0; + +/// M0 core JTAG mode (type state). +pub struct JtagM0; + +/// LP core JTAG mode (type state). +pub struct JtagLp; + +impl Alternate for JtagD0 { + const F: Function = Function::JtagD0; +} + +impl Alternate for JtagM0 { + const F: Function = Function::JtagM0; +} + +impl Alternate for JtagLp { + const F: Function = Function::JtagLp; +} + +// requires to set `.set_function(Function::JtagXx)` before use. +const JTAG_GPIO_CONFIG: GpioConfig = GpioConfig::RESET_VALUE + .enable_input() + .disable_output() + .enable_schmitt() + .set_drive(Drive::Drive0) + .set_pull(Pull::None); + +impl Pin { + /// Configures the pin to operate as D0 core JTAG. + #[inline] + pub fn into_jtag_d0(self) -> Pin { + let config = JTAG_GPIO_CONFIG.set_function(Function::JtagD0); + self.base.gpio_config[N].write(config); + Pin { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as M0 core JTAG. + #[inline] + pub fn into_jtag_m0(self) -> Pin { + let config = JTAG_GPIO_CONFIG.set_function(Function::JtagM0); + self.base.gpio_config[N].write(config); + Pin { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as LP core JTAG. + #[inline] + pub fn into_jtag_lp(self) -> Pin { + let config = JTAG_GPIO_CONFIG.set_function(Function::JtagLp); + self.base.gpio_config[N].write(config); + Pin { + base: self.base, + _mode: PhantomData, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 0e0f958fe11fa2e0a93670573069a00702cdd358..77a6bc9b43b097ba02edefba716cfddbf26a0544 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ use core::ops; pub mod glb; pub mod gpio; +pub mod jtag; /// Global register. pub struct GLB {