This commit is contained in:
parent
6ecd55ef25
commit
25521b3772
@ -25,7 +25,7 @@ stm32h7xx-hal = { version="0.16", features= ["stm32h743v", "ethernet"] }
|
|||||||
[dependencies.smoltcp]
|
[dependencies.smoltcp]
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["medium-ethernet", "proto-ipv4", "socket-raw"]
|
features = ["medium-ethernet", "proto-ipv4", "socket-raw", "socket-dhcpv4"]
|
||||||
|
|
||||||
[dependencies.rtic]
|
[dependencies.rtic]
|
||||||
version = "2"
|
version = "2"
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use core::mem::MaybeUninit;
|
|
||||||
|
|
||||||
use rtic::app;
|
use rtic::app;
|
||||||
|
use rtic_monotonics::systick::Systick;
|
||||||
|
use rtic_monotonics::Monotonic;
|
||||||
use satrs_stm32h7_nucleo_rtic as _; // global logger + panicking-behavior + memory layout
|
use satrs_stm32h7_nucleo_rtic as _; // global logger + panicking-behavior + memory layout
|
||||||
|
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
use smoltcp::iface::{Config, Interface, SocketSet, SocketStorage};
|
||||||
|
use smoltcp::time::Instant;
|
||||||
|
use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr};
|
||||||
use stm32h7xx_hal::ethernet;
|
use stm32h7xx_hal::ethernet;
|
||||||
|
|
||||||
const DEFAULT_BLINK_FREQ_MS: u32 = 1000;
|
const DEFAULT_BLINK_FREQ_MS: u32 = 1000;
|
||||||
@ -13,11 +18,61 @@ const DEFAULT_BLINK_FREQ_MS: u32 = 1000;
|
|||||||
#[link_section = ".sram3.eth"]
|
#[link_section = ".sram3.eth"]
|
||||||
static mut DES_RING: MaybeUninit<ethernet::DesRing<4, 4>> = MaybeUninit::uninit();
|
static mut DES_RING: MaybeUninit<ethernet::DesRing<4, 4>> = MaybeUninit::uninit();
|
||||||
|
|
||||||
|
// This data will be held by Net through a mutable reference
|
||||||
|
pub struct NetStorageStatic<'a> {
|
||||||
|
socket_storage: [SocketStorage<'a>; 8],
|
||||||
|
}
|
||||||
|
// MaybeUninit allows us write code that is correct even if STORE is not
|
||||||
|
// initialised by the runtime
|
||||||
|
static mut STORE: MaybeUninit<NetStorageStatic> = MaybeUninit::uninit();
|
||||||
|
|
||||||
/// Locally administered MAC address
|
/// Locally administered MAC address
|
||||||
const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];
|
const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];
|
||||||
|
|
||||||
|
pub struct Net<'a> {
|
||||||
|
iface: Interface,
|
||||||
|
ethdev: ethernet::EthernetDMA<4, 4>,
|
||||||
|
sockets: SocketSet<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Net<'a> {
|
||||||
|
pub fn new(
|
||||||
|
store: &'a mut NetStorageStatic<'a>,
|
||||||
|
mut ethdev: ethernet::EthernetDMA<4, 4>,
|
||||||
|
ethernet_addr: HardwareAddress,
|
||||||
|
now: Instant,
|
||||||
|
) -> Self {
|
||||||
|
let config = Config::new(ethernet_addr);
|
||||||
|
let mut iface = Interface::new(config, &mut ethdev, now);
|
||||||
|
// Set IP address
|
||||||
|
iface.update_ip_addrs(|addrs| {
|
||||||
|
let _ = addrs.push(IpCidr::new(IpAddress::v4(192, 168, 1, 99), 0));
|
||||||
|
});
|
||||||
|
|
||||||
|
let sockets = SocketSet::new(&mut store.socket_storage[..]);
|
||||||
|
|
||||||
|
Net::<'a> {
|
||||||
|
iface,
|
||||||
|
ethdev,
|
||||||
|
sockets,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Polls on the ethernet interface. You should refer to the smoltcp
|
||||||
|
/// documentation for poll() to understand how to call poll efficiently
|
||||||
|
pub fn poll(&mut self) -> bool {
|
||||||
|
let uptime = Systick::now() - Systick::ZERO;
|
||||||
|
let timestamp = smoltcp::time::Instant::from_millis(uptime.to_millis());
|
||||||
|
|
||||||
|
self.iface
|
||||||
|
.poll(timestamp, &mut self.ethdev, &mut self.sockets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[app(device = stm32h7xx_hal::stm32, peripherals = true)]
|
#[app(device = stm32h7xx_hal::stm32, peripherals = true)]
|
||||||
mod app {
|
mod app {
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use rtic_monotonics::systick::fugit::MillisDurationU32;
|
use rtic_monotonics::systick::fugit::MillisDurationU32;
|
||||||
use rtic_monotonics::systick::Systick;
|
use rtic_monotonics::systick::Systick;
|
||||||
@ -40,6 +95,7 @@ mod app {
|
|||||||
struct Local {
|
struct Local {
|
||||||
leds: BlinkyLeds,
|
leds: BlinkyLeds,
|
||||||
link_led: Pin<'B', 0, Output>,
|
link_led: Pin<'B', 0, Output>,
|
||||||
|
net: Net<'static>,
|
||||||
phy: ethernet::phy::LAN8742A<EthernetMAC>,
|
phy: ethernet::phy::LAN8742A<EthernetMAC>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +128,8 @@ mod app {
|
|||||||
systick_mono_token,
|
systick_mono_token,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Those are used in the example, I am not fully sure what they are good for.
|
// Those are used in the smoltcp of the stm32h7xx-hal , I am not fully sure what they are
|
||||||
|
// good for.
|
||||||
cx.core.SCB.enable_icache();
|
cx.core.SCB.enable_icache();
|
||||||
cx.core.DWT.enable_cycle_counter();
|
cx.core.DWT.enable_cycle_counter();
|
||||||
|
|
||||||
@ -101,7 +158,7 @@ mod app {
|
|||||||
let rmii_txd1 = gpiob.pb13.into_alternate::<11>();
|
let rmii_txd1 = gpiob.pb13.into_alternate::<11>();
|
||||||
|
|
||||||
let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS);
|
let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS);
|
||||||
let (_eth_dma, eth_mac) = ethernet::new(
|
let (eth_dma, eth_mac) = ethernet::new(
|
||||||
cx.device.ETHERNET_MAC,
|
cx.device.ETHERNET_MAC,
|
||||||
cx.device.ETHERNET_MTL,
|
cx.device.ETHERNET_MTL,
|
||||||
cx.device.ETHERNET_DMA,
|
cx.device.ETHERNET_DMA,
|
||||||
@ -116,8 +173,8 @@ mod app {
|
|||||||
rmii_txd0,
|
rmii_txd0,
|
||||||
rmii_txd1,
|
rmii_txd1,
|
||||||
),
|
),
|
||||||
// SAFETY: We do not move the returned DMA struct anymore, so this should be safe
|
// SAFETY: We do not move the returned DMA struct across thread boundaries, so this
|
||||||
// according to the docs.
|
// should be safe according to the docs.
|
||||||
unsafe { DES_RING.assume_init_mut() },
|
unsafe { DES_RING.assume_init_mut() },
|
||||||
mac_addr,
|
mac_addr,
|
||||||
ccdr.peripheral.ETH1MAC,
|
ccdr.peripheral.ETH1MAC,
|
||||||
@ -134,6 +191,22 @@ mod app {
|
|||||||
cortex_m::peripheral::NVIC::unmask(Interrupt::ETH);
|
cortex_m::peripheral::NVIC::unmask(Interrupt::ETH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unsafe: mutable reference to static storage, we only do this once
|
||||||
|
let store = unsafe {
|
||||||
|
let store_ptr = STORE.as_mut_ptr();
|
||||||
|
|
||||||
|
// Initialise the socket_storage field. Using `write` instead of
|
||||||
|
// assignment via `=` to not call `drop` on the old, uninitialised
|
||||||
|
// value
|
||||||
|
addr_of_mut!((*store_ptr).socket_storage).write([SocketStorage::EMPTY; 8]);
|
||||||
|
|
||||||
|
// Now that all fields are initialised we can safely use
|
||||||
|
// assume_init_mut to return a mutable reference to STORE
|
||||||
|
STORE.assume_init_mut()
|
||||||
|
};
|
||||||
|
|
||||||
|
let net = Net::new(store, eth_dma, mac_addr.into(), Instant::ZERO);
|
||||||
|
|
||||||
eth_link_check::spawn().expect("eth link check failed");
|
eth_link_check::spawn().expect("eth link check failed");
|
||||||
blink::spawn().expect("spawning blink task failed");
|
blink::spawn().expect("spawning blink task failed");
|
||||||
(
|
(
|
||||||
@ -144,6 +217,7 @@ mod app {
|
|||||||
Local {
|
Local {
|
||||||
link_led,
|
link_led,
|
||||||
leds,
|
leds,
|
||||||
|
net,
|
||||||
phy: lan8742a,
|
phy: lan8742a,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -181,11 +255,12 @@ mod app {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(binds=ETH)]
|
#[task(binds=ETH, local=[net])]
|
||||||
fn eth_isr(_: eth_isr::Context) {
|
fn eth_isr(cx: eth_isr::Context) {
|
||||||
// SAFETY: We do not write the register mentioned inside the docs anywhere else.
|
// SAFETY: We do not write the register mentioned inside the docs anywhere else.
|
||||||
unsafe {
|
unsafe {
|
||||||
ethernet::interrupt_handler();
|
ethernet::interrupt_handler();
|
||||||
}
|
}
|
||||||
|
cx.local.net.poll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user