Use core::cell::RefCell to refer to EthController
This commit is contained in:
parent
4ba5052623
commit
25e682763c
|
@ -171,7 +171,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Copied / modified from smoltcp:
|
// Copied / modified from smoltcp:
|
||||||
// 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(spi_eth);
|
||||||
let mut neighbor_cache_entries = [None; 16];
|
let mut neighbor_cache_entries = [None; 16];
|
||||||
let 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(
|
||||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -15,8 +15,8 @@ pub mod tx;
|
||||||
#[cfg(feature="smoltcp")]
|
#[cfg(feature="smoltcp")]
|
||||||
pub mod smoltcp_phy;
|
pub mod smoltcp_phy;
|
||||||
|
|
||||||
pub trait EthController<'c> {
|
pub trait EthController {
|
||||||
fn init_dev(&mut self, delay: &mut dyn DelayUs<u16>) -> Result<(), EthControllerError>;
|
fn init_dev(&mut self, delay: &mut impl 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>;
|
||||||
|
@ -58,9 +58,9 @@ impl <SPI: Transfer<u8>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'c, SPI: Transfer<u8>,
|
impl <SPI: Transfer<u8>,
|
||||||
NSS: OutputPin> EthController<'c> for SpiEth<SPI, NSS> {
|
NSS: OutputPin> EthController for SpiEth<SPI, NSS> {
|
||||||
fn init_dev(&mut self, delay: &mut dyn DelayUs<u16>) -> Result<(), EthControllerError> {
|
fn init_dev(&mut self, delay: &mut impl 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
|
||||||
|
|
|
@ -1,45 +1,40 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
EthController, rx, tx
|
EthController, rx, tx
|
||||||
};
|
};
|
||||||
use core::intrinsics::transmute;
|
use core::cell;
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
phy::{Device, DeviceCapabilities, RxToken, TxToken},
|
phy::{Device, DeviceCapabilities, RxToken, TxToken},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
Error
|
Error
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SmoltcpDevice<'c> {
|
pub struct SmoltcpDevice<EC: EthController> {
|
||||||
eth_controller: &'c mut dyn EthController<'c>,
|
pub eth_controller: cell::RefCell<EC>,
|
||||||
rx_packet_buf: [u8; rx::RAW_FRAME_LENGTH_MAX],
|
rx_packet_buf: [u8; rx::RAW_FRAME_LENGTH_MAX],
|
||||||
tx_packet_buf: [u8; tx::RAW_FRAME_LENGTH_MAX]
|
tx_packet_buf: [u8; tx::RAW_FRAME_LENGTH_MAX]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c> SmoltcpDevice<'c> {
|
impl<EC: EthController> SmoltcpDevice<EC> {
|
||||||
pub fn new(eth_controller: &'c mut dyn EthController<'c>) -> Self {
|
pub fn new(eth_controller: EC) -> Self {
|
||||||
SmoltcpDevice {
|
SmoltcpDevice {
|
||||||
eth_controller,
|
eth_controller: cell::RefCell::new(eth_controller),
|
||||||
rx_packet_buf: [0; rx::RAW_FRAME_LENGTH_MAX],
|
rx_packet_buf: [0; rx::RAW_FRAME_LENGTH_MAX],
|
||||||
tx_packet_buf: [0; tx::RAW_FRAME_LENGTH_MAX]
|
tx_packet_buf: [0; tx::RAW_FRAME_LENGTH_MAX]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'c> Device<'a> for SmoltcpDevice<'c> {
|
impl<'a, EC: 'a + EthController> Device<'a> for SmoltcpDevice<EC> {
|
||||||
type RxToken = EthRxToken<'a>;
|
type RxToken = EthRxToken<'a>;
|
||||||
type TxToken = EthTxToken<'a>;
|
type TxToken = EthTxToken<'a, EC>;
|
||||||
|
|
||||||
fn capabilities(&self) -> DeviceCapabilities {
|
fn capabilities(&self) -> DeviceCapabilities {
|
||||||
DeviceCapabilities::default()
|
DeviceCapabilities::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
|
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
|
||||||
// Extend self lifetime from 'c to 'a for tokens' access to EthController
|
let self_p = (&mut *self) as *mut SmoltcpDevice<EC>;
|
||||||
let self_trans = unsafe {
|
match self.eth_controller.borrow_mut().receive_next(false) {
|
||||||
transmute::<&mut SmoltcpDevice<'c>, &mut SmoltcpDevice<'a>>(&mut *self)
|
|
||||||
};
|
|
||||||
// Make self_a point to *self that has a lifetime of 'a (extended)
|
|
||||||
let self_a = self_trans as *mut SmoltcpDevice<'a>;
|
|
||||||
match self_trans.eth_controller.receive_next(false) {
|
|
||||||
Ok(rx_packet) => {
|
Ok(rx_packet) => {
|
||||||
// Write received packet to RX packet buffer
|
// Write received packet to RX packet buffer
|
||||||
rx_packet.write_frame_to(&mut self.rx_packet_buf);
|
rx_packet.write_frame_to(&mut self.rx_packet_buf);
|
||||||
|
@ -51,7 +46,7 @@ impl<'a, 'c> Device<'a> for SmoltcpDevice<'c> {
|
||||||
// Construct a blank TxToken
|
// Construct a blank TxToken
|
||||||
let tx_token = EthTxToken {
|
let tx_token = EthTxToken {
|
||||||
buf: &mut self.tx_packet_buf,
|
buf: &mut self.tx_packet_buf,
|
||||||
dev: self_a
|
dev: self_p
|
||||||
};
|
};
|
||||||
Some((rx_token, tx_token))
|
Some((rx_token, tx_token))
|
||||||
},
|
},
|
||||||
|
@ -60,16 +55,11 @@ impl<'a, 'c> Device<'a> for SmoltcpDevice<'c> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transmit(&'a mut self) -> Option<Self::TxToken> {
|
fn transmit(&'a mut self) -> Option<Self::TxToken> {
|
||||||
// Extend self lifetime from 'c to 'a for TxToken's access to EthController
|
let self_p = (&mut *self) as *mut SmoltcpDevice<EC>;
|
||||||
let self_trans = unsafe {
|
|
||||||
transmute::<&mut SmoltcpDevice<'c>, &mut SmoltcpDevice<'a>>(&mut *self)
|
|
||||||
};
|
|
||||||
// Make self_a point to *self that has a lifetime of 'a (extended)
|
|
||||||
let self_a = self_trans as *mut SmoltcpDevice<'a>;
|
|
||||||
// Construct a blank TxToken
|
// Construct a blank TxToken
|
||||||
let tx_token = EthTxToken {
|
let tx_token = EthTxToken {
|
||||||
buf: &mut self.tx_packet_buf,
|
buf: &mut self.tx_packet_buf,
|
||||||
dev: self_a
|
dev: self_p
|
||||||
};
|
};
|
||||||
Some(tx_token)
|
Some(tx_token)
|
||||||
}
|
}
|
||||||
|
@ -89,12 +79,12 @@ impl<'a> RxToken for EthRxToken<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EthTxToken<'a> {
|
pub struct EthTxToken<'a, EC: EthController> {
|
||||||
buf: &'a mut [u8],
|
buf: &'a mut [u8],
|
||||||
dev: *mut SmoltcpDevice<'a>
|
dev: *mut SmoltcpDevice<EC>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TxToken for EthTxToken<'a> {
|
impl<'a, EC: 'a + EthController> TxToken for EthTxToken<'a, EC> {
|
||||||
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R, Error>
|
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R, Error>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut [u8]) -> Result<R, Error>,
|
F: FnOnce(&mut [u8]) -> Result<R, Error>,
|
||||||
|
@ -108,7 +98,7 @@ impl<'a> TxToken for EthTxToken<'a> {
|
||||||
let eth_controller = unsafe {
|
let eth_controller = unsafe {
|
||||||
&mut (*self.dev).eth_controller
|
&mut (*self.dev).eth_controller
|
||||||
};
|
};
|
||||||
match eth_controller.send_raw_packet(&tx_packet) {
|
match eth_controller.borrow_mut().send_raw_packet(&tx_packet) {
|
||||||
Ok(_) => { result },
|
Ok(_) => { result },
|
||||||
Err(_) => Err(Error::Exhausted)
|
Err(_) => Err(Error::Exhausted)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue