forked from renet/ENC424J600
Simplify, styling & spelling
This commit is contained in:
parent
e9a3a5e550
commit
4ba5052623
|
@ -4,7 +4,7 @@
|
|||
use core::env;
|
||||
|
||||
extern crate panic_itm;
|
||||
use cortex_m::iprintln;
|
||||
use cortex_m::{iprintln, iprint};
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
@ -90,7 +90,7 @@ fn main() -> ! {
|
|||
let mut itm = cp.ITM;
|
||||
let stim0 = &mut itm.stim[0];
|
||||
|
||||
iprintln!(stim0,
|
||||
iprintln!(stim0,
|
||||
"Eth TCP Server on STM32-F407 via NIC100/ENC424J600");
|
||||
|
||||
// Get IP address from args
|
||||
|
@ -132,34 +132,38 @@ fn main() -> ! {
|
|||
spisel.set_low().unwrap();
|
||||
// Create SPI1 for HAL
|
||||
let spi_eth_port = Spi::spi1(
|
||||
spi1, (spi1_sck, spi1_miso, spi1_mosi),
|
||||
enc424j600::spi::interfaces::SPI_MODE,
|
||||
spi1, (spi1_sck, spi1_miso, spi1_mosi),
|
||||
enc424j600::spi::interfaces::SPI_MODE,
|
||||
Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ),
|
||||
clocks);
|
||||
let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss);
|
||||
// Init
|
||||
match spi_eth.init_dev(&mut delay) {
|
||||
Ok(_) => {
|
||||
iprintln!(stim0, "Ethernet initialised.")
|
||||
iprintln!(stim0, "Ethernet initialized")
|
||||
}
|
||||
Err(_) => {
|
||||
panic!("Ethernet initialisation Failed!")
|
||||
panic!("Ethernet initialization failed!")
|
||||
}
|
||||
}
|
||||
|
||||
// Setup SysTick
|
||||
// Reference to stm32-eth:examples/ip.rs
|
||||
timer_setup(delay.free(), clocks);
|
||||
iprintln!(stim0, "Timer initialised.");
|
||||
iprintln!(stim0, "Timer initialized");
|
||||
|
||||
// Read MAC
|
||||
let mut eth_mac_addr: [u8; 6] = [0; 6];
|
||||
spi_eth.read_from_mac(&mut eth_mac_addr);
|
||||
iprintln!(stim0,
|
||||
"MAC Address = {:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
|
||||
eth_mac_addr[0], eth_mac_addr[1],
|
||||
eth_mac_addr[2], eth_mac_addr[3],
|
||||
eth_mac_addr[4], eth_mac_addr[5]);
|
||||
for i in 0..6 {
|
||||
let byte = eth_mac_addr[i];
|
||||
match i {
|
||||
0 => iprint!(stim0, "MAC Address = {:02x}-", byte),
|
||||
1..=4 => iprint!(stim0, "{:02x}-", byte),
|
||||
5 => iprint!(stim0, "{:02x}\n", byte),
|
||||
_ => ()
|
||||
};
|
||||
}
|
||||
|
||||
// Init Rx/Tx buffers
|
||||
spi_eth.init_rxbuf();
|
||||
|
@ -199,10 +203,9 @@ fn main() -> ! {
|
|||
let mut socket_set = SocketSet::new(&mut socket_set_entries[..]);
|
||||
let echo_handle = socket_set.add(echo_socket);
|
||||
let greet_handle = socket_set.add(greet_socket);
|
||||
iprintln!(stim0,
|
||||
"TCP sockets will listen at {}", ip_addr);
|
||||
iprintln!(stim0, "TCP sockets will listen at {}", ip_addr);
|
||||
|
||||
// Copied / modified from:
|
||||
// Copied / modified from:
|
||||
// smoltcp:examples/loopback.rs, examples/server.rs;
|
||||
// stm32-eth:examples/ip.rs,
|
||||
// git.m-labs.hk/M-Labs/tnetplug
|
||||
|
@ -220,13 +223,13 @@ fn main() -> ! {
|
|||
{
|
||||
let mut socket = socket_set.get::<TcpSocket>(echo_handle);
|
||||
if !socket.is_open() {
|
||||
iprintln!(stim0,
|
||||
iprintln!(stim0,
|
||||
"[{}] Listening to port 1234 for echoing, time-out in 10s", instant);
|
||||
socket.listen(1234).unwrap();
|
||||
socket.set_timeout(Some(Duration::from_millis(10000)));
|
||||
}
|
||||
if socket.can_recv() {
|
||||
iprintln!(stim0,
|
||||
iprintln!(stim0,
|
||||
"[{}] Received packet: {:?}", instant, socket.recv(|buffer| {
|
||||
(buffer.len(), str::from_utf8(buffer).unwrap())
|
||||
}));
|
||||
|
@ -236,7 +239,7 @@ fn main() -> ! {
|
|||
{
|
||||
let mut socket = socket_set.get::<TcpSocket>(greet_handle);
|
||||
if !socket.is_open() {
|
||||
iprintln!(stim0,
|
||||
iprintln!(stim0,
|
||||
"[{}] Listening to port 4321 for greeting, \
|
||||
please connect to the port", instant);
|
||||
socket.listen(4321).unwrap();
|
||||
|
@ -245,13 +248,10 @@ fn main() -> ! {
|
|||
if socket.can_send() {
|
||||
let greeting = "Welcome to the server demo for STM32-F407!";
|
||||
write!(socket, "{}\n", greeting).unwrap();
|
||||
iprintln!(stim0,
|
||||
iprintln!(stim0,
|
||||
"[{}] Greeting sent, socket closed", instant);
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unreachable!()
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#![no_main]
|
||||
|
||||
extern crate panic_itm;
|
||||
use cortex_m::iprintln;
|
||||
use cortex_m::{iprintln, iprint};
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
@ -39,7 +39,7 @@ fn main() -> ! {
|
|||
let mut itm = cp.ITM;
|
||||
let stim0 = &mut itm.stim[0];
|
||||
|
||||
iprintln!(stim0,
|
||||
iprintln!(stim0,
|
||||
"Eth TX Pinging on STM32-F407 via NIC100/ENC424J600");
|
||||
|
||||
// NIC100 / ENC424J600 Set-up
|
||||
|
@ -57,7 +57,7 @@ fn main() -> ! {
|
|||
spisel.set_low().unwrap();
|
||||
// Create SPI1 for HAL
|
||||
let spi_eth_port = Spi::spi1(
|
||||
spi1, (spi1_sck, spi1_miso, spi1_mosi),
|
||||
spi1, (spi1_sck, spi1_miso, spi1_mosi),
|
||||
enc424j600::spi::interfaces::SPI_MODE,
|
||||
Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ),
|
||||
clocks);
|
||||
|
@ -65,25 +65,25 @@ fn main() -> ! {
|
|||
// Init
|
||||
match spi_eth.init_dev(&mut delay) {
|
||||
Ok(_) => {
|
||||
iprintln!(stim0, "Ethernet initialised.")
|
||||
iprintln!(stim0, "Ethernet initialized")
|
||||
}
|
||||
Err(_) => {
|
||||
panic!("Ethernet initialisation Failed!")
|
||||
panic!("Ethernet initialization failed!")
|
||||
}
|
||||
}
|
||||
|
||||
// Read MAC
|
||||
let mut eth_mac_addr: [u8; 6] = [0; 6];
|
||||
spi_eth.read_from_mac(&mut eth_mac_addr);
|
||||
iprintln!(stim0,
|
||||
"MAC Address = {:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
|
||||
eth_mac_addr[0], eth_mac_addr[1],
|
||||
eth_mac_addr[2], eth_mac_addr[3],
|
||||
eth_mac_addr[4], eth_mac_addr[5]);
|
||||
// Set to promiscuous mode
|
||||
spi_eth.set_promiscuous();
|
||||
iprintln!(stim0,
|
||||
"Promiscuous Mode ON");
|
||||
for i in 0..6 {
|
||||
let byte = eth_mac_addr[i];
|
||||
match i {
|
||||
0 => iprint!(stim0, "MAC Address = {:02x}-", byte),
|
||||
1..=4 => iprint!(stim0, "{:02x}-", byte),
|
||||
5 => iprint!(stim0, "{:02x}\n", byte),
|
||||
_ => ()
|
||||
};
|
||||
}
|
||||
|
||||
// Init Rx/Tx buffers
|
||||
spi_eth.init_rxbuf();
|
||||
|
@ -102,26 +102,23 @@ fn main() -> ! {
|
|||
loop {
|
||||
let mut eth_tx_packet = enc424j600::tx::TxPacket::new();
|
||||
eth_tx_packet.update_frame(ð_tx_dat, 64);
|
||||
iprintln!(stim0,
|
||||
"Sending packet (len={:}): \
|
||||
dest={:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x} \
|
||||
src={:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x} \
|
||||
data={:02x}{:02x}{:02x}{:02x} {:02x}{:02x}{:02x}{:02x} ...",
|
||||
eth_tx_packet.get_frame_length(),
|
||||
eth_tx_packet.get_frame_byte(0), eth_tx_packet.get_frame_byte(1), eth_tx_packet.get_frame_byte(2),
|
||||
eth_tx_packet.get_frame_byte(3), eth_tx_packet.get_frame_byte(4), eth_tx_packet.get_frame_byte(5),
|
||||
eth_tx_packet.get_frame_byte(6), eth_tx_packet.get_frame_byte(7), eth_tx_packet.get_frame_byte(8),
|
||||
eth_tx_packet.get_frame_byte(9), eth_tx_packet.get_frame_byte(10), eth_tx_packet.get_frame_byte(11),
|
||||
eth_tx_packet.get_frame_byte(12), eth_tx_packet.get_frame_byte(13),
|
||||
eth_tx_packet.get_frame_byte(14), eth_tx_packet.get_frame_byte(15),
|
||||
eth_tx_packet.get_frame_byte(16), eth_tx_packet.get_frame_byte(17),
|
||||
eth_tx_packet.get_frame_byte(18), eth_tx_packet.get_frame_byte(19)
|
||||
);
|
||||
iprint!(stim0,
|
||||
"Sending packet (len={:}): ", eth_tx_packet.get_frame_length());
|
||||
for i in 0..20 {
|
||||
let byte = eth_tx_packet.get_frame_byte(i);
|
||||
match i {
|
||||
0 => iprint!(stim0, "dest={:02x}-", byte),
|
||||
6 => iprint!(stim0, "src={:02x}-", byte),
|
||||
12 => iprint!(stim0, "data={:02x}", byte),
|
||||
1..=4 | 7..=10 => iprint!(stim0, "{:02x}-", byte),
|
||||
13..=14 | 16..=18 => iprint!(stim0, "{:02x}", byte),
|
||||
5 | 11 | 15 => iprint!(stim0, "{:02x} ", byte),
|
||||
19 => iprint!(stim0, "{:02x} ...\n", byte),
|
||||
_ => ()
|
||||
};
|
||||
}
|
||||
spi_eth.send_raw_packet(ð_tx_packet);
|
||||
iprintln!(stim0,
|
||||
"Packet sent");
|
||||
iprintln!(stim0, "Packet sent");
|
||||
delay.delay_ms(100_u32);
|
||||
}
|
||||
|
||||
unreachable!()
|
||||
}
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -40,14 +40,14 @@ impl From<spi::SpiPortError> for EthControllerError {
|
|||
}
|
||||
|
||||
/// Ethernet controller using SPI interface
|
||||
pub struct SpiEth<SPI: Transfer<u8>,
|
||||
pub struct SpiEth<SPI: Transfer<u8>,
|
||||
NSS: OutputPin> {
|
||||
spi_port: spi::SpiPort<SPI, NSS>,
|
||||
rx_buf: rx::RxBuffer,
|
||||
tx_buf: tx::TxBuffer
|
||||
}
|
||||
|
||||
impl <SPI: Transfer<u8>,
|
||||
impl <SPI: Transfer<u8>,
|
||||
NSS: OutputPin> SpiEth<SPI, NSS> {
|
||||
pub fn new(spi: SPI, nss: NSS) -> Self {
|
||||
SpiEth {
|
||||
|
@ -58,14 +58,14 @@ impl <SPI: Transfer<u8>,
|
|||
}
|
||||
}
|
||||
|
||||
impl <'c, SPI: Transfer<u8>,
|
||||
impl <'c, SPI: Transfer<u8>,
|
||||
NSS: OutputPin> EthController<'c> for SpiEth<SPI, NSS> {
|
||||
fn init_dev(&mut self, delay: &mut dyn DelayUs<u16>) -> Result<(), EthControllerError> {
|
||||
// Write 0x1234 to EUDAST
|
||||
self.spi_port.write_reg_16b(spi::addrs::EUDAST, 0x1234)?;
|
||||
// Verify that EUDAST is 0x1234
|
||||
let mut eudast = self.spi_port.read_reg_16b(spi::addrs::EUDAST)?;
|
||||
if eudast != 0x1234 {
|
||||
if eudast != 0x1234 {
|
||||
return Err(EthControllerError::GeneralError)
|
||||
}
|
||||
// Poll CLKRDY (ESTAT<12>) to check if it is set
|
||||
|
@ -80,7 +80,7 @@ impl <'c, SPI: Transfer<u8>,
|
|||
delay.delay_us(25_u16);
|
||||
// Verify that EUDAST is 0x0000
|
||||
eudast = self.spi_port.read_reg_16b(spi::addrs::EUDAST)?;
|
||||
if eudast != 0x0000 {
|
||||
if eudast != 0x0000 {
|
||||
return Err(EthControllerError::GeneralError)
|
||||
}
|
||||
// Wait for 256us
|
||||
|
@ -110,7 +110,7 @@ impl <'c, SPI: Transfer<u8>,
|
|||
/// 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
|
||||
fn receive_next(&mut self, is_poll: bool) -> Result<rx::RxPacket, EthControllerError> {
|
||||
fn receive_next(&mut self, is_poll: bool) -> Result<rx::RxPacket, EthControllerError> {
|
||||
// Poll PKTIF (EIR<4>) to check if it is set
|
||||
loop {
|
||||
let eir = self.spi_port.read_reg_16b(spi::addrs::EIR)?;
|
||||
|
@ -156,7 +156,7 @@ impl <'c, SPI: Transfer<u8>,
|
|||
// Set EGPWRPT pointer to next_addr
|
||||
self.spi_port.write_reg_16b(spi::addrs::EGPWRPT, self.tx_buf.get_next_addr())?;
|
||||
// Copy packet data to SRAM Buffer
|
||||
// 1-byte Opcode is included
|
||||
// 1-byte Opcode is included
|
||||
let mut txdat_buf: [u8; tx::RAW_FRAME_LENGTH_MAX + 1] = [0; tx::RAW_FRAME_LENGTH_MAX + 1];
|
||||
packet.write_frame_to(&mut txdat_buf[1..]);
|
||||
self.spi_port.write_txdat(&mut txdat_buf, packet.get_frame_length())?;
|
||||
|
@ -175,15 +175,15 @@ impl <'c, SPI: Transfer<u8>,
|
|||
// TODO: Read ETXSTAT to understand Ethernet transmission status
|
||||
// (See: Register 9-2, ENC424J600 Data Sheet)
|
||||
// Update TX buffer start address
|
||||
self.tx_buf.set_next_addr((self.tx_buf.get_next_addr() + packet.get_frame_length() as u16) %
|
||||
self.tx_buf.set_next_addr((self.tx_buf.get_next_addr() + packet.get_frame_length() as u16) %
|
||||
tx::GPBUFEN_DEFAULT);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set controller to Promiscuous Mode
|
||||
fn set_promiscuous(&mut self) -> Result<(), EthControllerError> {
|
||||
// From Section 10.12, ENC424J600 Data Sheet:
|
||||
// "To accept all incoming frames regardless of content (Promiscuous mode),
|
||||
// From Section 10.12, ENC424J600 Data Sheet:
|
||||
// "To accept all incoming frames regardless of content (Promiscuous mode),
|
||||
// set the CRCEN, RUNTEN, UCEN, NOTMEEN and MCEN bits."
|
||||
let erxfcon_lo = self.spi_port.read_reg_8b(spi::addrs::ERXFCON)?;
|
||||
self.spi_port.write_reg_8b(spi::addrs::ERXFCON, 0b0101_1110 | (erxfcon_lo & 0b1010_0001))?;
|
||||
|
|
20
src/spi.rs
20
src/spi.rs
|
@ -51,7 +51,7 @@ pub mod addrs {
|
|||
|
||||
/// Struct for SPI I/O interface on ENC424J600
|
||||
/// Note: stm32f4xx_hal::spi's pins include: SCK, MISO, MOSI
|
||||
pub struct SpiPort<SPI: Transfer<u8>,
|
||||
pub struct SpiPort<SPI: Transfer<u8>,
|
||||
NSS: OutputPin> {
|
||||
spi: SPI,
|
||||
nss: NSS,
|
||||
|
@ -62,14 +62,14 @@ pub enum SpiPortError {
|
|||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
impl <SPI: Transfer<u8>,
|
||||
impl <SPI: Transfer<u8>,
|
||||
NSS: OutputPin> SpiPort<SPI, NSS> {
|
||||
// TODO: return as Result()
|
||||
pub fn new(spi: SPI, mut nss: NSS) -> Self {
|
||||
nss.set_high();
|
||||
|
||||
|
||||
SpiPort {
|
||||
spi,
|
||||
spi,
|
||||
nss
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ impl <SPI: Transfer<u8>,
|
|||
}
|
||||
|
||||
// Currently requires manual slicing (buf[1..]) for the data read back
|
||||
pub fn read_rxdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize)
|
||||
pub fn read_rxdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize)
|
||||
-> Result<(), SpiPortError> {
|
||||
let r_valid = self.r_n(buf, opcodes::RERXDATA, data_length)?;
|
||||
Ok(r_valid)
|
||||
|
@ -96,7 +96,7 @@ impl <SPI: Transfer<u8>,
|
|||
|
||||
// Currenly requires actual data to be stored in buf[1..] instead of buf[0..]
|
||||
// TODO: Maybe better naming?
|
||||
pub fn write_txdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize)
|
||||
pub fn write_txdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize)
|
||||
-> Result<(), SpiPortError> {
|
||||
let w_valid = self.w_n(buf, opcodes::WEGPDATA, data_length)?;
|
||||
Ok(w_valid)
|
||||
|
@ -118,7 +118,7 @@ impl <SPI: Transfer<u8>,
|
|||
// 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
|
||||
fn rw_addr_u8(&mut self, opcode: u8, addr: u8, data: u8)
|
||||
fn rw_addr_u8(&mut self, opcode: u8, addr: u8, data: u8)
|
||||
-> Result<u8, SpiPortError> {
|
||||
// Enable chip select
|
||||
self.nss.set_low();
|
||||
|
@ -144,11 +144,11 @@ impl <SPI: Transfer<u8>,
|
|||
}
|
||||
|
||||
// TODO: Generalise transfer functions
|
||||
// Currently does NOT accept addr, read data is N-byte long
|
||||
// Currently does NOT accept addr, read data is N-byte long
|
||||
// Returns a reference to the data returned
|
||||
// Note: buf must be at least (data_length + 1)-byte long
|
||||
// TODO: Check and raise error for array size < (data_length + 1)
|
||||
fn r_n<'a>(&mut self, buf: &'a mut [u8], opcode: u8, data_length: usize)
|
||||
fn r_n<'a>(&mut self, buf: &'a mut [u8], opcode: u8, data_length: usize)
|
||||
-> Result<(), SpiPortError> {
|
||||
// Enable chip select
|
||||
self.nss.set_low();
|
||||
|
@ -171,7 +171,7 @@ impl <SPI: Transfer<u8>,
|
|||
|
||||
// Note: buf[0] is currently reserved for opcode to overwrite
|
||||
// TODO: Actual data should start from buf[0], not buf[1]
|
||||
fn w_n<'a>(&mut self, buf: &'a mut [u8], opcode: u8, data_length: usize)
|
||||
fn w_n<'a>(&mut self, buf: &'a mut [u8], opcode: u8, data_length: usize)
|
||||
-> Result<(), SpiPortError> {
|
||||
// Enable chip select
|
||||
self.nss.set_low();
|
||||
|
|
Loading…
Reference in New Issue