Remove cortex-m dependencies for delay #2
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
src/lib.rs
19
src/lib.rs
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
24
src/spi.rs
24
src/spi.rs
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue