Merge remote-tracking branch 'origin/main' into bxcan_timestamp

This commit is contained in:
chemicstry
2023-07-31 10:29:20 +03:00
237 changed files with 3313 additions and 1870 deletions

View File

@ -7,7 +7,7 @@ use core::cell::RefCell;
use defmt_rtt as _;
use embassy_boot_rp::*;
use embassy_executor::Spawner;
use embassy_rp::flash::Flash;
use embassy_rp::flash::{self, Flash};
use embassy_rp::gpio::{Level, Output};
use embassy_rp::watchdog::Watchdog;
use embassy_sync::blocking_mutex::Mutex;
@ -34,7 +34,7 @@ async fn main(_s: Spawner) {
let mut watchdog = Watchdog::new(p.WATCHDOG);
watchdog.start(Duration::from_secs(8));
let flash: Flash<_, FLASH_SIZE> = Flash::new(p.FLASH);
let flash = Flash::<_, flash::Blocking, FLASH_SIZE>::new(p.FLASH);
let flash = Mutex::new(RefCell::new(flash));
let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash);

View File

@ -34,3 +34,6 @@ log = { version = "0.4.17", optional = true }
[[bin]]
name = "rtos_trace"
required-features = ["nightly"]
[profile.release]
debug = 2

View File

@ -19,3 +19,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing
cortex-m-rt = "0.7.0"
panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
[profile.release]
debug = 2

View File

@ -57,5 +57,5 @@ embedded-hal-async = { version = "0.2.0-alpha.2", optional = true }
num-integer = { version = "0.1.45", default-features = false }
microfft = "0.5.0"
[patch.crates-io]
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
[profile.release]
debug = 2

View File

@ -53,3 +53,6 @@ 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 }
[profile.release]
debug = 2

View File

@ -53,7 +53,4 @@ pio = "0.2.1"
rand = { version = "0.8.5", default-features = false }
[profile.release]
debug = true
[patch.crates-io]
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
debug = 2

View File

@ -6,7 +6,7 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_rp::flash::{ERASE_SIZE, FLASH_BASE};
use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE};
use embassy_rp::peripherals::FLASH;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) {
// https://github.com/knurling-rs/defmt/pull/683
Timer::after(Duration::from_millis(10)).await;
let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH);
let mut flash = embassy_rp::flash::Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0);
// Get JEDEC id
let jedec = flash.jedec_id().unwrap();
@ -40,10 +40,12 @@ async fn main(_spawner: Spawner) {
multiwrite_bytes(&mut flash, ERASE_SIZE as u32);
background_read(&mut flash, (ERASE_SIZE * 2) as u32).await;
loop {}
}
fn multiwrite_bytes(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE>, offset: u32) {
fn multiwrite_bytes(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) {
info!(">>>> [multiwrite_bytes]");
let mut read_buf = [0u8; ERASE_SIZE];
defmt::unwrap!(flash.read(ADDR_OFFSET + offset, &mut read_buf));
@ -71,7 +73,7 @@ fn multiwrite_bytes(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE>,
}
}
fn erase_write_sector(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE>, offset: u32) {
fn erase_write_sector(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) {
info!(">>>> [erase_write_sector]");
let mut buf = [0u8; ERASE_SIZE];
defmt::unwrap!(flash.read(ADDR_OFFSET + offset, &mut buf));
@ -99,3 +101,35 @@ fn erase_write_sector(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE
defmt::panic!("unexpected");
}
}
async fn background_read(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) {
info!(">>>> [background_read]");
let mut buf = [0u32; 8];
defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await;
info!("Addr of flash block is {:x}", ADDR_OFFSET + offset + FLASH_BASE as u32);
info!("Contents start with {=u32:x}", buf[0]);
defmt::unwrap!(flash.erase(ADDR_OFFSET + offset, ADDR_OFFSET + offset + ERASE_SIZE as u32));
defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await;
info!("Contents after erase starts with {=u32:x}", buf[0]);
if buf.iter().any(|x| *x != 0xFFFFFFFF) {
defmt::panic!("unexpected");
}
for b in buf.iter_mut() {
*b = 0xDABA1234;
}
defmt::unwrap!(flash.write(ADDR_OFFSET + offset, unsafe {
core::slice::from_raw_parts(buf.as_ptr() as *const u8, buf.len() * 4)
}));
defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await;
info!("Contents after write starts with {=u32:x}", buf[0]);
if buf.iter().any(|x| *x != 0xDABA1234) {
defmt::panic!("unexpected");
}
}

View File

@ -8,7 +8,6 @@ use embassy_executor::Spawner;
use embassy_rp::bind_interrupts;
use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine};
use embassy_rp::relocate::RelocatedProgram;
use fixed::traits::ToFixed;
use fixed_macro::types::U56F8;
use {defmt_rtt as _, panic_probe as _};
@ -29,9 +28,8 @@ fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
".wrap",
);
let relocated = RelocatedProgram::new(&prg.program);
let mut cfg = Config::default();
cfg.use_program(&pio.load_program(&relocated), &[]);
cfg.use_program(&pio.load_program(&prg.program), &[]);
let out_pin = pio.make_pio_pin(pin);
cfg.set_out_pins(&[&out_pin]);
cfg.set_set_pins(&[&out_pin]);
@ -65,9 +63,8 @@ fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
".wrap",
);
let relocated = RelocatedProgram::new(&prg.program);
let mut cfg = Config::default();
cfg.use_program(&pio.load_program(&relocated), &[]);
cfg.use_program(&pio.load_program(&prg.program), &[]);
cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
cfg.shift_in.auto_fill = true;
cfg.shift_in.direction = ShiftDirection::Right;
@ -96,9 +93,8 @@ fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
"irq 3 [15]",
".wrap",
);
let relocated = RelocatedProgram::new(&prg.program);
let mut cfg = Config::default();
cfg.use_program(&pio.load_program(&relocated), &[]);
cfg.use_program(&pio.load_program(&prg.program), &[]);
cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
sm.set_config(&cfg);
}

View File

@ -8,7 +8,6 @@ use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
use embassy_rp::relocate::RelocatedProgram;
use embassy_rp::{bind_interrupts, Peripheral};
use fixed::traits::ToFixed;
use fixed_macro::types::U56F8;
@ -46,9 +45,8 @@ async fn main(_spawner: Spawner) {
".wrap",
);
let relocated = RelocatedProgram::new(&prg.program);
let mut cfg = Config::default();
cfg.use_program(&common.load_program(&relocated), &[]);
cfg.use_program(&common.load_program(&prg.program), &[]);
cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed();
cfg.shift_in = ShiftConfig {
auto_fill: true,

View File

@ -14,7 +14,6 @@ use embassy_rp::pio::{
Config, Direction, FifoJoin, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
};
use embassy_rp::pwm::{self, Pwm};
use embassy_rp::relocate::RelocatedProgram;
use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef};
use embassy_time::{Duration, Instant, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -127,9 +126,8 @@ impl<'l> HD44780<'l> {
sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]);
let relocated = RelocatedProgram::new(&prg.program);
let mut cfg = Config::default();
cfg.use_program(&common.load_program(&relocated), &[&e]);
cfg.use_program(&common.load_program(&prg.program), &[&e]);
cfg.clock_divider = 125u8.into();
cfg.set_out_pins(&[&db4, &db5, &db6, &db7]);
cfg.shift_out = ShiftConfig {
@ -201,9 +199,8 @@ impl<'l> HD44780<'l> {
"#
);
let relocated = RelocatedProgram::new(&prg.program);
let mut cfg = Config::default();
cfg.use_program(&common.load_program(&relocated), &[&e]);
cfg.use_program(&common.load_program(&prg.program), &[&e]);
cfg.clock_divider = 8u8.into(); // ~64ns/insn
cfg.set_jmp_pin(&db7);
cfg.set_set_pins(&[&rs, &rw]);

View File

@ -0,0 +1,394 @@
//! This example shows how to use the PIO module in the RP2040 chip to implement a duplex UART.
//! The PIO module is a very powerful peripheral that can be used to implement many different
//! protocols. It is a very flexible state machine that can be programmed to do almost anything.
//!
//! This example opens up a USB device that implements a CDC ACM serial port. It then uses the
//! PIO module to implement a UART that is connected to the USB serial port. This allows you to
//! communicate with a device connected to the RP2040 over USB serial.
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait)]
use defmt::{info, panic, trace};
use embassy_executor::Spawner;
use embassy_futures::join::{join, join3};
use embassy_rp::bind_interrupts;
use embassy_rp::peripherals::{PIO0, USB};
use embassy_rp::pio::InterruptHandler as PioInterruptHandler;
use embassy_rp::usb::{Driver, Instance, InterruptHandler};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_sync::pipe::Pipe;
use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State};
use embassy_usb::driver::EndpointError;
use embassy_usb::{Builder, Config};
use embedded_io::asynch::{Read, Write};
use {defmt_rtt as _, panic_probe as _};
use crate::uart::PioUart;
use crate::uart_rx::PioUartRx;
use crate::uart_tx::PioUartTx;
bind_interrupts!(struct Irqs {
USBCTRL_IRQ => InterruptHandler<USB>;
PIO0_IRQ_0 => PioInterruptHandler<PIO0>;
});
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
info!("Hello there!");
let p = embassy_rp::init(Default::default());
// Create the driver, from the HAL.
let driver = Driver::new(p.USB, Irqs);
// Create embassy-usb Config
let mut config = Config::new(0xc0de, 0xcafe);
config.manufacturer = Some("Embassy");
config.product = Some("PIO UART example");
config.serial_number = Some("12345678");
config.max_power = 100;
config.max_packet_size_0 = 64;
// Required for windows compatibility.
// 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 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 control_buf,
);
// Create classes on the builder.
let class = CdcAcmClass::new(&mut builder, &mut state, 64);
// Build the builder.
let mut usb = builder.build();
// Run the USB device.
let usb_fut = usb.run();
// PIO UART setup
let uart = PioUart::new(9600, p.PIO0, p.PIN_4, p.PIN_5);
let (mut uart_tx, mut uart_rx) = uart.split();
// Pipe setup
let usb_pipe: Pipe<NoopRawMutex, 20> = Pipe::new();
let mut usb_pipe_writer = usb_pipe.writer();
let mut usb_pipe_reader = usb_pipe.reader();
let uart_pipe: Pipe<NoopRawMutex, 20> = Pipe::new();
let mut uart_pipe_writer = uart_pipe.writer();
let mut uart_pipe_reader = uart_pipe.reader();
let (mut usb_tx, mut usb_rx) = class.split();
// Read + write from USB
let usb_future = async {
loop {
info!("Wait for USB connection");
usb_rx.wait_connection().await;
info!("Connected");
let _ = join(
usb_read(&mut usb_rx, &mut uart_pipe_writer),
usb_write(&mut usb_tx, &mut usb_pipe_reader),
)
.await;
info!("Disconnected");
}
};
// Read + write from UART
let uart_future = join(
uart_read(&mut uart_rx, &mut usb_pipe_writer),
uart_write(&mut uart_tx, &mut uart_pipe_reader),
);
// Run everything concurrently.
// If we had made everything `'static` above instead, we could do this using separate tasks instead.
join3(usb_fut, usb_future, uart_future).await;
}
struct Disconnected {}
impl From<EndpointError> for Disconnected {
fn from(val: EndpointError) -> Self {
match val {
EndpointError::BufferOverflow => panic!("Buffer overflow"),
EndpointError::Disabled => Disconnected {},
}
}
}
/// Read from the USB and write it to the UART TX pipe
async fn usb_read<'d, T: Instance + 'd>(
usb_rx: &mut Receiver<'d, Driver<'d, T>>,
uart_pipe_writer: &mut embassy_sync::pipe::Writer<'_, NoopRawMutex, 20>,
) -> Result<(), Disconnected> {
let mut buf = [0; 64];
loop {
let n = usb_rx.read_packet(&mut buf).await?;
let data = &buf[..n];
trace!("USB IN: {:x}", data);
uart_pipe_writer.write(data).await;
}
}
/// Read from the USB TX pipe and write it to the USB
async fn usb_write<'d, T: Instance + 'd>(
usb_tx: &mut Sender<'d, Driver<'d, T>>,
usb_pipe_reader: &mut embassy_sync::pipe::Reader<'_, NoopRawMutex, 20>,
) -> Result<(), Disconnected> {
let mut buf = [0; 64];
loop {
let n = usb_pipe_reader.read(&mut buf).await;
let data = &buf[..n];
trace!("USB OUT: {:x}", data);
usb_tx.write_packet(&data).await?;
}
}
/// Read from the UART and write it to the USB TX pipe
async fn uart_read(
uart_rx: &mut PioUartRx<'_>,
usb_pipe_writer: &mut embassy_sync::pipe::Writer<'_, NoopRawMutex, 20>,
) -> ! {
let mut buf = [0; 64];
loop {
let n = uart_rx.read(&mut buf).await.expect("UART read error");
if n == 0 {
continue;
}
let data = &buf[..n];
trace!("UART IN: {:x}", buf);
usb_pipe_writer.write(data).await;
}
}
/// Read from the UART TX pipe and write it to the UART
async fn uart_write(
uart_tx: &mut PioUartTx<'_>,
uart_pipe_reader: &mut embassy_sync::pipe::Reader<'_, NoopRawMutex, 20>,
) -> ! {
let mut buf = [0; 64];
loop {
let n = uart_pipe_reader.read(&mut buf).await;
let data = &buf[..n];
trace!("UART OUT: {:x}", data);
let _ = uart_tx.write(&data).await;
}
}
mod uart {
use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{Pio, PioPin};
use embassy_rp::Peripheral;
use crate::uart_rx::PioUartRx;
use crate::uart_tx::PioUartTx;
use crate::Irqs;
pub struct PioUart<'a> {
tx: PioUartTx<'a>,
rx: PioUartRx<'a>,
}
impl<'a> PioUart<'a> {
pub fn new(
baud: u64,
pio: impl Peripheral<P = PIO0> + 'a,
tx_pin: impl PioPin,
rx_pin: impl PioPin,
) -> PioUart<'a> {
let Pio {
mut common, sm0, sm1, ..
} = Pio::new(pio, Irqs);
let tx = PioUartTx::new(&mut common, sm0, tx_pin, baud);
let rx = PioUartRx::new(&mut common, sm1, rx_pin, baud);
PioUart { tx, rx }
}
pub fn split(self) -> (PioUartTx<'a>, PioUartRx<'a>) {
(self.tx, self.rx)
}
}
}
mod uart_tx {
use core::convert::Infallible;
use embassy_rp::gpio::Level;
use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
use embedded_io::asynch::Write;
use embedded_io::Io;
use fixed::traits::ToFixed;
use fixed_macro::types::U56F8;
pub struct PioUartTx<'a> {
sm_tx: StateMachine<'a, PIO0, 0>,
}
impl<'a> PioUartTx<'a> {
pub fn new(
common: &mut Common<'a, PIO0>,
mut sm_tx: StateMachine<'a, PIO0, 0>,
tx_pin: impl PioPin,
baud: u64,
) -> Self {
let prg = pio_proc::pio_asm!(
r#"
.side_set 1 opt
; An 8n1 UART transmit program.
; OUT pin 0 and side-set pin 0 are both mapped to UART TX pin.
pull side 1 [7] ; Assert stop bit, or stall with line in idle state
set x, 7 side 0 [7] ; Preload bit counter, assert start bit for 8 clocks
bitloop: ; This loop will run 8 times (8n1 UART)
out pins, 1 ; Shift 1 bit from OSR to the first OUT pin
jmp x-- bitloop [6] ; Each loop iteration is 8 cycles.
"#
);
let tx_pin = common.make_pio_pin(tx_pin);
sm_tx.set_pins(Level::High, &[&tx_pin]);
sm_tx.set_pin_dirs(Direction::Out, &[&tx_pin]);
let mut cfg = Config::default();
cfg.set_out_pins(&[&tx_pin]);
cfg.use_program(&common.load_program(&prg.program), &[&tx_pin]);
cfg.shift_out.auto_fill = false;
cfg.shift_out.direction = ShiftDirection::Right;
cfg.fifo_join = FifoJoin::TxOnly;
cfg.clock_divider = (U56F8!(125_000_000) / (8 * baud)).to_fixed();
sm_tx.set_config(&cfg);
sm_tx.set_enable(true);
Self { sm_tx }
}
pub async fn write_u8(&mut self, data: u8) {
self.sm_tx.tx().wait_push(data as u32).await;
}
}
impl Io for PioUartTx<'_> {
type Error = Infallible;
}
impl Write for PioUartTx<'_> {
async fn write(&mut self, buf: &[u8]) -> Result<usize, Infallible> {
for byte in buf {
self.write_u8(*byte).await;
}
Ok(buf.len())
}
}
}
mod uart_rx {
use core::convert::Infallible;
use embassy_rp::gpio::Level;
use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
use embedded_io::asynch::Read;
use embedded_io::Io;
use fixed::traits::ToFixed;
use fixed_macro::types::U56F8;
pub struct PioUartRx<'a> {
sm_rx: StateMachine<'a, PIO0, 1>,
}
impl<'a> PioUartRx<'a> {
pub fn new(
common: &mut Common<'a, PIO0>,
mut sm_rx: StateMachine<'a, PIO0, 1>,
rx_pin: impl PioPin,
baud: u64,
) -> Self {
let prg = pio_proc::pio_asm!(
r#"
; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
; break conditions more gracefully.
; IN pin 0 and JMP pin are both mapped to the GPIO used as UART RX.
start:
wait 0 pin 0 ; Stall until start bit is asserted
set x, 7 [10] ; Preload bit counter, then delay until halfway through
rx_bitloop: ; the first data bit (12 cycles incl wait, set).
in pins, 1 ; Shift data bit into ISR
jmp x-- rx_bitloop [6] ; Loop 8 times, each loop iteration is 8 cycles
jmp pin good_rx_stop ; Check stop bit (should be high)
irq 4 rel ; Either a framing error or a break. Set a sticky flag,
wait 1 pin 0 ; and wait for line to return to idle state.
jmp start ; Don't push data if we didn't see good framing.
good_rx_stop: ; No delay before returning to start; a little slack is
in null 24
push ; important in case the TX clock is slightly too fast.
"#
);
let mut cfg = Config::default();
cfg.use_program(&common.load_program(&prg.program), &[]);
let rx_pin = common.make_pio_pin(rx_pin);
sm_rx.set_pins(Level::High, &[&rx_pin]);
cfg.set_in_pins(&[&rx_pin]);
cfg.set_jmp_pin(&rx_pin);
sm_rx.set_pin_dirs(Direction::In, &[&rx_pin]);
cfg.clock_divider = (U56F8!(125_000_000) / (8 * baud)).to_fixed();
cfg.shift_in.auto_fill = false;
cfg.shift_in.direction = ShiftDirection::Right;
cfg.shift_in.threshold = 32;
cfg.fifo_join = FifoJoin::RxOnly;
sm_rx.set_config(&cfg);
sm_rx.set_enable(true);
Self { sm_rx }
}
pub async fn read_u8(&mut self) -> u8 {
self.sm_rx.rx().wait_pull().await as u8
}
}
impl Io for PioUartRx<'_> {
type Error = Infallible;
}
impl Read for PioUartRx<'_> {
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> {
let mut i = 0;
while i < buf.len() {
buf[i] = self.read_u8().await;
i += 1;
}
Ok(i)
}
}
}

View File

@ -12,7 +12,6 @@ use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{
Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
};
use embassy_rp::relocate::RelocatedProgram;
use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef};
use embassy_time::{Duration, Timer};
use fixed::types::U24F8;
@ -73,8 +72,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> Ws2812<'d, P, S, N> {
cfg.set_out_pins(&[&out_pin]);
cfg.set_set_pins(&[&out_pin]);
let relocated = RelocatedProgram::new(&prg);
cfg.use_program(&pio.load_program(&relocated), &[&out_pin]);
cfg.use_program(&pio.load_program(&prg), &[&out_pin]);
// Clock config, measured in kHz to avoid overflows
// TODO CLOCK_FREQ should come from embassy_rp

View File

@ -23,3 +23,6 @@ clap = { version = "3.0.0-beta.5", features = ["derive"] }
rand_core = { version = "0.6.3", features = ["std"] }
heapless = { version = "0.7.5", default-features = false }
static_cell = { version = "1.1", features = ["nightly"]}
[profile.release]
debug = 2

View File

@ -20,3 +20,6 @@ embedded-hal = "0.2.6"
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 }
[profile.release]
debug = 2

View File

@ -18,3 +18,6 @@ embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["de
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
static_cell = { version = "1.1", features = ["nightly"]}
[profile.release]
debug = 2

View File

@ -26,3 +26,6 @@ nb = "1.0.0"
[profile.dev]
opt-level = "s"
[profile.release]
debug = 2

View File

@ -21,3 +21,6 @@ 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 }
nb = "1.0.0"
[profile.release]
debug = 2

View File

@ -25,3 +25,6 @@ heapless = { version = "0.7.5", default-features = false }
nb = "1.0.0"
embedded-storage = "0.3.0"
static_cell = { version = "1.1", features = ["nightly"]}
[profile.release]
debug = 2

View File

@ -17,16 +17,10 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let mut spi = Spi::new(
p.SPI1,
p.PB3,
p.PB5,
p.PB4,
p.DMA1_CH3,
p.DMA1_CH2,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new(p.SPI1, p.PB3, p.PB5, p.PB4, p.DMA1_CH3, p.DMA1_CH2, spi_config);
for n in 0u32.. {
let mut write: String<128> = String::new();

View File

@ -0,0 +1,9 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# replace STM32F429ZITx with your chip as listed in `probe-rs-cli chip list`
runner = "probe-run --chip STM32F334R8"
[build]
target = "thumbv7em-none-eabihf"
[env]
DEFMT_LOG = "trace"

View File

@ -0,0 +1,26 @@
[package]
edition = "2021"
name = "embassy-stm32f3-examples"
version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
defmt = "0.3"
defmt-rtt = "0.4"
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
cortex-m-rt = "0.7.0"
embedded-hal = "0.2.6"
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 }
nb = "1.0.0"
embedded-storage = "0.3.0"
static_cell = { version = "1.1", features = ["nightly"]}

View File

@ -0,0 +1,5 @@
fn main() {
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
}

View File

@ -0,0 +1,27 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
info!("Hello World!");
let p = embassy_stm32::init(Default::default());
let mut out1 = Output::new(p.PA8, Level::Low, Speed::High);
out1.set_high();
Timer::after(Duration::from_millis(500)).await;
out1.set_low();
Timer::after(Duration::from_millis(500)).await;
info!("end program");
cortex_m::asm::bkpt();
}

View File

@ -0,0 +1,23 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::info;
use embassy_executor::Spawner;
use embassy_stm32::time::Hertz;
use embassy_stm32::Config;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: Spawner) -> ! {
let mut config = Config::default();
config.rcc.hse = Some(Hertz(8_000_000));
config.rcc.sysclk = Some(Hertz(16_000_000));
let _p = embassy_stm32::init(config);
loop {
info!("Hello World!");
Timer::after(Duration::from_secs(1)).await;
}
}

View File

@ -0,0 +1,71 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::hrtim::*;
use embassy_stm32::time::{khz, mhz};
use embassy_stm32::Config;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let mut config: Config = Default::default();
config.rcc.sysclk = Some(mhz(64));
config.rcc.hclk = Some(mhz(64));
config.rcc.pclk1 = Some(mhz(32));
config.rcc.pclk2 = Some(mhz(64));
let p = embassy_stm32::init(config);
info!("Hello World!");
let ch1 = PwmPin::new_cha(p.PA8);
let ch1n = ComplementaryPwmPin::new_cha(p.PA9);
let pwm = AdvancedPwm::new(
p.HRTIM1,
Some(ch1),
Some(ch1n),
None,
None,
None,
None,
None,
None,
None,
None,
);
info!("pwm constructed");
let mut buck_converter = BridgeConverter::new(pwm.ch_a, khz(5));
// embassy_stm32::pac::HRTIM1
// .tim(0)
// .setr(0)
// .modify(|w| w.set_sst(Activeeffect::SETACTIVE));
//
// Timer::after(Duration::from_millis(500)).await;
//
// embassy_stm32::pac::HRTIM1
// .tim(0)
// .rstr(0)
// .modify(|w| w.set_srt(Inactiveeffect::SETINACTIVE));
let max_duty = buck_converter.get_max_compare_value();
info!("max compare value: {}", max_duty);
buck_converter.set_dead_time(max_duty / 20);
buck_converter.set_primary_duty(max_duty / 2);
buck_converter.set_secondary_duty(3 * max_duty / 4);
buck_converter.start();
Timer::after(Duration::from_millis(500)).await;
info!("end program");
cortex_m::asm::bkpt();
}

View File

@ -11,13 +11,15 @@ use embassy_stm32::eth::{Ethernet, PacketQueue};
use embassy_stm32::peripherals::ETH;
use embassy_stm32::rng::Rng;
use embassy_stm32::time::mhz;
use embassy_stm32::{bind_interrupts, eth, Config};
use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
use embassy_time::{Duration, Timer};
use embedded_io::asynch::Write;
use static_cell::make_static;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
ETH => eth::InterruptHandler;
HASH_RNG => rng::InterruptHandler<peripherals::RNG>;
});
type Device = Ethernet<'static, ETH, GenericSMI>;
@ -36,7 +38,7 @@ async fn main(spawner: Spawner) -> ! {
info!("Hello World!");
// Generate random seed.
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut seed = [0; 8];
let _ = rng.async_fill_bytes(&mut seed).await;
let seed = u64::from_le_bytes(seed);

View File

@ -4,9 +4,10 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::pwm::Channel;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::khz;
use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::timer::Channel;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -15,7 +16,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PE9);
let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull);
let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10));
let max = pwm.get_max_duty();
pwm.enable(Channel::Ch1);

View File

@ -4,10 +4,11 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::pwm::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
use embassy_stm32::pwm::simple_pwm::PwmPin;
use embassy_stm32::pwm::Channel;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::khz;
use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
use embassy_stm32::timer::simple_pwm::PwmPin;
use embassy_stm32::timer::Channel;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -16,8 +17,8 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PE9);
let ch1n = ComplementaryPwmPin::new_ch1(p.PA7);
let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull);
let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull);
let mut pwm = ComplementaryPwm::new(
p.TIM1,
Some(ch1),

View File

@ -16,16 +16,10 @@ fn main() -> ! {
let p = embassy_stm32::init(Default::default());
let mut spi = Spi::new(
p.SPI3,
p.PC10,
p.PC12,
p.PC11,
NoDma,
NoDma,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config);
let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh);

View File

@ -17,16 +17,10 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let mut spi = Spi::new(
p.SPI1,
p.PB3,
p.PB5,
p.PB4,
p.DMA2_CH3,
p.DMA2_CH2,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new(p.SPI1, p.PB3, p.PB5, p.PB4, p.DMA2_CH3, p.DMA2_CH2, spi_config);
for n in 0u32.. {
let mut write: String<128> = String::new();

View File

@ -6,7 +6,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_net::tcp::TcpSocket;
use embassy_net::{Stack, StackResources};
use embassy_stm32::rng::Rng;
use embassy_stm32::rng::{self, Rng};
use embassy_stm32::time::mhz;
use embassy_stm32::usb_otg::Driver;
use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config};
@ -38,6 +38,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
bind_interrupts!(struct Irqs {
OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>;
HASH_RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
@ -104,7 +105,7 @@ async fn main(spawner: Spawner) {
//});
// Generate random seed
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut seed = [0; 8];
unwrap!(rng.async_fill_bytes(&mut seed).await);
let seed = u64::from_le_bytes(seed);

View File

@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32f767zi to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] }
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
@ -28,3 +28,6 @@ rand_core = "0.6.3"
critical-section = "1.1"
embedded-storage = "0.3.0"
static_cell = { version = "1.1", features = ["nightly"]}
[profile.release]
debug = 2

View File

@ -1,43 +1,5 @@
//! adapted from https://github.com/stm32-rs/stm32f7xx-hal/blob/master/build.rs
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use std::{env, io};
#[derive(Debug)]
enum Error {
Env(env::VarError),
Io(io::Error),
}
impl From<env::VarError> for Error {
fn from(error: env::VarError) -> Self {
Self::Env(error)
}
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Self {
Self::Io(error)
}
}
fn main() -> Result<(), Error> {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=memory.x");
let out_dir = env::var("OUT_DIR")?;
let out_dir = PathBuf::from(out_dir);
let memory_x = include_bytes!("memory.x").as_ref();
File::create(out_dir.join("memory.x"))?.write_all(memory_x)?;
// Tell Cargo where to find the file.
println!("cargo:rustc-link-search={}", out_dir.display());
fn main() {
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
Ok(())
}

View File

@ -1,12 +0,0 @@
/* For STM32F765,767,768,769,777,778,779 devices */
MEMORY
{
/* NOTE K = KiBi = 1024 bytes */
FLASH : ORIGIN = 0x08000000, LENGTH = 2M
RAM : ORIGIN = 0x20000000, LENGTH = 368K + 16K
}
/* This is where the call stack will be allocated. */
/* The stack is of the full descending type. */
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
_stack_start = ORIGIN(RAM) + LENGTH(RAM);

View File

@ -11,14 +11,16 @@ use embassy_stm32::eth::{Ethernet, PacketQueue};
use embassy_stm32::peripherals::ETH;
use embassy_stm32::rng::Rng;
use embassy_stm32::time::mhz;
use embassy_stm32::{bind_interrupts, eth, Config};
use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
use embassy_time::{Duration, Timer};
use embedded_io::asynch::Write;
use rand_core::RngCore;
use static_cell::make_static;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
ETH => eth::InterruptHandler;
RNG => rng::InterruptHandler<peripherals::RNG>;
});
type Device = Ethernet<'static, ETH, GenericSMI>;
@ -37,7 +39,7 @@ async fn main(spawner: Spawner) -> ! {
info!("Hello World!");
// Generate random seed.
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut seed = [0; 8];
rng.fill_bytes(&mut seed);
let seed = u64::from_le_bytes(seed);

View File

@ -20,3 +20,6 @@ embedded-hal = "0.2.6"
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 }
[profile.release]
debug = 2

View File

@ -76,7 +76,9 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Start test using spi as neopixel driver");
let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, NoDma, Hertz(4_000_000), Config::default());
let mut config = Config::default();
config.frequency = Hertz(4_000_000);
let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, NoDma, config);
let mut neopixels = Ws2812::new();

View File

@ -10,7 +10,6 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
defmt = "0.3"
@ -22,3 +21,6 @@ embedded-hal = "0.2.6"
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 }
[profile.release]
debug = 2

View File

@ -4,9 +4,10 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::pwm::Channel;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::khz;
use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::timer::Channel;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -15,7 +16,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PC0);
let ch1 = PwmPin::new_ch1(p.PC0, OutputType::PushPull);
let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10));
let max = pwm.get_max_duty();
pwm.enable(Channel::Ch1);

View File

@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32h563zi to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }

View File

@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 0x200000
RAM : ORIGIN = 0x20000000, LENGTH = 0x50000
}

View File

@ -12,14 +12,16 @@ use embassy_stm32::peripherals::ETH;
use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale};
use embassy_stm32::rng::Rng;
use embassy_stm32::time::Hertz;
use embassy_stm32::{bind_interrupts, eth, Config};
use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
use embassy_time::{Duration, Timer};
use embedded_io::asynch::Write;
use rand_core::RngCore;
use static_cell::make_static;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
ETH => eth::InterruptHandler;
RNG => rng::InterruptHandler<peripherals::RNG>;
});
type Device = Ethernet<'static, ETH, GenericSMI>;
@ -56,7 +58,7 @@ async fn main(spawner: Spawner) -> ! {
info!("Hello World!");
// Generate random seed.
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut seed = [0; 8];
rng.fill_bytes(&mut seed);
let seed = u64::from_le_bytes(seed);

View File

@ -5,14 +5,19 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rng::Rng;
use embassy_stm32::{bind_interrupts, peripherals, rng};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut buf = [0u8; 16];
unwrap!(rng.async_fill_bytes(&mut buf).await);

View File

@ -1,5 +1,5 @@
[target.thumbv7em-none-eabihf]
runner = 'probe-rs run --chip STM32H743ZITx'
runner = 'probe-rs run --chip STM32H7A3ZITxQ'
[build]
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

View File

@ -6,7 +6,7 @@ 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 = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "unstable-traits"] }
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }

View File

@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x8000000, LENGTH = 1024K
RAM : ORIGIN = 0x24000000, LENGTH = 384K
}

View File

@ -0,0 +1,140 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::dac::{DacChannel, ValueArray};
use embassy_stm32::pac::timer::vals::{Mms, Opm};
use embassy_stm32::peripherals::{TIM6, TIM7};
use embassy_stm32::rcc::low_level::RccPeripheral;
use embassy_stm32::time::{mhz, Hertz};
use embassy_stm32::timer::low_level::Basic16bitInstance;
use micromath::F32Ext;
use {defmt_rtt as _, panic_probe as _};
pub type Dac1Type =
embassy_stm32::dac::DacCh1<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH3>;
pub type Dac2Type =
embassy_stm32::dac::DacCh2<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH4>;
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let mut config = embassy_stm32::Config::default();
config.rcc.sys_ck = Some(mhz(400));
config.rcc.hclk = Some(mhz(100));
config.rcc.pll1.q_ck = Some(mhz(100));
// Initialize the board and obtain a Peripherals instance
let p: embassy_stm32::Peripherals = embassy_stm32::init(config);
// 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();
}
#[embassy_executor::task]
async fn dac_task1(mut dac: Dac1Type) {
let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM6 frequency is {}", TIM6::frequency());
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;
// Depends on your clock and on the specific chip used, you may need higher or lower values here
if reload < 10 {
error!("Reload value {} below threshold!", reload);
}
dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap();
dac.enable_channel().unwrap();
TIM6::enable();
TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1));
TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE));
TIM6::regs().cr1().modify(|w| {
w.set_opm(Opm::DISABLED);
w.set_cen(true);
});
debug!(
"TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM6::frequency(),
FREQUENCY,
reload,
reload as u16,
data.len()
);
// Loop technically not necessary if DMA circular mode is enabled
loop {
info!("Loop DAC1");
if let Err(e) = dac.write(ValueArray::Bit8(data), true).await {
error!("Could not write to dac: {}", e);
}
}
}
#[embassy_executor::task]
async fn dac_task2(mut dac: Dac2Type) {
let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM7 frequency is {}", TIM7::frequency());
const FREQUENCY: Hertz = Hertz::hz(600);
let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32;
if reload < 10 {
error!("Reload value {} below threshold!", reload);
}
TIM7::enable();
TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1));
TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE));
TIM7::regs().cr1().modify(|w| {
w.set_opm(Opm::DISABLED);
w.set_cen(true);
});
dac.select_trigger(embassy_stm32::dac::Ch2Trigger::Tim7).unwrap();
debug!(
"TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM7::frequency(),
FREQUENCY,
reload,
reload as u16,
data.len()
);
if let Err(e) = dac.write(ValueArray::Bit8(data), true).await {
error!("Could not write to dac: {}", e);
}
}
fn to_sine_wave(v: u8) -> u8 {
if v >= 128 {
// top half
let r = 3.14 * ((v - 128) as f32 / 128.0);
(r.sin() * 128.0 + 127.0) as u8
} else {
// bottom half
let r = 3.14 + 3.14 * (v as f32 / 128.0);
(r.sin() * 128.0 + 127.0) as u8
}
}
fn calculate_array<const N: usize>() -> [u8; N] {
let mut res = [0; N];
let mut i = 0;
while i < N {
res[i] = to_sine_wave(i as u8);
i += 1;
}
res
}

View File

@ -11,14 +11,16 @@ use embassy_stm32::eth::{Ethernet, PacketQueue};
use embassy_stm32::peripherals::ETH;
use embassy_stm32::rng::Rng;
use embassy_stm32::time::mhz;
use embassy_stm32::{bind_interrupts, eth, Config};
use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
use embassy_time::{Duration, Timer};
use embedded_io::asynch::Write;
use rand_core::RngCore;
use static_cell::make_static;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
ETH => eth::InterruptHandler;
RNG => rng::InterruptHandler<peripherals::RNG>;
});
type Device = Ethernet<'static, ETH, GenericSMI>;
@ -38,7 +40,7 @@ async fn main(spawner: Spawner) -> ! {
info!("Hello World!");
// Generate random seed.
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut seed = [0; 8];
rng.fill_bytes(&mut seed);
let seed = u64::from_le_bytes(seed);

View File

@ -11,15 +11,17 @@ use embassy_stm32::eth::{Ethernet, PacketQueue};
use embassy_stm32::peripherals::ETH;
use embassy_stm32::rng::Rng;
use embassy_stm32::time::mhz;
use embassy_stm32::{bind_interrupts, eth, Config};
use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
use embassy_time::{Duration, Timer};
use embedded_io::asynch::Write;
use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
use rand_core::RngCore;
use static_cell::make_static;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
ETH => eth::InterruptHandler;
RNG => rng::InterruptHandler<peripherals::RNG>;
});
type Device = Ethernet<'static, ETH, GenericSMI>;
@ -39,7 +41,7 @@ async fn main(spawner: Spawner) -> ! {
info!("Hello World!");
// Generate random seed.
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut seed = [0; 8];
rng.fill_bytes(&mut seed);
let seed = u64::from_le_bytes(seed);

View File

@ -6,8 +6,8 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::gpio::low_level::AFType;
use embassy_stm32::gpio::Speed;
use embassy_stm32::pwm::*;
use embassy_stm32::time::{khz, mhz, Hertz};
use embassy_stm32::timer::*;
use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef};
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};

View File

@ -4,9 +4,10 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::pwm::Channel;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::{khz, mhz};
use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::timer::Channel;
use embassy_stm32::Config;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -24,7 +25,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(config);
info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PA6);
let ch1 = PwmPin::new_ch1(p.PA6, OutputType::PushPull);
let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10));
let max = pwm.get_max_duty();
pwm.enable(Channel::Ch1);

View File

@ -5,14 +5,19 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rng::Rng;
use embassy_stm32::{bind_interrupts, peripherals, rng};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut buf = [0u8; 16];
unwrap!(rng.async_fill_bytes(&mut buf).await);

View File

@ -43,16 +43,10 @@ fn main() -> ! {
config.rcc.pll1.q_ck = Some(mhz(100));
let p = embassy_stm32::init(config);
let spi = spi::Spi::new(
p.SPI3,
p.PB3,
p.PB5,
p.PB4,
NoDma,
NoDma,
mhz(1),
spi::Config::default(),
);
let mut spi_config = spi::Config::default();
spi_config.frequency = mhz(1);
let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, NoDma, NoDma, spi_config);
let executor = EXECUTOR.init(Executor::new());

View File

@ -39,16 +39,10 @@ fn main() -> ! {
config.rcc.pll1.q_ck = Some(mhz(100));
let p = embassy_stm32::init(config);
let spi = spi::Spi::new(
p.SPI3,
p.PB3,
p.PB5,
p.PB4,
p.DMA1_CH3,
p.DMA1_CH4,
mhz(1),
spi::Config::default(),
);
let mut spi_config = spi::Config::default();
spi_config.frequency = mhz(1);
let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, p.DMA1_CH3, p.DMA1_CH4, spi_config);
let executor = EXECUTOR.init(Executor::new());

View File

@ -34,5 +34,5 @@ heapless = { version = "0.7.5", default-features = false }
embedded-hal = "0.2.6"
static_cell = "1.1"
[patch.crates-io]
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
[profile.release]
debug = 2

View File

@ -27,17 +27,11 @@ async fn main(_spawner: Spawner) {
config.rcc.enable_hsi48 = true;
let p = embassy_stm32::init(config);
let mut spi_config = spi::Config::default();
spi_config.frequency = khz(200);
// SPI for sx1276
let spi = spi::Spi::new(
p.SPI1,
p.PB3,
p.PA7,
p.PA6,
p.DMA1_CH3,
p.DMA1_CH2,
khz(200),
spi::Config::default(),
);
let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config);
let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low);
let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low);

View File

@ -12,8 +12,8 @@ use embassy_lora::LoraTimer;
use embassy_stm32::exti::{Channel, ExtiInput};
use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed};
use embassy_stm32::rng::Rng;
use embassy_stm32::spi;
use embassy_stm32::time::khz;
use embassy_stm32::{bind_interrupts, peripherals, rng, spi};
use embassy_time::Delay;
use lora_phy::mod_params::*;
use lora_phy::sx1276_7_8_9::SX1276_7_8_9;
@ -23,6 +23,10 @@ use lorawan_device::async_device::lora_radio::LoRaRadio;
use lorawan_device::async_device::{region, Device, JoinMode};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
RNG_LPUART1 => rng::InterruptHandler<peripherals::RNG>;
});
const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set this appropriately for the region
#[embassy_executor::main]
@ -32,17 +36,11 @@ async fn main(_spawner: Spawner) {
config.rcc.enable_hsi48 = true;
let p = embassy_stm32::init(config);
let mut spi_config = spi::Config::default();
spi_config.frequency = khz(200);
// SPI for sx1276
let spi = spi::Spi::new(
p.SPI1,
p.PB3,
p.PA7,
p.PA6,
p.DMA1_CH3,
p.DMA1_CH2,
khz(200),
spi::Config::default(),
);
let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config);
let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low);
let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low);
@ -66,7 +64,7 @@ async fn main(_spawner: Spawner) {
let radio = LoRaRadio::new(lora);
let region: region::Configuration = region::Configuration::new(LORAWAN_REGION);
let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG));
let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG, Irqs));
defmt::info!("Joining LoRaWAN network");

View File

@ -27,17 +27,11 @@ async fn main(_spawner: Spawner) {
config.rcc.enable_hsi48 = true;
let p = embassy_stm32::init(config);
let mut spi_config = spi::Config::default();
spi_config.frequency = khz(200);
// SPI for sx1276
let spi = spi::Spi::new(
p.SPI1,
p.PB3,
p.PA7,
p.PA6,
p.DMA1_CH3,
p.DMA1_CH2,
khz(200),
spi::Config::default(),
);
let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config);
let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low);
let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low);

View File

@ -27,17 +27,11 @@ async fn main(_spawner: Spawner) {
config.rcc.enable_hsi48 = true;
let p = embassy_stm32::init(config);
let mut spi_config = spi::Config::default();
spi_config.frequency = khz(200);
// SPI for sx1276
let spi = spi::Spi::new(
p.SPI1,
p.PB3,
p.PA7,
p.PA6,
p.DMA1_CH3,
p.DMA1_CH2,
khz(200),
spi::Config::default(),
);
let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config);
let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low);
let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low);

View File

@ -15,16 +15,10 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World, folks!");
let mut spi = Spi::new(
p.SPI1,
p.PB3,
p.PA7,
p.PA6,
NoDma,
NoDma,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, NoDma, NoDma, spi_config);
let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh);

View File

@ -20,3 +20,6 @@ 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 }
embedded-storage = "0.3.0"
[profile.release]
debug = 2

View File

@ -15,16 +15,10 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World, folks!");
let mut spi = Spi::new(
p.SPI1,
p.PA5,
p.PA7,
p.PA6,
NoDma,
NoDma,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new(p.SPI1, p.PA5, p.PA7, p.PA6, NoDma, NoDma, spi_config);
let mut cs = Output::new(p.PA4, Level::High, Speed::VeryHigh);

View File

@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32l4s5vi to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits", "chrono"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "memory-x", "time-driver-any", "exti", "unstable-traits", "chrono"] }
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false }
chrono = { version = "^0.4", default-features = false }
micromath = "2.0.0"
[profile.release]
debug = 2

View File

@ -1,34 +1,4 @@
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
fn main() {
// Put `memory.x` in our output directory and ensure it's
// on the linker search path.
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x"))
.unwrap()
.write_all(include_bytes!("memory.x"))
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
// By default, Cargo will re-run a build script whenever
// any file in the project changes. By specifying `memory.x`
// here, we ensure the build script is only re-run when
// `memory.x` is changed.
println!("cargo:rerun-if-changed=memory.x");
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");

View File

@ -1,7 +0,0 @@
MEMORY
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
/* These values correspond to the STM32L4S5 */
FLASH : ORIGIN = 0x08000000, LENGTH = 1024K
RAM : ORIGIN = 0x20000000, LENGTH = 128K
}

View File

@ -6,9 +6,13 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv};
use embassy_stm32::rng::Rng;
use embassy_stm32::Config;
use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let mut config = Config::default();
@ -24,7 +28,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!");
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut buf = [0u8; 16];
unwrap!(rng.async_fill_bytes(&mut buf).await);

View File

@ -15,16 +15,10 @@ fn main() -> ! {
let p = embassy_stm32::init(Default::default());
let mut spi = Spi::new(
p.SPI3,
p.PC10,
p.PC12,
p.PC11,
NoDma,
NoDma,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config);
let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh);

View File

@ -17,16 +17,10 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let spi = Spi::new(
p.SPI3,
p.PC10,
p.PC12,
p.PC11,
NoDma,
NoDma,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config);
let mut spi = BlockingAsync::new(spi);

View File

@ -14,16 +14,10 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let mut spi = Spi::new(
p.SPI3,
p.PC10,
p.PC12,
p.PC11,
p.DMA1_CH1,
p.DMA1_CH2,
Hertz(1_000_000),
Config::default(),
);
let mut spi_config = Config::default();
spi_config.frequency = Hertz(1_000_000);
let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, p.DMA1_CH1, p.DMA1_CH2, spi_config);
// These are the pins for the Inventek eS-Wifi SPI Wifi Adapter.

View File

@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false }
rand_core = { version = "0.6.3", default-features = false }
embedded-io = { version = "0.4.0", features = ["async"] }
static_cell = { version = "1.1", features = ["nightly"]}
[profile.release]
debug = 2

View File

@ -6,9 +6,13 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv};
use embassy_stm32::rng::Rng;
use embassy_stm32::Config;
use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let mut config = Config::default();
@ -23,7 +27,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!");
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut buf = [0u8; 16];
unwrap!(rng.async_fill_bytes(&mut buf).await);

View File

@ -9,7 +9,7 @@ use embassy_net::{Stack, StackResources};
use embassy_stm32::rcc::*;
use embassy_stm32::rng::Rng;
use embassy_stm32::usb::Driver;
use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config};
use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState};
use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
use embassy_usb::{Builder, UsbDevice};
@ -24,6 +24,7 @@ const MTU: usize = 1514;
bind_interrupts!(struct Irqs {
USB_FS => usb::InterruptHandler<peripherals::USB>;
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::task]
@ -99,7 +100,7 @@ async fn main(spawner: Spawner) {
//});
// Generate random seed
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let seed = rng.next_u64();
// Init network stack

View File

@ -23,3 +23,6 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
heapless = { version = "0.7.5", default-features = false }
micromath = "2.0.0"
[profile.release]
debug = 2

View File

@ -52,3 +52,6 @@ required-features = ["ble"]
[[bin]]
name = "gatt_server"
required-features = ["ble"]
[profile.release]
debug = 2

View File

@ -8,6 +8,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::hci::host::uart::UartHci;
use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
use embassy_stm32_wpan::hci::types::AdvertisingType;
@ -54,7 +55,9 @@ async fn main(_spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -8,6 +8,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::hci::event::command::{CommandComplete, ReturnParameters};
use embassy_stm32_wpan::hci::host::uart::{Packet, UartHci};
use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
@ -62,7 +63,9 @@ async fn main(_spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -6,6 +6,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::mac::commands::{AssociateResponse, ResetRequest, SetRequest, StartRequest};
use embassy_stm32_wpan::mac::event::MacEvent;
use embassy_stm32_wpan::mac::typedefs::{MacChannel, MacStatus, PanId, PibId, SecurityLevel};
@ -30,7 +31,7 @@ async fn main(spawner: Spawner) {
- 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
- Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_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.
@ -39,7 +40,7 @@ async fn main(spawner: Spawner) {
- 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.
stm32wb5x_BLE_Mac_802_15_4_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.
@ -49,7 +50,9 @@ async fn main(spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -6,6 +6,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::mac::commands::{ResetRequest, SetRequest, StartRequest};
use embassy_stm32_wpan::mac::typedefs::{MacChannel, PanId, PibId};
use embassy_stm32_wpan::mac::{self, Runner};
@ -36,7 +37,7 @@ async fn main(spawner: Spawner) {
- 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
- Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_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.
@ -45,7 +46,7 @@ async fn main(spawner: Spawner) {
- 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.
stm32wb5x_BLE_Mac_802_15_4_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.
@ -55,7 +56,9 @@ async fn main(spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -6,6 +6,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::mac::commands::{AssociateRequest, DataRequest, GetRequest, ResetRequest, SetRequest};
use embassy_stm32_wpan::mac::event::MacEvent;
use embassy_stm32_wpan::mac::typedefs::{
@ -32,7 +33,7 @@ async fn main(spawner: Spawner) {
- 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
- Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_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.
@ -41,7 +42,7 @@ async fn main(spawner: Spawner) {
- 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.
stm32wb5x_BLE_Mac_802_15_4_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.
@ -51,7 +52,9 @@ async fn main(spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -6,6 +6,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::TlMbox;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -41,7 +42,9 @@ async fn main(_spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -6,6 +6,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::TlMbox;
use {defmt_rtt as _, panic_probe as _};
@ -40,7 +41,9 @@ async fn main(_spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -6,6 +6,7 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::rcc::WPAN_DEFAULT;
use embassy_stm32_wpan::sub::mm;
use embassy_stm32_wpan::TlMbox;
use {defmt_rtt as _, panic_probe as _};
@ -27,7 +28,7 @@ async fn main(spawner: Spawner) {
- 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
- Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_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.
@ -36,7 +37,7 @@ async fn main(spawner: Spawner) {
- 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.
stm32wb5x_BLE_Mac_802_15_4_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.
@ -46,7 +47,9 @@ async fn main(spawner: Spawner) {
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());
let mut config = embassy_stm32::Config::default();
config.rcc = WPAN_DEFAULT;
let p = embassy_stm32::init(config);
info!("Hello World!");
let config = Config::default();

View File

@ -28,5 +28,5 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
heapless = { version = "0.7.5", default-features = false }
chrono = { version = "^0.4", default-features = false }
[patch.crates-io]
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
[profile.release]
debug = 2

View File

@ -10,9 +10,9 @@ use embassy_executor::Spawner;
use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant};
use embassy_lora::LoraTimer;
use embassy_stm32::gpio::{Level, Output, Pin, Speed};
use embassy_stm32::rng::Rng;
use embassy_stm32::rng::{self, Rng};
use embassy_stm32::spi::Spi;
use embassy_stm32::{bind_interrupts, pac};
use embassy_stm32::{bind_interrupts, pac, peripherals};
use embassy_time::Delay;
use lora_phy::mod_params::*;
use lora_phy::sx1261_2::SX1261_2;
@ -26,6 +26,7 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th
bind_interrupts!(struct Irqs{
SUBGHZ_RADIO => InterruptHandler;
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
@ -58,7 +59,7 @@ async fn main(_spawner: Spawner) {
};
let radio = LoRaRadio::new(lora);
let region: region::Configuration = region::Configuration::new(LORAWAN_REGION);
let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG));
let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG, Irqs));
defmt::info!("Joining LoRaWAN network");

View File

@ -4,10 +4,14 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::pac;
use embassy_stm32::rng::Rng;
use embassy_stm32::rng::{self, Rng};
use embassy_stm32::{bind_interrupts, pac, peripherals};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs{
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let mut config = embassy_stm32::Config::default();
@ -21,7 +25,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!");
let mut rng = Rng::new(p.RNG);
let mut rng = Rng::new(p.RNG, Irqs);
let mut buf = [0u8; 16];
unwrap!(rng.async_fill_bytes(&mut buf).await);

View File

@ -17,3 +17,6 @@ wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] }
log = "0.4.11"
critical-section = { version = "1.1", features = ["std"] }
[profile.release]
debug = 2