Merge branch 'master' into usb_msc

This commit is contained in:
chemicstry
2023-02-27 01:19:52 +02:00
142 changed files with 3965 additions and 1165 deletions

View File

@ -1,11 +1,12 @@
[package]
edition = "2021"
name = "embassy-nrf-examples"
name = "embassy-nrf52840-examples"
version = "0.1.0"
license = "MIT OR Apache-2.0"
[features]
default = ["nightly"]
msos-descriptor = ["embassy-usb/msos-descriptor"]
nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-net/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embedded-io/async", "embassy-net",
"embassy-lora", "lorawan-device", "lorawan"]
@ -14,7 +15,7 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true }
embedded-io = "0.4.0"
@ -34,4 +35,8 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
rand = { version = "0.8.4", default-features = false }
embedded-storage = "0.3.0"
usbd-hid = "0.6.0"
serde = { version = "1.0.136", default-features = false }
serde = { version = "1.0.136", default-features = false }
[[bin]]
name = "usb_serial_winusb"
required-features = ["msos-descriptor"]

View File

@ -24,9 +24,9 @@ async fn main(_spawner: Spawner) {
let sample_rate = master_clock.sample_rate();
info!("Sample rate: {}", sample_rate);
let config = Config::default()
.sample_width(SampleWidth::_16bit)
.channels(Channels::MonoLeft);
let mut config = Config::default();
config.sample_width = SampleWidth::_16bit;
config.channels = Channels::MonoLeft;
let irq = interrupt::take!(I2S);
let buffers_out = MultiBuffering::<Sample, NUM_BUFFERS, NUM_SAMPLES>::new();

View File

@ -22,9 +22,9 @@ async fn main(_spawner: Spawner) {
let sample_rate = master_clock.sample_rate();
info!("Sample rate: {}", sample_rate);
let config = Config::default()
.sample_width(SampleWidth::_16bit)
.channels(Channels::MonoLeft);
let mut config = Config::default();
config.sample_width = SampleWidth::_16bit;
config.channels = Channels::MonoLeft;
let irq = interrupt::take!(I2S);
let buffers = DoubleBuffering::<Sample, NUM_SAMPLES>::new();

View File

@ -23,9 +23,9 @@ async fn main(_spawner: Spawner) {
let sample_rate = master_clock.sample_rate();
info!("Sample rate: {}", sample_rate);
let config = Config::default()
.sample_width(SampleWidth::_16bit)
.channels(Channels::MonoLeft);
let mut config = Config::default();
config.sample_width = SampleWidth::_16bit;
config.channels = Channels::MonoLeft;
let irq = interrupt::take!(I2S);
let buffers = DoubleBuffering::<Sample, NUM_SAMPLES>::new();

View File

@ -5,7 +5,7 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_nrf::interrupt;
use embassy_nrf::saadc::{ChannelConfig, Config, Saadc, SamplerState};
use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc};
use embassy_nrf::timer::Frequency;
use embassy_time::Duration;
use {defmt_rtt as _, panic_probe as _};
@ -61,7 +61,7 @@ async fn main(_p: Spawner) {
c = 0;
a = 0;
}
SamplerState::Sampled
CallbackResult::Continue
},
)
.await;

View File

@ -9,7 +9,7 @@ use embassy_executor::Spawner;
use embassy_net::tcp::TcpSocket;
use embassy_net::{Stack, StackResources};
use embassy_nrf::rng::Rng;
use embassy_nrf::usb::{Driver, PowerUsb};
use embassy_nrf::usb::{Driver, HardwareVbusDetect};
use embassy_nrf::{interrupt, pac, peripherals};
use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState};
use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
@ -18,7 +18,7 @@ use embedded_io::asynch::Write;
use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _};
type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>;
type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>;
macro_rules! singleton {
($val:expr) => {{
@ -46,8 +46,31 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
stack.run().await
}
#[inline(never)]
pub fn test_function() -> (usize, u32, [u32; 2]) {
let mut array = [3; 2];
let mut index = 0;
let mut result = 0;
for x in [1, 2] {
if x == 1 {
array[1] = 99;
} else {
index = if x == 2 { 1 } else { 0 };
// grabs value from array[0], not array[1]
result = array[index];
}
}
(index, result, array)
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
info!("{:?}", test_function());
let p = embassy_nrf::init(Default::default());
let clock: pac::CLOCK = unsafe { mem::transmute(()) };
@ -58,7 +81,7 @@ async fn main(spawner: Spawner) {
// Create the driver, from the HAL.
let irq = interrupt::take!(USBD);
let power_irq = interrupt::take!(POWER_CLOCK);
let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
let driver = Driver::new(p.USBD, irq, HardwareVbusDetect::new(power_irq));
// Create embassy-usb Config
let mut config = Config::new(0xc0de, 0xcafe);
@ -82,7 +105,6 @@ async fn main(spawner: Spawner) {
&mut singleton!([0; 256])[..],
&mut singleton!([0; 256])[..],
&mut singleton!([0; 128])[..],
None,
);
// Our MAC addr.

View File

@ -10,13 +10,13 @@ use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_futures::select::{select, Either};
use embassy_nrf::gpio::{Input, Pin, Pull};
use embassy_nrf::usb::{Driver, PowerUsb};
use embassy_nrf::usb::{Driver, HardwareVbusDetect};
use embassy_nrf::{interrupt, pac};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::signal::Signal;
use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State};
use embassy_usb::control::OutResponse;
use embassy_usb::{Builder, Config, DeviceStateHandler};
use embassy_usb::{Builder, Config, Handler};
use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
use {defmt_rtt as _, panic_probe as _};
@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) {
// Create the driver, from the HAL.
let irq = interrupt::take!(USBD);
let power_irq = interrupt::take!(POWER_CLOCK);
let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
let driver = Driver::new(p.USBD, irq, HardwareVbusDetect::new(power_irq));
// Create embassy-usb Config
let mut config = Config::new(0xc0de, 0xcafe);
@ -52,7 +52,7 @@ async fn main(_spawner: Spawner) {
let mut bos_descriptor = [0; 256];
let mut control_buf = [0; 64];
let request_handler = MyRequestHandler {};
let device_state_handler = MyDeviceStateHandler::new();
let mut device_handler = MyDeviceHandler::new();
let mut state = State::new();
@ -63,9 +63,10 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
Some(&device_state_handler),
);
builder.handler(&mut device_handler);
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: KeyboardReport::desc(),
@ -164,20 +165,20 @@ impl RequestHandler for MyRequestHandler {
}
}
struct MyDeviceStateHandler {
struct MyDeviceHandler {
configured: AtomicBool,
}
impl MyDeviceStateHandler {
impl MyDeviceHandler {
fn new() -> Self {
MyDeviceStateHandler {
MyDeviceHandler {
configured: AtomicBool::new(false),
}
}
}
impl DeviceStateHandler for MyDeviceStateHandler {
fn enabled(&self, enabled: bool) {
impl Handler for MyDeviceHandler {
fn enabled(&mut self, enabled: bool) {
self.configured.store(false, Ordering::Relaxed);
SUSPENDED.store(false, Ordering::Release);
if enabled {
@ -187,17 +188,17 @@ impl DeviceStateHandler for MyDeviceStateHandler {
}
}
fn reset(&self) {
fn reset(&mut self) {
self.configured.store(false, Ordering::Relaxed);
info!("Bus reset, the Vbus current limit is 100mA");
}
fn addressed(&self, addr: u8) {
fn addressed(&mut self, addr: u8) {
self.configured.store(false, Ordering::Relaxed);
info!("USB address set to: {}", addr);
}
fn configured(&self, configured: bool) {
fn configured(&mut self, configured: bool) {
self.configured.store(configured, Ordering::Relaxed);
if configured {
info!("Device configured, it may now draw up to the configured current limit from Vbus.")
@ -206,7 +207,7 @@ impl DeviceStateHandler for MyDeviceStateHandler {
}
}
fn suspended(&self, suspended: bool) {
fn suspended(&mut self, suspended: bool) {
if suspended {
info!("Device suspended, the Vbus current limit is 500µA (or 2.5mA for high-power devices with remote wakeup enabled).");
SUSPENDED.store(true, Ordering::Release);

View File

@ -7,7 +7,7 @@ use core::mem;
use defmt::*;
use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_nrf::usb::{Driver, PowerUsb};
use embassy_nrf::usb::{Driver, HardwareVbusDetect};
use embassy_nrf::{interrupt, pac};
use embassy_time::{Duration, Timer};
use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State};
@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) {
// Create the driver, from the HAL.
let irq = interrupt::take!(USBD);
let power_irq = interrupt::take!(POWER_CLOCK);
let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
let driver = Driver::new(p.USBD, irq, HardwareVbusDetect::new(power_irq));
// Create embassy-usb Config
let mut config = Config::new(0xc0de, 0xcafe);
@ -55,7 +55,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -7,7 +7,7 @@ use core::mem;
use defmt::{info, panic};
use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_nrf::usb::{Driver, Instance, PowerUsb, UsbSupply};
use embassy_nrf::usb::{Driver, HardwareVbusDetect, Instance, VbusDetect};
use embassy_nrf::{interrupt, pac};
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
use embassy_usb::driver::EndpointError;
@ -26,7 +26,7 @@ async fn main(_spawner: Spawner) {
// Create the driver, from the HAL.
let irq = interrupt::take!(USBD);
let power_irq = interrupt::take!(POWER_CLOCK);
let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
let driver = Driver::new(p.USBD, irq, HardwareVbusDetect::new(power_irq));
// Create embassy-usb Config
let mut config = Config::new(0xc0de, 0xcafe);
@ -59,7 +59,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.
@ -97,7 +96,7 @@ impl From<EndpointError> for Disconnected {
}
}
async fn echo<'d, T: Instance + 'd, P: UsbSupply + 'd>(
async fn echo<'d, T: Instance + 'd, P: VbusDetect + 'd>(
class: &mut CdcAcmClass<'d, Driver<'d, T, P>>,
) -> Result<(), Disconnected> {
let mut buf = [0; 64];

View File

@ -6,7 +6,7 @@ use core::mem;
use defmt::{info, panic, unwrap};
use embassy_executor::Spawner;
use embassy_nrf::usb::{Driver, PowerUsb};
use embassy_nrf::usb::{Driver, HardwareVbusDetect};
use embassy_nrf::{interrupt, pac, peripherals};
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
use embassy_usb::driver::EndpointError;
@ -14,7 +14,7 @@ use embassy_usb::{Builder, Config, UsbDevice};
use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _};
type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>;
type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>;
#[embassy_executor::task]
async fn usb_task(mut device: UsbDevice<'static, MyDriver>) {
@ -42,7 +42,7 @@ async fn main(spawner: Spawner) {
// Create the driver, from the HAL.
let irq = interrupt::take!(USBD);
let power_irq = interrupt::take!(POWER_CLOCK);
let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
let driver = Driver::new(p.USBD, irq, HardwareVbusDetect::new(power_irq));
// Create embassy-usb Config
let mut config = Config::new(0xc0de, 0xcafe);
@ -83,7 +83,6 @@ async fn main(spawner: Spawner) {
&mut res.config_descriptor,
&mut res.bos_descriptor,
&mut res.control_buf,
None,
);
// Create classes on the builder.

View File

@ -0,0 +1,130 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use core::mem;
use defmt::{info, panic};
use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_nrf::usb::{Driver, HardwareVbusDetect, Instance, VbusDetect};
use embassy_nrf::{interrupt, pac};
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
use embassy_usb::driver::EndpointError;
use embassy_usb::msos::{self, windows_version};
use embassy_usb::types::InterfaceNumber;
use embassy_usb::{Builder, Config};
use {defmt_rtt as _, panic_probe as _};
// This is a randomly generated GUID to allow clients on Windows to find our device
const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"];
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_nrf::init(Default::default());
let clock: pac::CLOCK = unsafe { mem::transmute(()) };
info!("Enabling ext hfosc...");
clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
while clock.events_hfclkstarted.read().bits() != 1 {}
// Create the driver, from the HAL.
let irq = interrupt::take!(USBD);
let power_irq = interrupt::take!(POWER_CLOCK);
let driver = Driver::new(p.USBD, irq, HardwareVbusDetect::new(power_irq));
// Create embassy-usb Config
let mut config = Config::new(0xc0de, 0xcafe);
config.manufacturer = Some("Embassy");
config.product = Some("USB-serial example");
config.serial_number = Some("12345678");
config.max_power = 100;
config.max_packet_size_0 = 64;
// Required for windows compatiblity.
// https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
config.device_class = 0xEF;
config.device_sub_class = 0x02;
config.device_protocol = 0x01;
config.composite_with_iads = true;
// Create embassy-usb DeviceBuilder using the driver and config.
// It needs some buffers for building the descriptors.
let mut device_descriptor = [0; 256];
let mut config_descriptor = [0; 256];
let mut bos_descriptor = [0; 256];
let mut msos_descriptor = [0; 256];
let mut control_buf = [0; 64];
let mut state = State::new();
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,
&mut control_buf,
);
builder.msos_descriptor(windows_version::WIN8_1, 2);
// Create classes on the builder.
let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
// Since we want to create MS OS feature descriptors that apply to a function that has already been added to the
// builder, need to get the MsOsDescriptorWriter from the builder and manually add those descriptors.
// Inside a class constructor, you would just need to call `FunctionBuilder::msos_feature` instead.
let msos_writer = builder.msos_writer();
msos_writer.configuration(0);
msos_writer.function(InterfaceNumber(0));
msos_writer.function_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
msos_writer.function_feature(msos::RegistryPropertyFeatureDescriptor::new(
"DeviceInterfaceGUIDs",
msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
));
// Build the builder.
let mut usb = builder.build();
// Run the USB device.
let usb_fut = usb.run();
// Do stuff with the class!
let echo_fut = async {
loop {
class.wait_connection().await;
info!("Connected");
let _ = echo(&mut class).await;
info!("Disconnected");
}
};
// Run everything concurrently.
// If we had made everything `'static` above instead, we could do this using separate tasks instead.
join(usb_fut, echo_fut).await;
}
struct Disconnected {}
impl From<EndpointError> for Disconnected {
fn from(val: EndpointError) -> Self {
match val {
EndpointError::BufferOverflow => panic!("Buffer overflow"),
EndpointError::Disabled => Disconnected {},
}
}
}
async fn echo<'d, T: Instance + 'd, P: VbusDetect + 'd>(
class: &mut CdcAcmClass<'d, Driver<'d, T, P>>,
) -> Result<(), Disconnected> {
let mut buf = [0; 64];
loop {
let n = class.read_packet(&mut buf).await?;
let data = &buf[..n];
info!("data: {:x}", data);
class.write_packet(data).await?;
}
}

View File

@ -1,6 +1,6 @@
[package]
edition = "2021"
name = "embassy-nrf-examples"
name = "embassy-nrf5340-examples"
version = "0.1.0"
license = "MIT OR Apache-2.0"

View File

@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) {
config.baudrate = uarte::Baudrate::BAUD115200;
let irq = interrupt::take!(SERIAL0);
let mut uart = uarte::Uarte::new(p.UARTETWISPI0, irq, p.P1_00, p.P1_01, config);
let mut uart = uarte::Uarte::new(p.SERIAL0, irq, p.P1_00, p.P1_01, config);
info!("uarte initialized!");

View File

@ -4,7 +4,7 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_rp::gpio::{AnyPin, Pin};
use embassy_rp::pio::{Pio0, PioPeripherial, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2};
use embassy_rp::pio::{Pio0, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2};
use embassy_rp::pio_instr_util;
use embassy_rp::relocate::RelocatedProgram;
use {defmt_rtt as _, panic_probe as _};

View File

@ -4,7 +4,7 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_rp::pio::{PioPeripherial, PioStateMachine, ShiftDirection};
use embassy_rp::pio::{PioPeripheral, PioStateMachine, ShiftDirection};
use embassy_rp::relocate::RelocatedProgram;
use embassy_rp::{pio_instr_util, Peripheral};
use {defmt_rtt as _, panic_probe as _};

View File

@ -73,7 +73,6 @@ async fn main(spawner: Spawner) {
&mut singleton!([0; 256])[..],
&mut singleton!([0; 256])[..],
&mut singleton!([0; 128])[..],
None,
);
// Our MAC addr.

View File

@ -53,7 +53,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] }
embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] }
embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "tcp", "udp", "dhcpv4"] }
embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "tcp", "udp", "dns", "dhcpv4", "unstable-traits", "proto-ipv6"] }
embassy-net-driver = { version = "0.1.0", path = "../../embassy-net-driver" }
embedded-io = { version = "0.4.0", features = ["async", "std", "futures"] }
critical-section = { version = "1.1", features = ["std"] }

View File

@ -65,7 +65,7 @@ async fn main_task(spawner: Spawner) {
let seed = u64::from_le_bytes(seed);
// Init network stack
let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed));
let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed));
// Launch network task
spawner.spawn(net_task(stack)).unwrap();

View File

@ -0,0 +1,98 @@
#![feature(type_alias_impl_trait)]
use std::default::Default;
use clap::Parser;
use embassy_executor::{Executor, Spawner};
use embassy_net::dns::DnsQueryType;
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
use heapless::Vec;
use log::*;
use rand_core::{OsRng, RngCore};
use static_cell::StaticCell;
#[path = "../tuntap.rs"]
mod tuntap;
use crate::tuntap::TunTapDevice;
macro_rules! singleton {
($val:expr) => {{
type T = impl Sized;
static STATIC_CELL: StaticCell<T> = StaticCell::new();
STATIC_CELL.init_with(move || $val)
}};
}
#[derive(Parser)]
#[clap(version = "1.0")]
struct Opts {
/// TAP device name
#[clap(long, default_value = "tap0")]
tap: String,
/// use a static IP instead of DHCP
#[clap(long)]
static_ip: bool,
}
#[embassy_executor::task]
async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! {
stack.run().await
}
#[embassy_executor::task]
async fn main_task(spawner: Spawner) {
let opts: Opts = Opts::parse();
// Init network device
let device = TunTapDevice::new(&opts.tap).unwrap();
// Choose between dhcp or static ip
let config = if opts.static_ip {
Config::Static(embassy_net::StaticConfig {
address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24),
dns_servers: Vec::from_slice(&[Ipv4Address::new(8, 8, 4, 4).into(), Ipv4Address::new(8, 8, 8, 8).into()])
.unwrap(),
gateway: Some(Ipv4Address::new(192, 168, 69, 100)),
})
} else {
Config::Dhcp(Default::default())
};
// Generate random seed
let mut seed = [0; 8];
OsRng.fill_bytes(&mut seed);
let seed = u64::from_le_bytes(seed);
// Init network stack
let stack: &Stack<_> = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed));
// Launch network task
spawner.spawn(net_task(stack)).unwrap();
let host = "example.com";
info!("querying host {:?}...", host);
match stack.dns_query(host, DnsQueryType::A).await {
Ok(r) => {
info!("query response: {:?}", r);
}
Err(e) => {
warn!("query error: {:?}", e);
}
};
}
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
fn main() {
env_logger::builder()
.filter_level(log::LevelFilter::Debug)
.filter_module("async_io", log::LevelFilter::Info)
.format_timestamp_nanos()
.init();
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(main_task(spawner)).unwrap();
});
}

View File

@ -62,7 +62,7 @@ async fn main_task(spawner: Spawner) {
let seed = u64::from_le_bytes(seed);
// Init network stack
let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed));
let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed));
// Launch network task
spawner.spawn(net_task(stack)).unwrap();

View File

@ -58,7 +58,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -55,7 +55,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -4,15 +4,20 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::sdmmc::Sdmmc;
use embassy_stm32::sdmmc::{DataBlock, Sdmmc};
use embassy_stm32::time::mhz;
use embassy_stm32::{interrupt, Config};
use {defmt_rtt as _, panic_probe as _};
/// This is a safeguard to not overwrite any data on the SD card.
/// If you don't care about SD card contents, set this to `true` to test writes.
const ALLOW_WRITES: bool = false;
#[embassy_executor::main]
async fn main(_spawner: Spawner) -> ! {
let mut config = Config::default();
config.rcc.sys_ck = Some(mhz(48));
config.rcc.pll48 = true;
let p = embassy_stm32::init(config);
info!("Hello World!");
@ -34,11 +39,42 @@ async fn main(_spawner: Spawner) -> ! {
// Should print 400kHz for initialization
info!("Configured clock: {}", sdmmc.clock().0);
unwrap!(sdmmc.init_card(mhz(25)).await);
unwrap!(sdmmc.init_card(mhz(48)).await);
let card = unwrap!(sdmmc.card());
info!("Card: {:#?}", Debug2Format(card));
info!("Clock: {}", sdmmc.clock());
// Arbitrary block index
let block_idx = 16;
// SDMMC uses `DataBlock` instead of `&[u8]` to ensure 4 byte alignment required by the hardware.
let mut block = DataBlock([0u8; 512]);
sdmmc.read_block(block_idx, &mut block).await.unwrap();
info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
if !ALLOW_WRITES {
info!("Writing is disabled.");
loop {}
}
info!("Filling block with 0x55");
block.fill(0x55);
sdmmc.write_block(block_idx, &block).await.unwrap();
info!("Write done");
sdmmc.read_block(block_idx, &mut block).await.unwrap();
info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
info!("Filling block with 0xAA");
block.fill(0xAA);
sdmmc.write_block(block_idx, &block).await.unwrap();
info!("Write done");
sdmmc.read_block(block_idx, &mut block).await.unwrap();
info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
loop {}
}

View File

@ -82,7 +82,6 @@ async fn main(spawner: Spawner) {
&mut singleton!([0; 256])[..],
&mut singleton!([0; 256])[..],
&mut singleton!([0; 128])[..],
None,
);
// Our MAC addr.

View File

@ -57,7 +57,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -13,6 +13,7 @@ use {defmt_rtt as _, panic_probe as _};
async fn main(_spawner: Spawner) -> ! {
let mut config = Config::default();
config.rcc.sys_ck = Some(mhz(200));
config.rcc.pll48 = true;
let p = embassy_stm32::init(config);
info!("Hello World!");

View File

@ -58,7 +58,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -9,7 +9,7 @@ embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["de
embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits"] }
embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits", "proto-ipv6"] }
embedded-io = { version = "0.4.0", features = ["async"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
@ -21,7 +21,7 @@ cortex-m-rt = "0.7.0"
embedded-hal = "0.2.6"
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
embedded-hal-async = { version = "=0.2.0-alpha.0" }
embedded-nal-async = "0.3.0"
embedded-nal-async = "0.4.0"
panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
heapless = { version = "0.7.5", default-features = false }

View File

@ -57,7 +57,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -59,7 +59,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -79,7 +79,6 @@ async fn main(spawner: Spawner) {
&mut singleton!([0; 256])[..],
&mut singleton!([0; 256])[..],
&mut singleton!([0; 128])[..],
None,
);
// Our MAC addr.

View File

@ -51,7 +51,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -59,7 +59,6 @@ async fn main(_spawner: Spawner) {
&mut config_descriptor,
&mut bos_descriptor,
&mut control_buf,
None,
);
// Create classes on the builder.

View File

@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000004, LENGTH = 191K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K
}