diff --git a/Cargo.toml b/Cargo.toml index 0b87be7..c75624d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ nal = [ "embedded-time", "embedded-nal", "heapless", "smoltcp-phy", "smoltcp/socket-tcp", "smoltcp/ethernet" ] +cortex-m-cpu = ["cortex-m"] # Example-based features smoltcp-examples = [ "smoltcp-phy", "smoltcp/socket-tcp", "smoltcp/ethernet" diff --git a/src/lib.rs b/src/lib.rs index 0cc484e..d9f466d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,24 +44,28 @@ impl From for Error { /// ENC424J600 controller in SPI mode pub struct Enc424j600, - NSS: OutputPin, - F: FnMut(u32) -> ()> { - spi_port: spi::SpiPort, + NSS: OutputPin> { + spi_port: spi::SpiPort, rx_buf: rx::RxBuffer, - tx_buf: tx::TxBuffer + tx_buf: tx::TxBuffer, } impl , - NSS: OutputPin, - F: FnMut(u32) -> ()> Enc424j600 { - pub fn new(spi: SPI, nss: NSS, delay_ns: F) -> Self { + NSS: OutputPin> Enc424j600 { + pub fn new(spi: SPI, nss: NSS) -> Self { Enc424j600 { - spi_port: spi::SpiPort::new(spi, nss, delay_ns), + spi_port: spi::SpiPort::new(spi, nss), rx_buf: rx::RxBuffer::new(), - tx_buf: tx::TxBuffer::new() + tx_buf: tx::TxBuffer::new(), } } + #[cfg(feature = "cortex-m-cpu")] + pub fn cpu_freq_mhz(mut self, freq: u32) -> Self { + self.spi_port = self.spi_port.cpu_freq_mhz(freq); + self + } + pub fn init(&mut self, delay: &mut impl DelayUs) -> Result<(), Error> { self.reset(delay)?; self.init_rxbuf()?; @@ -145,8 +149,7 @@ impl , } impl , - NSS: OutputPin, - F: FnMut(u32) -> ()> EthPhy for Enc424j600 { + NSS: OutputPin> EthPhy for Enc424j600 { /// Receive the next packet and return it /// Set is_poll to true for returning until PKTIF is set; /// Set is_poll to false for returning Err when PKTIF is not set diff --git a/src/spi.rs b/src/spi.rs index 4484719..d43964c 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -62,11 +62,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, - F: FnMut(u32) -> ()> { + NSS: OutputPin> { spi: SPI, nss: NSS, - delay_ns: F, + #[cfg(feature = "cortex-m-cpu")] + cpu_freq_mhz: f32, } pub enum Error { @@ -76,19 +76,25 @@ pub enum Error { #[allow(unused_must_use)] impl , - NSS: OutputPin, - F: FnMut(u32) -> ()> SpiPort { + NSS: OutputPin> SpiPort { // TODO: return as Result() - pub fn new(spi: SPI, mut nss: NSS, delay_ns: F) -> Self { + pub fn new(spi: SPI, mut nss: NSS) -> Self { nss.set_high(); SpiPort { spi, nss, - delay_ns, + #[cfg(feature = "cortex-m-cpu")] + cpu_freq_mhz: 0., } } + #[cfg(feature = "cortex-m-cpu")] + pub fn cpu_freq_mhz(mut self, freq: u32) -> Self { + self.cpu_freq_mhz = freq as f32; + self + } + pub fn read_reg_8b(&mut self, addr: u8) -> Result { // Using RCRU instruction to read using unbanked (full) address let mut buf: [u8; 4] = [0; 4]; @@ -180,10 +186,6 @@ impl , } } - pub fn delay_us(&mut self, duration: u32) { - (self.delay_ns)(duration * 1000) - } - // TODO: Actual data should start from buf[0], not buf[1] // Completes an SPI transfer for reading data to the given buffer, // or writing data from the buffer. @@ -195,10 +197,12 @@ impl , assert!(buf.len() > data_length); // Enable chip select self.nss.set_low(); + // >=50ns min. CS_n setup time + #[cfg(feature = "cortex-m-cpu")] match opcode { opcodes::RCRU | opcodes::WCRU | opcodes::RRXDATA | opcodes::WGPDATA => { - (self.delay_ns)(50); // >=50ns min. CS_n setup time + cortex_m::asm::delay((0.05*(self.cpu_freq_mhz+1.)) as u32); } _ => { } } @@ -209,9 +213,13 @@ impl , opcodes::RCRU | opcodes::WCRU | opcodes::RRXDATA | opcodes::WGPDATA => { // Disable chip select - (self.delay_ns)(50); // >=50ns min. CS_n hold time + // >=50ns min. CS_n hold time + #[cfg(feature = "cortex-m-cpu")] + cortex_m::asm::delay((0.05*(self.cpu_freq_mhz+1.)) as u32); self.nss.set_high(); - (self.delay_ns)(20); // >=20ns min. CS_n disable time + // >=20ns min. CS_n disable time + #[cfg(feature = "cortex-m-cpu")] + cortex_m::asm::delay((0.02*(self.cpu_freq_mhz+1.)) as u32); } _ => { } }