wpan: fix comp errors and impl. some of runner

This commit is contained in:
xoviat 2023-07-17 20:14:06 -05:00
parent 8f23b6faa6
commit d040871f7a
4 changed files with 255 additions and 17 deletions

View file

@ -25,6 +25,8 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
type TxToken<'a> = TxToken where Self: 'a; type TxToken<'a> = TxToken where Self: 'a;
fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
self.runner.rx_waker.register(cx.waker());
// WAKER.register(cx.waker()); // WAKER.register(cx.waker());
// if self.rx.available().is_some() && self.tx.available().is_some() { // if self.rx.available().is_some() && self.tx.available().is_some() {
// Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx })) // Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx }))
@ -36,6 +38,8 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
} }
fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> { fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
self.runner.tx_waker.register(cx.waker());
// WAKER.register(cx.waker()); // WAKER.register(cx.waker());
// / if self.tx.available().is_some() { // / if self.tx.available().is_some() {
// / Some(TxToken { tx: &mut self.tx }) // / Some(TxToken { tx: &mut self.tx })
@ -84,7 +88,7 @@ impl embassy_net_driver::RxToken for RxToken {
// NOTE(unwrap): we checked the queue wasn't full when creating the token. // NOTE(unwrap): we checked the queue wasn't full when creating the token.
// let pkt = unwrap!(self.rx.available()); // let pkt = unwrap!(self.rx.available());
let pkt = &[]; let pkt = &mut [];
let r = f(&mut pkt[0..]); let r = f(&mut pkt[0..]);
// self.rx.pop_packet(); // self.rx.pop_packet();
r r
@ -102,7 +106,7 @@ impl embassy_net_driver::TxToken for TxToken {
{ {
// NOTE(unwrap): we checked the queue wasn't full when creating the token. // NOTE(unwrap): we checked the queue wasn't full when creating the token.
// let pkt = unwrap!(self.tx.available()); // let pkt = unwrap!(self.tx.available());
let pkt = &[]; let pkt = &mut [];
let r = f(&mut pkt[..len]); let r = f(&mut pkt[..len]);
// self.tx.transmit(len); // self.tx.transmit(len);
r r

View file

@ -15,16 +15,11 @@ use core::slice;
pub use crate::mac::control::{Control, Error as ControlError}; pub use crate::mac::control::{Control, Error as ControlError};
use crate::mac::driver::Driver; use crate::mac::driver::Driver;
pub use crate::mac::runner::Runner; pub use crate::mac::runner::Runner;
use crate::sub::mac::Mac;
const MTU: usize = 127; const MTU: usize = 127;
pub async fn new<'a>(mac: Mac) -> (Runner, Control<'a>, Driver<'a>) { pub async fn new<'a>(runner: &'a Runner) -> (Control<'a>, Driver<'a>) {
let runner = Runner::new(mac); (Control::new(runner), Driver::new(runner))
let control = Control::new(&runner);
let driver = Driver::new(&runner);
(runner, control, driver)
} }
fn slice8_mut(x: &mut [u32]) -> &mut [u8] { fn slice8_mut(x: &mut [u32]) -> &mut [u8] {

View file

@ -1,27 +1,86 @@
use embassy_futures::select::{select3, Either3}; use embassy_futures::select::{select3, Either3};
use embassy_sync::waitqueue::AtomicWaker;
use crate::mac::event::{Event, MacEvent};
use crate::mac::MTU; use crate::mac::MTU;
use crate::sub::mac::Mac; use crate::sub::mac::Mac;
pub(crate) struct TxRing {
// stores n packets of up to mtu size
ring: [[u8; MTU]; 5],
pending: bool,
// start: u8,
// end: u8,
}
impl TxRing {
pub(crate) fn new() -> Self {
Self {
ring: [[0; MTU]; 5],
pending: false,
}
}
// wait for a free packet to become available
pub fn is_packet_free(&self) -> bool {
!self.pending
}
// get the next available free packet
pub fn get_free_packet<'a>(&'a mut self) -> &'a mut [u8] {
self.pending = true;
&mut self.ring[0]
}
pub fn get_packet_to_transmit<'a>(&'a mut self) -> Option<&'a [u8]> {
if self.pending {
self.pending = false;
Some(&self.ring[0])
} else {
None
}
}
}
pub struct Runner { pub struct Runner {
mac: Mac, mac_subsystem: Mac,
// TODO: tx_ring pub(crate) rx_ring: Option<Event>,
// TODO: rx_buf pub(crate) tx_ring: TxRing,
pub(crate) rx_waker: AtomicWaker,
pub(crate) tx_waker: AtomicWaker,
} }
impl Runner { impl Runner {
pub(crate) fn new(mac: Mac) -> Self { pub fn new(mac: Mac) -> Self {
Self { mac } Self {
mac_subsystem: mac,
rx_ring: None,
tx_ring: TxRing::new(),
rx_waker: AtomicWaker::new(),
tx_waker: AtomicWaker::new(),
}
} }
pub(crate) async fn init(&mut self, firmware: &[u8]) { pub(crate) async fn init(&mut self, firmware: &[u8]) {
debug!("wifi init done"); debug!("wifi init done");
} }
pub async fn run(mut self) -> ! { pub async fn run(&self) -> ! {
let mut buf = [0; 512];
loop { loop {
// TODO let event = self.mac_subsystem.read().await;
if let Ok(evt) = event.mac_event() {
match evt {
MacEvent::McpsDataInd(data_ind) => {
// TODO: store mac_event in rx_ring
self.rx_waker.wake();
}
_ => {}
}
}
// TODO: select tx event
} }
} }
} }

View file

@ -0,0 +1,180 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32_wpan::mac::commands::{AssociateResponse, ResetRequest, SetRequest, StartRequest};
use embassy_stm32_wpan::mac::typedefs::{MacChannel, MacStatus, PanId, PibId, SecurityLevel};
use embassy_stm32_wpan::mac::{self, Runner};
use embassy_stm32_wpan::sub::mm;
use embassy_stm32_wpan::TlMbox;
use static_cell::make_static;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs{
IPCC_C1_RX => ReceiveInterruptHandler;
IPCC_C1_TX => TransmitInterruptHandler;
});
#[embassy_executor::task]
async fn run_mm_queue(memory_manager: mm::MemoryManager) {
memory_manager.run_queue().await;
}
#[embassy_executor::task]
async fn run_mac(runner: &'static Runner) {
runner.run().await;
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
/*
How to make this work:
- Obtain a NUCLEO-STM32WB55 from your preferred supplier.
- Download and Install STM32CubeProgrammer.
- Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from
gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x
- Open STM32CubeProgrammer
- On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware.
- Once complete, click connect to connect to the device.
- On the left hand pane, click the RSS signal icon to open "Firmware Upgrade Services".
- In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file
- Select that file, the memory address, "verify download", and then "Firmware Upgrade".
- Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the
stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address.
- Select that file, the memory address, "verify download", and then "Firmware Upgrade".
- Select "Start Wireless Stack".
- Disconnect from the device.
- In the examples folder for stm32wb, modify the memory.x file to match your target device.
- Run this example.
Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name.
*/
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let config = Config::default();
let mbox = TlMbox::init(p.IPCC, Irqs, config);
spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap();
let sys_event = mbox.sys_subsystem.read().await;
info!("sys event: {}", sys_event.payload());
core::mem::drop(sys_event);
let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
info!("initialized mac: {}", result);
info!("resetting");
mbox.mac_subsystem
.send_command(&ResetRequest {
set_default_pib: true,
..Default::default()
})
.await
.unwrap();
{
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt.mac_event());
}
info!("setting extended address");
let extended_address: u64 = 0xACDE480000000001;
mbox.mac_subsystem
.send_command(&SetRequest {
pib_attribute_ptr: &extended_address as *const _ as *const u8,
pib_attribute: PibId::ExtendedAddress,
})
.await
.unwrap();
{
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt.mac_event());
}
info!("setting short address");
let short_address: u16 = 0x1122;
mbox.mac_subsystem
.send_command(&SetRequest {
pib_attribute_ptr: &short_address as *const _ as *const u8,
pib_attribute: PibId::ShortAddress,
})
.await
.unwrap();
{
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt.mac_event());
}
info!("setting association permit");
let association_permit: bool = true;
mbox.mac_subsystem
.send_command(&SetRequest {
pib_attribute_ptr: &association_permit as *const _ as *const u8,
pib_attribute: PibId::AssociationPermit,
})
.await
.unwrap();
{
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt.mac_event());
}
info!("setting TX power");
let transmit_power: i8 = 2;
mbox.mac_subsystem
.send_command(&SetRequest {
pib_attribute_ptr: &transmit_power as *const _ as *const u8,
pib_attribute: PibId::TransmitPower,
})
.await
.unwrap();
{
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt.mac_event());
}
info!("starting FFD device");
mbox.mac_subsystem
.send_command(&StartRequest {
pan_id: PanId([0x1A, 0xAA]),
channel_number: MacChannel::Channel16,
beacon_order: 0x0F,
superframe_order: 0x0F,
pan_coordinator: true,
battery_life_extension: false,
..Default::default()
})
.await
.unwrap();
{
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt.mac_event());
}
info!("setting RX on when idle");
let rx_on_while_idle: bool = true;
mbox.mac_subsystem
.send_command(&SetRequest {
pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
pib_attribute: PibId::RxOnWhenIdle,
})
.await
.unwrap();
{
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt.mac_event());
}
let runner = make_static!(Runner::new(mbox.mac_subsystem));
spawner.spawn(run_mac(runner)).unwrap();
let (driver, control) = mac::new(runner).await;
}