Skip to content

Commit

Permalink
Update embedded-hal traits (#47)
Browse files Browse the repository at this point in the history
* Update delays to use EH 1.0 rc1 traits

* Update gpio to use EH 1.0 rc1 traits

* Update clock to use EH 1.0 rc1 traits

* Update i2c to use EH 1.0 rc1 traits

* Switch timer to implement 0.2 countdown, as 1.0 does not have it yet

* Switch serial to implement embedded-hal-nb 1.0 rc1 traits

* Switch spi to implement embedded-hal-nb 1.0 rc1 traits

* Switch watchdog from embedded-hal 1.0 traits to 0.2 traits

* Switch timer from associated type error to CountDownError to match newer e-h traits

* Add embedded-hal 1.0 and embedded-hal-nb error impls for gpio, i2c, serial, spi

* Update types and errorkind on delay 0.2 and 1.0 impls

* Add mapping from i2c::Error to e-h::i2c::ErrorKind

* Add mapping from serial::Error to e-h-nb::serial::ErrorKind

* Update watchdog impls to match e-h 0.2 traits

* Fix CountDownTimer signature. Removed wrap-check as 500 years runtime is unlikely

* Add void to dependencies

* Remove unused import + dead code

* Fix examples

* Don't try to implement I2c::transaction - leave it as Unimplemented!() for now

* Implement eh 0.2 DelayMs for all integer types
  • Loading branch information
9names authored Oct 16, 2023
1 parent dfa6556 commit 0b230e8
Show file tree
Hide file tree
Showing 14 changed files with 204 additions and 175 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ description = "HAL for the bl602 microcontroller"

[dependencies]
bl602-pac = { git = "https://github.com/sipeed/bl602-pac", branch = "main" }
embedded-hal = "=1.0.0-alpha.5"
embedded-hal = "=1.0.0-rc.1"
embedded-hal-nb = "=1.0.0-rc.1"
embedded-time = "0.12.0"
riscv = "0.10.1"
nb = "1.0"
paste = "1.0"
void = { default-features = false, version = "1.0.2" }

[dependencies.embedded-hal-zero]
version = "0.2.5"
Expand Down
8 changes: 4 additions & 4 deletions examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#![no_main]

use bl602_hal as hal;
use embedded_hal::delay::blocking::DelayMs;
use embedded_hal::digital::blocking::OutputPin;
use embedded_hal::delay::DelayUs;
use embedded_hal::digital::OutputPin;
use hal::{
clock::{Strict, SysclkFreq, UART_PLL_FREQ},
pac,
Expand All @@ -30,9 +30,9 @@ fn main() -> ! {

loop {
gpio5.set_high().unwrap();
d.delay_ms(1000).unwrap();
d.delay_ms(1000);

gpio5.set_low().unwrap();
d.delay_ms(1000).unwrap();
d.delay_ms(1000);
}
}
4 changes: 2 additions & 2 deletions examples/led_interrupt_switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

use bl602_hal as hal;
use core::mem::MaybeUninit;
use embedded_hal::digital::blocking::OutputPin;
use embedded_hal::digital::blocking::StatefulOutputPin;
use embedded_hal::digital::OutputPin;
use embedded_hal::digital::StatefulOutputPin;
use hal::{interrupts::*, pac, prelude::*};
use panic_halt as _;

Expand Down
6 changes: 3 additions & 3 deletions examples/led_timer_interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use bl602_hal as hal;
use core::cell::RefCell;
use core::ops::DerefMut;
use critical_section::{self, Mutex};
use embedded_hal::digital::blocking::{OutputPin, ToggleableOutputPin};
use embedded_hal::timer::nb::CountDown;
use embedded_hal::digital::{OutputPin, ToggleableOutputPin};
use embedded_hal_zero::timer::CountDown;
use embedded_time::{duration::*, rate::*};
use hal::{
clock::{Strict, SysclkFreq},
Expand Down Expand Up @@ -107,7 +107,7 @@ fn main() -> ! {
// a timer without needing to configure any match values or handle any interrupts:
loop {
// Start the timer's CountDown functionality. The countdown will last 3000ms.
timer_ch1.start(3_000u32.milliseconds()).ok();
timer_ch1.start(3_000u32.milliseconds());
// The .wait() function returns an error until the timer has finished counting down.
while timer_ch1.wait().is_err() {
// Stay in the while loop until the timer is done.
Expand Down
4 changes: 2 additions & 2 deletions examples/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use bl602_hal as hal;
use core::fmt::Write;
use embedded_hal::delay::blocking::DelayMs;
use embedded_hal::delay::DelayUs;
use hal::{
clock::{Strict, SysclkFreq, UART_PLL_FREQ},
pac,
Expand Down Expand Up @@ -44,6 +44,6 @@ fn main() -> ! {

loop {
serial.write_str("Hello Rust\r\n").ok();
d.delay_ms(1000).unwrap();
d.delay_ms(1000);
}
}
18 changes: 9 additions & 9 deletions examples/watchdog_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ use core::cell::RefCell;
use core::fmt::Write;
use core::ops::DerefMut;
use critical_section::{self, Mutex};
use embedded_hal::delay::blocking::DelayMs;
use embedded_hal::digital::blocking::{OutputPin, ToggleableOutputPin};
use embedded_hal::watchdog::blocking::{Enable, Watchdog};
use embedded_hal::delay::DelayUs;
use embedded_hal::digital::{OutputPin, ToggleableOutputPin};
use embedded_hal_zero::watchdog::{Watchdog, WatchdogEnable};
use embedded_time::{duration::*, rate::*};
use hal::{
clock::{Strict, SysclkFreq, UART_PLL_FREQ},
Expand Down Expand Up @@ -86,7 +86,7 @@ fn main() -> ! {

// Set up the watchdog timer to the slowest tick rate possible:
let timers = dp.TIMER.split();
let watchdog = timers
let mut watchdog = timers
.watchdog
.set_clock_source(WdtClockSource::Rc32Khz, 125.Hz());

Expand All @@ -112,7 +112,7 @@ fn main() -> ! {

// The watchdog timer doesn't begin counting ticks until it is started. We don't need to handle
// the error state, since the watchdog start function will never actually return an Err().
let watchdog = watchdog.start(10_u32.seconds()).unwrap();
watchdog.start(10_u32.seconds());

// Move the references to their UnsafeCells once initialized, and before interrupts are enabled:
critical_section::with(|cs| G_INTERRUPT_LED_PIN_R.borrow(cs).replace(Some(r_led_pin)));
Expand All @@ -126,10 +126,10 @@ fn main() -> ! {
// In order to use the watchdog once it has been moved into the RefCell, you must call free():
critical_section::with(|cs| {
if let Some(watchdog) = G_LED_TIMER.borrow(cs).borrow_mut().deref_mut() {
watchdog.feed().ok();
watchdog.feed();
}
});
d.delay_ms(20_000).ok();
d.delay_ms(20_000);
}
}

Expand All @@ -145,14 +145,14 @@ fn Watchdog(_: &mut TrapFrame) {
critical_section::with(|cs| {
if let Some(watchdog) = G_LED_TIMER.borrow(cs).borrow_mut().deref_mut() {
watchdog.clear_interrupt();
watchdog.feed().ok();
watchdog.feed();
}
});

// Toggle the red led whenever the interrupt is triggered:
critical_section::with(|cs| {
if let Some(led_pin) = G_INTERRUPT_LED_PIN_R.borrow(cs).borrow_mut().deref_mut() {
led_pin.toggle().ok();
led_pin.toggle();
}
});

Expand Down
24 changes: 12 additions & 12 deletions src/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::delay::*;
use crate::gpio::ClkCfg;
use crate::pac;
use core::num::NonZeroU32;
use embedded_hal::delay::blocking::DelayUs;
use embedded_hal::delay::DelayUs;
use embedded_time::rate::{Extensions, Hertz};

/// Internal high-speed RC oscillator frequency
Expand Down Expand Up @@ -367,13 +367,13 @@ fn glb_set_system_clk_div(hclkdiv: u8, bclkdiv: u8) {
let mut delay = McycleDelay::new(system_core_clock_get());

// This delay used to be 8 NOPS (1/4 us). Might need to be replaced again.
delay.delay_us(1).unwrap();
delay.delay_us(1);

unsafe { &*pac::GLB::ptr() }
.clk_cfg0
.modify(|_, w| w.reg_hclk_en().set_bit().reg_bclk_en().set_bit());

delay.delay_us(1).unwrap();
delay.delay_us(1);
}

// This is a reference implementation of `PDS_Select_XTAL_As_PLL_Ref`.
Expand Down Expand Up @@ -532,7 +532,7 @@ fn pds_power_on_pll(freq: u32) {
pds.pu_rst_clkpll
.modify(|_, w| w.pu_clkpll_sfreg().set_bit());

delay.delay_us(5).unwrap();
delay.delay_us(5);

pds.pu_rst_clkpll.modify(|_, w| w.pu_clkpll().set_bit());

Expand All @@ -547,22 +547,22 @@ fn pds_power_on_pll(freq: u32) {
.set_bit()
});

delay.delay_us(5).unwrap();
delay.delay_us(5);

pds.pu_rst_clkpll
.modify(|_, w| w.clkpll_sdm_reset().set_bit());

delay.delay_us(1).unwrap();
delay.delay_us(1);

pds.pu_rst_clkpll
.modify(|_, w| w.clkpll_reset_fbdv().set_bit());

delay.delay_us(2).unwrap();
delay.delay_us(2);

pds.pu_rst_clkpll
.modify(|_, w| w.clkpll_reset_fbdv().clear_bit());

delay.delay_us(1).unwrap();
delay.delay_us(1);

pds.pu_rst_clkpll
.modify(|_, w| w.clkpll_sdm_reset().clear_bit());
Expand All @@ -576,7 +576,7 @@ fn aon_power_on_xtal() -> Result<(), &'static str> {
let mut delaysrc = McycleDelay::new(system_core_clock_get());
let mut timeout: u32 = 0;

delaysrc.delay_us(10).unwrap();
delaysrc.delay_us(10);

while unsafe { &*pac::AON::ptr() }
.tsen
Expand All @@ -585,7 +585,7 @@ fn aon_power_on_xtal() -> Result<(), &'static str> {
.bit_is_clear()
&& timeout < 120
{
delaysrc.delay_us(10).unwrap();
delaysrc.delay_us(10);
timeout += 1;
}

Expand Down Expand Up @@ -653,7 +653,7 @@ fn glb_set_system_clk_pll(target_core_clk: u32, xtal_freq: u32) {
pds_power_on_pll_rom(xtal_freq);

let mut delay = McycleDelay::new(system_core_clock_get());
delay.delay_us(55).unwrap();
delay.delay_us(55);

pds_enable_pll_all_clks();

Expand Down Expand Up @@ -695,7 +695,7 @@ fn glb_set_system_clk_pll(target_core_clk: u32, xtal_freq: u32) {
let mut delay = McycleDelay::new(system_core_clock_get());

// This delay used to be 8 NOPS (1/4 us). (GLB_CLK_SET_DUMMY_WAIT) Might need to be replaced again.
delay.delay_us(1).unwrap();
delay.delay_us(1);

// use 120Mhz PLL tap for PKA clock since we're using PLL
// NOTE: This isn't documented in the datasheet!
Expand Down
86 changes: 75 additions & 11 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Delays

use core::convert::Infallible;
use embedded_hal::delay::blocking::{DelayMs, DelayUs};
use embedded_hal::delay::DelayUs;
use embedded_hal_zero::blocking::delay::{DelayMs as DelayMsZero, DelayUs as DelayUsZero};

/// Use RISCV machine-mode cycle counter (`mcycle`) as a delay provider.
///
Expand Down Expand Up @@ -43,26 +43,90 @@ impl McycleDelay {
}
}

impl DelayUs<u64> for McycleDelay {
type Error = Infallible;
// embedded-hal 1.0 traits
impl DelayUs for McycleDelay {
/// Performs a busy-wait loop until the number of microseconds `us` has elapsed
#[inline]
fn delay_us(&mut self, us: u32) {
McycleDelay::delay_cycles((us as u64 * (self.core_frequency as u64)) / 1_000_000);
}
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: u32) {
McycleDelay::delay_cycles((ms as u64 * (self.core_frequency as u64)) / 1000);
}
}

// embedded-hal 0.2 traits
impl DelayUsZero<u64> for McycleDelay {
/// Performs a busy-wait loop until the number of microseconds `us` has elapsed
#[inline]
fn delay_us(&mut self, us: u64) -> Result<(), Infallible> {
fn delay_us(&mut self, us: u64) {
McycleDelay::delay_cycles((us * (self.core_frequency as u64)) / 1_000_000);
}
}

Ok(())
// Call DelayMsZero::<u64>::delay_ms for all of u8/u16/u32/i8/i16/i32/i64
impl DelayMsZero<u8> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: u8) {
DelayMsZero::<u64>::delay_ms(self, ms as u64);
}
}

impl DelayMs<u64> for McycleDelay {
type Error = Infallible;
impl DelayMsZero<u16> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: u16) {
DelayMsZero::<u64>::delay_ms(self, ms as u64);
}
}

impl DelayMsZero<u32> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: u64) -> Result<(), Infallible> {
McycleDelay::delay_cycles((ms * (self.core_frequency as u64)) / 1000);
fn delay_ms(&mut self, ms: u32) {
DelayMsZero::<u64>::delay_ms(self, ms as u64);
}
}

Ok(())
impl DelayMsZero<i8> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: i8) {
DelayMsZero::<u64>::delay_ms(self, ms as u64);
}
}

impl DelayMsZero<i16> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: i16) {
DelayMsZero::<u64>::delay_ms(self, ms as u64);
}
}

impl DelayMsZero<i32> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: i32) {
DelayMsZero::<u64>::delay_ms(self, ms as u64);
}
}

impl DelayMsZero<i64> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: i64) {
DelayMsZero::<u64>::delay_ms(self, ms as u64);
}
}

impl DelayMsZero<u64> for McycleDelay {
/// Performs a busy-wait loop until the number of milliseconds `ms` has elapsed
#[inline]
fn delay_ms(&mut self, ms: u64) {
McycleDelay::delay_cycles((ms * (self.core_frequency as u64)) / 1000);
}
}
14 changes: 7 additions & 7 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ macro_rules! impl_glb {
pub mod pin {
use core::marker::PhantomData;
use core::convert::Infallible;
use embedded_hal::digital::blocking::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
use embedded_hal_zero::digital::v2::{
InputPin as InputPinZero,
OutputPin as OutputPinZero,
Expand Down Expand Up @@ -454,10 +454,11 @@ macro_rules! impl_glb {
}
}


impl<MODE> InputPin for $Pini<Input<MODE>> {
impl<MODE> embedded_hal::digital::ErrorType for $Pini<Input<MODE>> {
type Error = Infallible;
}

impl<MODE> InputPin for $Pini<Input<MODE>> {
fn is_high(&self) -> Result<bool, Self::Error> {
Ok(self.is_high_inner())
}
Expand Down Expand Up @@ -538,10 +539,11 @@ macro_rules! impl_glb {
}
}


impl<MODE> OutputPin for $Pini<Output<MODE>> {
impl<MODE> embedded_hal::digital::ErrorType for $Pini<Output<MODE>> {
type Error = Infallible;
}

impl<MODE> OutputPin for $Pini<Output<MODE>> {
fn set_high(&mut self) -> Result<(), Self::Error> {
self.set_high_inner();
Ok(())
Expand Down Expand Up @@ -589,8 +591,6 @@ macro_rules! impl_glb {


impl<MODE> ToggleableOutputPin for $Pini<Output<MODE>> {
type Error = Infallible;

fn toggle(&mut self) -> Result<(), Self::Error> {
if self.is_output_high_inner() {
self.set_low_inner()
Expand Down
Loading

0 comments on commit 0b230e8

Please sign in to comment.