diff --git a/examples/tcp_stm32f407.rs b/examples/tcp_stm32f407.rs index b841517..80e3278 100644 --- a/examples/tcp_stm32f407.rs +++ b/examples/tcp_stm32f407.rs @@ -80,7 +80,9 @@ use stm32f4xx_hal::{ }; type BoosterSpiEth = enc424j600::SpiEth< Spi>, PA6>, PA7>)>, - PA4>>; + PA4>, + fn(u32) -> () +>; pub struct NetStorage { ip_addrs: [IpCidr; 1], @@ -153,11 +155,15 @@ const APP: () = { enc424j600::spi::interfaces::SPI_MODE, Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ), clocks); - enc424j600::SpiEth::new(spi_eth_port, spi1_nss) + + 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 - match spi_eth.init_dev(&mut delay) { + match spi_eth.init_dev() { Ok(_) => { iprintln!(stim0, "Initializing Ethernet...") } diff --git a/examples/tx_stm32f407.rs b/examples/tx_stm32f407.rs index 4dd10ac..268e254 100644 --- a/examples/tx_stm32f407.rs +++ b/examples/tx_stm32f407.rs @@ -30,7 +30,8 @@ use stm32f4xx_hal::{ }; type BoosterSpiEth = enc424j600::SpiEth< Spi>, PA6>, PA7>)>, - PA4>>; + PA4>, + fn(u32)>; #[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] const APP: () = { @@ -82,11 +83,15 @@ const APP: () = { enc424j600::spi::interfaces::SPI_MODE, Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ), clocks); - enc424j600::SpiEth::new(spi_eth_port, spi1_nss) + + let delay_ns: fn(u32) -> () = |time_ns| { + cortex_m::asm::delay((time_ns*21)/125 + 1) + }; + enc424j600::SpiEth::new(spi_eth_port, spi1_nss, delay_ns) }; // Init - match spi_eth.init_dev(&mut delay) { + match spi_eth.init_dev() { Ok(_) => { iprintln!(stim0, "Initializing Ethernet...") } diff --git a/src/lib.rs b/src/lib.rs index af883e9..71e6e7c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,6 @@ pub mod spi; use embedded_hal::{ blocking::{ spi::Transfer, - delay::DelayUs, }, digital::v2::OutputPin, }; @@ -19,7 +18,7 @@ pub mod smoltcp_phy; pub const RAW_FRAME_LENGTH_MAX: usize = 1518; pub trait EthController { - fn init_dev(&mut self, delay: &mut impl DelayUs) -> Result<(), EthControllerError>; + fn init_dev(&mut self) -> Result<(), EthControllerError>; fn init_rxbuf(&mut self) -> Result<(), EthControllerError>; fn init_txbuf(&mut self) -> Result<(), EthControllerError>; fn receive_next(&mut self, is_poll: bool) -> Result; @@ -45,17 +44,19 @@ impl From for EthControllerError { /// Ethernet controller using SPI interface pub struct SpiEth, - NSS: OutputPin> { - spi_port: spi::SpiPort, + NSS: OutputPin, + F: FnMut(u32) -> ()> { + spi_port: spi::SpiPort, rx_buf: rx::RxBuffer, tx_buf: tx::TxBuffer } impl , - NSS: OutputPin> SpiEth { - pub fn new(spi: SPI, nss: NSS) -> Self { + NSS: OutputPin, + F: FnMut(u32) -> ()> SpiEth { + pub fn new(spi: SPI, nss: NSS, delay_ns: F) -> Self { SpiEth { - spi_port: spi::SpiPort::new(spi, nss), + spi_port: spi::SpiPort::new(spi, nss, delay_ns), rx_buf: rx::RxBuffer::new(), tx_buf: tx::TxBuffer::new() } @@ -63,8 +64,9 @@ impl , } impl , - NSS: OutputPin> EthController for SpiEth { - fn init_dev(&mut self, delay: &mut impl DelayUs) -> Result<(), EthControllerError> { + NSS: OutputPin, + F: FnMut(u32) -> ()> EthController for SpiEth { + fn init_dev(&mut self) -> Result<(), EthControllerError> { // Write 0x1234 to EUDAST self.spi_port.write_reg_16b(spi::addrs::EUDAST, 0x1234)?; // Verify that EUDAST is 0x1234 @@ -80,15 +82,13 @@ impl , // Set ETHRST (ECON2<4>) to 1 let econ2 = self.spi_port.read_reg_8b(spi::addrs::ECON2)?; self.spi_port.write_reg_8b(spi::addrs::ECON2, 0x10 | (econ2 & 0b11101111))?; - // Wait for 25us - delay.delay_us(25_u16); + self.spi_port.delay_us(25); // Verify that EUDAST is 0x0000 eudast = self.spi_port.read_reg_16b(spi::addrs::EUDAST)?; if eudast != 0x0000 { return Err(EthControllerError::GeneralError) } - // Wait for 256us - delay.delay_us(256_u16); + self.spi_port.delay_us(256); Ok(()) } diff --git a/src/spi.rs b/src/spi.rs index c2f5dcc..a5dd23c 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -52,9 +52,11 @@ pub mod addrs { /// Struct for SPI I/O interface on ENC424J600 /// Note: stm32f4xx_hal::spi's pins include: SCK, MISO, MOSI pub struct SpiPort, - NSS: OutputPin> { + NSS: OutputPin, + F: FnMut(u32) -> ()> { spi: SPI, nss: NSS, + delay_ns: F, } pub enum SpiPortError { @@ -63,14 +65,16 @@ pub enum SpiPortError { #[allow(unused_must_use)] impl , - NSS: OutputPin> SpiPort { + NSS: OutputPin, + F: FnMut(u32) -> ()> SpiPort { // TODO: return as Result() - pub fn new(spi: SPI, mut nss: NSS) -> Self { + pub fn new(spi: SPI, mut nss: NSS, delay_ns: F) -> Self { nss.set_high(); SpiPort { spi, - nss + nss, + delay_ns, } } @@ -115,6 +119,10 @@ impl , Ok(()) } + pub fn delay_us(&mut self, duration: u32) { + (self.delay_ns)(duration * 1000) + } + // TODO: Generalise transfer functions // TODO: (Make data read/write as reference to array) // Currently requires 1-byte addr, read/write data is only 1-byte @@ -131,17 +139,17 @@ impl , match self.spi.transfer(&mut buf) { Ok(_) => { // Disable chip select - cortex_m::asm::delay(10_u32); + (self.delay_ns)(60); self.nss.set_high(); - cortex_m::asm::delay(5_u32); + (self.delay_ns)(30); Ok(buf[2]) }, // TODO: Maybe too naive? Err(_) => { // Disable chip select - cortex_m::asm::delay(10_u32); + (self.delay_ns)(60); self.nss.set_high(); - cortex_m::asm::delay(5_u32); + (self.delay_ns)(30); Err(SpiPortError::TransferError) } }