* Changed delay source from DelayUs from embedded-hal to user-defined closure

* Updated examples
- Removed delay.rs
- Removed over-obvious comments
This commit is contained in:
occheung 2021-01-22 17:44:02 +08:00
parent c146eb155d
commit 366ff1c80e
5 changed files with 41 additions and 68 deletions

View File

@ -1,34 +0,0 @@
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
#[derive(Clone, Copy)]
pub struct AsmDelay {
frequency_us: u32,
frequency_ms: u32,
}
impl AsmDelay {
pub fn new(freq: u32) -> AsmDelay {
AsmDelay {
frequency_us: (freq / 1_000_000),
frequency_ms: (freq / 1_000),
}
}
}
impl<U> DelayUs<U> for AsmDelay
where
U: Into<u32>,
{
fn delay_us(&mut self, us: U) {
cortex_m::asm::delay(self.frequency_us * us.into())
}
}
impl<U> DelayMs<U> for AsmDelay
where
U: Into<u32>,
{
fn delay_ms(&mut self, ms: U) {
cortex_m::asm::delay(self.frequency_ms * ms.into())
}
}

View File

@ -83,7 +83,7 @@ use stm32f4xx_hal::{
type BoosterSpiEth = enc424j600::SpiEth< type BoosterSpiEth = enc424j600::SpiEth<
Spi<SPI1, (PA5<Alternate<AF5>>, PA6<Alternate<AF5>>, PA7<Alternate<AF5>>)>, Spi<SPI1, (PA5<Alternate<AF5>>, PA6<Alternate<AF5>>, PA7<Alternate<AF5>>)>,
PA4<Output<PushPull>>, PA4<Output<PushPull>>,
AsmDelay fn(u32) -> ()
>; >;
pub struct NetStorage { pub struct NetStorage {
@ -99,6 +99,10 @@ static mut NET_STORE: NetStorage = NetStorage {
neighbor_cache: [None; 8], neighbor_cache: [None; 8],
}; };
pub fn delay_ns(time_ns: u32) {
cortex_m::asm::delay((time_ns*168_000_000)/1_000_000_000 + 1)
}
#[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] #[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = { const APP: () = {
struct Resources { struct Resources {
@ -157,7 +161,11 @@ const APP: () = {
enc424j600::spi::interfaces::SPI_MODE, enc424j600::spi::interfaces::SPI_MODE,
Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ), Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ),
clocks); clocks);
enc424j600::SpiEth::new(spi_eth_port, spi1_nss, asm_delay)
let delay_ns_fp: fn(u32) -> () = |time_ns| {
cortex_m::asm::delay((time_ns*21)/125 + 1)
};
enc424j600::SpiEth::new(spi_eth_port, spi1_nss, delay_ns_fp)
}; };
// Init controller // Init controller

View File

@ -13,15 +13,13 @@ use stm32f4xx_hal::{
gpio::GpioExt, gpio::GpioExt,
time::U32Ext, time::U32Ext,
stm32::ITM, stm32::ITM,
delay::Delay,
spi::Spi, spi::Spi,
time::Hertz time::Hertz
}; };
use enc424j600; use enc424j600;
use enc424j600::EthController; use enc424j600::EthController;
mod delay;
use delay::AsmDelay;
/// ///
use stm32f4xx_hal::{ use stm32f4xx_hal::{
stm32::SPI1, stm32::SPI1,
@ -33,13 +31,13 @@ use stm32f4xx_hal::{
type BoosterSpiEth = enc424j600::SpiEth< type BoosterSpiEth = enc424j600::SpiEth<
Spi<SPI1, (PA5<Alternate<AF5>>, PA6<Alternate<AF5>>, PA7<Alternate<AF5>>)>, Spi<SPI1, (PA5<Alternate<AF5>>, PA6<Alternate<AF5>>, PA7<Alternate<AF5>>)>,
PA4<Output<PushPull>>, PA4<Output<PushPull>>,
AsmDelay>; fn(u32)>;
#[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] #[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = { const APP: () = {
struct Resources { struct Resources {
spi_eth: BoosterSpiEth, spi_eth: BoosterSpiEth,
delay: AsmDelay, delay: Delay,
itm: ITM, itm: ITM,
} }
@ -57,7 +55,7 @@ const APP: () = {
//.pclk2(64.mhz()) //.pclk2(64.mhz())
.require_pll48clk() .require_pll48clk()
.freeze(); .freeze();
let mut asm_delay = AsmDelay::new(clocks.sysclk().0); let mut delay = Delay::new(c.core.SYST, clocks);
// Init ITM // Init ITM
let mut itm = c.core.ITM; let mut itm = c.core.ITM;
@ -76,7 +74,7 @@ const APP: () = {
// Map SPISEL: see Table 1, NIC100 Manual // Map SPISEL: see Table 1, NIC100 Manual
let mut spisel = gpioa.pa1.into_push_pull_output(); let mut spisel = gpioa.pa1.into_push_pull_output();
spisel.set_high().unwrap(); spisel.set_high().unwrap();
asm_delay.delay_ms(1_u32); delay.delay_ms(1_u32);
spisel.set_low().unwrap(); spisel.set_low().unwrap();
// Create SPI1 for HAL // Create SPI1 for HAL
let mut spi_eth = { let mut spi_eth = {
@ -85,7 +83,11 @@ const APP: () = {
enc424j600::spi::interfaces::SPI_MODE, enc424j600::spi::interfaces::SPI_MODE,
Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ), Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ),
clocks); clocks);
enc424j600::SpiEth::new(spi_eth_port, spi1_nss, asm_delay)
let delay_ns_fp: fn(u32) -> () = |time_ns| {
cortex_m::asm::delay((time_ns*21)/125 + 1)
};
enc424j600::SpiEth::new(spi_eth_port, spi1_nss, delay_ns_fp)
}; };
// Init // Init
@ -118,7 +120,7 @@ const APP: () = {
init::LateResources { init::LateResources {
spi_eth, spi_eth,
delay: asm_delay, delay,
itm, itm,
} }
} }

View File

@ -4,7 +4,6 @@ pub mod spi;
use embedded_hal::{ use embedded_hal::{
blocking::{ blocking::{
spi::Transfer, spi::Transfer,
delay::DelayUs,
}, },
digital::v2::OutputPin, digital::v2::OutputPin,
}; };
@ -46,18 +45,18 @@ impl From<spi::SpiPortError> for EthControllerError {
/// Ethernet controller using SPI interface /// Ethernet controller using SPI interface
pub struct SpiEth<SPI: Transfer<u8>, pub struct SpiEth<SPI: Transfer<u8>,
NSS: OutputPin, NSS: OutputPin,
Delay: DelayUs<u16>> { F: FnMut(u32) -> ()> {
spi_port: spi::SpiPort<SPI, NSS, Delay>, spi_port: spi::SpiPort<SPI, NSS, F>,
rx_buf: rx::RxBuffer, rx_buf: rx::RxBuffer,
tx_buf: tx::TxBuffer tx_buf: tx::TxBuffer
} }
impl <SPI: Transfer<u8>, impl <SPI: Transfer<u8>,
NSS: OutputPin, NSS: OutputPin,
Delay: DelayUs<u16>> SpiEth<SPI, NSS, Delay> { F: FnMut(u32) -> ()> SpiEth<SPI, NSS, F> {
pub fn new(spi: SPI, nss: NSS, delay: Delay) -> Self { pub fn new(spi: SPI, nss: NSS, f: F) -> Self {
SpiEth { SpiEth {
spi_port: spi::SpiPort::new(spi, nss, delay), spi_port: spi::SpiPort::new(spi, nss, f),
rx_buf: rx::RxBuffer::new(), rx_buf: rx::RxBuffer::new(),
tx_buf: tx::TxBuffer::new() tx_buf: tx::TxBuffer::new()
} }
@ -66,7 +65,7 @@ impl <SPI: Transfer<u8>,
impl <SPI: Transfer<u8>, impl <SPI: Transfer<u8>,
NSS: OutputPin, NSS: OutputPin,
Delay: DelayUs<u16>> EthController for SpiEth<SPI, NSS, Delay> { F: FnMut(u32) -> ()> EthController for SpiEth<SPI, NSS, F> {
fn init_dev(&mut self) -> Result<(), EthControllerError> { fn init_dev(&mut self) -> Result<(), EthControllerError> {
// Write 0x1234 to EUDAST // Write 0x1234 to EUDAST
self.spi_port.write_reg_16b(spi::addrs::EUDAST, 0x1234)?; self.spi_port.write_reg_16b(spi::addrs::EUDAST, 0x1234)?;
@ -83,15 +82,13 @@ impl <SPI: Transfer<u8>,
// Set ETHRST (ECON2<4>) to 1 // Set ETHRST (ECON2<4>) to 1
let econ2 = self.spi_port.read_reg_8b(spi::addrs::ECON2)?; let econ2 = self.spi_port.read_reg_8b(spi::addrs::ECON2)?;
self.spi_port.write_reg_8b(spi::addrs::ECON2, 0x10 | (econ2 & 0b11101111))?; self.spi_port.write_reg_8b(spi::addrs::ECON2, 0x10 | (econ2 & 0b11101111))?;
// Wait for 25us self.spi_port.delay_us(25);
self.spi_port.delay_us(25_u16);
// Verify that EUDAST is 0x0000 // Verify that EUDAST is 0x0000
eudast = self.spi_port.read_reg_16b(spi::addrs::EUDAST)?; eudast = self.spi_port.read_reg_16b(spi::addrs::EUDAST)?;
if eudast != 0x0000 { if eudast != 0x0000 {
return Err(EthControllerError::GeneralError) return Err(EthControllerError::GeneralError)
} }
// Wait for 256us self.spi_port.delay_us(256);
self.spi_port.delay_us(256_u16);
Ok(()) Ok(())
} }

View File

@ -1,5 +1,5 @@
use embedded_hal::{ use embedded_hal::{
blocking::{spi::Transfer, delay::DelayUs}, blocking::{spi::Transfer},
digital::v2::OutputPin, digital::v2::OutputPin,
}; };
@ -53,10 +53,10 @@ pub mod addrs {
/// Note: stm32f4xx_hal::spi's pins include: SCK, MISO, MOSI /// Note: stm32f4xx_hal::spi's pins include: SCK, MISO, MOSI
pub struct SpiPort<SPI: Transfer<u8>, pub struct SpiPort<SPI: Transfer<u8>,
NSS: OutputPin, NSS: OutputPin,
Delay: DelayUs<u16>> { F: FnMut(u32) -> ()> {
spi: SPI, spi: SPI,
nss: NSS, nss: NSS,
delay: Delay, delay_ns: F,
} }
pub enum SpiPortError { pub enum SpiPortError {
@ -66,15 +66,15 @@ pub enum SpiPortError {
#[allow(unused_must_use)] #[allow(unused_must_use)]
impl <SPI: Transfer<u8>, impl <SPI: Transfer<u8>,
NSS: OutputPin, NSS: OutputPin,
Delay: DelayUs<u16>> SpiPort<SPI, NSS, Delay> { F: FnMut(u32) -> ()> SpiPort<SPI, NSS, F> {
// TODO: return as Result() // TODO: return as Result()
pub fn new(spi: SPI, mut nss: NSS, delay: Delay) -> Self { pub fn new(spi: SPI, mut nss: NSS, f: F) -> Self {
nss.set_high(); nss.set_high();
SpiPort { SpiPort {
spi, spi,
nss, nss,
delay delay_ns: f,
} }
} }
@ -119,8 +119,8 @@ impl <SPI: Transfer<u8>,
Ok(()) Ok(())
} }
pub fn delay_us(&mut self, duration: u16) { pub fn delay_us(&mut self, duration: u32) {
self.delay.delay_us(duration) (self.delay_ns)(duration * 1000)
} }
// TODO: Generalise transfer functions // TODO: Generalise transfer functions
@ -139,17 +139,17 @@ impl <SPI: Transfer<u8>,
match self.spi.transfer(&mut buf) { match self.spi.transfer(&mut buf) {
Ok(_) => { Ok(_) => {
// Disable chip select // Disable chip select
self.delay_us(1); (self.delay_ns)(60);
self.nss.set_high(); self.nss.set_high();
self.delay_us(1); (self.delay_ns)(30);
Ok(buf[2]) Ok(buf[2])
}, },
// TODO: Maybe too naive? // TODO: Maybe too naive?
Err(_) => { Err(_) => {
// Disable chip select // Disable chip select
self.delay_us(1); (self.delay_ns)(60);
self.nss.set_high(); self.nss.set_high();
self.delay_us(1); (self.delay_ns)(30);
Err(SpiPortError::TransferError) Err(SpiPortError::TransferError)
} }
} }