Skip to content

Commit

Permalink
lib: update embedded-hal into 1.0.0
Browse files Browse the repository at this point in the history
Signed-off-by: Zhouqi Jiang <luojia@hust.edu.cn>
  • Loading branch information
luojia65 committed Jan 10, 2024
1 parent fb6c239 commit 7eb0c08
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 118 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ edition = "2021"
targets = ["riscv64gc-unknown-none-elf"]

[dependencies]
embedded-hal = { version = "0.2.7", features = ["unproven"] }
embedded-hal = "1.0.0"
embedded-io = "0.6.1"
nb = "1"
k210-pac = "0.2.0"
bitflags = "1.3"
31 changes: 10 additions & 21 deletions src/gpio.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! General Purpose Input/Output (GPIO)

use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit, u32_toggle_bit};
use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit};
use crate::fpioa::{IoPin, Mode, Pull};
use crate::pac;
use crate::sysctl::{self, APB0};
use core::marker::PhantomData;
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin};

/// Extension trait to split a GPIO peripheral into independent pins
pub trait GpioExt {
Expand Down Expand Up @@ -186,17 +186,20 @@ impl<GPIO: GpioIndex, PIN: IoPin, MODE: Active> Gpio<GPIO, PIN, MODE> {
}
}

impl<GPIO: GpioIndex, PIN, MODE> InputPin for Gpio<GPIO, PIN, Input<MODE>> {
impl<GPIO: GpioIndex, PIN, MODE> ErrorType for Gpio<GPIO, PIN, MODE> {
// All GPIO operations are infallible.
type Error = core::convert::Infallible;
}

fn is_high(&self) -> Result<bool, Self::Error> {
impl<GPIO: GpioIndex, PIN, MODE> InputPin for Gpio<GPIO, PIN, Input<MODE>> {
fn is_high(&mut self) -> Result<bool, Self::Error> {
Ok(unsafe {
let p = &(*pac::GPIO::ptr()).data_input as *const _ as *const _;
u32_bit_is_set(p, GPIO::INDEX as usize)
})
}

fn is_low(&self) -> Result<bool, Self::Error> {
fn is_low(&mut self) -> Result<bool, Self::Error> {
Ok(unsafe {
let p = &(*pac::GPIO::ptr()).data_input as *const _ as *const _;
u32_bit_is_clear(p, GPIO::INDEX as usize)
Expand All @@ -205,8 +208,6 @@ impl<GPIO: GpioIndex, PIN, MODE> InputPin for Gpio<GPIO, PIN, Input<MODE>> {
}

impl<GPIO: GpioIndex, PIN> OutputPin for Gpio<GPIO, PIN, Output> {
type Error = core::convert::Infallible;

fn set_high(&mut self) -> Result<(), Self::Error> {
unsafe {
let p = &(*pac::GPIO::ptr()).data_output as *const _ as *mut _;
Expand All @@ -225,29 +226,17 @@ impl<GPIO: GpioIndex, PIN> OutputPin for Gpio<GPIO, PIN, Output> {
}

impl<GPIO: GpioIndex, PIN> StatefulOutputPin for Gpio<GPIO, PIN, Output> {
fn is_set_high(&self) -> Result<bool, Self::Error> {
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
Ok(unsafe {
let p = &(*pac::GPIO::ptr()).data_output as *const _ as *const _;
u32_bit_is_set(p, GPIO::INDEX as usize)
})
}

fn is_set_low(&self) -> Result<bool, Self::Error> {
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
Ok(unsafe {
let p = &(*pac::GPIO::ptr()).data_output as *const _ as *const _;
u32_bit_is_clear(p, GPIO::INDEX as usize)
})
}
}

impl<GPIO: GpioIndex, PIN> ToggleableOutputPin for Gpio<GPIO, PIN, Output> {
type Error = core::convert::Infallible;

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);
}
Ok(())
}
}
22 changes: 8 additions & 14 deletions src/gpiohs.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! High-speed GPIO peripheral (GPIOHS)

use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit, u32_toggle_bit};
use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit};
use crate::pac::GPIOHS;
use core::marker::PhantomData;
use embedded_hal::digital::v2::{InputPin, OutputPin};
use embedded_hal::digital::{ErrorType, InputPin, OutputPin};

// todo: verify

Expand Down Expand Up @@ -114,17 +114,20 @@ impl<MODE> Gpiohs0<MODE> {
}
}

impl<MODE> InputPin for Gpiohs0<Input<MODE>> {
impl<MODE> ErrorType for Gpiohs0<MODE> {
// All GPIO operations are infallible.
type Error = core::convert::Infallible;
}

fn is_high(&self) -> Result<bool, Self::Error> {
impl<MODE> InputPin for Gpiohs0<Input<MODE>> {
fn is_high(&mut self) -> Result<bool, Self::Error> {
Ok(unsafe {
let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _;
u32_bit_is_set(p, 0)
})
}

fn is_low(&self) -> Result<bool, Self::Error> {
fn is_low(&mut self) -> Result<bool, Self::Error> {
Ok(unsafe {
let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _;
u32_bit_is_clear(p, 0)
Expand All @@ -133,8 +136,6 @@ impl<MODE> InputPin for Gpiohs0<Input<MODE>> {
}

impl<MODE> OutputPin for Gpiohs0<Output<MODE>> {
type Error = core::convert::Infallible;

fn set_high(&mut self) -> Result<(), Self::Error> {
unsafe {
let p = &(*GPIOHS::ptr()).output_val as *const _ as *mut _;
Expand Down Expand Up @@ -211,13 +212,6 @@ trait GpiohsAccess {
}
}

fn toggle_pin(index: usize) {
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 _;
Expand Down
7 changes: 0 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ pub mod prelude {
pub use crate::stdout::Write as _k210_hal_stdout_Write;
pub use crate::sysctl::SysctlExt as _k210_hal_sysctl_SysctlExt;
pub use crate::time::U32Ext as _k210_hal_time_U32Ext;
pub use embedded_hal::prelude::*;
}

mod bit_utils {
Expand All @@ -49,12 +48,6 @@ mod bit_utils {
}
}

#[inline(always)]
pub(crate) unsafe fn u32_toggle_bit(p: *mut u32, index: usize) {
let mask = 1 << index;
*p ^= mask;
}

#[inline(always)]
pub(crate) unsafe fn u32_bit_is_set(r: *const u32, index: usize) -> bool {
(*r & 1 << index) != 0
Expand Down
103 changes: 54 additions & 49 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
use core::convert::Infallible;
use core::mem;

use embedded_hal::serial;

use crate::clock::Clocks;
use crate::pac::{uart1, UART1, UART2, UART3, UARTHS};
use crate::time::Bps;
Expand Down Expand Up @@ -98,44 +96,48 @@ impl Serial<UARTHS> {
}
}

impl serial::Read<u8> for Rx<UARTHS> {
type Error = Infallible;

fn read(&mut self) -> nb::Result<u8, Infallible> {
let rxdata = self.uart.rxdata.read();
impl embedded_io::ErrorType for Rx<UARTHS> {
type Error = core::convert::Infallible;
}

if rxdata.empty().bit_is_set() {
Err(nb::Error::WouldBlock)
} else {
Ok(rxdata.data().bits() as u8)
impl embedded_io::Read for Rx<UARTHS> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> {
while self.uart.rxdata.read().empty().bit_is_set() {
// Block until rxdata available.
core::hint::spin_loop()
}
let len = buf.len();
for slot in buf {
*slot = self.uart.rxdata.read().data().bits();
}
Ok(len)
}
}

impl serial::Write<u8> for Tx<UARTHS> {
type Error = Infallible;

fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> {
let txdata = self.uart.txdata.read();
impl embedded_io::ErrorType for Tx<UARTHS> {
type Error = core::convert::Infallible;
}

if txdata.full().bit_is_set() {
Err(nb::Error::WouldBlock)
} else {
impl embedded_io::Write for Tx<UARTHS> {
fn write(&mut self, bytes: &[u8]) -> Result<usize, Infallible> {
while self.uart.txdata.read().full().bit_is_set() {
// Block until txdata available.
core::hint::spin_loop()
}
for byte in bytes {
unsafe {
(*UARTHS::ptr()).txdata.write(|w| w.data().bits(byte));
self.uart.txdata.write(|w| w.data().bits(*byte));
}
Ok(())
}
Ok(bytes.len())
}

fn flush(&mut self) -> nb::Result<(), Infallible> {
let txdata = self.uart.txdata.read();

if txdata.full().bit_is_set() {
Err(nb::Error::WouldBlock)
} else {
Ok(())
fn flush(&mut self) -> Result<(), Infallible> {
while self.uart.txdata.read().full().bit_is_set() {
// Block until flush complete. If you don't want a block, use embedded_io_async traits instead.
core::hint::spin_loop()
}
Ok(())
}
}

Expand Down Expand Up @@ -207,40 +209,43 @@ impl<UART: UartX> Serial<UART> {
}
}

impl<UART: UartX> serial::Read<u8> for Rx<UART> {
type Error = Infallible;

fn read(&mut self) -> nb::Result<u8, Infallible> {
let lsr = self.uart.lsr.read();
impl<UART: UartX> embedded_io::ErrorType for Rx<UART> {
type Error = core::convert::Infallible;
}

if (lsr.bits() & (1 << 0)) == 0 {
impl<UART: UartX> embedded_io::Read for Rx<UART> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> {
while (self.uart.lsr.read().bits() & (1 << 0)) == 0 {
// Data Ready bit
Err(nb::Error::WouldBlock)
} else {
let rbr = self.uart.rbr_dll_thr.read();
Ok((rbr.bits() & 0xff) as u8)
core::hint::spin_loop()
}
let len = buf.len();
for slot in buf {
*slot = (self.uart.rbr_dll_thr.read().bits() & 0xff) as u8;
}
Ok(len)
}
}

impl<UART: UartX> serial::Write<u8> for Tx<UART> {
type Error = Infallible;

fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> {
let lsr = self.uart.lsr.read();
impl<UART: UartX> embedded_io::ErrorType for Tx<UART> {
type Error = core::convert::Infallible;
}

if (lsr.bits() & (1 << 5)) != 0 {
impl<UART: UartX> embedded_io::Write for Tx<UART> {
fn write(&mut self, bytes: &[u8]) -> Result<usize, Infallible> {
while (self.uart.lsr.read().bits() & (1 << 5)) != 0 {
// Transmit Holding Register Empty bit
Err(nb::Error::WouldBlock)
} else {
core::hint::spin_loop();
}
for byte in bytes {
unsafe {
self.uart.rbr_dll_thr.write(|w| w.bits(byte.into()));
self.uart.rbr_dll_thr.write(|w| w.bits(*byte as u32));
}
Ok(())
}
Ok(bytes.len())
}

fn flush(&mut self) -> nb::Result<(), Infallible> {
fn flush(&mut self) -> Result<(), Infallible> {
// TODO
Ok(())
}
Expand Down
27 changes: 19 additions & 8 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use crate::clock::Clocks;
use crate::pac::SPI0;
use crate::sysctl::{self, APB0};
use core::convert::Infallible;
pub use embedded_hal::spi::{Mode, Phase, Polarity};

///
Expand Down Expand Up @@ -64,21 +63,33 @@ impl Spi<SPI0> {
}
}

impl embedded_hal::spi::FullDuplex<u8> for Spi<SPI0> {
/// An enumeration of SPI errors
type Error = Infallible;
impl embedded_hal::spi::ErrorType for Spi<SPI0> {
type Error = core::convert::Infallible;
}

impl embedded_hal::spi::SpiBus<u8> for Spi<SPI0> {
/// Reads the word stored in the shift register
///
/// **NOTE** A word must be sent to the slave before attempting to call this
/// method.
fn read(&mut self) -> nb::Result<u8, Self::Error> {
fn read(&mut self, _words: &mut [u8]) -> Result<(), Self::Error> {
todo!()
}

fn write(&mut self, _words: &[u8]) -> Result<(), Self::Error> {
todo!()
}

/// Sends a word to the slave
fn send(&mut self, word: u8) -> nb::Result<(), Self::Error> {
todo!("{}", word)
fn transfer(&mut self, _read: &mut [u8], _write: &[u8]) -> Result<(), Self::Error> {
todo!()
}

fn transfer_in_place(&mut self, _words: &mut [u8]) -> Result<(), Self::Error> {
todo!()
}

fn flush(&mut self) -> Result<(), Self::Error> {
todo!()
}
}

Expand Down
Loading

0 comments on commit 7eb0c08

Please sign in to comment.