This commit is contained in:
Gustav Toft 2024-04-04 15:52:44 +02:00
commit a373633d0d
222 changed files with 5557 additions and 4554 deletions

View file

@ -41,7 +41,6 @@ async fn main(_spawner: Spawner) {
config.product = Some("USB-DFU Runtime example");
config.serial_number = Some("1235678");
let mut device_descriptor = [0; 256];
let mut config_descriptor = [0; 256];
let mut bos_descriptor = [0; 256];
let mut control_buf = [0; 64];
@ -49,7 +48,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [],

View file

@ -49,7 +49,6 @@ fn main() -> ! {
let mut buffer = AlignedBuffer([0; WRITE_SIZE]);
let updater = BlockingFirmwareUpdater::new(fw_config, &mut buffer.0[..]);
let mut device_descriptor = [0; 256];
let mut config_descriptor = [0; 256];
let mut bos_descriptor = [0; 256];
let mut control_buf = [0; 4096];
@ -57,7 +56,6 @@ fn main() -> ! {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [],

View file

@ -70,7 +70,6 @@ async fn main(spawner: Spawner) {
config.device_protocol = 0x01;
// Create embassy-usb DeviceBuilder using the driver and config.
static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new();
@ -78,7 +77,6 @@ async fn main(spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut DEVICE_DESC.init([0; 256])[..],
&mut CONFIG_DESC.init([0; 256])[..],
&mut BOS_DESC.init([0; 256])[..],
&mut MSOS_DESC.init([0; 128])[..],

View file

@ -50,7 +50,6 @@ async fn main(_spawner: Spawner) {
// 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];
@ -63,7 +62,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -43,7 +43,6 @@ async fn main(_spawner: Spawner) {
// 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];
@ -55,7 +54,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -48,7 +48,6 @@ async fn main(_spawner: Spawner) {
// 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];
@ -59,7 +58,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -67,7 +67,6 @@ async fn main(spawner: Spawner) {
let state = STATE.init(State::new());
// Create embassy-usb DeviceBuilder using the driver and config.
static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new();
@ -75,7 +74,6 @@ async fn main(spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut DEVICE_DESC.init([0; 256])[..],
&mut CONFIG_DESC.init([0; 256])[..],
&mut BOS_DESC.init([0; 256])[..],
&mut MSOS_DESC.init([0; 128])[..],

View file

@ -53,7 +53,6 @@ async fn main(_spawner: Spawner) {
// 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];
@ -64,7 +63,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -30,10 +30,14 @@ fn main() -> ! {
let p = embassy_rp::init(Default::default());
let led = Output::new(p.PIN_25, Level::Low);
spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || {
let executor1 = EXECUTOR1.init(Executor::new());
executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led))));
});
spawn_core1(
p.CORE1,
unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
move || {
let executor1 = EXECUTOR1.init(Executor::new());
executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led))));
},
);
let executor0 = EXECUTOR0.init(Executor::new());
executor0.run(|spawner| unwrap!(spawner.spawn(core0_task())));

View file

@ -35,7 +35,7 @@ async fn main(_spawner: Spawner) {
// allowing direct connection of the display to the RP2040 without level shifters.
let p = embassy_rp::init(Default::default());
let _pwm = Pwm::new_output_b(p.PWM_CH7, p.PIN_15, {
let _pwm = Pwm::new_output_b(p.PWM_SLICE7, p.PIN_15, {
let mut c = pwm::Config::default();
c.divider = 125.into();
c.top = 100;

View file

@ -60,7 +60,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -70,7 +69,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) {
let mut c: Config = Default::default();
c.top = 0x8000;
c.compare_b = 8;
let mut pwm = Pwm::new_output_b(p.PWM_CH4, p.PIN_25, c.clone());
let mut pwm = Pwm::new_output_b(p.PWM_SLICE4, p.PIN_25, c.clone());
loop {
info!("current LED duty cycle: {}/32768", c.compare_b);

View file

@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let cfg: Config = Default::default();
let pwm = Pwm::new_input(p.PWM_CH2, p.PIN_5, InputMode::RisingEdge, cfg);
let pwm = Pwm::new_input(p.PWM_SLICE2, p.PIN_5, InputMode::RisingEdge, cfg);
let mut ticker = Ticker::every(Duration::from_secs(1));
loop {

View file

@ -64,14 +64,12 @@ async fn main(spawner: Spawner) {
config.device_protocol = 0x01;
// Create embassy-usb DeviceBuilder using the driver and config.
static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
let mut builder = Builder::new(
driver,
config,
&mut DEVICE_DESC.init([0; 256])[..],
&mut CONFIG_DESC.init([0; 256])[..],
&mut BOS_DESC.init([0; 256])[..],
&mut [], // no msos descriptors

View file

@ -36,7 +36,6 @@ async fn main(_spawner: Spawner) {
// 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];
// You can also add a Microsoft OS descriptor.
@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -39,7 +39,6 @@ async fn main(_spawner: Spawner) {
// 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];
// You can also add a Microsoft OS descriptor.
@ -53,7 +52,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -54,7 +53,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -93,7 +93,6 @@ async fn main(_spawner: Spawner) {
// 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];
@ -106,7 +105,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -71,7 +71,6 @@ async fn main(_spawner: Spawner) {
// 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];
@ -80,7 +79,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -56,7 +55,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -57,7 +56,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -1,5 +1,3 @@
use std::default::Default;
use clap::Parser;
use embassy_executor::{Executor, Spawner};
use embassy_net::tcp::TcpSocket;

View file

@ -1,5 +1,3 @@
use std::default::Default;
use clap::Parser;
use embassy_executor::{Executor, Spawner};
use embassy_net::dns::DnsQueryType;

View file

@ -1,5 +1,4 @@
use core::fmt::Write as _;
use std::default::Default;
use clap::Parser;
use embassy_executor::{Executor, Spawner};

View file

@ -23,6 +23,7 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
heapless = { version = "0.8", default-features = false }
nb = "1.0.0"
static_cell = "2.0.0"
[profile.dev]
opt-level = "s"

View file

@ -3,12 +3,14 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::can::frame::Envelope;
use embassy_stm32::can::{
filter, Can, Fifo, Frame, Id, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, StandardId,
TxInterruptHandler,
};
use embassy_stm32::peripherals::CAN;
use embassy_stm32::{bind_interrupts, Config};
use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
@ -21,6 +23,27 @@ bind_interrupts!(struct Irqs {
// This example is configured to work with real CAN transceivers on B8/B9.
// See other examples for loopback.
fn handle_frame(env: Envelope, read_mode: &str) {
match env.frame.id() {
Id::Extended(id) => {
defmt::println!(
"{} Extended Frame id={:x} {:02x}",
read_mode,
id.as_raw(),
env.frame.data()
);
}
Id::Standard(id) => {
defmt::println!(
"{} Standard Frame id={:x} {:02x}",
read_mode,
id.as_raw(),
env.frame.data()
);
}
}
}
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Config::default());
@ -28,36 +51,86 @@ async fn main(_spawner: Spawner) {
// Set alternate pin mapping to B8/B9
embassy_stm32::pac::AFIO.mapr().modify(|w| w.set_can1_remap(2));
static RX_BUF: StaticCell<embassy_stm32::can::RxBuf<10>> = StaticCell::new();
static TX_BUF: StaticCell<embassy_stm32::can::TxBuf<10>> = StaticCell::new();
let mut can = Can::new(p.CAN, p.PB8, p.PB9, Irqs);
can.as_mut()
.modify_filters()
can.modify_filters()
.enable_bank(0, Fifo::Fifo0, filter::Mask32::accept_all());
can.as_mut()
.modify_config()
can.modify_config()
.set_loopback(false)
.set_silent(false)
.leave_disabled();
can.set_bitrate(250_000);
.set_bitrate(250_000);
can.enable().await;
let mut i: u8 = 0;
/*
// Example for using buffered Tx and Rx without needing to
// split first as is done below.
let mut can = can.buffered(
TX_BUF.init(embassy_stm32::can::TxBuf::<10>::new()),
RX_BUF.init(embassy_stm32::can::RxBuf::<10>::new()));
loop {
let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
can.write(&tx_frame).await;
match can.read().await {
Ok((frame, ts)) => {
handle_frame(Envelope { ts, frame }, "Buf");
}
Err(err) => {
defmt::println!("Error {}", err);
}
}
i += 1;
}
*/
let (mut tx, mut rx) = can.split();
// This example shows using the wait_not_empty API before try read
while i < 3 {
let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
tx.write(&tx_frame).await;
rx.wait_not_empty().await;
let env = rx.try_read().unwrap();
handle_frame(env, "Wait");
i += 1;
}
// This example shows using the full async non-buffered API
while i < 6 {
let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
tx.write(&tx_frame).await;
match rx.read().await {
Ok(env) => {
handle_frame(env, "NoBuf");
}
Err(err) => {
defmt::println!("Error {}", err);
}
}
i += 1;
}
// This example shows using buffered RX and TX. User passes in desired buffer (size)
// It's possible this way to have just RX or TX buffered.
let mut rx = rx.buffered(RX_BUF.init(embassy_stm32::can::RxBuf::<10>::new()));
let mut tx = tx.buffered(TX_BUF.init(embassy_stm32::can::TxBuf::<10>::new()));
loop {
let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
can.write(&tx_frame).await;
tx.write(&tx_frame).await;
match can.read().await {
Ok(env) => match env.frame.id() {
Id::Extended(id) => {
defmt::println!("Extended Frame id={:x} {:02x}", id.as_raw(), env.frame.data());
}
Id::Standard(id) => {
defmt::println!("Standard Frame id={:x} {:02x}", id.as_raw(), env.frame.data());
}
},
match rx.read().await {
Ok(envelope) => {
handle_frame(envelope, "Buf");
}
Err(err) => {
defmt::println!("Error {}", err);
}

View file

@ -60,7 +60,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 7];
@ -70,7 +69,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -1,8 +1,6 @@
#![no_std]
#![no_main]
use core::convert::TryFrom;
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::time::Hertz;

View file

@ -54,7 +54,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 7];
@ -64,7 +63,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -35,17 +35,12 @@ async fn main(_spawner: Spawner) {
let mut can = Can::new(p.CAN1, p.PA11, p.PA12, Irqs);
can.as_mut()
.modify_filters()
.enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
can.as_mut()
.modify_config()
can.modify_config()
.set_loopback(true) // Receive own frames
.set_silent(true)
.leave_disabled();
can.set_bitrate(1_000_000);
.set_bitrate(1_000_000);
can.enable().await;

View file

@ -89,14 +89,12 @@ async fn main(spawner: Spawner) {
config.device_protocol = 0x01;
// Create embassy-usb DeviceBuilder using the driver and config.
static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
let mut builder = Builder::new(
driver,
config,
&mut DEVICE_DESC.init([0; 256])[..],
&mut CONFIG_DESC.init([0; 256])[..],
&mut BOS_DESC.init([0; 256])[..],
&mut [], // no msos descriptors

View file

@ -69,7 +69,6 @@ async fn main(_spawner: Spawner) {
// 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];
// You can also add a Microsoft OS descriptor.
@ -84,7 +83,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -64,7 +64,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -76,7 +75,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -117,7 +117,6 @@ async fn main(_spawner: Spawner) {
// 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];
@ -130,7 +129,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,

View file

@ -64,7 +64,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -74,7 +73,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -15,8 +15,9 @@
use embassy_executor::Spawner;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::khz;
use embassy_stm32::timer::low_level::CountingMode;
use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::timer::{Channel, CountingMode};
use embassy_stm32::timer::Channel;
use embassy_time::{Duration, Ticker, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -60,7 +61,7 @@ async fn main(_spawner: Spawner) {
// construct ws2812 non-return-to-zero (NRZ) code bit by bit
// ws2812 only need 24 bits for each LED, but we add one bit more to keep PWM output low
let max_duty = ws2812_pwm.get_max_duty();
let max_duty = ws2812_pwm.get_max_duty() as u16;
let n0 = 8 * max_duty / 25; // ws2812 Bit 0 high level timing
let n1 = 2 * n0; // ws2812 Bit 1 high level timing

View file

@ -47,20 +47,18 @@ async fn main(spawner: Spawner) {
static CAN: StaticCell<Can<'static, CAN3>> = StaticCell::new();
let can = CAN.init(Can::new(p.CAN3, p.PA8, p.PA15, Irqs));
can.as_mut()
.modify_filters()
.enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
can.as_mut()
.modify_config()
can.modify_config()
.set_bit_timing(can::util::NominalBitTiming {
prescaler: NonZeroU16::new(2).unwrap(),
seg1: NonZeroU8::new(13).unwrap(),
seg2: NonZeroU8::new(2).unwrap(),
sync_jump_width: NonZeroU8::new(1).unwrap(),
}) // http://www.bittiming.can-wiki.info/
.set_loopback(true)
.enable();
.set_loopback(true);
can.enable().await;
let (tx, mut rx) = can.split();

View file

@ -64,7 +64,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -74,7 +73,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -36,7 +36,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 7];
@ -46,7 +45,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -36,7 +36,7 @@ async fn main(_spawner: Spawner) {
}
let peripherals = embassy_stm32::init(config);
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
can.set_extended_filter(
can::filter::ExtendedFilterSlot::_0,
@ -56,21 +56,22 @@ async fn main(_spawner: Spawner) {
info!("Configured");
let mut can = can.start(match use_fd {
true => can::FdcanOperatingMode::InternalLoopbackMode,
false => can::FdcanOperatingMode::NormalOperationMode,
true => can::OperatingMode::InternalLoopbackMode,
false => can::OperatingMode::NormalOperationMode,
});
let mut i = 0;
let mut last_read_ts = embassy_time::Instant::now();
loop {
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
info!("Writing frame");
_ = can.write(&frame).await;
match can.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (ts, rx_frame) = (envelope.ts, envelope.frame);
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(
@ -105,7 +106,8 @@ async fn main(_spawner: Spawner) {
}
match can.read_fd().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (ts, rx_frame) = (envelope.ts, envelope.frame);
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(
@ -129,12 +131,13 @@ async fn main(_spawner: Spawner) {
let (mut tx, mut rx) = can.split();
// With split
loop {
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
info!("Writing frame");
_ = tx.write(&frame).await;
match rx.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (ts, rx_frame) = (envelope.ts, envelope.frame);
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(
@ -156,7 +159,7 @@ async fn main(_spawner: Spawner) {
}
}
let can = can::Fdcan::join(tx, rx);
let can = can::Can::join(tx, rx);
info!("\n\n\nBuffered\n");
if use_fd {
@ -173,7 +176,8 @@ async fn main(_spawner: Spawner) {
_ = can.write(frame).await;
match can.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (ts, rx_frame) = (envelope.ts, envelope.frame);
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(
@ -198,7 +202,7 @@ async fn main(_spawner: Spawner) {
RX_BUF.init(can::RxBuf::<10>::new()),
);
loop {
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
info!("Writing frame");
// You can use any of these approaches to send. The writer makes it
@ -208,7 +212,8 @@ async fn main(_spawner: Spawner) {
can.writer().write(frame).await;
match can.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (ts, rx_frame) = (envelope.ts, envelope.frame);
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(

View file

@ -56,7 +56,6 @@ async fn main(_spawner: Spawner) {
config.device_protocol = 0x01;
config.composite_with_iads = true;
let mut device_descriptor = [0; 256];
let mut config_descriptor = [0; 256];
let mut bos_descriptor = [0; 256];
let mut control_buf = [0; 64];
@ -66,7 +65,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) {
let peripherals = embassy_stm32::init(config);
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
// 250k bps
can.set_bitrate(250_000);
@ -38,12 +38,13 @@ async fn main(_spawner: Spawner) {
let mut last_read_ts = embassy_time::Instant::now();
loop {
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
info!("Writing frame");
_ = can.write(&frame).await;
match can.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (rx_frame, ts) = envelope.parts();
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(
@ -69,12 +70,13 @@ async fn main(_spawner: Spawner) {
let (mut tx, mut rx) = can.split();
// With split
loop {
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
info!("Writing frame");
_ = tx.write(&frame).await;
match rx.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (rx_frame, ts) = envelope.parts();
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(

View file

@ -65,7 +65,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -75,7 +74,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -6,9 +6,9 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32h743bi to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "chrono"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }

View file

@ -78,9 +78,9 @@ async fn main(_spawner: Spawner) {
);
defmt::info!("attempting capture");
defmt::unwrap!(dcmi.capture(unsafe { &mut FRAME }).await);
defmt::unwrap!(dcmi.capture(unsafe { &mut *core::ptr::addr_of_mut!(FRAME) }).await);
defmt::info!("captured frame: {:x}", unsafe { &FRAME });
defmt::info!("captured frame: {:x}", unsafe { &*core::ptr::addr_of!(FRAME) });
defmt::info!("main loop running");
loop {

View file

@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) {
let peripherals = embassy_stm32::init(config);
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
// 250k bps
can.set_bitrate(250_000);
@ -38,12 +38,13 @@ async fn main(_spawner: Spawner) {
let mut last_read_ts = embassy_time::Instant::now();
loop {
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
info!("Writing frame");
_ = can.write(&frame).await;
match can.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (rx_frame, ts) = envelope.parts();
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(
@ -69,12 +70,13 @@ async fn main(_spawner: Spawner) {
let (mut tx, mut rx) = can.split();
// With split
loop {
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
info!("Writing frame");
_ = tx.write(&frame).await;
match rx.read().await {
Ok((rx_frame, ts)) => {
Ok(envelope) => {
let (rx_frame, ts) = envelope.parts();
let delta = (ts - last_read_ts).as_millis();
last_read_ts = ts;
info!(

View file

@ -6,9 +6,9 @@ use embassy_executor::Spawner;
use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
use embassy_stm32::pac::timer::vals::Mms;
use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
use embassy_stm32::rcc::low_level::RccPeripheral;
use embassy_stm32::rcc::frequency;
use embassy_stm32::time::Hertz;
use embassy_stm32::timer::low_level::BasicInstance;
use embassy_stm32::timer::low_level::Timer;
use micromath::F32Ext;
use {defmt_rtt as _, panic_probe as _};
@ -51,19 +51,19 @@ async fn main(spawner: Spawner) {
// Obtain two independent channels (p.DAC1 can only be consumed once, though!)
let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split();
spawner.spawn(dac_task1(dac_ch1)).ok();
spawner.spawn(dac_task2(dac_ch2)).ok();
spawner.spawn(dac_task1(p.TIM6, dac_ch1)).ok();
spawner.spawn(dac_task2(p.TIM7, dac_ch2)).ok();
}
#[embassy_executor::task]
async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM6 frequency is {}", TIM6::frequency());
info!("TIM6 frequency is {}", frequency::<TIM6>());
const FREQUENCY: Hertz = Hertz::hz(200);
// Compute the reload value such that we obtain the FREQUENCY for the sine
let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32;
let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
// Depends on your clock and on the specific chip used, you may need higher or lower values here
if reload < 10 {
@ -74,17 +74,17 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
dac.set_triggering(true);
dac.enable();
TIM6::enable_and_reset();
TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
TIM6::regs_basic().cr1().modify(|w| {
let tim = Timer::new(tim);
tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
tim.regs_basic().cr1().modify(|w| {
w.set_opm(false);
w.set_cen(true);
});
debug!(
"TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM6::frequency(),
frequency::<TIM6>(),
FREQUENCY,
reload,
reload as u16,
@ -99,22 +99,22 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
}
#[embassy_executor::task]
async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM7 frequency is {}", TIM7::frequency());
info!("TIM7 frequency is {}", frequency::<TIM6>());
const FREQUENCY: Hertz = Hertz::hz(600);
let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32;
let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
if reload < 10 {
error!("Reload value {} below threshold!", reload);
}
TIM7::enable_and_reset();
TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
TIM7::regs_basic().cr1().modify(|w| {
let tim = Timer::new(tim);
tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
tim.regs_basic().cr1().modify(|w| {
w.set_opm(false);
w.set_cen(true);
});
@ -125,7 +125,7 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
debug!(
"TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM7::frequency(),
frequency::<TIM7>(),
FREQUENCY,
reload,
reload as u16,

View file

@ -64,19 +64,21 @@ async fn main(spawner: Spawner) -> ! {
let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new();
// warning: Not all STM32H7 devices have the exact same pins here
// for STM32H747XIH, replace p.PB13 for PG12
let device = Ethernet::new(
PACKETS.init(PacketQueue::<4, 4>::new()),
p.ETH,
Irqs,
p.PA1,
p.PA2,
p.PC1,
p.PA7,
p.PC4,
p.PC5,
p.PG13,
p.PB13,
p.PG11,
p.PA1, // ref_clk
p.PA2, // mdio
p.PC1, // eth_mdc
p.PA7, // CRS_DV: Carrier Sense
p.PC4, // RX_D0: Received Bit 0
p.PC5, // RX_D1: Received Bit 1
p.PG13, // TX_D0: Transmit Bit 0
p.PB13, // TX_D1: Transmit Bit 1
p.PG11, // TX_EN: Transmit Enable
GenericSMI::new(0),
mac_addr,
);

View file

@ -3,11 +3,11 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::gpio::low_level::AFType;
use embassy_stm32::gpio::Speed;
use embassy_stm32::gpio::{AFType, Flex, Pull, Speed};
use embassy_stm32::time::{khz, Hertz};
use embassy_stm32::timer::*;
use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef};
use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer};
use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel};
use embassy_stm32::{into_ref, Config, Peripheral};
use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _};
@ -56,11 +56,15 @@ async fn main(_spawner: Spawner) {
Timer::after_millis(300).await;
}
}
pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> {
inner: PeripheralRef<'d, T>,
pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> {
tim: LLTimer<'d, T>,
_ch1: Flex<'d>,
_ch2: Flex<'d>,
_ch3: Flex<'d>,
_ch4: Flex<'d>,
}
impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
pub fn new(
tim: impl Peripheral<P = T> + 'd,
ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
@ -69,25 +73,33 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd,
freq: Hertz,
) -> Self {
into_ref!(tim, ch1, ch2, ch3, ch4);
into_ref!(ch1, ch2, ch3, ch4);
T::enable_and_reset();
let af1 = ch1.af_num();
let af2 = ch2.af_num();
let af3 = ch3.af_num();
let af4 = ch4.af_num();
let mut ch1 = Flex::new(ch1);
let mut ch2 = Flex::new(ch2);
let mut ch3 = Flex::new(ch3);
let mut ch4 = Flex::new(ch4);
ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
ch1.set_speed(Speed::VeryHigh);
ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch2.set_speed(Speed::VeryHigh);
ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch3.set_speed(Speed::VeryHigh);
ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch4.set_speed(Speed::VeryHigh);
ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull);
let mut this = Self { inner: tim };
let mut this = Self {
tim: LLTimer::new(tim),
_ch1: ch1,
_ch2: ch2,
_ch3: ch3,
_ch4: ch4,
};
this.set_frequency(freq);
this.inner.start();
this.tim.start();
let r = T::regs_gp32();
let r = this.tim.regs_gp32();
r.ccmr_output(0)
.modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into()));
r.ccmr_output(0)
@ -101,23 +113,26 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
}
pub fn enable(&mut self, channel: Channel) {
T::regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), true));
self.tim.regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), true));
}
pub fn disable(&mut self, channel: Channel) {
T::regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), false));
self.tim
.regs_gp32()
.ccer()
.modify(|w| w.set_cce(channel.index(), false));
}
pub fn set_frequency(&mut self, freq: Hertz) {
<T as embassy_stm32::timer::low_level::GeneralPurpose32bitInstance>::set_frequency(&mut self.inner, freq);
self.tim.set_frequency(freq);
}
pub fn get_max_duty(&self) -> u32 {
T::regs_gp32().arr().read()
self.tim.regs_gp32().arr().read()
}
pub fn set_duty(&mut self, channel: Channel, duty: u32) {
defmt::assert!(duty < self.get_max_duty());
T::regs_gp32().ccr(channel.index()).write_value(duty)
self.tim.regs_gp32().ccr(channel.index()).write_value(duty)
}
}

View file

@ -0,0 +1,145 @@
//! This example showcases how to create multiple Executor instances to run tasks at
//! different priority levels.
//!
//! Low priority executor runs in thread mode (not interrupt), and uses `sev` for signaling
//! there's work in the queue, and `wfe` for waiting for work.
//!
//! Medium and high priority executors run in two interrupts with different priorities.
//! Signaling work is done by pending the interrupt. No "waiting" needs to be done explicitly, since
//! when there's work the interrupt will trigger and run the executor.
//!
//! Sample output below. Note that high priority ticks can interrupt everything else, and
//! medium priority computations can interrupt low priority computations, making them to appear
//! to take significantly longer time.
//!
//! ```not_rust
//! [med] Starting long computation
//! [med] done in 992 ms
//! [high] tick!
//! [low] Starting long computation
//! [med] Starting long computation
//! [high] tick!
//! [high] tick!
//! [med] done in 993 ms
//! [med] Starting long computation
//! [high] tick!
//! [high] tick!
//! [med] done in 993 ms
//! [low] done in 3972 ms
//! [med] Starting long computation
//! [high] tick!
//! [high] tick!
//! [med] done in 993 ms
//! ```
//!
//! For comparison, try changing the code so all 3 tasks get spawned on the low priority executor.
//! You will get an output like the following. Note that no computation is ever interrupted.
//!
//! ```not_rust
//! [high] tick!
//! [med] Starting long computation
//! [med] done in 496 ms
//! [low] Starting long computation
//! [low] done in 992 ms
//! [med] Starting long computation
//! [med] done in 496 ms
//! [high] tick!
//! [low] Starting long computation
//! [low] done in 992 ms
//! [high] tick!
//! [med] Starting long computation
//! [med] done in 496 ms
//! [high] tick!
//! ```
//!
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt::*;
use embassy_executor::{Executor, InterruptExecutor};
use embassy_stm32::interrupt;
use embassy_stm32::interrupt::{InterruptExt, Priority};
use embassy_time::{Instant, Timer};
use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::task]
async fn run_high() {
loop {
info!(" [high] tick!");
Timer::after_ticks(27374).await;
}
}
#[embassy_executor::task]
async fn run_med() {
loop {
let start = Instant::now();
info!(" [med] Starting long computation");
// Spin-wait to simulate a long CPU computation
cortex_m::asm::delay(128_000_000); // ~1 second
let end = Instant::now();
let ms = end.duration_since(start).as_ticks() / 33;
info!(" [med] done in {} ms", ms);
Timer::after_ticks(23421).await;
}
}
#[embassy_executor::task]
async fn run_low() {
loop {
let start = Instant::now();
info!("[low] Starting long computation");
// Spin-wait to simulate a long CPU computation
cortex_m::asm::delay(256_000_000); // ~2 seconds
let end = Instant::now();
let ms = end.duration_since(start).as_ticks() / 33;
info!("[low] done in {} ms", ms);
Timer::after_ticks(32983).await;
}
}
static EXECUTOR_HIGH: InterruptExecutor = InterruptExecutor::new();
static EXECUTOR_MED: InterruptExecutor = InterruptExecutor::new();
static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new();
#[interrupt]
unsafe fn UART4() {
EXECUTOR_HIGH.on_interrupt()
}
#[interrupt]
unsafe fn UART5() {
EXECUTOR_MED.on_interrupt()
}
#[entry]
fn main() -> ! {
info!("Hello World!");
let _p = embassy_stm32::init(Default::default());
// High-priority executor: UART4, priority level 6
interrupt::UART4.set_priority(Priority::P6);
let spawner = EXECUTOR_HIGH.start(interrupt::UART4);
unwrap!(spawner.spawn(run_high()));
// Medium-priority executor: UART5, priority level 7
interrupt::UART5.set_priority(Priority::P7);
let spawner = EXECUTOR_MED.start(interrupt::UART5);
unwrap!(spawner.spawn(run_med()));
// Low priority executor: runs in thread mode, using WFE/SEV
let executor = EXECUTOR_LOW.init(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run_low()));
});
}

View file

@ -65,7 +65,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -75,7 +74,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) {
config.device_protocol = 0x01;
config.composite_with_iads = true;
let mut device_descriptor = [0; 256];
let mut config_descriptor = [0; 256];
let mut bos_descriptor = [0; 256];
let mut control_buf = [0; 64];
@ -56,7 +55,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -6,9 +6,9 @@ use embassy_executor::Spawner;
use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
use embassy_stm32::pac::timer::vals::Mms;
use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
use embassy_stm32::rcc::low_level::RccPeripheral;
use embassy_stm32::rcc::frequency;
use embassy_stm32::time::Hertz;
use embassy_stm32::timer::low_level::BasicInstance;
use embassy_stm32::timer::low_level::Timer;
use micromath::F32Ext;
use {defmt_rtt as _, panic_probe as _};
@ -22,19 +22,19 @@ async fn main(spawner: Spawner) {
// Obtain two independent channels (p.DAC1 can only be consumed once, though!)
let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split();
spawner.spawn(dac_task1(dac_ch1)).ok();
spawner.spawn(dac_task2(dac_ch2)).ok();
spawner.spawn(dac_task1(p.TIM6, dac_ch1)).ok();
spawner.spawn(dac_task2(p.TIM7, dac_ch2)).ok();
}
#[embassy_executor::task]
async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM6 frequency is {}", TIM6::frequency());
info!("TIM6 frequency is {}", frequency::<TIM6>());
const FREQUENCY: Hertz = Hertz::hz(200);
// Compute the reload value such that we obtain the FREQUENCY for the sine
let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32;
let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
// Depends on your clock and on the specific chip used, you may need higher or lower values here
if reload < 10 {
@ -45,17 +45,17 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
dac.set_triggering(true);
dac.enable();
TIM6::enable_and_reset();
TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
TIM6::regs_basic().cr1().modify(|w| {
let tim = Timer::new(tim);
tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
tim.regs_basic().cr1().modify(|w| {
w.set_opm(false);
w.set_cen(true);
});
debug!(
"TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM6::frequency(),
frequency::<TIM6>(),
FREQUENCY,
reload,
reload as u16,
@ -70,22 +70,22 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
}
#[embassy_executor::task]
async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM7 frequency is {}", TIM7::frequency());
info!("TIM7 frequency is {}", frequency::<TIM7>());
const FREQUENCY: Hertz = Hertz::hz(600);
let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32;
let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
if reload < 10 {
error!("Reload value {} below threshold!", reload);
}
TIM7::enable_and_reset();
TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
TIM7::regs_basic().cr1().modify(|w| {
let tim = Timer::new(tim);
tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
tim.regs_basic().cr1().modify(|w| {
w.set_opm(false);
w.set_cen(true);
});
@ -96,7 +96,7 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
debug!(
"TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM7::frequency(),
frequency::<TIM7>(),
FREQUENCY,
reload,
reload as u16,

View file

@ -42,7 +42,7 @@ bind_interrupts!(struct Irqs {
RNG => rng::InterruptHandler<peripherals::RNG>;
});
use embassy_net_adin1110::{self, Device, Runner, ADIN1110};
use embassy_net_adin1110::{Device, Runner, ADIN1110};
use embedded_hal_bus::spi::ExclusiveDevice;
use hal::gpio::Pull;
use hal::i2c::Config as I2C_Config;
@ -93,12 +93,6 @@ async fn main(spawner: Spawner) {
let dp = embassy_stm32::init(config);
// RM0432rev9, 5.1.2: Independent I/O supply rail
// After reset, the I/Os supplied by VDDIO2 are logically and electrically isolated and
// therefore are not available. The isolation must be removed before using any I/O from
// PG[15:2], by setting the IOSV bit in the PWR_CR2 register, once the VDDIO2 supply is present
pac::PWR.cr2().modify(|w| w.set_iosv(true));
let reset_status = pac::RCC.bdcr().read().0;
defmt::println!("bdcr before: 0x{:X}", reset_status);

View file

@ -60,7 +60,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -70,7 +69,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -79,14 +79,12 @@ async fn main(spawner: Spawner) {
config.device_protocol = 0x01;
// Create embassy-usb DeviceBuilder using the driver and config.
static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
let mut builder = Builder::new(
driver,
config,
&mut DEVICE_DESC.init([0; 256])[..],
&mut CONFIG_DESC.init([0; 256])[..],
&mut BOS_DESC.init([0; 256])[..],
&mut [], // no msos descriptors

View file

@ -51,7 +51,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -62,7 +61,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -47,7 +47,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 7];
@ -57,7 +56,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors

View file

@ -61,7 +61,6 @@ async fn main(_spawner: Spawner) {
// 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 control_buf = [0; 64];
@ -71,7 +70,6 @@ async fn main(_spawner: Spawner) {
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut [], // no msos descriptors