Simplify, styling & spelling

pull/3/head
Harry Ho 2020-12-29 11:08:35 +08:00
parent e9a3a5e550
commit 4ba5052623
5 changed files with 73 additions and 76 deletions

View File

@ -4,7 +4,7 @@
use core::env; use core::env;
extern crate panic_itm; extern crate panic_itm;
use cortex_m::iprintln; use cortex_m::{iprintln, iprint};
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
@ -90,7 +90,7 @@ fn main() -> ! {
let mut itm = cp.ITM; let mut itm = cp.ITM;
let stim0 = &mut itm.stim[0]; let stim0 = &mut itm.stim[0];
iprintln!(stim0, iprintln!(stim0,
"Eth TCP Server on STM32-F407 via NIC100/ENC424J600"); "Eth TCP Server on STM32-F407 via NIC100/ENC424J600");
// Get IP address from args // Get IP address from args
@ -132,34 +132,38 @@ fn main() -> ! {
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(
spi1, (spi1_sck, spi1_miso, spi1_mosi), spi1, (spi1_sck, spi1_miso, spi1_mosi),
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);
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(&mut delay) { match spi_eth.init_dev(&mut delay) {
Ok(_) => { Ok(_) => {
iprintln!(stim0, "Ethernet initialised.") iprintln!(stim0, "Ethernet initialized")
} }
Err(_) => { Err(_) => {
panic!("Ethernet initialisation Failed!") panic!("Ethernet initialization failed!")
} }
} }
// Setup SysTick // Setup SysTick
// Reference to stm32-eth:examples/ip.rs // Reference to stm32-eth:examples/ip.rs
timer_setup(delay.free(), clocks); timer_setup(delay.free(), clocks);
iprintln!(stim0, "Timer initialised."); iprintln!(stim0, "Timer initialized");
// Read MAC // Read MAC
let mut eth_mac_addr: [u8; 6] = [0; 6]; let mut eth_mac_addr: [u8; 6] = [0; 6];
spi_eth.read_from_mac(&mut eth_mac_addr); spi_eth.read_from_mac(&mut eth_mac_addr);
iprintln!(stim0, for i in 0..6 {
"MAC Address = {:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}", let byte = eth_mac_addr[i];
eth_mac_addr[0], eth_mac_addr[1], match i {
eth_mac_addr[2], eth_mac_addr[3], 0 => iprint!(stim0, "MAC Address = {:02x}-", byte),
eth_mac_addr[4], eth_mac_addr[5]); 1..=4 => iprint!(stim0, "{:02x}-", byte),
5 => iprint!(stim0, "{:02x}\n", byte),
_ => ()
};
}
// Init Rx/Tx buffers // Init Rx/Tx buffers
spi_eth.init_rxbuf(); spi_eth.init_rxbuf();
@ -199,10 +203,9 @@ fn main() -> ! {
let mut socket_set = SocketSet::new(&mut socket_set_entries[..]); let mut socket_set = SocketSet::new(&mut socket_set_entries[..]);
let echo_handle = socket_set.add(echo_socket); let echo_handle = socket_set.add(echo_socket);
let greet_handle = socket_set.add(greet_socket); let greet_handle = socket_set.add(greet_socket);
iprintln!(stim0, iprintln!(stim0, "TCP sockets will listen at {}", ip_addr);
"TCP sockets will listen at {}", ip_addr);
// Copied / modified from: // Copied / modified from:
// smoltcp:examples/loopback.rs, examples/server.rs; // smoltcp:examples/loopback.rs, examples/server.rs;
// stm32-eth:examples/ip.rs, // stm32-eth:examples/ip.rs,
// git.m-labs.hk/M-Labs/tnetplug // git.m-labs.hk/M-Labs/tnetplug
@ -220,13 +223,13 @@ fn main() -> ! {
{ {
let mut socket = socket_set.get::<TcpSocket>(echo_handle); let mut socket = socket_set.get::<TcpSocket>(echo_handle);
if !socket.is_open() { if !socket.is_open() {
iprintln!(stim0, iprintln!(stim0,
"[{}] Listening to port 1234 for echoing, time-out in 10s", instant); "[{}] Listening to port 1234 for echoing, time-out in 10s", instant);
socket.listen(1234).unwrap(); socket.listen(1234).unwrap();
socket.set_timeout(Some(Duration::from_millis(10000))); socket.set_timeout(Some(Duration::from_millis(10000)));
} }
if socket.can_recv() { if socket.can_recv() {
iprintln!(stim0, iprintln!(stim0,
"[{}] Received packet: {:?}", instant, socket.recv(|buffer| { "[{}] Received packet: {:?}", instant, socket.recv(|buffer| {
(buffer.len(), str::from_utf8(buffer).unwrap()) (buffer.len(), str::from_utf8(buffer).unwrap())
})); }));
@ -236,7 +239,7 @@ fn main() -> ! {
{ {
let mut socket = socket_set.get::<TcpSocket>(greet_handle); let mut socket = socket_set.get::<TcpSocket>(greet_handle);
if !socket.is_open() { if !socket.is_open() {
iprintln!(stim0, iprintln!(stim0,
"[{}] Listening to port 4321 for greeting, \ "[{}] Listening to port 4321 for greeting, \
please connect to the port", instant); please connect to the port", instant);
socket.listen(4321).unwrap(); socket.listen(4321).unwrap();
@ -245,13 +248,10 @@ fn main() -> ! {
if socket.can_send() { if socket.can_send() {
let greeting = "Welcome to the server demo for STM32-F407!"; let greeting = "Welcome to the server demo for STM32-F407!";
write!(socket, "{}\n", greeting).unwrap(); write!(socket, "{}\n", greeting).unwrap();
iprintln!(stim0, iprintln!(stim0,
"[{}] Greeting sent, socket closed", instant); "[{}] Greeting sent, socket closed", instant);
socket.close(); socket.close();
} }
} }
} }
unreachable!()
} }

View File

@ -2,7 +2,7 @@
#![no_main] #![no_main]
extern crate panic_itm; extern crate panic_itm;
use cortex_m::iprintln; use cortex_m::{iprintln, iprint};
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
@ -39,7 +39,7 @@ fn main() -> ! {
let mut itm = cp.ITM; let mut itm = cp.ITM;
let stim0 = &mut itm.stim[0]; let stim0 = &mut itm.stim[0];
iprintln!(stim0, iprintln!(stim0,
"Eth TX Pinging on STM32-F407 via NIC100/ENC424J600"); "Eth TX Pinging on STM32-F407 via NIC100/ENC424J600");
// NIC100 / ENC424J600 Set-up // NIC100 / ENC424J600 Set-up
@ -57,7 +57,7 @@ fn main() -> ! {
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(
spi1, (spi1_sck, spi1_miso, spi1_mosi), spi1, (spi1_sck, spi1_miso, spi1_mosi),
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);
@ -65,25 +65,25 @@ fn main() -> ! {
// Init // Init
match spi_eth.init_dev(&mut delay) { match spi_eth.init_dev(&mut delay) {
Ok(_) => { Ok(_) => {
iprintln!(stim0, "Ethernet initialised.") iprintln!(stim0, "Ethernet initialized")
} }
Err(_) => { Err(_) => {
panic!("Ethernet initialisation Failed!") panic!("Ethernet initialization failed!")
} }
} }
// Read MAC // Read MAC
let mut eth_mac_addr: [u8; 6] = [0; 6]; let mut eth_mac_addr: [u8; 6] = [0; 6];
spi_eth.read_from_mac(&mut eth_mac_addr); spi_eth.read_from_mac(&mut eth_mac_addr);
iprintln!(stim0, for i in 0..6 {
"MAC Address = {:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}", let byte = eth_mac_addr[i];
eth_mac_addr[0], eth_mac_addr[1], match i {
eth_mac_addr[2], eth_mac_addr[3], 0 => iprint!(stim0, "MAC Address = {:02x}-", byte),
eth_mac_addr[4], eth_mac_addr[5]); 1..=4 => iprint!(stim0, "{:02x}-", byte),
// Set to promiscuous mode 5 => iprint!(stim0, "{:02x}\n", byte),
spi_eth.set_promiscuous(); _ => ()
iprintln!(stim0, };
"Promiscuous Mode ON"); }
// Init Rx/Tx buffers // Init Rx/Tx buffers
spi_eth.init_rxbuf(); spi_eth.init_rxbuf();
@ -102,26 +102,23 @@ fn main() -> ! {
loop { loop {
let mut eth_tx_packet = enc424j600::tx::TxPacket::new(); let mut eth_tx_packet = enc424j600::tx::TxPacket::new();
eth_tx_packet.update_frame(&eth_tx_dat, 64); eth_tx_packet.update_frame(&eth_tx_dat, 64);
iprintln!(stim0, iprint!(stim0,
"Sending packet (len={:}): \ "Sending packet (len={:}): ", eth_tx_packet.get_frame_length());
dest={:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x} \ for i in 0..20 {
src={:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x} \ let byte = eth_tx_packet.get_frame_byte(i);
data={:02x}{:02x}{:02x}{:02x} {:02x}{:02x}{:02x}{:02x} ...", match i {
eth_tx_packet.get_frame_length(), 0 => iprint!(stim0, "dest={:02x}-", byte),
eth_tx_packet.get_frame_byte(0), eth_tx_packet.get_frame_byte(1), eth_tx_packet.get_frame_byte(2), 6 => iprint!(stim0, "src={:02x}-", byte),
eth_tx_packet.get_frame_byte(3), eth_tx_packet.get_frame_byte(4), eth_tx_packet.get_frame_byte(5), 12 => iprint!(stim0, "data={:02x}", byte),
eth_tx_packet.get_frame_byte(6), eth_tx_packet.get_frame_byte(7), eth_tx_packet.get_frame_byte(8), 1..=4 | 7..=10 => iprint!(stim0, "{:02x}-", byte),
eth_tx_packet.get_frame_byte(9), eth_tx_packet.get_frame_byte(10), eth_tx_packet.get_frame_byte(11), 13..=14 | 16..=18 => iprint!(stim0, "{:02x}", byte),
eth_tx_packet.get_frame_byte(12), eth_tx_packet.get_frame_byte(13), 5 | 11 | 15 => iprint!(stim0, "{:02x} ", byte),
eth_tx_packet.get_frame_byte(14), eth_tx_packet.get_frame_byte(15), 19 => iprint!(stim0, "{:02x} ...\n", byte),
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) };
); }
spi_eth.send_raw_packet(&eth_tx_packet); spi_eth.send_raw_packet(&eth_tx_packet);
iprintln!(stim0, iprintln!(stim0, "Packet sent");
"Packet sent");
delay.delay_ms(100_u32); delay.delay_ms(100_u32);
} }
unreachable!()
} }

View File

@ -40,14 +40,14 @@ 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>, spi_port: spi::SpiPort<SPI, NSS>,
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> SpiEth<SPI, NSS> {
pub fn new(spi: SPI, nss: NSS) -> Self { pub fn new(spi: SPI, nss: NSS) -> Self {
SpiEth { 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> { NSS: OutputPin> EthController<'c> for SpiEth<SPI, NSS> {
fn init_dev(&mut self, delay: &mut dyn DelayUs<u16>) -> 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
let mut eudast = self.spi_port.read_reg_16b(spi::addrs::EUDAST)?; let mut eudast = self.spi_port.read_reg_16b(spi::addrs::EUDAST)?;
if eudast != 0x1234 { if eudast != 0x1234 {
return Err(EthControllerError::GeneralError) return Err(EthControllerError::GeneralError)
} }
// Poll CLKRDY (ESTAT<12>) to check if it is set // Poll CLKRDY (ESTAT<12>) to check if it is set
@ -80,7 +80,7 @@ impl <'c, SPI: Transfer<u8>,
delay.delay_us(25_u16); 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 // Wait for 256us
@ -110,7 +110,7 @@ impl <'c, SPI: Transfer<u8>,
/// Receive the next packet and return it /// Receive the next packet and return it
/// Set is_poll to true for returning until PKTIF is set; /// Set is_poll to true for returning until PKTIF is set;
/// Set is_poll to false for returning Err when PKTIF is not 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 // Poll PKTIF (EIR<4>) to check if it is set
loop { loop {
let eir = self.spi_port.read_reg_16b(spi::addrs::EIR)?; 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 // Set EGPWRPT pointer to next_addr
self.spi_port.write_reg_16b(spi::addrs::EGPWRPT, self.tx_buf.get_next_addr())?; self.spi_port.write_reg_16b(spi::addrs::EGPWRPT, self.tx_buf.get_next_addr())?;
// Copy packet data to SRAM Buffer // 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]; 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..]); packet.write_frame_to(&mut txdat_buf[1..]);
self.spi_port.write_txdat(&mut txdat_buf, packet.get_frame_length())?; 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 // TODO: Read ETXSTAT to understand Ethernet transmission status
// (See: Register 9-2, ENC424J600 Data Sheet) // (See: Register 9-2, ENC424J600 Data Sheet)
// Update TX buffer start address // 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); tx::GPBUFEN_DEFAULT);
Ok(()) Ok(())
} }
/// Set controller to Promiscuous Mode /// Set controller to Promiscuous Mode
fn set_promiscuous(&mut self) -> Result<(), EthControllerError> { fn set_promiscuous(&mut self) -> Result<(), EthControllerError> {
// From Section 10.12, ENC424J600 Data Sheet: // From Section 10.12, ENC424J600 Data Sheet:
// "To accept all incoming frames regardless of content (Promiscuous mode), // "To accept all incoming frames regardless of content (Promiscuous mode),
// set the CRCEN, RUNTEN, UCEN, NOTMEEN and MCEN bits." // set the CRCEN, RUNTEN, UCEN, NOTMEEN and MCEN bits."
let erxfcon_lo = self.spi_port.read_reg_8b(spi::addrs::ERXFCON)?; 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))?; self.spi_port.write_reg_8b(spi::addrs::ERXFCON, 0b0101_1110 | (erxfcon_lo & 0b1010_0001))?;

View File

@ -51,7 +51,7 @@ 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> {
spi: SPI, spi: SPI,
nss: NSS, nss: NSS,
@ -62,14 +62,14 @@ 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> SpiPort<SPI, NSS> {
// 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) -> Self {
nss.set_high(); nss.set_high();
SpiPort { SpiPort {
spi, spi,
nss nss
} }
} }
@ -88,7 +88,7 @@ impl <SPI: Transfer<u8>,
} }
// Currently requires manual slicing (buf[1..]) for the data read back // 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> { -> Result<(), SpiPortError> {
let r_valid = self.r_n(buf, opcodes::RERXDATA, data_length)?; let r_valid = self.r_n(buf, opcodes::RERXDATA, data_length)?;
Ok(r_valid) 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..] // Currenly requires actual data to be stored in buf[1..] instead of buf[0..]
// TODO: Maybe better naming? // 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> { -> Result<(), SpiPortError> {
let w_valid = self.w_n(buf, opcodes::WEGPDATA, data_length)?; let w_valid = self.w_n(buf, opcodes::WEGPDATA, data_length)?;
Ok(w_valid) Ok(w_valid)
@ -118,7 +118,7 @@ impl <SPI: Transfer<u8>,
// 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
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> { -> Result<u8, SpiPortError> {
// Enable chip select // Enable chip select
self.nss.set_low(); self.nss.set_low();
@ -144,11 +144,11 @@ impl <SPI: Transfer<u8>,
} }
// TODO: Generalise transfer functions // 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 // Returns a reference to the data returned
// Note: buf must be at least (data_length + 1)-byte long // Note: buf must be at least (data_length + 1)-byte long
// TODO: Check and raise error for array size < (data_length + 1) // 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> { -> Result<(), SpiPortError> {
// Enable chip select // Enable chip select
self.nss.set_low(); self.nss.set_low();
@ -171,7 +171,7 @@ impl <SPI: Transfer<u8>,
// Note: buf[0] is currently reserved for opcode to overwrite // Note: buf[0] is currently reserved for opcode to overwrite
// TODO: Actual data should start from buf[0], not buf[1] // 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> { -> Result<(), SpiPortError> {
// Enable chip select // Enable chip select
self.nss.set_low(); self.nss.set_low();

View File

@ -36,7 +36,7 @@ impl TxBuffer {
pub fn get_next_addr(& self) -> u16{ pub fn get_next_addr(& self) -> u16{
self.next_addr self.next_addr
} }
pub fn set_tail_addr(&mut self, addr: u16) { pub fn set_tail_addr(&mut self, addr: u16) {
self.tail_addr = addr; self.tail_addr = addr;
} }