From d955e5423f370083f49ea03ee3785ec2fded1182 Mon Sep 17 00:00:00 2001 From: Andelf Date: Wed, 18 Nov 2020 15:44:48 +0800 Subject: [PATCH 1/2] fix: revert embedded-hal to 0.2.4 --- Cargo.toml | 4 +- src/gpio.rs | 38 +++++++++--------- src/gpiohs.rs | 108 +++++++++++++++++++++++++------------------------- src/serial.rs | 12 +++--- src/spi.rs | 20 +++++----- src/stdout.rs | 4 +- 6 files changed, 93 insertions(+), 93 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index feae6d1..879b44d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" targets = ["riscv64gc-unknown-none-elf"] [dependencies] -embedded-hal = "1.0.0-alpha.1" -nb = "0.1.1" +embedded-hal = { version = "0.2.4", features = ["unproven"] } +nb = "1.0.0" k210-pac = "0.2.0" bitflags = "1.2.1" diff --git a/src/gpio.rs b/src/gpio.rs index efe0fb9..f025ee0 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -5,7 +5,7 @@ use crate::pac; use crate::sysctl::{self, APB0}; use crate::fpioa::{IoPin, Pull, Mode}; use crate::bit_utils::{u32_set_bit, u32_toggle_bit, u32_bit_is_set, u32_bit_is_clear}; -use embedded_hal::digital::{OutputPin, StatefulOutputPin, InputPin, ToggleableOutputPin}; +use embedded_hal::digital::v2::{OutputPin, StatefulOutputPin, InputPin, ToggleableOutputPin}; /// Extension trait to split a GPIO peripheral into independent pins pub trait GpioExt { @@ -15,7 +15,7 @@ pub trait GpioExt { macro_rules! def_gpio_pins { ($($GPIOX: ident: ($num: expr, $gpiox: ident, $func: ident);)+) => { - + impl GpioExt for pac::GPIO { fn split(self, apb0: &mut APB0) -> Parts { // enable APB0 bus @@ -23,7 +23,7 @@ impl GpioExt for pac::GPIO { // enable sysctl peripheral sysctl::clk_en_peri().modify(|_r, w| w.gpio_clk_en().set_bit()); // return ownership - Parts { + Parts { $( $gpiox: $GPIOX { _ownership: () }, )+ } } @@ -151,7 +151,7 @@ impl Gpio { #[inline] fn direction_in(&mut self) { - unsafe { + unsafe { let p = &(*pac::GPIO::ptr()).direction as *const _ as *mut _; u32_set_bit(p, false, GPIO::INDEX as usize); } @@ -159,7 +159,7 @@ impl Gpio { #[inline] fn direction_out(&mut self) { - unsafe { + unsafe { let p = &(*pac::GPIO::ptr()).direction as *const _ as *mut _; u32_set_bit(p, true, GPIO::INDEX as usize); } @@ -169,15 +169,15 @@ impl Gpio { impl InputPin for Gpio> { type Error = core::convert::Infallible; - fn try_is_high(&self) -> Result { - Ok(unsafe { + fn is_high(&self) -> Result { + Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_input as *const _ as *const _; u32_bit_is_set(p, GPIO::INDEX as usize) }) } - fn try_is_low(&self) -> Result { - Ok(unsafe { + fn is_low(&self) -> Result { + Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_input as *const _ as *const _; u32_bit_is_clear(p, GPIO::INDEX as usize) }) @@ -187,16 +187,16 @@ impl InputPin for Gpio> { impl OutputPin for Gpio { type Error = core::convert::Infallible; - fn try_set_high(&mut self) -> Result<(), Self::Error> { - unsafe { + fn set_high(&mut self) -> Result<(), Self::Error> { + unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *mut _; u32_set_bit(p, true, GPIO::INDEX as usize); } Ok(()) } - fn try_set_low(&mut self) -> Result<(), Self::Error> { - unsafe { + fn set_low(&mut self) -> Result<(), Self::Error> { + unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *mut _; u32_set_bit(p, false, GPIO::INDEX as usize); } @@ -205,15 +205,15 @@ impl OutputPin for Gpio { } impl StatefulOutputPin for Gpio { - fn try_is_set_high(&self) -> Result { - Ok(unsafe { + fn is_set_high(&self) -> Result { + Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *const _; u32_bit_is_set(p, GPIO::INDEX as usize) }) } - fn try_is_set_low(&self) -> Result { - Ok(unsafe { + fn is_set_low(&self) -> Result { + Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *const _; u32_bit_is_clear(p, GPIO::INDEX as usize) }) @@ -223,8 +223,8 @@ impl StatefulOutputPin for Gpio { impl ToggleableOutputPin for Gpio { type Error = core::convert::Infallible; - fn try_toggle(&mut self) -> Result<(), Self::Error> { - unsafe { + fn toggle(&mut self) -> Result<(), Self::Error> { + unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *mut _; u32_toggle_bit(p, GPIO::INDEX as usize); } diff --git a/src/gpiohs.rs b/src/gpiohs.rs index 9be4195..4c89804 100644 --- a/src/gpiohs.rs +++ b/src/gpiohs.rs @@ -3,7 +3,7 @@ use crate::pac::GPIOHS; use core::marker::PhantomData; use crate::bit_utils::{u32_set_bit, u32_toggle_bit, u32_bit_is_set, u32_bit_is_clear}; -use embedded_hal::digital::{InputPin, OutputPin}; +use embedded_hal::digital::v2::{InputPin, OutputPin}; // todo: verify @@ -25,7 +25,7 @@ pub trait GpiohsExt { impl GpiohsExt for GPIOHS { fn split(self) -> Parts { - Parts { + Parts { gpiohs0: Gpiohs0 { _mode: PhantomData }, } } @@ -117,15 +117,15 @@ impl Gpiohs0 { impl InputPin for Gpiohs0> { type Error = core::convert::Infallible; - fn try_is_high(&self) -> Result { - Ok(unsafe { + fn is_high(&self) -> Result { + Ok(unsafe { let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _; u32_bit_is_set(p, 0) }) } - fn try_is_low(&self) -> Result { - Ok(unsafe { + fn is_low(&self) -> Result { + Ok(unsafe { let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _; u32_bit_is_clear(p, 0) }) @@ -135,16 +135,16 @@ impl InputPin for Gpiohs0> { impl OutputPin for Gpiohs0> { type Error = core::convert::Infallible; - fn try_set_high(&mut self) -> Result<(), Self::Error> { - unsafe { + fn set_high(&mut self) -> Result<(), Self::Error> { + unsafe { let p = &(*GPIOHS::ptr()).output_val as *const _ as *mut _; u32_set_bit(p, true, 0); } Ok(()) } - fn try_set_low(&mut self) -> Result<(), Self::Error> { - unsafe { + fn set_low(&mut self) -> Result<(), Self::Error> { + unsafe { let p = &(*GPIOHS::ptr()).output_val as *const _ as *mut _; u32_set_bit(p, false, 0); } @@ -156,187 +156,187 @@ trait GpiohsAccess { fn peripheral() -> &'static mut crate::pac::gpiohs::RegisterBlock; fn set_drive(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().drive as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().drive as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn input_value(index: usize) -> bool { - unsafe { - let p = &mut Self::peripheral().input_val as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().input_val as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn set_input_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().input_en as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().input_en as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn set_iof_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().iof_en as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().iof_en as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn set_iof_sel(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().iof_sel as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().iof_sel as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn set_output_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().output_en as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().output_en as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn set_output_value(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().output_val as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().output_val as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn set_output_xor(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().output_xor as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().output_xor as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn toggle_pin(index: usize) { - unsafe { - let p = &mut Self::peripheral().output_val as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().output_val as *mut _ as *mut _; u32_toggle_bit(p, index); } } fn set_pullup_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().pullup_en as *mut _ as *mut _; + unsafe { + let p = &mut Self::peripheral().pullup_en as *mut _ as *mut _; u32_set_bit(p, bit, index); } } fn set_rise_ie(index: usize, bit: bool) { unsafe { - let p = &mut Self::peripheral().rise_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().rise_ie as *mut _ as *mut _; u32_set_bit(p, bit, index); } } - + fn clear_rise_ip(index: usize) { unsafe { - let p = &mut Self::peripheral().rise_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().rise_ip as *mut _ as *mut _; u32_set_bit(p, true, index); } } - + fn set_fall_ie(index: usize, bit: bool) { unsafe { - let p = &mut Self::peripheral().fall_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().fall_ie as *mut _ as *mut _; u32_set_bit(p, bit, index); } } - + fn clear_fall_ip(index: usize) { unsafe { - let p = &mut Self::peripheral().fall_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().fall_ip as *mut _ as *mut _; u32_set_bit(p, true, index); } } - + fn set_high_ie(index: usize, bit: bool) { unsafe { - let p = &mut Self::peripheral().high_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().high_ie as *mut _ as *mut _; u32_set_bit(p, bit, index); } } - + fn clear_high_ip(index: usize,) { unsafe { - let p = &mut Self::peripheral().high_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().high_ip as *mut _ as *mut _; u32_set_bit(p, true, index); } } - + fn set_low_ie(index: usize, bit: bool) { unsafe { - let p = &mut Self::peripheral().low_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().low_ie as *mut _ as *mut _; u32_set_bit(p, bit, index); } } - + fn clear_low_ip(index: usize) { unsafe { - let p = &mut Self::peripheral().low_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().low_ip as *mut _ as *mut _; u32_set_bit(p, true, index); } } fn has_rise_ie(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().rise_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().rise_ie as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn has_fall_ie(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().fall_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().fall_ie as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn has_high_ie(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().high_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().high_ie as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn has_low_ie(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().low_ie as *mut _ as *mut _; + let p = &mut Self::peripheral().low_ie as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn has_rise_ip(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().rise_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().rise_ip as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn has_fall_ip(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().fall_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().fall_ip as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn has_high_ip(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().high_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().high_ip as *mut _ as *mut _; u32_bit_is_set(p, index) } } fn has_low_ip(index: usize) -> bool { unsafe { - let p = &mut Self::peripheral().low_ip as *mut _ as *mut _; + let p = &mut Self::peripheral().low_ip as *mut _ as *mut _; u32_bit_is_set(p, index) } } - + } impl GpiohsAccess for GPIOHS { diff --git a/src/serial.rs b/src/serial.rs index 302fbb5..356b4d2 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -100,7 +100,7 @@ impl Serial { impl serial::Read for Rx { type Error = Infallible; - fn try_read(&mut self) -> nb::Result { + fn read(&mut self) -> nb::Result { let rxdata = self.uart.rxdata.read(); if rxdata.empty().bit_is_set() { @@ -114,7 +114,7 @@ impl serial::Read for Rx { impl serial::Write for Tx { type Error = Infallible; - fn try_write(&mut self, byte: u8) -> nb::Result<(), Infallible> { + fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> { let txdata = self.uart.txdata.read(); if txdata.full().bit_is_set() { @@ -127,7 +127,7 @@ impl serial::Write for Tx { } } - fn try_flush(&mut self) -> nb::Result<(), Infallible> { + fn flush(&mut self) -> nb::Result<(), Infallible> { let txdata = self.uart.txdata.read(); if txdata.full().bit_is_set() { @@ -200,7 +200,7 @@ impl Serial { impl serial::Read for Rx { type Error = Infallible; - fn try_read(&mut self) -> nb::Result { + fn read(&mut self) -> nb::Result { let lsr = self.uart.lsr.read(); if (lsr.bits() & (1<<0)) == 0 { // Data Ready bit @@ -215,7 +215,7 @@ impl serial::Read for Rx { impl serial::Write for Tx { type Error = Infallible; - fn try_write(&mut self, byte: u8) -> nb::Result<(), Infallible> { + fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> { let lsr = self.uart.lsr.read(); if (lsr.bits() & (1<<5)) != 0 { // Transmit Holding Register Empty bit @@ -228,7 +228,7 @@ impl serial::Write for Tx { } } - fn try_flush(&mut self) -> nb::Result<(), Infallible> { + fn flush(&mut self) -> nb::Result<(), Infallible> { // TODO Ok(()) } diff --git a/src/spi.rs b/src/spi.rs index 89a7f91..38bfbe8 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -6,18 +6,18 @@ use crate::sysctl::{self, APB0}; pub use embedded_hal::spi::{Mode, Polarity, Phase}; use core::convert::Infallible; -/// +/// pub struct Spi { spi: SPI } impl Spi { pub fn spi0( - spi: SPI0, - mode: Mode, - frame_format: FrameFormat, - endian: Endian, - clock: &Clocks, + spi: SPI0, + mode: Mode, + frame_format: FrameFormat, + endian: Endian, + clock: &Clocks, apb0: &mut APB0 ) -> Self { let work_mode = hal_mode_to_pac(mode); @@ -53,14 +53,14 @@ impl Spi { // enable APB0 bus apb0.enable(); // enable peripheral via sysctl - sysctl::clk_en_peri().modify(|_r, w| + sysctl::clk_en_peri().modify(|_r, w| w.spi0_clk_en().set_bit()); Spi { spi } } pub fn release(self) -> SPI0 { // power off - sysctl::clk_en_peri().modify(|_r, w| + sysctl::clk_en_peri().modify(|_r, w| w.spi0_clk_en().clear_bit()); self.spi } @@ -74,12 +74,12 @@ impl embedded_hal::spi::FullDuplex for Spi { /// /// **NOTE** A word must be sent to the slave before attempting to call this /// method. - fn try_read(&mut self) -> nb::Result { + fn read(&mut self) -> nb::Result { todo!() } /// Sends a word to the slave - fn try_send(&mut self, word: u8) -> nb::Result<(), Self::Error> { + fn send(&mut self, word: u8) -> nb::Result<(), Self::Error> { todo!("{}", word) } } diff --git a/src/stdout.rs b/src/stdout.rs index 8483cc4..98eb10b 100644 --- a/src/stdout.rs +++ b/src/stdout.rs @@ -13,14 +13,14 @@ impl<'p, T> Write for Stdout<'p, T> fn write_str(&mut self, s: &str) -> core::fmt::Result { for byte in s.as_bytes() { if *byte == b'\n' { - let res = block!(self.0.try_write(b'\r')); + let res = block!(self.0.write(b'\r')); if res.is_err() { return Err(core::fmt::Error); } } - let res = block!(self.0.try_write(*byte)); + let res = block!(self.0.write(*byte)); if res.is_err() { return Err(core::fmt::Error); From f49dc2206e4325e8c7a1135ee7524aa816e4ab03 Mon Sep 17 00:00:00 2001 From: Andelf Date: Mon, 23 Nov 2020 00:53:46 +0800 Subject: [PATCH 2/2] feat(gpiohs): impl basic gpiohs --- src/gpiohs.rs | 465 ++++++++++++++++++++++---------------------------- 1 file changed, 201 insertions(+), 264 deletions(-) diff --git a/src/gpiohs.rs b/src/gpiohs.rs index 4c89804..14993f9 100644 --- a/src/gpiohs.rs +++ b/src/gpiohs.rs @@ -1,346 +1,283 @@ //! High-speed GPIO peripheral (GPIOHS) -use crate::pac::GPIOHS; +// use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit, u32_toggle_bit}; +use crate::fpioa::{IoPin, Mode, Pull}; +use crate::pac; use core::marker::PhantomData; -use crate::bit_utils::{u32_set_bit, u32_toggle_bit, u32_bit_is_set, u32_bit_is_clear}; -use embedded_hal::digital::v2::{InputPin, OutputPin}; +use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}; -// todo: verify +// reused type state +pub use crate::gpio::{Active, Floating, Input, Output, PullDown, PullUp, Unknown}; -/// Floating mode (type state) -pub struct Floating; - -/// PullUp mode (type state) -pub struct PullUp; - -/// Input mode (type state) -pub struct Input(MODE); - -/// Output mode (type state) -pub struct Output(MODE); +/// GPIOHS Index +pub trait GpiohsIndex { + type FUNC; + const INDEX: u8; +} pub trait GpiohsExt { fn split(self) -> Parts; } -impl GpiohsExt for GPIOHS { - fn split(self) -> Parts { - Parts { - gpiohs0: Gpiohs0 { _mode: PhantomData }, - } - } -} - -pub struct Parts { - pub gpiohs0: Gpiohs0>, -} - -pub struct Gpiohs0 { - _mode: PhantomData, -} +pub use gpiohs_pins::*; -impl Gpiohs0 { - pub fn into_pull_up_input(self) -> Gpiohs0> { - GPIOHS::set_output_en(0, false); - GPIOHS::set_input_en(0, true); - GPIOHS::set_pullup_en(0, true); - Gpiohs0 { _mode: PhantomData } - } - - // todo: all modes -} +macro_rules! def_gpiohs_pins { + ($($GPIOHSX: ident: ($num: expr, $gpiohsx: ident, $func: ident);)+) => { -bitflags::bitflags! { - pub struct Edge: u8 { - const RISING = 0b00000001; - const FALLING = 0b00000010; - const HIGH = 0b00000100; - const LOW = 0b00001000; - } -} + pub struct Parts { + $( pub $gpiohsx: $GPIOHSX, )+ + } -impl Gpiohs0 { - pub fn trigger_on_edge(&mut self, edge: Edge) { - // clear all pending bits - GPIOHS::clear_rise_ip(0); - GPIOHS::clear_fall_ip(0); - GPIOHS::clear_high_ip(0); - GPIOHS::clear_low_ip(0); - // enable interrupts according to flags - GPIOHS::set_rise_ie(0, edge.contains(Edge::RISING)); - GPIOHS::set_fall_ie(0, edge.contains(Edge::FALLING)); - GPIOHS::set_high_ie(0, edge.contains(Edge::HIGH)); - GPIOHS::set_low_ie(0, edge.contains(Edge::LOW)); - } - pub fn check_edges(&self) -> Edge { - let mut ans = Edge::empty(); - if GPIOHS::has_rise_ip(0) { - ans |= Edge::RISING; - } - if GPIOHS::has_fall_ip(0) { - ans |= Edge::FALLING; + impl GpiohsExt for pac::GPIOHS { + fn split(self) -> Parts { + Parts { + $( $gpiohsx: $GPIOHSX { _ownership: () }, )+ + } + } } - if GPIOHS::has_high_ip(0) { - ans |= Edge::HIGH; - } - if GPIOHS::has_low_ip(0) { - ans |= Edge::LOW; - } - ans - } - pub fn clear_interrupt_pending_bits(&mut self) { - if GPIOHS::has_rise_ie(0) { - GPIOHS::set_rise_ie(0, false); - GPIOHS::clear_rise_ip(0); - GPIOHS::set_rise_ie(0, true); - } - if GPIOHS::has_fall_ie(0) { - GPIOHS::set_fall_ie(0, false); - GPIOHS::clear_fall_ip(0); - GPIOHS::set_fall_ie(0, true); - } - if GPIOHS::has_high_ie(0) { - GPIOHS::set_high_ie(0, false); - GPIOHS::clear_high_ip(0); - GPIOHS::set_high_ie(0, true); - } - if GPIOHS::has_low_ie(0) { - GPIOHS::set_low_ie(0, false); - GPIOHS::clear_low_ip(0); - GPIOHS::set_low_ie(0, true); + /// All GPIOHS pins + pub mod gpiohs_pins { + use super::GpiohsIndex; + $( + /// GPIOHS pin + pub struct $GPIOHSX { + pub(crate) _ownership: () + } + + impl GpiohsIndex for $GPIOHSX { + type FUNC = crate::fpioa::functions::$func; + const INDEX: u8 = $num; + } + )+ } } } -impl InputPin for Gpiohs0> { - type Error = core::convert::Infallible; - - fn is_high(&self) -> Result { - Ok(unsafe { - let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _; - u32_bit_is_set(p, 0) - }) - } - - fn is_low(&self) -> Result { - Ok(unsafe { - let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _; - u32_bit_is_clear(p, 0) - }) - } +def_gpiohs_pins! { + GPIOHS0: (0, gpiohs0, GPIOHS0); + GPIOHS1: (1, gpiohs1, GPIOHS1); + GPIOHS2: (2, gpiohs2, GPIOHS2); + GPIOHS3: (3, gpiohs3, GPIOHS3); + GPIOHS4: (4, gpiohs4, GPIOHS4); + GPIOHS5: (5, gpiohs5, GPIOHS5); + GPIOHS6: (6, gpiohs6, GPIOHS6); + GPIOHS7: (7, gpiohs7, GPIOHS7); + GPIOHS8: (8, gpiohs8, GPIOHS8); + GPIOHS9: (9, gpiohs9, GPIOHS9); + GPIOHS10: (10, gpiohs10, GPIOHS10); + GPIOHS11: (11, gpiohs11, GPIOHS11); + GPIOHS12: (12, gpiohs12, GPIOHS12); + GPIOHS13: (13, gpiohs13, GPIOHS13); + GPIOHS14: (14, gpiohs14, GPIOHS14); + GPIOHS15: (15, gpiohs15, GPIOHS15); + GPIOHS16: (16, gpiohs16, GPIOHS16); + GPIOHS17: (17, gpiohs17, GPIOHS17); + GPIOHS18: (18, gpiohs18, GPIOHS18); + GPIOHS19: (19, gpiohs19, GPIOHS19); + GPIOHS20: (20, gpiohs20, GPIOHS20); + GPIOHS21: (21, gpiohs21, GPIOHS21); + GPIOHS22: (22, gpiohs22, GPIOHS22); + GPIOHS23: (23, gpiohs23, GPIOHS23); + GPIOHS24: (24, gpiohs24, GPIOHS24); + GPIOHS25: (25, gpiohs25, GPIOHS25); + GPIOHS26: (26, gpiohs26, GPIOHS26); + GPIOHS27: (27, gpiohs27, GPIOHS27); + GPIOHS28: (28, gpiohs28, GPIOHS28); + GPIOHS29: (29, gpiohs29, GPIOHS29); + GPIOHS30: (30, gpiohs30, GPIOHS30); + GPIOHS31: (31, gpiohs31, GPIOHS31); } -impl OutputPin for Gpiohs0> { - type Error = core::convert::Infallible; - - fn set_high(&mut self) -> Result<(), Self::Error> { - unsafe { - let p = &(*GPIOHS::ptr()).output_val as *const _ as *mut _; - u32_set_bit(p, true, 0); - } - Ok(()) - } - - fn set_low(&mut self) -> Result<(), Self::Error> { - unsafe { - let p = &(*GPIOHS::ptr()).output_val as *const _ as *mut _; - u32_set_bit(p, false, 0); - } - Ok(()) - } +/// GPIOHS wrapper struct +pub struct Gpiohs { + gpiohs: GPIOHS, + pin: PIN, + _mode: PhantomData, } -trait GpiohsAccess { - fn peripheral() -> &'static mut crate::pac::gpiohs::RegisterBlock; - - fn set_drive(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().drive as *mut _ as *mut _; - u32_set_bit(p, bit, index); - } - } - - fn input_value(index: usize) -> bool { - unsafe { - let p = &mut Self::peripheral().input_val as *mut _ as *mut _; - u32_bit_is_set(p, index) - } - } - - fn set_input_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().input_en as *mut _ as *mut _; - u32_set_bit(p, bit, index); - } - } - - fn set_iof_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().iof_en as *mut _ as *mut _; - u32_set_bit(p, bit, index); - } - } - - fn set_iof_sel(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().iof_sel as *mut _ as *mut _; - u32_set_bit(p, bit, index); - } - } - - fn set_output_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().output_en as *mut _ as *mut _; - u32_set_bit(p, bit, index); - } - } - - fn set_output_value(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().output_val as *mut _ as *mut _; - u32_set_bit(p, bit, index); +impl> Gpiohs { + pub fn new(gpiohs: GPIOHS, pin: PIN) -> Gpiohs { + Gpiohs { + gpiohs, + pin, + _mode: PhantomData, } } +} - fn set_output_xor(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().output_xor as *mut _ as *mut _; - u32_set_bit(p, bit, index); - } +impl Gpiohs { + pub fn free(self) -> (GPIOHS, PIN) { + (self.gpiohs, self.pin) } +} - fn toggle_pin(index: usize) { - unsafe { - let p = &mut Self::peripheral().output_val as *mut _ as *mut _; - u32_toggle_bit(p, index); +impl Gpiohs { + pub fn into_floating_input(mut self) -> Gpiohs> { + self.pin.set_io_pull(Pull::None); + self.direction_in(); + Gpiohs { + gpiohs: self.gpiohs, + pin: self.pin, + _mode: PhantomData, } } - fn set_pullup_en(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().pullup_en as *mut _ as *mut _; - u32_set_bit(p, bit, index); + pub fn into_pull_up_input(mut self) -> Gpiohs> { + self.pin.set_io_pull(Pull::Up); + self.direction_in(); + self.enable_pullup(); + Gpiohs { + gpiohs: self.gpiohs, + pin: self.pin, + _mode: PhantomData, } } - fn set_rise_ie(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().rise_ie as *mut _ as *mut _; - u32_set_bit(p, bit, index); + pub fn into_pull_down_input(mut self) -> Gpiohs> { + self.pin.set_io_pull(Pull::Down); + self.direction_in(); + self.disable_pullup(); + Gpiohs { + gpiohs: self.gpiohs, + pin: self.pin, + _mode: PhantomData, } } - fn clear_rise_ip(index: usize) { - unsafe { - let p = &mut Self::peripheral().rise_ip as *mut _ as *mut _; - u32_set_bit(p, true, index); + pub fn into_push_pull_output(mut self) -> Gpiohs { + self.pin.set_io_pull(Pull::Down); + self.direction_out(); + Gpiohs { + gpiohs: self.gpiohs, + pin: self.pin, + _mode: PhantomData, } } - fn set_fall_ie(index: usize, bit: bool) { + #[inline] + fn direction_in(&mut self) { unsafe { - let p = &mut Self::peripheral().fall_ie as *mut _ as *mut _; - u32_set_bit(p, bit, index); + (*pac::GPIOHS::ptr()) + .output_en + .modify(|r, w| w.bits(r.bits() & (!(1 << GPIOHS::INDEX)))); + (*pac::GPIOHS::ptr()) + .input_en + .modify(|r, w| w.bits(r.bits() | (1 << GPIOHS::INDEX))); } } - fn clear_fall_ip(index: usize) { + #[inline] + fn direction_out(&mut self) { unsafe { - let p = &mut Self::peripheral().fall_ip as *mut _ as *mut _; - u32_set_bit(p, true, index); + (*pac::GPIOHS::ptr()) + .output_en + .modify(|r, w| w.bits(r.bits() | (1 << GPIOHS::INDEX))); + (*pac::GPIOHS::ptr()) + .input_en + .modify(|r, w| w.bits(r.bits() & (!(1 << GPIOHS::INDEX)))); } } - fn set_high_ie(index: usize, bit: bool) { + #[inline] + fn enable_pullup(&mut self) { unsafe { - let p = &mut Self::peripheral().high_ie as *mut _ as *mut _; - u32_set_bit(p, bit, index); + (*pac::GPIOHS::ptr()) + .pullup_en + .modify(|r, w| w.bits(r.bits() | (1 << GPIOHS::INDEX))); } } - fn clear_high_ip(index: usize,) { + #[inline] + fn disable_pullup(&mut self) { unsafe { - let p = &mut Self::peripheral().high_ip as *mut _ as *mut _; - u32_set_bit(p, true, index); + (*pac::GPIOHS::ptr()) + .pullup_en + .modify(|r, w| w.bits(r.bits() & (!(1 << GPIOHS::INDEX)))); } } +} - fn set_low_ie(index: usize, bit: bool) { - unsafe { - let p = &mut Self::peripheral().low_ie as *mut _ as *mut _; - u32_set_bit(p, bit, index); - } - } +impl InputPin for Gpiohs> { + type Error = core::convert::Infallible; - fn clear_low_ip(index: usize) { - unsafe { - let p = &mut Self::peripheral().low_ip as *mut _ as *mut _; - u32_set_bit(p, true, index); - } + fn is_high(&self) -> Result { + Ok( + unsafe { + ((*pac::GPIOHS::ptr()).input_val.read().bits() >> GPIOHS::INDEX) & 0b1 == 0b1 + }, + ) } - fn has_rise_ie(index: usize) -> bool { - unsafe { - let p = &mut Self::peripheral().rise_ie as *mut _ as *mut _; - u32_bit_is_set(p, index) - } + fn is_low(&self) -> Result { + Ok( + unsafe { + ((*pac::GPIOHS::ptr()).input_val.read().bits() >> GPIOHS::INDEX) & 0b1 == 0b0 + }, + ) } +} - fn has_fall_ie(index: usize) -> bool { - unsafe { - let p = &mut Self::peripheral().fall_ie as *mut _ as *mut _; - u32_bit_is_set(p, index) - } - } +impl OutputPin for Gpiohs { + type Error = core::convert::Infallible; - fn has_high_ie(index: usize) -> bool { + fn set_high(&mut self) -> Result<(), Self::Error> { unsafe { - let p = &mut Self::peripheral().high_ie as *mut _ as *mut _; - u32_bit_is_set(p, index) + (*pac::GPIOHS::ptr()) + .output_val + .modify(|r, w| w.bits(r.bits() | (1 << GPIOHS::INDEX))); } + Ok(()) } - fn has_low_ie(index: usize) -> bool { + fn set_low(&mut self) -> Result<(), Self::Error> { unsafe { - let p = &mut Self::peripheral().low_ie as *mut _ as *mut _; - u32_bit_is_set(p, index) + (*pac::GPIOHS::ptr()) + .output_val + .modify(|r, w| w.bits(r.bits() & (!(1 << GPIOHS::INDEX as u8)))); } + Ok(()) } +} - fn has_rise_ip(index: usize) -> bool { - unsafe { - let p = &mut Self::peripheral().rise_ip as *mut _ as *mut _; - u32_bit_is_set(p, index) - } +impl StatefulOutputPin for Gpiohs { + fn is_set_high(&self) -> Result { + Ok(unsafe { + ((*pac::GPIOHS::ptr()).output_val.read().bits() >> GPIOHS::INDEX) & 0b1 == 0b1 + }) } - fn has_fall_ip(index: usize) -> bool { - unsafe { - let p = &mut Self::peripheral().fall_ip as *mut _ as *mut _; - u32_bit_is_set(p, index) - } + fn is_set_low(&self) -> Result { + Ok(unsafe { + ((*pac::GPIOHS::ptr()).output_val.read().bits() >> GPIOHS::INDEX) & 0b1 == 0b0 + }) } +} - fn has_high_ip(index: usize) -> bool { - unsafe { - let p = &mut Self::peripheral().high_ip as *mut _ as *mut _; - u32_bit_is_set(p, index) - } - } +impl ToggleableOutputPin for Gpiohs { + type Error = core::convert::Infallible; - fn has_low_ip(index: usize) -> bool { + fn toggle(&mut self) -> Result<(), Self::Error> { unsafe { - let p = &mut Self::peripheral().low_ip as *mut _ as *mut _; - u32_bit_is_set(p, index) + (*pac::GPIOHS::ptr()) + .output_val + .modify(|r, w| w.bits(r.bits() ^ (1 << GPIOHS::INDEX))) } + Ok(()) } - } -impl GpiohsAccess for GPIOHS { - fn peripheral() -> &'static mut crate::pac::gpiohs::RegisterBlock { - unsafe { &mut *(GPIOHS::ptr() as *mut _) } - } +/// Gpiohs pin trigger edge type +#[derive(Clone, Copy, Debug)] +pub enum Edge { + None, + Falling, + Rising, + Both, + Low, + High = 8, } + +// TODO: interrupt +// TODO: Drive Strength \ No newline at end of file