wpan: refactor control, driver
This commit is contained in:
@@ -1,102 +1,110 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(async_fn_in_trait, type_alias_impl_trait, concat_bytes)]
|
||||
#![deny(unused_must_use)]
|
||||
|
||||
use core::slice;
|
||||
use core::task::Context;
|
||||
|
||||
use embassy_net_driver_channel as ch;
|
||||
use embedded_hal_1::digital::OutputPin;
|
||||
use events::Events;
|
||||
use ioctl::IoctlState;
|
||||
use embassy_net_driver::{Capabilities, LinkState, Medium};
|
||||
|
||||
use crate::bus::Bus;
|
||||
pub use crate::bus::SpiBusCyw43;
|
||||
pub use crate::control::{Control, Error as ControlError};
|
||||
pub use crate::runner::Runner;
|
||||
pub use crate::structs::BssInfo;
|
||||
use crate::mac::runner::Runner;
|
||||
use crate::mac::MTU;
|
||||
|
||||
const MTU: usize = 1514;
|
||||
|
||||
pub struct State {
|
||||
ioctl_state: IoctlState,
|
||||
ch: ch::State<MTU, 4, 4>,
|
||||
events: Events,
|
||||
pub struct Driver<'d> {
|
||||
runner: &'d Runner,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ioctl_state: IoctlState::new(),
|
||||
ch: ch::State::new(),
|
||||
events: Events::new(),
|
||||
}
|
||||
impl<'d> Driver<'d> {
|
||||
pub(crate) fn new(runner: &'d Runner) -> Self {
|
||||
Self { runner: runner }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PowerManagementMode {
|
||||
/// Custom, officially unsupported mode. Use at your own risk.
|
||||
/// All power-saving features set to their max at only a marginal decrease in power consumption
|
||||
/// as oppposed to `Aggressive`.
|
||||
SuperSave,
|
||||
impl<'d> embassy_net_driver::Driver for Driver<'d> {
|
||||
// type RxToken<'a> = RxToken<'a, 'd> where Self: 'a;
|
||||
// type TxToken<'a> = TxToken<'a, 'd> where Self: 'a;
|
||||
type RxToken<'a> = RxToken where Self: 'a;
|
||||
type TxToken<'a> = TxToken where Self: 'a;
|
||||
|
||||
/// Aggressive power saving mode.
|
||||
Aggressive,
|
||||
fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
|
||||
// WAKER.register(cx.waker());
|
||||
// if self.rx.available().is_some() && self.tx.available().is_some() {
|
||||
// Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx }))
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
|
||||
/// The default mode.
|
||||
PowerSave,
|
||||
None
|
||||
}
|
||||
|
||||
/// Performance is prefered over power consumption but still some power is conserved as opposed to
|
||||
/// `None`.
|
||||
Performance,
|
||||
fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
|
||||
// WAKER.register(cx.waker());
|
||||
// / if self.tx.available().is_some() {
|
||||
// / Some(TxToken { tx: &mut self.tx })
|
||||
// / } else {
|
||||
// / None
|
||||
// / }
|
||||
|
||||
/// Unlike all the other PM modes, this lowers the power consumption at all times at the cost of
|
||||
/// a much lower throughput.
|
||||
ThroughputThrottling,
|
||||
None
|
||||
}
|
||||
|
||||
/// No power management is configured. This consumes the most power.
|
||||
None,
|
||||
}
|
||||
fn capabilities(&self) -> Capabilities {
|
||||
let mut caps = Capabilities::default();
|
||||
caps.max_transmission_unit = MTU;
|
||||
// caps.max_burst_size = Some(self.tx.len());
|
||||
|
||||
impl Default for PowerManagementMode {
|
||||
fn default() -> Self {
|
||||
Self::PowerSave
|
||||
caps.medium = Medium::Ieee802154;
|
||||
caps
|
||||
}
|
||||
|
||||
fn link_state(&mut self, cx: &mut Context) -> LinkState {
|
||||
// if self.phy.poll_link(&mut self.station_management, cx) {
|
||||
// LinkState::Up
|
||||
// } else {
|
||||
// LinkState::Down
|
||||
// }
|
||||
|
||||
LinkState::Down
|
||||
}
|
||||
|
||||
fn ethernet_address(&self) -> [u8; 6] {
|
||||
// self.mac_addr
|
||||
|
||||
[0; 6]
|
||||
}
|
||||
}
|
||||
|
||||
impl PowerManagementMode {
|
||||
// TODO
|
||||
pub struct RxToken {
|
||||
// rx: &'a mut RDesRing<'d>,
|
||||
}
|
||||
|
||||
pub type NetDriver<'a> = ch::Device<'a, MTU>;
|
||||
impl embassy_net_driver::RxToken for RxToken {
|
||||
fn consume<R, F>(self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> R,
|
||||
{
|
||||
// NOTE(unwrap): we checked the queue wasn't full when creating the token.
|
||||
// let pkt = unwrap!(self.rx.available());
|
||||
|
||||
pub async fn new<'a, PWR, SPI>(
|
||||
state: &'a mut State,
|
||||
pwr: PWR,
|
||||
spi: SPI,
|
||||
firmware: &[u8],
|
||||
) -> (NetDriver<'a>, Control<'a>, Runner<'a, PWR, SPI>)
|
||||
where
|
||||
PWR: OutputPin,
|
||||
SPI: SpiBusCyw43,
|
||||
{
|
||||
let (ch_runner, device) = ch::new(&mut state.ch, [0; 6]);
|
||||
let state_ch = ch_runner.state_runner();
|
||||
|
||||
let mut runner = Runner::new(ch_runner, Bus::new(pwr, spi), &state.ioctl_state, &state.events);
|
||||
|
||||
runner.init(firmware).await;
|
||||
|
||||
(
|
||||
device,
|
||||
Control::new(state_ch, &state.events, &state.ioctl_state),
|
||||
runner,
|
||||
)
|
||||
let pkt = &[];
|
||||
let r = f(&mut pkt[0..]);
|
||||
// self.rx.pop_packet();
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
fn slice8_mut(x: &mut [u32]) -> &mut [u8] {
|
||||
let len = x.len() * 4;
|
||||
unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) }
|
||||
pub struct TxToken {
|
||||
// tx: &'a mut TDesRing<'d>,
|
||||
}
|
||||
|
||||
impl embassy_net_driver::TxToken for TxToken {
|
||||
fn consume<R, F>(self, len: usize, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> R,
|
||||
{
|
||||
// NOTE(unwrap): we checked the queue wasn't full when creating the token.
|
||||
// let pkt = unwrap!(self.tx.available());
|
||||
let pkt = &[];
|
||||
let r = f(&mut pkt[..len]);
|
||||
// self.tx.transmit(len);
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user