Remove cortex-m dependencies for delay (#2)

Co-Authored-By: occheung <dc@m-labs.hk>
Co-Committed-By: occheung <dc@m-labs.hk>
This commit is contained in:
occheung 2021-01-25 12:35:23 +08:00 committed by sb10q
parent 1ce193b8aa
commit 1add94c12e
4 changed files with 46 additions and 27 deletions

View File

@ -80,7 +80,9 @@ 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>>,
fn(u32) -> ()
>;
pub struct NetStorage { pub struct NetStorage {
ip_addrs: [IpCidr; 1], ip_addrs: [IpCidr; 1],
@ -153,11 +155,15 @@ 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)
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
match spi_eth.init_dev(&mut delay) { match spi_eth.init_dev() {
Ok(_) => { Ok(_) => {
iprintln!(stim0, "Initializing Ethernet...") iprintln!(stim0, "Initializing Ethernet...")
} }

View File

@ -30,7 +30,8 @@ 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>>,
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: () = {
@ -82,11 +83,15 @@ 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)
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 // Init
match spi_eth.init_dev(&mut delay) { match spi_eth.init_dev() {
Ok(_) => { Ok(_) => {
iprintln!(stim0, "Initializing Ethernet...") iprintln!(stim0, "Initializing Ethernet...")
} }

View File

@ -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,
}; };
@ -19,7 +18,7 @@ pub mod smoltcp_phy;
pub const RAW_FRAME_LENGTH_MAX: usize = 1518; pub const RAW_FRAME_LENGTH_MAX: usize = 1518;
pub trait EthController { pub trait EthController {
fn init_dev(&mut self, delay: &mut impl DelayUs<u16>) -> Result<(), EthControllerError>; fn init_dev(&mut self) -> 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>;
@ -45,17 +44,19 @@ 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,
spi_port: spi::SpiPort<SPI, NSS>, F: FnMut(u32) -> ()> {
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> SpiEth<SPI, NSS> { NSS: OutputPin,
pub fn new(spi: SPI, nss: NSS) -> Self { F: FnMut(u32) -> ()> SpiEth<SPI, NSS, F> {
pub fn new(spi: SPI, nss: NSS, delay_ns: F) -> Self {
SpiEth { SpiEth {
spi_port: spi::SpiPort::new(spi, nss), spi_port: spi::SpiPort::new(spi, nss, delay_ns),
rx_buf: rx::RxBuffer::new(), rx_buf: rx::RxBuffer::new(),
tx_buf: tx::TxBuffer::new() tx_buf: tx::TxBuffer::new()
} }
@ -63,8 +64,9 @@ impl <SPI: Transfer<u8>,
} }
impl <SPI: Transfer<u8>, impl <SPI: Transfer<u8>,
NSS: OutputPin> EthController for SpiEth<SPI, NSS> { NSS: OutputPin,
fn init_dev(&mut self, delay: &mut impl DelayUs<u16>) -> Result<(), EthControllerError> { F: FnMut(u32) -> ()> EthController for SpiEth<SPI, NSS, F> {
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)?;
// Verify that EUDAST is 0x1234 // Verify that EUDAST is 0x1234
@ -80,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);
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 self.spi_port.delay_us(256);
delay.delay_us(256_u16);
Ok(()) Ok(())
} }

View File

@ -52,9 +52,11 @@ pub mod addrs {
/// Struct for SPI I/O interface on ENC424J600 /// Struct for SPI I/O interface on ENC424J600
/// 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,
F: FnMut(u32) -> ()> {
spi: SPI, spi: SPI,
nss: NSS, nss: NSS,
delay_ns: F,
} }
pub enum SpiPortError { pub enum SpiPortError {
@ -63,14 +65,16 @@ pub enum SpiPortError {
#[allow(unused_must_use)] #[allow(unused_must_use)]
impl <SPI: Transfer<u8>, impl <SPI: Transfer<u8>,
NSS: OutputPin> SpiPort<SPI, NSS> { NSS: OutputPin,
F: FnMut(u32) -> ()> SpiPort<SPI, NSS, F> {
// TODO: return as Result() // 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(); nss.set_high();
SpiPort { SpiPort {
spi, spi,
nss nss,
delay_ns,
} }
} }
@ -115,6 +119,10 @@ impl <SPI: Transfer<u8>,
Ok(()) Ok(())
} }
pub fn delay_us(&mut self, duration: u32) {
(self.delay_ns)(duration * 1000)
}
// TODO: Generalise transfer functions // TODO: Generalise transfer functions
// TODO: (Make data read/write as reference to array) // TODO: (Make data read/write as reference to array)
// Currently requires 1-byte addr, read/write data is only 1-byte // Currently requires 1-byte addr, read/write data is only 1-byte
@ -131,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
cortex_m::asm::delay(10_u32); (self.delay_ns)(60);
self.nss.set_high(); self.nss.set_high();
cortex_m::asm::delay(5_u32); (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
cortex_m::asm::delay(10_u32); (self.delay_ns)(60);
self.nss.set_high(); self.nss.set_high();
cortex_m::asm::delay(5_u32); (self.delay_ns)(30);
Err(SpiPortError::TransferError) Err(SpiPortError::TransferError)
} }
} }