Add software delays on controller init; add missing SPISEL delay

This commit is contained in:
Harry Ho 2020-12-28 16:01:45 +08:00
parent ae0d77cbf1
commit e9a3a5e550
3 changed files with 19 additions and 8 deletions

View File

@ -8,11 +8,13 @@ use cortex_m::iprintln;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
use embedded_hal::blocking::delay::DelayMs;
use stm32f4xx_hal::{ use stm32f4xx_hal::{
rcc::RccExt, rcc::RccExt,
gpio::GpioExt, gpio::GpioExt,
time::U32Ext, time::U32Ext,
stm32::{CorePeripherals, Peripherals}, stm32::{CorePeripherals, Peripherals},
delay::Delay,
spi::Spi, spi::Spi,
time::Hertz time::Hertz
}; };
@ -36,7 +38,7 @@ use stm32f4xx_hal::{
rcc::Clocks, rcc::Clocks,
time::MilliSeconds, time::MilliSeconds,
timer::{Timer, Event as TimerEvent}, timer::{Timer, Event as TimerEvent},
stm32::SYST, stm32::SYST
}; };
/// Rate in Hz /// Rate in Hz
const TIMER_RATE: u32 = 20; const TIMER_RATE: u32 = 20;
@ -117,6 +119,7 @@ fn main() -> ! {
// NIC100 / ENC424J600 Set-up // NIC100 / ENC424J600 Set-up
let spi1 = dp.SPI1; let spi1 = dp.SPI1;
let gpioa = dp.GPIOA.split(); let gpioa = dp.GPIOA.split();
let mut delay = Delay::new(cp.SYST, clocks);
// Mapping: see Table 9, STM32F407ZG Manual // Mapping: see Table 9, STM32F407ZG Manual
let spi1_sck = gpioa.pa5.into_alternate_af5(); let spi1_sck = gpioa.pa5.into_alternate_af5();
let spi1_miso = gpioa.pa6.into_alternate_af5(); let spi1_miso = gpioa.pa6.into_alternate_af5();
@ -125,6 +128,7 @@ fn main() -> ! {
// 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();
delay.delay_ms(1_u32);
spisel.set_low().unwrap(); spisel.set_low().unwrap();
// Create SPI1 for HAL // Create SPI1 for HAL
let spi_eth_port = Spi::spi1( let spi_eth_port = Spi::spi1(
@ -134,7 +138,7 @@ fn main() -> ! {
clocks); clocks);
let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss); let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss);
// Init // Init
match spi_eth.init_dev() { match spi_eth.init_dev(&mut delay) {
Ok(_) => { Ok(_) => {
iprintln!(stim0, "Ethernet initialised.") iprintln!(stim0, "Ethernet initialised.")
} }
@ -145,7 +149,7 @@ fn main() -> ! {
// Setup SysTick // Setup SysTick
// Reference to stm32-eth:examples/ip.rs // Reference to stm32-eth:examples/ip.rs
timer_setup(cp.SYST, clocks); timer_setup(delay.free(), clocks);
iprintln!(stim0, "Timer initialised."); iprintln!(stim0, "Timer initialised.");
// Read MAC // Read MAC
@ -165,7 +169,7 @@ fn main() -> ! {
// examples/loopback.rs, examples/multicast.rs // examples/loopback.rs, examples/multicast.rs
let device = smoltcp_phy::SmoltcpDevice::new(&mut spi_eth); let device = smoltcp_phy::SmoltcpDevice::new(&mut spi_eth);
let mut neighbor_cache_entries = [None; 16]; 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( let ip_addr = IpCidr::new(IpAddress::v4(
arg_ip[0], arg_ip[1], arg_ip[2], arg_ip[3]), arg_ip_pref); arg_ip[0], arg_ip[1], arg_ip[2], arg_ip[3]), arg_ip_pref);
let mut ip_addrs = [ip_addr]; let mut ip_addrs = [ip_addr];

View File

@ -63,7 +63,7 @@ fn main() -> ! {
clocks); clocks);
let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss); let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss);
// Init // Init
match spi_eth.init_dev() { match spi_eth.init_dev(&mut delay) {
Ok(_) => { Ok(_) => {
iprintln!(stim0, "Ethernet initialised.") iprintln!(stim0, "Ethernet initialised.")
} }

View File

@ -2,7 +2,10 @@
pub mod spi; pub mod spi;
use embedded_hal::{ use embedded_hal::{
blocking::spi::Transfer, blocking::{
spi::Transfer,
delay::DelayUs,
},
digital::v2::OutputPin, digital::v2::OutputPin,
}; };
@ -13,7 +16,7 @@ pub mod tx;
pub mod smoltcp_phy; pub mod smoltcp_phy;
pub trait EthController<'c> { pub trait EthController<'c> {
fn init_dev(&mut self) -> Result<(), EthControllerError>; fn init_dev(&mut self, delay: &mut dyn DelayUs<u16>) -> Result<(), EthControllerError>;
fn init_rxbuf(&mut self) -> Result<(), EthControllerError>; fn init_rxbuf(&mut self) -> Result<(), EthControllerError>;
fn init_txbuf(&mut self) -> Result<(), EthControllerError>; fn init_txbuf(&mut self) -> Result<(), EthControllerError>;
fn receive_next(&mut self, is_poll: bool) -> Result<rx::RxPacket, EthControllerError>; fn receive_next(&mut self, is_poll: bool) -> Result<rx::RxPacket, EthControllerError>;
@ -57,7 +60,7 @@ impl <SPI: Transfer<u8>,
impl <'c, SPI: Transfer<u8>, impl <'c, SPI: Transfer<u8>,
NSS: OutputPin> EthController<'c> for SpiEth<SPI, NSS> { NSS: OutputPin> EthController<'c> for SpiEth<SPI, NSS> {
fn init_dev(&mut self) -> Result<(), EthControllerError> { fn init_dev(&mut self, delay: &mut dyn DelayUs<u16>) -> 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)?;
// Verify that EUDAST is 0x1234 // Verify that EUDAST is 0x1234
@ -73,11 +76,15 @@ impl <'c, 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
delay.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
delay.delay_us(256_u16);
Ok(()) Ok(())
} }