From e9a3a5e550e6fe1f589b885efa1dac07ffe00d6d Mon Sep 17 00:00:00 2001 From: Harry Ho Date: Mon, 28 Dec 2020 16:01:45 +0800 Subject: [PATCH] Add software delays on controller init; add missing SPISEL delay --- examples/tcp_stm32f407.rs | 12 ++++++++---- examples/tx_stm32f407.rs | 2 +- src/lib.rs | 13 ++++++++++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/examples/tcp_stm32f407.rs b/examples/tcp_stm32f407.rs index f9b0f1e..48b26cb 100644 --- a/examples/tcp_stm32f407.rs +++ b/examples/tcp_stm32f407.rs @@ -8,11 +8,13 @@ use cortex_m::iprintln; use cortex_m_rt::entry; use embedded_hal::digital::v2::OutputPin; +use embedded_hal::blocking::delay::DelayMs; use stm32f4xx_hal::{ rcc::RccExt, gpio::GpioExt, time::U32Ext, stm32::{CorePeripherals, Peripherals}, + delay::Delay, spi::Spi, time::Hertz }; @@ -36,7 +38,7 @@ use stm32f4xx_hal::{ rcc::Clocks, time::MilliSeconds, timer::{Timer, Event as TimerEvent}, - stm32::SYST, + stm32::SYST }; /// Rate in Hz const TIMER_RATE: u32 = 20; @@ -117,6 +119,7 @@ fn main() -> ! { // NIC100 / ENC424J600 Set-up let spi1 = dp.SPI1; let gpioa = dp.GPIOA.split(); + let mut delay = Delay::new(cp.SYST, clocks); // Mapping: see Table 9, STM32F407ZG Manual let spi1_sck = gpioa.pa5.into_alternate_af5(); let spi1_miso = gpioa.pa6.into_alternate_af5(); @@ -125,6 +128,7 @@ fn main() -> ! { // Map SPISEL: see Table 1, NIC100 Manual let mut spisel = gpioa.pa1.into_push_pull_output(); spisel.set_high().unwrap(); + delay.delay_ms(1_u32); spisel.set_low().unwrap(); // Create SPI1 for HAL let spi_eth_port = Spi::spi1( @@ -134,7 +138,7 @@ fn main() -> ! { clocks); let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss); // Init - match spi_eth.init_dev() { + match spi_eth.init_dev(&mut delay) { Ok(_) => { iprintln!(stim0, "Ethernet initialised.") } @@ -145,7 +149,7 @@ fn main() -> ! { // Setup SysTick // Reference to stm32-eth:examples/ip.rs - timer_setup(cp.SYST, clocks); + timer_setup(delay.free(), clocks); iprintln!(stim0, "Timer initialised."); // Read MAC @@ -165,7 +169,7 @@ fn main() -> ! { // examples/loopback.rs, examples/multicast.rs let device = smoltcp_phy::SmoltcpDevice::new(&mut spi_eth); let mut neighbor_cache_entries = [None; 16]; - let mut neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]); + let neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]); let ip_addr = IpCidr::new(IpAddress::v4( arg_ip[0], arg_ip[1], arg_ip[2], arg_ip[3]), arg_ip_pref); let mut ip_addrs = [ip_addr]; diff --git a/examples/tx_stm32f407.rs b/examples/tx_stm32f407.rs index df81aba..561dffd 100644 --- a/examples/tx_stm32f407.rs +++ b/examples/tx_stm32f407.rs @@ -63,7 +63,7 @@ fn main() -> ! { clocks); let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss); // Init - match spi_eth.init_dev() { + match spi_eth.init_dev(&mut delay) { Ok(_) => { iprintln!(stim0, "Ethernet initialised.") } diff --git a/src/lib.rs b/src/lib.rs index 8a5490c..0fa33a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,10 @@ pub mod spi; use embedded_hal::{ - blocking::spi::Transfer, + blocking::{ + spi::Transfer, + delay::DelayUs, + }, digital::v2::OutputPin, }; @@ -13,7 +16,7 @@ pub mod tx; pub mod smoltcp_phy; pub trait EthController<'c> { - fn init_dev(&mut self) -> Result<(), EthControllerError>; + fn init_dev(&mut self, delay: &mut dyn DelayUs) -> 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; @@ -57,7 +60,7 @@ impl , impl <'c, SPI: Transfer, NSS: OutputPin> EthController<'c> for SpiEth { - fn init_dev(&mut self) -> Result<(), EthControllerError> { + fn init_dev(&mut self, delay: &mut dyn DelayUs) -> Result<(), EthControllerError> { // Write 0x1234 to EUDAST self.spi_port.write_reg_16b(spi::addrs::EUDAST, 0x1234)?; // Verify that EUDAST is 0x1234 @@ -73,11 +76,15 @@ impl <'c, SPI: Transfer, // 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); // 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); Ok(()) }