diff --git a/bouffalo-hal/src/glb/mod.rs b/bouffalo-hal/src/glb/mod.rs index 8d13c48..8ab87f8 100644 --- a/bouffalo-hal/src/glb/mod.rs +++ b/bouffalo-hal/src/glb/mod.rs @@ -29,3 +29,14 @@ pub enum Drive { /// Drive strength 3. Drive3 = 3, } + +cfg_if::cfg_if! { + if #[cfg(feature = "glb-v1")] { + pub use v1::RegisterBlock; + } else if #[cfg(feature = "glb-v2")] { + pub use v2::RegisterBlock; + } else { + /// Global configuration registers. + pub struct RegisterBlock {} + } +} diff --git a/bouffalo-hal/src/gpio.rs b/bouffalo-hal/src/gpio.rs index b165b23..656be1d 100644 --- a/bouffalo-hal/src/gpio.rs +++ b/bouffalo-hal/src/gpio.rs @@ -1,26 +1,27 @@ //! General Purpose Input/Output. +mod pad_dummy; +mod pad_v1; +mod pad_v2; mod typestate; -#[cfg(feature = "glb-v1")] -use crate::glb::v1; -#[cfg(any(doc, feature = "glb-v2"))] -use crate::glb::v2; -use crate::glb::{Drive, Pull}; -use core::{marker::PhantomData, ops::Deref}; +pub use typestate::*; +pub use {pad_v1::Padv1, pad_v2::Padv2}; + +use crate::glb::{self, Drive}; +use core::ops::Deref; use embedded_hal::digital::{ErrorType, InputPin, OutputPin}; pub use typestate::Alternate; -use typestate::{Disabled, Floating, Input, Output, PullDown, PullUp, Sdh}; -pub use typestate::{I2c, JtagD0, JtagLp, JtagM0, MmUart, Pwm, Spi, Uart}; -#[cfg(feature = "glb-v1")] -pub use crate::glb::v1::RegisterBlock as GlbRegisterBlock; -#[cfg(any(doc, feature = "glb-v2"))] -pub use crate::glb::v2::RegisterBlock as GlbRegisterBlock; -#[cfg(not(any(doc, feature = "glb-v1", feature = "glb-v2")))] -pub struct GlbRegisterBlock {} +cfg_if::cfg_if! { + if #[cfg(feature = "glb-v1")] { + pub use crate::glb::v1; + } else if #[cfg(feature = "glb-v2")] { + pub use crate::glb::v2; + } +} -/// Individual GPIO pin. +/// Individual GPIO pad. /// /// Generic Purpose Input/Output, or GPIO, is a standard interface used to connect the /// microcontroller to external hardware. There are multiple GPIO pads on one chip, @@ -49,7 +50,7 @@ pub struct GlbRegisterBlock {} /// # pub struct Peripherals { gpio: Pads } /// # pub struct GLBv2; /// # impl core::ops::Deref for GLBv2 { -/// # type Target = bouffalo_hal::gpio::GlbRegisterBlock; +/// # type Target = bouffalo_hal::glb::RegisterBlock; /// # fn deref(&self) -> &Self::Target { unimplemented!() } /// # } /// # fn main() -> ! { @@ -102,7 +103,7 @@ pub struct GlbRegisterBlock {} /// # } /// # pub struct GLBv2; /// # impl core::ops::Deref for GLBv2 { -/// # type Target = bouffalo_hal::gpio::GlbRegisterBlock; +/// # type Target = bouffalo_hal::glb::RegisterBlock; /// # fn deref(&self) -> &Self::Target { unimplemented!() } /// # } /// # pub struct UART0; @@ -141,82 +142,45 @@ pub struct GlbRegisterBlock {} /// # } /// ``` pub struct Pad { - #[cfg(any(feature = "glb-v1", feature = "glb-v2"))] - pub(crate) base: GLB, + #[cfg(feature = "glb-v1")] + inner: pad_v1::Padv1, + #[cfg(feature = "glb-v2")] + inner: pad_v2::Padv2, #[cfg(not(any(feature = "glb-v1", feature = "glb-v2")))] - pub(crate) _base_not_implemented: PhantomData, - pub(crate) _mode: PhantomData, + inner: pad_dummy::PadDummy, } -impl, const N: usize, M> ErrorType for Pad> { +impl ErrorType for Pad> { type Error = core::convert::Infallible; } -impl, const N: usize, M> ErrorType - for Pad> -{ +impl ErrorType for Pad> { type Error = core::convert::Infallible; } -impl, const N: usize, M> InputPin for Pad> { +impl, const N: usize, M> InputPin + for Pad> +{ #[inline] fn is_high(&mut self) -> Result { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - Ok(self.base.gpio_input_value.read() & (1 << N) != 0) - } else if #[cfg(feature = "glb-v2")] { - Ok(self.base.gpio_input[N >> 5].read() & (1 << (N & 0x1F)) != 0) - } else { - unimplemented!() - } - } + self.inner.is_high() } #[inline] fn is_low(&mut self) -> Result { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - Ok(self.base.gpio_input_value.read() & (1 << N) == 0) - } else if #[cfg(feature = "glb-v2")] { - Ok(self.base.gpio_input[N >> 5].read() & (1 << (N & 0x1F)) == 0) - } else { - unimplemented!() - } - } + self.inner.is_low() } } -impl, const N: usize, M> OutputPin +impl, const N: usize, M> OutputPin for Pad> { #[inline] fn set_low(&mut self) -> Result<(), Self::Error> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let val = self.base.gpio_output_value.read(); - unsafe { self.base.gpio_output_value.write(val & !(1 << N)) }; - Ok(()) - } else if #[cfg(feature = "glb-v2")] { - unsafe { self.base.gpio_clear[N >> 5].write(1 << (N & 0x1F)) }; - Ok(()) - } else { - unimplemented!() - } - } + self.inner.set_low() } #[inline] fn set_high(&mut self) -> Result<(), Self::Error> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let val = self.base.gpio_output_value.read(); - unsafe { self.base.gpio_output_value.write(val | (1 << N)) }; - Ok(()) - } else if #[cfg(feature = "glb-v2")] { - unsafe { self.base.gpio_set[N >> 5].write(1 << (N & 0x1F)) }; - Ok(()) - } else { - unimplemented!() - } - } + self.inner.set_high() } } @@ -224,7 +188,7 @@ impl, const N: usize, M> OutputPin // ecosystem crates, as some of them depends on embedded-hal v0.2.7 traits. // We encourage ecosystem developers to use embedded-hal v1.0.0 traits; after that, this part of code // would be removed in the future. -impl, const N: usize, M> +impl, const N: usize, M> embedded_hal_027::digital::v2::OutputPin for Pad> { type Error = core::convert::Infallible; @@ -242,543 +206,218 @@ impl, const N: usize, M> // have such functionality to read back the previously set pin state. // It is recommended that users add a variable to store the pin state if necessary; see examples/gpio-demo. -impl, const N: usize, M> Pad> { +impl, const N: usize, M> Pad> { /// Enable schmitt trigger. #[inline] pub fn enable_schmitt(&mut self) { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1].read().enable_schmitt(N & 0x1); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N].read().enable_schmitt(); - unsafe { self.base.gpio_config[N].write(config) }; - } else { - unimplemented!() - } - } + self.inner.enable_schmitt() } /// Disable schmitt trigger. #[inline] pub fn disable_schmitt(&mut self) { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1].read().disable_schmitt(N & 0x1); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N].read().disable_schmitt(); - unsafe { self.base.gpio_config[N].write(config) }; - } else { - unimplemented!() - } - } + self.inner.disable_schmitt() } /// Clear interrupt flag. #[inline] pub fn clear_interrupt(&mut self) { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - unsafe { self.base.gpio_interrupt_clear.write(1 << N) }; - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N].read().clear_interrupt(); - unsafe { self.base.gpio_config[N].write(config) }; - } else { - unimplemented!() - } - } + self.inner.clear_interrupt() } /// Check if interrupt flag is set. #[inline] pub fn has_interrupt(&self) -> bool { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - self.base.gpio_interrupt_state.read() & (1 << N) != 0 - } else if #[cfg(feature = "glb-v2")] { - self.base.gpio_config[N].read().has_interrupt() - } else { - unimplemented!() - } - } + self.inner.has_interrupt() } /// Mask interrupt. #[inline] pub fn mask_interrupt(&mut self) { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_interrupt_mask.read() | (1 << N); - unsafe { self.base.gpio_interrupt_mask.write(config) }; - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N].read().mask_interrupt(); - unsafe { self.base.gpio_config[N].write(config) }; - } else { - unimplemented!() - } - } + self.inner.mask_interrupt() } /// Unmask interrupt. #[inline] pub fn unmask_interrupt(&mut self) { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_interrupt_mask.read() & !(1 << N); - unsafe { self.base.gpio_interrupt_mask.write(config) }; - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N].read().unmask_interrupt(); - unsafe { self.base.gpio_config[N].write(config) }; - } else { - unimplemented!() - } - } + self.inner.unmask_interrupt(); } } -#[cfg(feature = "glb-v1")] -impl, const N: usize, M> Pad> { - /// Get interrupt mode. - #[inline] - pub fn interrupt_mode(&self) -> v1::InterruptMode { - self.base.gpio_interrupt_mode[N >> 1] - .read() - .interrupt_mode(N & 0x1) - } - /// Set interrupt mode. - #[inline] - pub fn set_interrupt_mode(&mut self, val: v1::InterruptMode) { - let config = self.base.gpio_interrupt_mode[N >> 1] - .read() - .set_interrupt_mode(N & 0x1, val); - unsafe { self.base.gpio_interrupt_mode[N >> 1].write(config) }; - } -} - -#[cfg(feature = "glb-v2")] -impl, const N: usize, M> Pad> { - /// Get interrupt mode. - #[inline] - pub fn interrupt_mode(&self) -> v2::InterruptMode { - self.base.gpio_config[N].read().interrupt_mode() - } - /// Set interrupt mode. - #[inline] - pub fn set_interrupt_mode(&mut self, val: v2::InterruptMode) { - let config = self.base.gpio_config[N].read().set_interrupt_mode(val); - unsafe { self.base.gpio_config[N].write(config) }; - } -} - -#[cfg(feature = "glb-v1")] -impl, const N: usize, M> Pad> { +impl, const N: usize, M> Pad> { /// Get drive strength of this pin. #[inline] pub fn drive(&self) -> Drive { - self.base.gpio_config[N >> 1].read().drive(N & 0x1) + self.inner.drive() } /// Set drive strength of this pin. #[inline] pub fn set_drive(&mut self, val: Drive) { - let config = self.base.gpio_config[N >> 1].read().set_drive(N & 0x1, val); - unsafe { self.base.gpio_config[N >> 1].write(config) }; + self.inner.set_drive(val) } } -#[cfg(feature = "glb-v2")] -impl, const N: usize, M> Pad> { - /// Get drive strength of this pin. +#[cfg(feature = "glb-v1")] +impl, const N: usize, M> Pad> { + /// Get interrupt mode. #[inline] - pub fn drive(&self) -> Drive { - self.base.gpio_config[N].read().drive() + pub fn interrupt_mode(&self) -> v1::InterruptMode { + self.inner.interrupt_mode() } - /// Set drive strength of this pin. + /// Set interrupt mode. #[inline] - pub fn set_drive(&mut self, val: Drive) { - let config = self.base.gpio_config[N].read().set_drive(val); - unsafe { self.base.gpio_config[N].write(config) }; + pub fn set_interrupt_mode(&mut self, val: v1::InterruptMode) { + self.inner.set_interrupt_mode(val) } } #[cfg(feature = "glb-v2")] -impl, const N: usize, M: Alternate> Pad { - /// Configures the pin to operate as a SPI pin. +impl, const N: usize, M> Pad> { + /// Get interrupt mode. #[inline] - pub fn into_spi(self) -> Pad> - where - Spi: Alternate, - { - let config = v2::GpioConfig::RESET_VALUE - .enable_input() - .disable_output() - .enable_schmitt() - .set_pull(Pull::Up) - .set_drive(Drive::Drive0) - .set_function(Spi::::F); - unsafe { - self.base.gpio_config[N].write(config); - } - - Pad { - base: self.base, - _mode: PhantomData, - } + pub fn interrupt_mode(&self) -> v2::InterruptMode { + self.inner.interrupt_mode() } -} - -#[cfg(feature = "glb-v2")] -impl, const N: usize, M: Alternate> Pad { - /// Configures the pin to operate as a SDH pin. + /// Set interrupt mode. #[inline] - pub fn into_sdh(self) -> Pad { - let config = v2::GpioConfig::RESET_VALUE - .enable_input() - .disable_output() - .enable_schmitt() - .set_pull(Pull::Up) - .set_drive(Drive::Drive0) - .set_function(Sdh::F); - unsafe { - self.base.gpio_config[N].write(config); - } - - Pad { - base: self.base, - _mode: PhantomData, - } + pub fn set_interrupt_mode(&mut self, val: v2::InterruptMode) { + self.inner.set_interrupt_mode(val) } } -impl, const N: usize, M: Alternate> Pad { +impl, const N: usize, M> Pad { /// Configures the pin to operate as a pull up output pin. #[inline] pub fn into_pull_up_output(self) -> Pad> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1] - .read() - .set_function(N & 0x1, v1::Function::Gpio) - .disable_input(N & 0x1) - .set_pull(N & 0x1, Pull::Up); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - let val = self.base.gpio_output_enable.read(); - unsafe { self.base.gpio_output_enable.write(val | (1 << N)) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N] - .read() - .set_function(v2::Function::Gpio) - .set_mode(v2::Mode::SetClear) - .disable_input() - .enable_output() - .set_pull(Pull::Up); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else { - unimplemented!() - } + Pad { + inner: self.inner.into_pull_up_output(), } } /// Configures the pin to operate as a pull down output pin. #[inline] pub fn into_pull_down_output(self) -> Pad> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1] - .read() - .set_function(N & 0x1, v1::Function::Gpio) - .disable_input(N & 0x1) - .set_pull(N & 0x1, Pull::Down); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - let val = self.base.gpio_output_enable.read(); - unsafe { self.base.gpio_output_enable.write(val | (1 << N)) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N] - .read() - .set_function(v2::Function::Gpio) - .set_mode(v2::Mode::SetClear) - .disable_input() - .enable_output() - .set_pull(Pull::Down); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else { - unimplemented!() - } + Pad { + inner: self.inner.into_pull_down_output(), } } /// Configures the pin to operate as a floating output pin. #[inline] pub fn into_floating_output(self) -> Pad> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1] - .read() - .set_function(N & 0x1, v1::Function::Gpio) - .disable_input(N & 0x1) - .set_pull(N & 0x1, Pull::None); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - let val = self.base.gpio_output_enable.read(); - unsafe { self.base.gpio_output_enable.write(val | (1 << N)) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N] - .read() - .set_function(v2::Function::Gpio) - .set_mode(v2::Mode::SetClear) - .disable_input() - .enable_output() - .set_pull(Pull::None); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else { - unimplemented!() - } + Pad { + inner: self.inner.into_floating_output(), } } /// Configures the pin to operate as a pull up input pin. #[inline] pub fn into_pull_up_input(self) -> Pad> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1] - .read() - .set_function(N & 0x1, v1::Function::Gpio) - .enable_input(N & 0x1) - .set_pull(N & 0x1, Pull::Up); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - let val = self.base.gpio_output_enable.read(); - unsafe { self.base.gpio_output_enable.write(val & !(1 << N)) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N] - .read() - .set_function(v2::Function::Gpio) - .set_mode(v2::Mode::SetClear) - .enable_input() - .disable_output() - .set_pull(Pull::Up); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else { - unimplemented!() - } + Pad { + inner: self.inner.into_pull_up_input(), } } /// Configures the pin to operate as a pull down input pin. #[inline] pub fn into_pull_down_input(self) -> Pad> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1] - .read() - .set_function(N & 0x1, v1::Function::Gpio) - .enable_input(N & 0x1) - .set_pull(N & 0x1, Pull::Down); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - let val = self.base.gpio_output_enable.read(); - unsafe { self.base.gpio_output_enable.write(val & !(1 << N)) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N] - .read() - .set_function(v2::Function::Gpio) - .set_mode(v2::Mode::SetClear) - .enable_input() - .disable_output() - .set_pull(Pull::Down); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else { - unimplemented!() - } + Pad { + inner: self.inner.into_pull_down_input(), } } /// Configures the pin to operate as a floating input pin. #[inline] pub fn into_floating_input(self) -> Pad> { - cfg_if::cfg_if! { - if #[cfg(feature = "glb-v1")] { - let config = self.base.gpio_config[N >> 1] - .read() - .set_function(N & 0x1, v1::Function::Gpio) - .enable_input(N & 0x1) - .set_pull(N & 0x1, Pull::None); - unsafe { self.base.gpio_config[N >> 1].write(config) }; - let val = self.base.gpio_output_enable.read(); - unsafe { self.base.gpio_output_enable.write(val & !(1 << N)) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else if #[cfg(feature = "glb-v2")] { - let config = self.base.gpio_config[N] - .read() - .set_function(v2::Function::Gpio) - .set_mode(v2::Mode::SetClear) - .enable_input() - .disable_output() - .set_pull(Pull::None); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } else { - unimplemented!() - } + Pad { + inner: self.inner.into_floating_input(), } } } +// TODO: #[doc(cfg(feature = "glb-v2"))] once feature(doc_cfg) is stablized #[cfg(any(doc, feature = "glb-v2"))] -const UART_GPIO_CONFIG: v2::GpioConfig = v2::GpioConfig::RESET_VALUE - .enable_input() - .enable_output() - .enable_schmitt() - .set_drive(Drive::Drive0) - .set_pull(Pull::Up) - .set_function(v2::Function::Uart); - -impl, const N: usize, M: Alternate> Pad { +impl, const N: usize, M> Pad { + /// Configures the pin to operate as a SPI pin. + #[inline] + pub fn into_spi(self) -> Pad> + where + Spi: Alternate, + { + Pad { + inner: self.inner.into_spi(), + } + } + /// Configures the pin to operate as a SDH pin. + #[inline] + pub fn into_sdh(self) -> Pad { + Pad { + inner: self.inner.into_sdh(), + } + } /// Configures the pin to operate as UART signal. - #[cfg(any(doc, feature = "glb-v2"))] #[inline] pub fn into_uart(self) -> Pad { - unsafe { self.base.gpio_config[N].write(UART_GPIO_CONFIG) }; Pad { - base: self.base, - _mode: PhantomData, + inner: self.inner.into_uart(), } } -} - -impl, const N: usize, M: Alternate> Pad { /// Configures the pin to operate as multi-media cluster UART signal. - #[cfg(any(doc, feature = "glb-v2"))] #[inline] pub fn into_mm_uart(self) -> Pad { - unsafe { - self.base.gpio_config[N].write(UART_GPIO_CONFIG.set_function(v2::Function::MmUart)) - }; Pad { - base: self.base, - _mode: PhantomData, + inner: self.inner.into_mm_uart(), } } -} - -impl, const N: usize, M: Alternate> Pad { /// Configures the pin to operate as a pull up Pulse Width Modulation signal pin. - #[cfg(any(doc, feature = "glb-v2"))] #[inline] pub fn into_pull_up_pwm(self) -> Pad> where Pwm: Alternate, { - let config = v2::GpioConfig::RESET_VALUE - .disable_input() - .enable_output() - .enable_schmitt() - .set_drive(Drive::Drive0) - .set_pull(Pull::Up) - .set_function(Pwm::::F); - unsafe { self.base.gpio_config[N].write(config) }; Pad { - base: self.base, - _mode: PhantomData, + inner: self.inner.into_pull_up_pwm(), } } /// Configures the pin to operate as a pull down Pulse Width Modulation signal pin. - #[cfg(any(doc, feature = "glb-v2"))] #[inline] pub fn into_pull_down_pwm(self) -> Pad> where Pwm: Alternate, { - let config = v2::GpioConfig::RESET_VALUE - .disable_input() - .enable_output() - .enable_schmitt() - .set_drive(Drive::Drive0) - .set_pull(Pull::Down) - .set_function(Pwm::::F); - unsafe { self.base.gpio_config[N].write(config) }; Pad { - base: self.base, - _mode: PhantomData, + inner: self.inner.into_pull_down_pwm(), } } /// Configures the pin to operate as floating Pulse Width Modulation signal pin. - #[cfg(any(doc, feature = "glb-v2"))] #[inline] pub fn into_floating_pwm(self) -> Pad> where Pwm: Alternate, { - let config = v2::GpioConfig::RESET_VALUE - .disable_input() - .enable_output() - .enable_schmitt() - .set_drive(Drive::Drive0) - .set_pull(Pull::None) - .set_function(Pwm::::F); - unsafe { self.base.gpio_config[N].write(config) }; Pad { - base: self.base, - _mode: PhantomData, + inner: self.inner.into_floating_pwm(), } } -} - -impl, const N: usize, M: Alternate> Pad { /// Configures the pin to operate as an Inter-Integrated Circuit signal pin. - #[cfg(any(doc, feature = "glb-v2"))] #[inline] pub fn into_i2c(self) -> Pad> where I2c: Alternate, { - let config = v2::GpioConfig::RESET_VALUE - .enable_input() - .enable_output() - .enable_schmitt() - .set_drive(Drive::Drive0) - .set_pull(Pull::Up) - .set_function(I2c::::F); - unsafe { - self.base.gpio_config[N].write(config); + Pad { + inner: self.inner.into_i2c(), + } + } + /// Configures the pin to operate as D0 core JTAG. + #[inline] + pub fn into_jtag_d0(self) -> Pad { + Pad { + inner: self.inner.into_jtag_d0(), } + } + /// Configures the pin to operate as M0 core JTAG. + #[inline] + pub fn into_jtag_m0(self) -> Pad { + Pad { + inner: self.inner.into_jtag_m0(), + } + } + /// Configures the pin to operate as LP core JTAG. + #[inline] + pub fn into_jtag_lp(self) -> Pad { Pad { - base: self.base, - _mode: PhantomData, + inner: self.inner.into_jtag_lp(), } } } diff --git a/bouffalo-hal/src/gpio/pad_dummy.rs b/bouffalo-hal/src/gpio/pad_dummy.rs new file mode 100644 index 0000000..817a825 --- /dev/null +++ b/bouffalo-hal/src/gpio/pad_dummy.rs @@ -0,0 +1,104 @@ +#![allow(dead_code)] +use super::typestate::{Floating, Input, Output, PullDown, PullUp}; +use crate::glb::Drive; +use core::marker::PhantomData; +use embedded_hal::digital::{ErrorType, InputPin, OutputPin}; + +pub struct PadDummy { + _unused: PhantomData<(GLB, M)>, +} + +impl PadDummy> { + #[inline] + pub fn enable_schmitt(&mut self) { + unimplemented!() + } + #[inline] + pub fn disable_schmitt(&mut self) { + unimplemented!() + } + #[inline] + pub fn clear_interrupt(&mut self) { + unimplemented!() + } + #[inline] + pub fn has_interrupt(&self) -> bool { + unimplemented!() + } + #[inline] + pub fn mask_interrupt(&mut self) { + unimplemented!() + } + #[inline] + pub fn unmask_interrupt(&mut self) { + unimplemented!() + } +} + +impl PadDummy> { + #[inline] + pub fn drive(&self) -> Drive { + unimplemented!() + } + #[inline] + pub fn set_drive(&mut self, _: Drive) { + unimplemented!() + } +} + +impl PadDummy { + #[inline] + pub fn into_pull_up_output(self) -> PadDummy> { + unimplemented!() + } + #[inline] + pub fn into_pull_down_output(self) -> PadDummy> { + unimplemented!() + } + #[inline] + pub fn into_floating_output(self) -> PadDummy> { + unimplemented!() + } + #[inline] + pub fn into_pull_up_input(self) -> PadDummy> { + unimplemented!() + } + #[inline] + pub fn into_pull_down_input(self) -> PadDummy> { + unimplemented!() + } + #[inline] + pub fn into_floating_input(self) -> PadDummy> { + unimplemented!() + } +} + +impl ErrorType for PadDummy> { + type Error = core::convert::Infallible; +} + +impl ErrorType for PadDummy> { + type Error = core::convert::Infallible; +} + +impl InputPin for PadDummy> { + #[inline] + fn is_high(&mut self) -> Result { + unimplemented!() + } + #[inline] + fn is_low(&mut self) -> Result { + unimplemented!() + } +} + +impl OutputPin for PadDummy> { + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + unimplemented!() + } + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + unimplemented!() + } +} diff --git a/bouffalo-hal/src/gpio/pad_v1.rs b/bouffalo-hal/src/gpio/pad_v1.rs new file mode 100644 index 0000000..9e14485 --- /dev/null +++ b/bouffalo-hal/src/gpio/pad_v1.rs @@ -0,0 +1,222 @@ +use super::typestate::{Floating, Input, Output, PullDown, PullUp}; +use crate::glb::{v1, Drive, Pull}; +use core::{marker::PhantomData, ops::Deref}; +use embedded_hal::digital::{ErrorType, InputPin, OutputPin}; + +/// GPIO pad of BL602 and BL702. +pub struct Padv1 { + base: GLB, + _mode: PhantomData, +} + +impl, const N: usize, M> Padv1> { + /// Enable schmitt trigger. + #[inline] + pub fn enable_schmitt(&mut self) { + let config = self.base.gpio_config[N >> 1].read().enable_schmitt(N & 0x1); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + } + /// Disable schmitt trigger. + #[inline] + pub fn disable_schmitt(&mut self) { + let config = self.base.gpio_config[N >> 1] + .read() + .disable_schmitt(N & 0x1); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + } + /// Clear interrupt flag. + #[inline] + pub fn clear_interrupt(&mut self) { + unsafe { self.base.gpio_interrupt_clear.write(1 << N) }; + } + /// Check if interrupt flag is set. + #[inline] + pub fn has_interrupt(&self) -> bool { + self.base.gpio_interrupt_state.read() & (1 << N) != 0 + } + /// Mask interrupt. + #[inline] + pub fn mask_interrupt(&mut self) { + let config = self.base.gpio_interrupt_mask.read() | (1 << N); + unsafe { self.base.gpio_interrupt_mask.write(config) }; + } + /// Unmask interrupt. + #[inline] + pub fn unmask_interrupt(&mut self) { + let config = self.base.gpio_interrupt_mask.read() & !(1 << N); + unsafe { self.base.gpio_interrupt_mask.write(config) }; + } +} + +impl, const N: usize, M> Padv1> { + /// Get drive strength of this pin. + #[inline] + pub fn drive(&self) -> Drive { + self.base.gpio_config[N >> 1].read().drive(N & 0x1) + } + /// Set drive strength of this pin. + #[inline] + pub fn set_drive(&mut self, val: Drive) { + let config = self.base.gpio_config[N >> 1].read().set_drive(N & 0x1, val); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + } +} + +impl, const N: usize, M> Padv1> { + /// Get interrupt mode. + #[inline] + pub fn interrupt_mode(&self) -> v1::InterruptMode { + self.base.gpio_interrupt_mode[N >> 1] + .read() + .interrupt_mode(N & 0x1) + } + /// Set interrupt mode. + #[inline] + pub fn set_interrupt_mode(&mut self, val: v1::InterruptMode) { + let config = self.base.gpio_interrupt_mode[N >> 1] + .read() + .set_interrupt_mode(N & 0x1, val); + unsafe { self.base.gpio_interrupt_mode[N >> 1].write(config) }; + } +} + +impl, const N: usize, M> Padv1 { + /// Configures the pin to operate as a pull up output pin. + #[inline] + pub fn into_pull_up_output(self) -> Padv1> { + let config = self.base.gpio_config[N >> 1] + .read() + .set_function(N & 0x1, v1::Function::Gpio) + .disable_input(N & 0x1) + .set_pull(N & 0x1, Pull::Up); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + let val = self.base.gpio_output_enable.read(); + unsafe { self.base.gpio_output_enable.write(val | (1 << N)) }; + Padv1 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull down output pin. + #[inline] + pub fn into_pull_down_output(self) -> Padv1> { + let config = self.base.gpio_config[N >> 1] + .read() + .set_function(N & 0x1, v1::Function::Gpio) + .disable_input(N & 0x1) + .set_pull(N & 0x1, Pull::Down); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + let val = self.base.gpio_output_enable.read(); + unsafe { self.base.gpio_output_enable.write(val | (1 << N)) }; + Padv1 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a floating output pin. + #[inline] + pub fn into_floating_output(self) -> Padv1> { + let config = self.base.gpio_config[N >> 1] + .read() + .set_function(N & 0x1, v1::Function::Gpio) + .disable_input(N & 0x1) + .set_pull(N & 0x1, Pull::None); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + let val = self.base.gpio_output_enable.read(); + unsafe { self.base.gpio_output_enable.write(val | (1 << N)) }; + Padv1 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull up input pin. + #[inline] + pub fn into_pull_up_input(self) -> Padv1> { + let config = self.base.gpio_config[N >> 1] + .read() + .set_function(N & 0x1, v1::Function::Gpio) + .enable_input(N & 0x1) + .set_pull(N & 0x1, Pull::Up); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + let val = self.base.gpio_output_enable.read(); + unsafe { self.base.gpio_output_enable.write(val & !(1 << N)) }; + Padv1 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull down input pin. + #[inline] + pub fn into_pull_down_input(self) -> Padv1> { + let config = self.base.gpio_config[N >> 1] + .read() + .set_function(N & 0x1, v1::Function::Gpio) + .enable_input(N & 0x1) + .set_pull(N & 0x1, Pull::Down); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + let val = self.base.gpio_output_enable.read(); + unsafe { self.base.gpio_output_enable.write(val & !(1 << N)) }; + Padv1 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a floating input pin. + #[inline] + pub fn into_floating_input(self) -> Padv1> { + let config = self.base.gpio_config[N >> 1] + .read() + .set_function(N & 0x1, v1::Function::Gpio) + .enable_input(N & 0x1) + .set_pull(N & 0x1, Pull::None); + unsafe { self.base.gpio_config[N >> 1].write(config) }; + let val = self.base.gpio_output_enable.read(); + unsafe { self.base.gpio_output_enable.write(val & !(1 << N)) }; + Padv1 { + base: self.base, + _mode: PhantomData, + } + } +} + +impl, const N: usize, M> ErrorType + for Padv1> +{ + type Error = core::convert::Infallible; +} + +impl, const N: usize, M> ErrorType + for Padv1> +{ + type Error = core::convert::Infallible; +} + +impl, const N: usize, M> InputPin + for Padv1> +{ + #[inline] + fn is_high(&mut self) -> Result { + Ok(self.base.gpio_input_value.read() & (1 << N) != 0) + } + #[inline] + fn is_low(&mut self) -> Result { + Ok(self.base.gpio_input_value.read() & (1 << N) == 0) + } +} + +impl, const N: usize, M> OutputPin + for Padv1> +{ + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + let val = self.base.gpio_output_value.read(); + unsafe { self.base.gpio_output_value.write(val & !(1 << N)) }; + Ok(()) + } + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + let val = self.base.gpio_output_value.read(); + unsafe { self.base.gpio_output_value.write(val | (1 << N)) }; + Ok(()) + } +} diff --git a/bouffalo-hal/src/gpio/pad_v2.rs b/bouffalo-hal/src/gpio/pad_v2.rs new file mode 100644 index 0000000..8341234 --- /dev/null +++ b/bouffalo-hal/src/gpio/pad_v2.rs @@ -0,0 +1,406 @@ +use super::{ + typestate::{ + Alternate, Floating, I2c, Input, JtagD0, JtagLp, JtagM0, MmUart, Output, PullDown, PullUp, + Pwm, Sdh, Uart, + }, + Spi, +}; +use crate::glb::{v2, Drive, Pull}; +use core::{marker::PhantomData, ops::Deref}; +use embedded_hal::digital::{ErrorType, InputPin, OutputPin}; + +/// GPIO pad of BL808 and BL616. +pub struct Padv2 { + base: GLB, + _mode: PhantomData, +} + +impl, const N: usize, M> Padv2> { + /// Enable schmitt trigger. + #[inline] + pub fn enable_schmitt(&mut self) { + let config = self.base.gpio_config[N].read().enable_schmitt(); + unsafe { self.base.gpio_config[N].write(config) }; + } + /// Disable schmitt trigger. + #[inline] + pub fn disable_schmitt(&mut self) { + let config = self.base.gpio_config[N].read().disable_schmitt(); + unsafe { self.base.gpio_config[N].write(config) }; + } + /// Clear interrupt flag. + #[inline] + pub fn clear_interrupt(&mut self) { + let config = self.base.gpio_config[N].read().clear_interrupt(); + unsafe { self.base.gpio_config[N].write(config) }; + } + /// Check if interrupt flag is set. + #[inline] + pub fn has_interrupt(&self) -> bool { + self.base.gpio_config[N].read().has_interrupt() + } + /// Mask interrupt. + #[inline] + pub fn mask_interrupt(&mut self) { + let config = self.base.gpio_config[N].read().mask_interrupt(); + unsafe { self.base.gpio_config[N].write(config) }; + } + /// Unmask interrupt. + #[inline] + pub fn unmask_interrupt(&mut self) { + let config = self.base.gpio_config[N].read().unmask_interrupt(); + unsafe { self.base.gpio_config[N].write(config) }; + } +} + +impl, const N: usize, M> Padv2> { + /// Get drive strength of this pin. + #[inline] + pub fn drive(&self) -> Drive { + self.base.gpio_config[N].read().drive() + } + /// Set drive strength of this pin. + #[inline] + pub fn set_drive(&mut self, val: Drive) { + let config = self.base.gpio_config[N].read().set_drive(val); + unsafe { self.base.gpio_config[N].write(config) }; + } +} + +impl, const N: usize, M> Padv2> { + /// Get interrupt mode. + #[inline] + pub fn interrupt_mode(&self) -> v2::InterruptMode { + self.base.gpio_config[N].read().interrupt_mode() + } + /// Set interrupt mode. + #[inline] + pub fn set_interrupt_mode(&mut self, val: v2::InterruptMode) { + let config = self.base.gpio_config[N].read().set_interrupt_mode(val); + unsafe { self.base.gpio_config[N].write(config) }; + } +} + +impl, const N: usize, M> Padv2 { + /// Configures the pin to operate as a pull up output pin. + #[inline] + pub fn into_pull_up_output(self) -> Padv2> { + let config = self.base.gpio_config[N] + .read() + .set_function(v2::Function::Gpio) + .set_mode(v2::Mode::SetClear) + .disable_input() + .enable_output() + .set_pull(Pull::Up); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull down output pin. + #[inline] + pub fn into_pull_down_output(self) -> Padv2> { + let config = self.base.gpio_config[N] + .read() + .set_function(v2::Function::Gpio) + .set_mode(v2::Mode::SetClear) + .disable_input() + .enable_output() + .set_pull(Pull::Down); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a floating output pin. + #[inline] + pub fn into_floating_output(self) -> Padv2> { + let config = self.base.gpio_config[N] + .read() + .set_function(v2::Function::Gpio) + .set_mode(v2::Mode::SetClear) + .disable_input() + .enable_output() + .set_pull(Pull::None); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull up input pin. + #[inline] + pub fn into_pull_up_input(self) -> Padv2> { + let config = self.base.gpio_config[N] + .read() + .set_function(v2::Function::Gpio) + .set_mode(v2::Mode::SetClear) + .enable_input() + .disable_output() + .set_pull(Pull::Up); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull down input pin. + #[inline] + pub fn into_pull_down_input(self) -> Padv2> { + let config = self.base.gpio_config[N] + .read() + .set_function(v2::Function::Gpio) + .set_mode(v2::Mode::SetClear) + .enable_input() + .disable_output() + .set_pull(Pull::Down); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a floating input pin. + #[inline] + pub fn into_floating_input(self) -> Padv2> { + let config = self.base.gpio_config[N] + .read() + .set_function(v2::Function::Gpio) + .set_mode(v2::Mode::SetClear) + .enable_input() + .disable_output() + .set_pull(Pull::None); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } +} + +const UART_GPIO_CONFIG: v2::GpioConfig = v2::GpioConfig::RESET_VALUE + .enable_input() + .enable_output() + .enable_schmitt() + .set_drive(Drive::Drive0) + .set_pull(Pull::Up) + .set_function(v2::Function::Uart); +const JTAG_GPIO_CONFIG: v2::GpioConfig = v2::GpioConfig::RESET_VALUE + .enable_input() + .disable_output() + .enable_schmitt() + .set_drive(Drive::Drive0) + .set_pull(Pull::None); + +impl, const N: usize, M> Padv2 { + /// Configures the pin to operate as UART signal. + #[inline] + pub fn into_uart(self) -> Padv2 { + unsafe { self.base.gpio_config[N].write(UART_GPIO_CONFIG) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as multi-media cluster UART signal. + #[inline] + pub fn into_mm_uart(self) -> Padv2 { + unsafe { + self.base.gpio_config[N].write(UART_GPIO_CONFIG.set_function(v2::Function::MmUart)) + }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull up Pulse Width Modulation signal pin. + #[inline] + pub fn into_pull_up_pwm(self) -> Padv2> + where + Pwm: Alternate, + { + let config = v2::GpioConfig::RESET_VALUE + .disable_input() + .enable_output() + .enable_schmitt() + .set_drive(Drive::Drive0) + .set_pull(Pull::Up) + .set_function(Pwm::::F); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a pull down Pulse Width Modulation signal pin. + #[inline] + pub fn into_pull_down_pwm(self) -> Padv2> + where + Pwm: Alternate, + { + let config = v2::GpioConfig::RESET_VALUE + .disable_input() + .enable_output() + .enable_schmitt() + .set_drive(Drive::Drive0) + .set_pull(Pull::Down) + .set_function(Pwm::::F); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as floating Pulse Width Modulation signal pin. + #[inline] + pub fn into_floating_pwm(self) -> Padv2> + where + Pwm: Alternate, + { + let config = v2::GpioConfig::RESET_VALUE + .disable_input() + .enable_output() + .enable_schmitt() + .set_drive(Drive::Drive0) + .set_pull(Pull::None) + .set_function(Pwm::::F); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + #[inline] + pub fn into_i2c(self) -> Padv2> + where + I2c: Alternate, + { + let config = v2::GpioConfig::RESET_VALUE + .enable_input() + .enable_output() + .enable_schmitt() + .set_drive(Drive::Drive0) + .set_pull(Pull::Up) + .set_function(I2c::::F); + unsafe { + self.base.gpio_config[N].write(config); + } + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as D0 core JTAG. + #[inline] + pub fn into_jtag_d0(self) -> Padv2 { + let config = JTAG_GPIO_CONFIG.set_function(v2::Function::JtagD0); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as M0 core JTAG. + #[inline] + pub fn into_jtag_m0(self) -> Padv2 { + let config = JTAG_GPIO_CONFIG.set_function(v2::Function::JtagM0); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as LP core JTAG. + #[inline] + pub fn into_jtag_lp(self) -> Padv2 { + let config = JTAG_GPIO_CONFIG.set_function(v2::Function::JtagLp); + unsafe { self.base.gpio_config[N].write(config) }; + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a SPI pin. + #[inline] + pub fn into_spi(self) -> Padv2> + where + Spi: Alternate, + { + let config = v2::GpioConfig::RESET_VALUE + .enable_input() + .disable_output() + .enable_schmitt() + .set_pull(Pull::Up) + .set_drive(Drive::Drive0) + .set_function(Spi::::F); + unsafe { + self.base.gpio_config[N].write(config); + } + + Padv2 { + base: self.base, + _mode: PhantomData, + } + } + /// Configures the pin to operate as a SDH pin. + #[inline] + pub fn into_sdh(self) -> Padv2 { + let config = v2::GpioConfig::RESET_VALUE + .enable_input() + .disable_output() + .enable_schmitt() + .set_pull(Pull::Up) + .set_drive(Drive::Drive0) + .set_function(Sdh::F); + unsafe { + self.base.gpio_config[N].write(config); + } + + Padv2 { + base: self.base, + _mode: PhantomData, + } + } +} + +impl, const N: usize, M> ErrorType + for Padv2> +{ + type Error = core::convert::Infallible; +} + +impl, const N: usize, M> ErrorType + for Padv2> +{ + type Error = core::convert::Infallible; +} + +impl, const N: usize, M> InputPin + for Padv2> +{ + #[inline] + fn is_high(&mut self) -> Result { + Ok(self.base.gpio_input[N >> 5].read() & (1 << (N & 0x1F)) != 0) + } + #[inline] + fn is_low(&mut self) -> Result { + Ok(self.base.gpio_input[N >> 5].read() & (1 << (N & 0x1F)) == 0) + } +} + +impl, const N: usize, M> OutputPin + for Padv2> +{ + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + unsafe { self.base.gpio_clear[N >> 5].write(1 << (N & 0x1F)) }; + Ok(()) + } + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + unsafe { self.base.gpio_set[N >> 5].write(1 << (N & 0x1F)) }; + Ok(()) + } +} diff --git a/bouffalo-hal/src/gpio/typestate.rs b/bouffalo-hal/src/gpio/typestate.rs index a3a847e..4972ddb 100644 --- a/bouffalo-hal/src/gpio/typestate.rs +++ b/bouffalo-hal/src/gpio/typestate.rs @@ -4,7 +4,6 @@ use core::marker::PhantomData; /// Alternate type state. pub trait Alternate { /// Function number for this alternate type state. - #[cfg(feature = "glb-v2")] const F: v2::Function; } @@ -31,17 +30,14 @@ pub struct PullUp; pub struct Floating; impl Alternate for Input { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Gpio; } impl Alternate for Output { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Gpio; } impl Alternate for Disabled { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Gpio; } @@ -49,7 +45,6 @@ impl Alternate for Disabled { pub struct Uart; impl Alternate for Uart { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Uart; } @@ -57,7 +52,6 @@ impl Alternate for Uart { pub struct MmUart; impl Alternate for MmUart { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::MmUart; } @@ -71,17 +65,14 @@ pub struct JtagM0; pub struct JtagLp; impl Alternate for JtagD0 { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::JtagD0; } impl Alternate for JtagM0 { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::JtagM0; } impl Alternate for JtagLp { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::JtagLp; } @@ -89,12 +80,10 @@ impl Alternate for JtagLp { pub struct Spi; impl Alternate for Spi<0> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Spi0; } impl Alternate for Spi<1> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Spi1; } @@ -102,7 +91,6 @@ impl Alternate for Spi<1> { pub struct Sdh; impl Alternate for Sdh { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Sdh; } @@ -110,22 +98,18 @@ impl Alternate for Sdh { pub struct I2c; impl Alternate for I2c<0> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::I2c0; } impl Alternate for I2c<1> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::I2c1; } impl Alternate for I2c<2> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::I2c2; } impl Alternate for I2c<3> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::I2c3; } @@ -133,11 +117,9 @@ impl Alternate for I2c<3> { pub struct Pwm; impl Alternate for Pwm<0> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Pwm0; } impl Alternate for Pwm<1> { - #[cfg(feature = "glb-v2")] const F: v2::Function = v2::Function::Pwm1; } diff --git a/bouffalo-hal/src/jtag.rs b/bouffalo-hal/src/jtag.rs deleted file mode 100644 index 5be0f78..0000000 --- a/bouffalo-hal/src/jtag.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! JTAG interface feature support. - -#[cfg(any(doc, feature = "glb-v2"))] -use crate::glb::{ - self, - v2::{Function, GpioConfig}, - Drive, Pull, -}; -#[cfg(any(doc, feature = "glb-v2"))] -use crate::gpio::Pad; -use crate::gpio::{Alternate, JtagD0, JtagLp, JtagM0}; -#[cfg(any(doc, feature = "glb-v2"))] -use core::marker::PhantomData; -#[cfg(any(doc, feature = "glb-v2"))] -use core::ops::Deref; - -// requires to set `.set_function(Function::JtagXx)` before use. -#[cfg(feature = "glb-v2")] -const JTAG_GPIO_CONFIG: GpioConfig = GpioConfig::RESET_VALUE - .enable_input() - .disable_output() - .enable_schmitt() - .set_drive(Drive::Drive0) - .set_pull(Pull::None); - -#[cfg(any(doc, feature = "glb-v2"))] -impl, const N: usize, M: Alternate> Pad { - /// Configures the pin to operate as D0 core JTAG. - #[inline] - pub fn into_jtag_d0(self) -> Pad { - let config = JTAG_GPIO_CONFIG.set_function(Function::JtagD0); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } - /// Configures the pin to operate as M0 core JTAG. - #[inline] - pub fn into_jtag_m0(self) -> Pad { - let config = JTAG_GPIO_CONFIG.set_function(Function::JtagM0); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } - /// Configures the pin to operate as LP core JTAG. - #[inline] - pub fn into_jtag_lp(self) -> Pad { - let config = JTAG_GPIO_CONFIG.set_function(Function::JtagLp); - unsafe { self.base.gpio_config[N].write(config) }; - Pad { - base: self.base, - _mode: PhantomData, - } - } -} diff --git a/bouffalo-hal/src/lib.rs b/bouffalo-hal/src/lib.rs index e9a2448..7f7f1fa 100644 --- a/bouffalo-hal/src/lib.rs +++ b/bouffalo-hal/src/lib.rs @@ -21,7 +21,6 @@ pub mod hbn; pub mod i2c; pub mod i2s; pub mod ir; -pub mod jtag; pub mod lz4d; pub mod psram; pub mod pwm; diff --git a/bouffalo-rt/examples/blinky-bl616/Cargo.toml b/bouffalo-rt/examples/blinky-bl616/Cargo.toml index e34be61..ce831db 100644 --- a/bouffalo-rt/examples/blinky-bl616/Cargo.toml +++ b/bouffalo-rt/examples/blinky-bl616/Cargo.toml @@ -7,7 +7,7 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bouffalo-rt = { version = "0.0.0", path = "../..", features = ["bl616"]} +bouffalo-rt = { version = "0.0.0", path = "../..", features = ["bl616"] } embedded-hal = "1.0.0" panic-halt = "1.0.0" riscv = "0.12.1"