embassy/src/lib.rs

252 lines
6.4 KiB
Rust
Raw Normal View History

2022-07-10 19:45:26 +02:00
#![no_std]
#![no_main]
2023-02-19 16:31:33 +01:00
#![allow(incomplete_features)]
#![feature(async_fn_in_trait, type_alias_impl_trait, concat_bytes)]
2022-07-11 03:07:39 +02:00
#![deny(unused_must_use)]
2022-07-10 19:45:26 +02:00
// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;
2022-12-26 23:21:58 +01:00
mod bus;
mod consts;
2022-07-11 03:07:39 +02:00
mod countries;
mod events;
2022-07-11 00:25:35 +02:00
mod structs;
2023-03-02 12:10:13 +01:00
mod control;
mod nvram;
mod runner;
2022-07-11 00:25:35 +02:00
use core::cell::Cell;
2022-07-10 19:45:26 +02:00
2022-12-27 01:19:26 +01:00
use embassy_net_driver_channel as ch;
2022-10-02 21:28:34 +02:00
use embedded_hal_1::digital::OutputPin;
2023-03-01 19:03:46 +01:00
use events::EventQueue;
2022-07-10 19:45:26 +02:00
2022-12-26 23:21:58 +01:00
use crate::bus::Bus;
2023-02-19 16:31:33 +01:00
pub use crate::bus::SpiBusCyw43;
2023-03-02 12:10:13 +01:00
pub use crate::control::Control;
pub use crate::runner::Runner;
2022-09-15 09:56:12 +02:00
2022-12-27 01:19:26 +01:00
const MTU: usize = 1514;
#[derive(Clone, Copy)]
pub enum IoctlType {
Get = 0,
Set = 2,
}
#[allow(unused)]
2022-07-10 19:45:26 +02:00
#[derive(Clone, Copy, PartialEq, Eq)]
enum Core {
WLAN = 0,
SOCSRAM = 1,
SDIOD = 2,
}
impl Core {
fn base_addr(&self) -> u32 {
match self {
Self::WLAN => CHIP.arm_core_base_address,
Self::SOCSRAM => CHIP.socsram_wrapper_base_address,
Self::SDIOD => CHIP.sdiod_core_base_address,
}
}
}
#[allow(unused)]
2022-07-10 19:45:26 +02:00
struct Chip {
arm_core_base_address: u32,
socsram_base_address: u32,
socsram_wrapper_base_address: u32,
sdiod_core_base_address: u32,
pmu_base_address: u32,
chip_ram_size: u32,
atcm_ram_base_address: u32,
socram_srmem_size: u32,
chanspec_band_mask: u32,
chanspec_band_2g: u32,
chanspec_band_5g: u32,
chanspec_band_shift: u32,
chanspec_bw_10: u32,
chanspec_bw_20: u32,
chanspec_bw_40: u32,
chanspec_bw_mask: u32,
chanspec_bw_shift: u32,
chanspec_ctl_sb_lower: u32,
chanspec_ctl_sb_upper: u32,
chanspec_ctl_sb_none: u32,
chanspec_ctl_sb_mask: u32,
}
const WRAPPER_REGISTER_OFFSET: u32 = 0x100000;
// Data for CYW43439
const CHIP: Chip = Chip {
arm_core_base_address: 0x18003000 + WRAPPER_REGISTER_OFFSET,
socsram_base_address: 0x18004000,
socsram_wrapper_base_address: 0x18004000 + WRAPPER_REGISTER_OFFSET,
sdiod_core_base_address: 0x18002000,
pmu_base_address: 0x18000000,
chip_ram_size: 512 * 1024,
atcm_ram_base_address: 0,
socram_srmem_size: 64 * 1024,
chanspec_band_mask: 0xc000,
chanspec_band_2g: 0x0000,
chanspec_band_5g: 0xc000,
chanspec_band_shift: 14,
chanspec_bw_10: 0x0800,
chanspec_bw_20: 0x1000,
chanspec_bw_40: 0x1800,
chanspec_bw_mask: 0x3800,
chanspec_bw_shift: 11,
chanspec_ctl_sb_lower: 0x0000,
chanspec_ctl_sb_upper: 0x0100,
chanspec_ctl_sb_none: 0x0000,
chanspec_ctl_sb_mask: 0x0700,
};
#[derive(Clone, Copy)]
2022-07-11 00:25:35 +02:00
enum IoctlState {
Idle,
Pending {
kind: IoctlType,
2022-07-11 00:25:35 +02:00
cmd: u32,
iface: u32,
2022-07-12 03:34:27 +02:00
buf: *mut [u8],
},
Sent {
buf: *mut [u8],
},
Done {
resp_len: usize,
2022-07-11 00:25:35 +02:00
},
2022-07-10 19:45:26 +02:00
}
2022-07-11 00:25:35 +02:00
pub struct State {
ioctl_state: Cell<IoctlState>,
2022-12-27 01:19:26 +01:00
ch: ch::State<MTU, 4, 4>,
2023-03-01 19:03:46 +01:00
events: EventQueue,
2022-07-10 19:45:26 +02:00
}
2022-07-11 00:25:35 +02:00
impl State {
pub fn new() -> Self {
Self {
ioctl_state: Cell::new(IoctlState::Idle),
2022-12-27 01:19:26 +01:00
ch: ch::State::new(),
2023-03-01 19:03:46 +01:00
events: EventQueue::new(),
2022-07-11 00:25:35 +02:00
}
}
2022-07-10 19:45:26 +02:00
}
#[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,
/// Aggressive power saving mode.
Aggressive,
/// The default mode.
PowerSave,
/// Performance is prefered over power consumption but still some power is conserved as opposed to
/// `None`.
Performance,
/// Unlike all the other PM modes, this lowers the power consumption at all times at the cost of
/// a much lower throughput.
ThroughputThrottling,
/// No power management is configured. This consumes the most power.
None,
}
impl Default for PowerManagementMode {
fn default() -> Self {
Self::PowerSave
}
}
impl PowerManagementMode {
fn sleep_ret_ms(&self) -> u16 {
match self {
PowerManagementMode::SuperSave => 2000,
PowerManagementMode::Aggressive => 2000,
PowerManagementMode::PowerSave => 200,
PowerManagementMode::Performance => 20,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn beacon_period(&self) -> u8 {
match self {
PowerManagementMode::SuperSave => 255,
PowerManagementMode::Aggressive => 1,
PowerManagementMode::PowerSave => 1,
PowerManagementMode::Performance => 1,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn dtim_period(&self) -> u8 {
match self {
PowerManagementMode::SuperSave => 255,
PowerManagementMode::Aggressive => 1,
PowerManagementMode::PowerSave => 1,
PowerManagementMode::Performance => 1,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn assoc(&self) -> u8 {
match self {
PowerManagementMode::SuperSave => 255,
PowerManagementMode::Aggressive => 10,
PowerManagementMode::PowerSave => 10,
PowerManagementMode::Performance => 1,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn mode(&self) -> u32 {
match self {
PowerManagementMode::ThroughputThrottling => 1,
_ => 2,
}
}
}
2022-12-27 01:19:26 +01:00
pub type NetDriver<'a> = ch::Device<'a, MTU>;
pub async fn new<'a, PWR, SPI>(
2022-12-27 01:19:26 +01:00
state: &'a mut State,
pwr: PWR,
spi: SPI,
firmware: &[u8],
2022-12-27 01:19:26 +01:00
) -> (NetDriver<'a>, Control<'a>, Runner<'a, PWR, SPI>)
where
PWR: OutputPin,
SPI: SpiBusCyw43,
{
2022-12-27 01:19:26 +01:00
let (ch_runner, device) = ch::new(&mut state.ch, [0; 6]);
let state_ch = ch_runner.state_runner();
2023-03-02 12:10:13 +01:00
let mut runner = Runner::new(ch_runner, Bus::new(pwr, spi), &state.ioctl_state, &state.events);
2022-07-10 19:45:26 +02:00
runner.init(firmware).await;
2022-07-11 00:25:35 +02:00
2022-12-27 01:19:26 +01:00
(
device,
2023-03-02 12:10:13 +01:00
Control::new(state_ch, &state.events, &state.ioctl_state),
2022-12-27 01:19:26 +01:00
runner,
)
2022-07-11 00:25:35 +02:00
}