Skip to content

Commit

Permalink
embedded-hal v1
Browse files Browse the repository at this point in the history
  • Loading branch information
romancardenas committed Oct 14, 2024
1 parent b56ebb4 commit f7e9e47
Show file tree
Hide file tree
Showing 16 changed files with 813 additions and 894 deletions.
3 changes: 2 additions & 1 deletion e310x-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ edition = "2021"
rust-version = "1.72"

[dependencies]
embedded-hal = { version = "0.2.6", features = ["unproven"] }
embedded-hal = { version = "1.0.0" }
embedded-hal-nb = { version = "1.0.0" }
nb = "1.0.0"
riscv = { version = "0.11.1", features = ["critical-section-single-hart"] }
e310x = { path = "../e310x", version = "0.11.0", features = ["rt", "critical-section"] }
Expand Down
97 changes: 9 additions & 88 deletions e310x-hal/src/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::clock::Clocks;
use crate::core::clint::{MTIME, MTIMECMP};
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::delay::DelayNs;
use riscv::register::{mie, mip};

/// Machine timer (mtime) as a busyloop delay provider
Expand All @@ -18,68 +18,16 @@ impl Delay {
}
}

impl DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
let ticks = (us as u64) * TICKS_PER_SECOND / 1_000_000;
impl DelayNs for Delay {
fn delay_ns(&mut self, ns: u32) {
let ticks = (ns as u64) * TICKS_PER_SECOND / 1_000_000_000;

let mtime = MTIME;
let t = mtime.mtime() + ticks;
while mtime.mtime() < t {}
}
}

// This is a workaround to allow `delay_us(42)` construction without specifying a type.
impl DelayUs<i32> for Delay {
#[inline(always)]
fn delay_us(&mut self, us: i32) {
assert!(us >= 0);
self.delay_us(us as u32);
}
}

impl DelayUs<u16> for Delay {
#[inline(always)]
fn delay_us(&mut self, us: u16) {
self.delay_us(u32::from(us));
}
}

impl DelayUs<u8> for Delay {
#[inline(always)]
fn delay_us(&mut self, us: u8) {
self.delay_us(u32::from(us));
}
}

impl DelayMs<u32> for Delay {
fn delay_ms(&mut self, ms: u32) {
self.delay_us(ms * 1000);
}
}

// This is a workaround to allow `delay_ms(42)` construction without specifying a type.
impl DelayMs<i32> for Delay {
#[inline(always)]
fn delay_ms(&mut self, ms: i32) {
assert!(ms >= 0);
self.delay_ms(ms as u32);
}
}

impl DelayMs<u16> for Delay {
#[inline(always)]
fn delay_ms(&mut self, ms: u16) {
self.delay_ms(u32::from(ms));
}
}

impl DelayMs<u8> for Delay {
#[inline(always)]
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u32::from(ms));
}
}

/// Machine timer (mtime) as a sleep delay provider using mtimecmp
pub struct Sleep {
clock_freq: u32,
Expand All @@ -96,17 +44,15 @@ impl Sleep {
}
}

impl DelayMs<u32> for Sleep {
fn delay_ms(&mut self, ms: u32) {
let ticks = (ms as u64) * (self.clock_freq as u64) / 1000;
impl DelayNs for Sleep {
fn delay_ns(&mut self, ns: u32) {
let ticks = (ns as u64) * u64::from(self.clock_freq) / 1_000_000_000;
let t = MTIME.mtime() + ticks;

self.mtimecmp.set_mtimecmp(t);

// Enable timer interrupt
unsafe {
mie::set_mtimer();
}
unsafe { mie::set_mtimer() };

// Wait For Interrupt will put CPU to sleep until an interrupt hits
// in our case when internal timer mtime value >= mtimecmp value
Expand All @@ -122,31 +68,6 @@ impl DelayMs<u32> for Sleep {
}

// Clear timer interrupt
unsafe {
mie::clear_mtimer();
}
}
}

// This is a workaround to allow `delay_ms(42)` construction without specifying a type.
impl DelayMs<i32> for Sleep {
#[inline(always)]
fn delay_ms(&mut self, ms: i32) {
assert!(ms >= 0);
self.delay_ms(ms as u32);
}
}

impl DelayMs<u16> for Sleep {
#[inline(always)]
fn delay_ms(&mut self, ms: u16) {
self.delay_ms(u32::from(ms));
}
}

impl DelayMs<u8> for Sleep {
#[inline(always)]
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u32::from(ms));
unsafe { mie::clear_mtimer() };
}
}
46 changes: 24 additions & 22 deletions e310x-hal/src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ macro_rules! gpio {
use core::marker::PhantomData;
use core::convert::Infallible;

use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin,
ToggleableOutputPin};
use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin, ErrorType};
use e310x::$GPIOX;
use super::{Unknown, IOF0, IOF1, Drive, Floating, GpioExt, Input, Invert,
NoInvert, Output, PullUp, Regular, PinIndex, PeripheralAccess};
Expand Down Expand Up @@ -195,7 +194,6 @@ macro_rules! gpio {
$PXi { _mode: PhantomData }
}


/// Configures the pin to serve as alternate function 1 (AF1)
pub fn into_iof1(self) -> $PXi<IOF1<NoInvert>> {
$GPIOX::set_out_xor(Self::INDEX, false);
Expand All @@ -212,7 +210,6 @@ macro_rules! gpio {
$PXi { _mode: PhantomData }
}


/// Configures the pin to serve as inverted alternate function 1 (AF1)
pub fn into_inverted_iof1(self) -> $PXi<IOF1<Invert>> {
$GPIOX::set_out_xor(Self::INDEX, true);
Expand Down Expand Up @@ -276,47 +273,52 @@ macro_rules! gpio {
}
}

impl<MODE> InputPin for $PXi<Input<MODE>> {
impl<MODE> ErrorType for $PXi<Input<MODE>> {
type Error = Infallible;
}

fn is_high(&self) -> Result<bool, Infallible> {
Ok($GPIOX::input_value(Self::INDEX))

}

fn is_low(&self) -> Result<bool, Infallible> {
Ok(!self.is_high()?)
}
impl<MODE> ErrorType for $PXi<Output<MODE>> {
type Error = Infallible;
}

impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
fn is_set_high(&self) -> Result<bool, Infallible> {
impl<MODE> InputPin for $PXi<Input<MODE>> {
#[inline]
fn is_high(&mut self) -> Result<bool, Self::Error> {
Ok($GPIOX::input_value(Self::INDEX))
}

fn is_set_low(&self) -> Result<bool, Infallible> {
Ok(!self.is_set_high()?)
#[inline]
fn is_low(&mut self) -> Result<bool, Self::Error> {
Ok(!self.is_high()?)
}
}

impl<MODE> OutputPin for $PXi<Output<MODE>> {
type Error = Infallible;

#[inline]
fn set_high(&mut self) -> Result<(), Infallible> {
$GPIOX::set_output_value(Self::INDEX, true);
Ok(())
}

#[inline]
fn set_low(&mut self) -> Result<(), Infallible> {
$GPIOX::set_output_value(Self::INDEX, false);
Ok(())
}
}

impl<MODE> ToggleableOutputPin for $PXi<Output<MODE>> {
type Error = Infallible;
impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
#[inline]
fn is_set_high(&mut self) -> Result<bool, Infallible> {
Ok($GPIOX::input_value(Self::INDEX))
}

#[inline]
fn is_set_low(&mut self) -> Result<bool, Infallible> {
Ok(!self.is_set_high()?)
}

/// Toggles the pin state.
#[inline]
fn toggle(&mut self) -> Result<(), Infallible> {
$GPIOX::toggle_pin(Self::INDEX);
Ok(())
Expand Down
Loading

0 comments on commit f7e9e47

Please sign in to comment.