Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating smoltcp on DMA branch #183

Merged
merged 9 commits into from
Jan 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ stm32-fmc = { version = "0.2", optional = true }
synopsys-usb-otg = { version = "^0.2.2", features = ["cortex-m"], optional = true }

[dependencies.smoltcp]
version = "0.6.0"
version = "0.7.0"
default-features = false
features = ["ethernet", "proto-ipv4", "proto-dhcpv4", "socket-tcp", "socket-raw"]
features = ["ethernet", "proto-ipv4"]
optional = true

[dependencies.chrono]
Expand All @@ -64,7 +64,7 @@ usb-device = "0.2.5"
usbd-serial = "0.1.0"

[dev-dependencies.smoltcp]
version = "0.6.0"
version = "0.7.0"
default-features = false
features = ["ethernet", "proto-ipv4", "proto-ipv6", "socket-raw"]

Expand Down
16 changes: 8 additions & 8 deletions examples/ethernet-rtic-stm32h747i-disco.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];
static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new();

/// Net storage with static initialisation - another global singleton
pub struct NetStorageStatic<'a, 'b> {
pub struct NetStorageStatic<'a> {
ip_addrs: [IpCidr; 1],
socket_set_entries: [Option<SocketSetItem<'a, 'b>>; 8],
socket_set_entries: [Option<SocketSetItem<'a>>; 8],
neighbor_cache_storage: [Option<(IpAddress, Neighbor)>; 8],
routes_storage: [Option<(IpCidr, Route)>; 1],
}
Expand All @@ -73,13 +73,13 @@ static mut STORE: NetStorageStatic = NetStorageStatic {
routes_storage: [None; 1],
};

pub struct Net<'a: 'b, 'b> {
iface: EthernetInterface<'a, 'a, 'a, ethernet::EthernetDMA<'a>>,
sockets: SocketSet<'a, 'a, 'b>,
pub struct Net<'a> {
iface: EthernetInterface<'a, ethernet::EthernetDMA<'a>>,
sockets: SocketSet<'a>,
}
impl<'a, 'b> Net<'a, 'b> {
impl<'a> Net<'a> {
pub fn new(
store: &'static mut NetStorageStatic<'a, 'b>,
store: &'static mut NetStorageStatic<'a>,
ethdev: ethernet::EthernetDMA<'a>,
ethernet_addr: EthernetAddress,
) -> Self {
Expand Down Expand Up @@ -117,7 +117,7 @@ impl<'a, 'b> Net<'a, 'b> {
#[app(device = stm32h7xx_hal::stm32, peripherals = true)]
const APP: () = {
struct Resources {
net: Net<'static, 'static>,
net: Net<'static>,
lan8742a: ethernet::phy::LAN8742A<ethernet::EthernetMAC>,
link_led: gpio::gpioi::PI14<gpio::Output<gpio::PushPull>>,
}
Expand Down
11 changes: 5 additions & 6 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use crate::stm32::{ADC1, ADC2};
#[cfg(not(feature = "rm0455"))]
use crate::stm32::{ADC3, ADC3_COMMON};

use crate::delay::Delay;
use crate::gpio::gpioa::{PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7};
use crate::gpio::gpiob::{PB0, PB1};
use crate::gpio::gpioc::{PC0, PC1, PC2, PC3, PC4, PC5};
Expand Down Expand Up @@ -304,7 +303,7 @@ pub trait AdcExt<ADC>: Sized {

fn adc(
self,
delay: &mut Delay,
delay: &mut impl DelayUs<u8>,
prec: Self::Rec,
clocks: &CoreClocks,
) -> Adc<ADC, Disabled>;
Expand Down Expand Up @@ -344,7 +343,7 @@ fn check_clock(prec: &impl AdcClkSelGetter, clocks: &CoreClocks) -> Hertz {
pub fn adc12(
adc1: ADC1,
adc2: ADC2,
delay: &mut Delay,
delay: &mut impl DelayUs<u8>,
prec: rec::Adc12,
clocks: &CoreClocks,
) -> (Adc<ADC1, Disabled>, Adc<ADC2, Disabled>) {
Expand Down Expand Up @@ -403,7 +402,7 @@ macro_rules! adc_hal {
type Rec = rec::$Rec;

fn adc(self,
delay: &mut Delay,
delay: &mut impl DelayUs<u8>,
prec: rec::$Rec,
clocks: &CoreClocks) -> Adc<$ADC, Disabled>
{
Expand All @@ -416,7 +415,7 @@ macro_rules! adc_hal {
///
/// Sets all configurable parameters to one-shot defaults,
/// performs a boot-time calibration.
pub fn $adcX(adc: $ADC, delay: &mut Delay,
pub fn $adcX(adc: $ADC, delay: &mut impl DelayUs<u8>,
prec: rec::$Rec, clocks: &CoreClocks
) -> Self {
// Consume ADC register block, produce Self with default
Expand Down Expand Up @@ -455,7 +454,7 @@ macro_rules! adc_hal {
/// Disables Deeppowerdown-mode and enables voltage regulator
///
/// Note: After power-up, a [`calibration`](#method.calibrate) shall be run
pub fn power_up(&mut self, delay: &mut Delay) {
pub fn power_up(&mut self, delay: &mut impl DelayUs<u8>) {
// Refer to RM0433 Rev 6 - Chapter 24.4.6
self.rb.cr.modify(|_, w|
w.deeppwd().clear_bit()
Expand Down
117 changes: 115 additions & 2 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,50 @@
//! Delays
//! Delay providers
//!
//! There are currently two delay providers. In general you should prefer to use
//! [Delay](Delay), however if you do not have access to `SYST` you can use
//! [DelayFromCountDownTimer](DelayFromCountDownTimer) with any timer that
//! implements the [CountDown](embedded_hal::timer::CountDown) trait. This can be
//! useful if you're using [RTIC](https://rtic.rs)'s schedule API, which occupies
//! the `SYST` peripheral.
//!
//! # Examples
//!
//! ## Delay
//!
//! ```no_run
//! let mut delay = Delay::new(core.SYST, device.clocks);
//!
//! delay.delay_ms(500);
//!
//! // Release SYST from the delay
//! let syst = delay.free();
//! ```
//!
//! ## DelayFromCountDownTimer
//!
//! ```no_run
//! let timer2 = device
//! .TIM2
//! .timer(100.ms(), device.peripheral.TIM2, &mut device.clocks);
//! let mut delay = DelayFromCountDownTimer::new(timer2);
//!
//! delay.delay_ms(500);
//!
//! // Release the timer from the delay
//! let timer2 = delay.free();
//! ```

use cast::u32;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::peripheral::SYST;

use crate::nb::block;
use crate::rcc::CoreClocks;
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use crate::time::{Hertz, U32Ext};
use embedded_hal::{
blocking::delay::{DelayMs, DelayUs},
timer::CountDown,
};

pub trait DelayExt {
fn delay(self, clocks: CoreClocks) -> Delay;
Expand Down Expand Up @@ -105,3 +144,77 @@ impl DelayUs<u8> for Delay {
self.delay_us(u32(us))
}
}

/// CountDown Timer as a delay provider
pub struct DelayFromCountDownTimer<T>(T);

impl<T> DelayFromCountDownTimer<T> {
/// Creates delay provider from a CountDown timer
pub fn new(timer: T) -> Self {
Self(timer)
}

/// Releases the Timer
pub fn free(self) -> T {
self.0
}
}

macro_rules! impl_delay_from_count_down_timer {
($(($Delay:ident, $delay:ident, $num:expr)),+) => {
$(

impl<T> $Delay<u32> for DelayFromCountDownTimer<T>
where
T: CountDown<Time = Hertz>,
{
fn $delay(&mut self, t: u32) {
let mut time_left = t;

// Due to the LpTimer having only a 3 bit scaler, it is
// possible that the max timeout we can set is
// (128 * 65536) / clk_hz milliseconds.
// Assuming the fastest clk_hz = 480Mhz this is roughly ~17ms,
// or a frequency of ~57.2Hz. We use a 60Hz frequency for each
// loop step here to ensure that we stay within these bounds.
let looping_delay = $num / 60;
let looping_delay_hz = Hertz($num / looping_delay);

self.0.start(looping_delay_hz);
while time_left > looping_delay {
block!(self.0.wait()).ok();
time_left = time_left - looping_delay;
}

if time_left > 0 {
self.0.start(($num / time_left).hz());
block!(self.0.wait()).ok();
}
}
}

impl<T> $Delay<u16> for DelayFromCountDownTimer<T>
where
T: CountDown<Time = Hertz>,
{
fn $delay(&mut self, t: u16) {
self.$delay(t as u32);
}
}

impl<T> $Delay<u8> for DelayFromCountDownTimer<T>
where
T: CountDown<Time = Hertz>,
{
fn $delay(&mut self, t: u8) {
self.$delay(t as u32);
}
}
)+
}
}

impl_delay_from_count_down_timer! {
(DelayMs, delay_ms, 1_000),
(DelayUs, delay_us, 1_000_000)
}
33 changes: 19 additions & 14 deletions src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,28 +218,28 @@ macro_rules! hal {
self.pause();

// Reset counter
self.tim.cnt.reset();
self.reset_counter();

// UEV event occours on next overflow
self.tim.cr1.modify(|_, w| w.urs().counter_only());
self.clear_uif_bit();
self.urs_counter_only();
self.clear_irq();

// Set PSC and ARR
self.set_freq(timeout);

// Generate an update event to force an update of the ARR register. This ensures
// the first timer cycle is of the specified duration.
self.tim.egr.write(|w| w.ug().set_bit());
self.apply_freq();

// Start counter
self.resume()
}

fn wait(&mut self) -> nb::Result<(), Void> {
if self.tim.sr.read().uif().bit_is_clear() {
if self.is_irq_clear() {
Err(nb::Error::WouldBlock)
} else {
self.clear_uif_bit();
self.clear_irq();
Ok(())
}
}
Expand Down Expand Up @@ -270,16 +270,16 @@ macro_rules! hal {
timer.pause();

// UEV event occours on next overflow
timer.tim.cr1.modify(|_, w| w.urs().counter_only());
timer.clear_uif_bit();
timer.urs_counter_only();
timer.clear_irq();

// Set PSC and ARR
timer.set_tick_freq(frequency);

// Generate an update event to force an update of the ARR
// register. This ensures the first timer cycle is of the
// specified duration.
timer.tim.egr.write(|w| w.ug().set_bit());
timer.apply_freq();

// Start counter
timer.resume();
Expand Down Expand Up @@ -386,11 +386,6 @@ macro_rules! hal {
self.tim.egr.write(|w| w.ug().set_bit());
}

/// Clear uif bit
pub fn clear_uif_bit(&mut self) {
self.tim.sr.modify(|_, w| w.uif().clear_bit());
}

/// Pauses the TIM peripheral
pub fn pause(&mut self) {
self.tim.cr1.modify(|_, w| w.cen().clear_bit());
Expand All @@ -401,6 +396,11 @@ macro_rules! hal {
self.tim.cr1.modify(|_, w| w.cen().set_bit());
}

/// Set Update Request Source to counter overflow/underflow only
pub fn urs_counter_only(&mut self) {
self.tim.cr1.modify(|_, w| w.urs().counter_only());
}

/// Reset the counter of the TIM peripheral
pub fn reset_counter(&mut self) {
self.tim.cnt.reset();
Expand Down Expand Up @@ -431,6 +431,11 @@ macro_rules! hal {
}
}

/// Check if Update Interrupt flag is cleared
pub fn is_irq_clear(&mut self) -> bool {
self.tim.sr.read().uif().bit_is_clear()
}

/// Clears interrupt flag
pub fn clear_irq(&mut self) {
self.tim.sr.modify(|_, w| {
Expand Down