Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions embassy-lora/src/stm32wl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use embassy_stm32::{
TxParams,
},
};
use embedded_hal::digital::v2::OutputPin;
use lorawan_device::async_device::{
radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig},
Timings,
Expand Down Expand Up @@ -329,22 +328,22 @@ impl<'a> RadioSwitch<'a> {
}

pub(crate) fn set_rx(&mut self) {
self.ctrl1.set_high().unwrap();
self.ctrl2.set_low().unwrap();
self.ctrl3.set_high().unwrap();
self.ctrl1.set_high();
self.ctrl2.set_low();
self.ctrl3.set_high();
}

pub(crate) fn set_tx_lp(&mut self) {
self.ctrl1.set_high().unwrap();
self.ctrl2.set_high().unwrap();
self.ctrl3.set_high().unwrap();
self.ctrl1.set_high();
self.ctrl2.set_high();
self.ctrl3.set_high();
}

#[allow(dead_code)]
pub(crate) fn set_tx_hp(&mut self) {
self.ctrl2.set_high().unwrap();
self.ctrl1.set_low().unwrap();
self.ctrl3.set_high().unwrap();
self.ctrl2.set_high();
self.ctrl1.set_low();
self.ctrl3.set_high();
}
}

Expand Down
2 changes: 0 additions & 2 deletions embassy-stm32/.pep8

This file was deleted.

14 changes: 8 additions & 6 deletions embassy-stm32/src/dma/bdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,17 @@ pac::dma_channels! {
($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => {
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {

unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: *const[W], reg_addr: *mut W) {
let (ptr, len) = super::slice_ptr_parts(buf);
low_level_api::start_transfer(
pac::$dma_peri,
$channel_num,
#[cfg(any(bdma_v2, dmamux))]
request,
vals::Dir::FROMMEMORY,
reg_addr as *const u32,
buf.as_ptr() as *mut u32,
buf.len(),
ptr as *mut u32,
len,
true,
vals::Size::from(W::bits()),
#[cfg(dmamux)]
Expand Down Expand Up @@ -129,16 +130,17 @@ pac::dma_channels! {
)
}

unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *const W, buf: *mut [W]) {
let (ptr, len) = super::slice_ptr_parts_mut(buf);
low_level_api::start_transfer(
pac::$dma_peri,
$channel_num,
#[cfg(any(bdma_v2, dmamux))]
request,
vals::Dir::FROMPERIPHERAL,
reg_addr as *const u32,
buf.as_ptr() as *mut u32,
buf.len(),
ptr as *mut u32,
len,
true,
vals::Size::from(W::bits()),
#[cfg(dmamux)]
Expand Down
14 changes: 8 additions & 6 deletions embassy-stm32/src/dma/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@ pub(crate) unsafe fn init() {
pac::dma_channels! {
($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: *const [W], reg_addr: *mut W) {
let (ptr, len) = super::slice_ptr_parts(buf);
low_level_api::start_transfer(
pac::$dma_peri,
$channel_num,
request,
vals::Dir::MEMORYTOPERIPHERAL,
reg_addr as *const u32,
buf.as_ptr() as *mut u32,
buf.len(),
ptr as *mut u32,
len,
true,
vals::Size::from(W::bits()),
#[cfg(dmamux)]
Expand Down Expand Up @@ -121,15 +122,16 @@ pac::dma_channels! {
)
}

unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *const W, buf: *mut [W]) {
let (ptr, len) = super::slice_ptr_parts_mut(buf);
low_level_api::start_transfer(
pac::$dma_peri,
$channel_num,
request,
vals::Dir::PERIPHERALTOMEMORY,
reg_addr as *const u32,
buf.as_ptr() as *mut u32,
buf.len(),
ptr as *mut u32,
len,
true,
vals::Size::from(W::bits()),
#[cfg(dmamux)]
Expand Down
49 changes: 32 additions & 17 deletions embassy-stm32/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub use dmamux::*;

use core::future::Future;
use core::marker::PhantomData;
use core::mem;
use core::pin::Pin;
use core::task::Waker;
use core::task::{Context, Poll};
Expand All @@ -36,12 +37,13 @@ pub(crate) mod sealed {
/// Starts this channel for writing a stream of words.
///
/// Safety:
/// - `buf` must point to a valid buffer for DMA reading.
/// - `buf` must be alive for the entire duration of the DMA transfer.
/// - `reg_addr` must be a valid peripheral register address to write to.
unsafe fn start_write<W: super::Word>(
&mut self,
request: Request,
buf: &[W],
buf: *const [W],
reg_addr: *mut W,
);

Expand All @@ -60,13 +62,14 @@ pub(crate) mod sealed {
/// Starts this channel for reading a stream of words.
///
/// Safety:
/// - `buf` must point to a valid buffer for DMA writing.
/// - `buf` must be alive for the entire duration of the DMA transfer.
/// - `reg_addr` must be a valid peripheral register address to write to.
/// - `reg_addr` must be a valid peripheral register address to read from.
unsafe fn start_read<W: super::Word>(
&mut self,
request: Request,
reg_addr: *mut W,
buf: &mut [W],
reg_addr: *const W,
buf: *mut [W],
);

/// Requests the channel to stop.
Expand Down Expand Up @@ -132,10 +135,7 @@ mod transfers {

unsafe { channel.start_read::<W>(request, reg_addr, buf) };

Transfer {
channel,
_phantom: PhantomData,
}
Transfer::new(channel)
}

#[allow(unused)]
Expand All @@ -150,10 +150,7 @@ mod transfers {

unsafe { channel.start_write::<W>(request, buf, reg_addr) };

Transfer {
channel,
_phantom: PhantomData,
}
Transfer::new(channel)
}

#[allow(unused)]
Expand All @@ -168,17 +165,24 @@ mod transfers {

unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr) };

Transfer {
channel,
_phantom: PhantomData,
}
Transfer::new(channel)
}

struct Transfer<'a, C: Channel> {
pub(crate) struct Transfer<'a, C: Channel> {
channel: C,
_phantom: PhantomData<&'a mut C>,
}

impl<'a, C: Channel> Transfer<'a, C> {
pub(crate) fn new(channel: impl Unborrow<Target = C> + 'a) -> Self {
unborrow!(channel);
Self {
channel,
_phantom: PhantomData,
}
}
}

impl<'a, C: Channel> Drop for Transfer<'a, C> {
fn drop(&mut self) {
self.channel.request_stop();
Expand Down Expand Up @@ -221,3 +225,14 @@ pub(crate) unsafe fn init() {
#[cfg(dmamux)]
dmamux::init();
}

// TODO: replace transmutes with core::ptr::metadata once it's stable
#[allow(unused)]
pub(crate) fn slice_ptr_parts<T>(slice: *const [T]) -> (usize, usize) {
unsafe { mem::transmute(slice) }
}

#[allow(unused)]
pub(crate) fn slice_ptr_parts_mut<T>(slice: *mut [T]) -> (usize, usize) {
unsafe { mem::transmute(slice) }
}
84 changes: 72 additions & 12 deletions embassy-stm32/src/exti.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use core::future::Future;
use core::marker::PhantomData;
use core::pin::Pin;
use core::task::{Context, Poll};
use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
use embassy::traits::gpio::{
WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge,
};
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unsafe_impl_unborrow;
Expand Down Expand Up @@ -94,61 +96,119 @@ impl<'d, T: GpioPin> ExtiInput<'d, T> {
pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self {
Self { pin }
}

pub fn is_high(&self) -> bool {
self.pin.is_high()
}

pub fn is_low(&self) -> bool {
self.pin.is_low()
}

pub async fn wait_for_high<'a>(&'a mut self) {
let fut = ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, false);
if self.is_high() {
return;
}
fut.await
}

pub async fn wait_for_low<'a>(&'a mut self) {
let fut = ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), false, true);
if self.is_low() {
return;
}
fut.await
}

pub async fn wait_for_rising_edge<'a>(&'a mut self) {
ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, false).await
}

pub async fn wait_for_falling_edge<'a>(&'a mut self) {
ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), false, true).await
}

pub async fn wait_for_any_edge<'a>(&'a mut self) {
ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, true).await
}
}

impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
type Error = Infallible;

fn is_high(&self) -> Result<bool, Self::Error> {
self.pin.is_high()
Ok(self.is_high())
}

fn is_low(&self) -> Result<bool, Self::Error> {
self.pin.is_low()
Ok(self.is_low())
}
}

impl<'d, T: GpioPin> WaitForHigh for ExtiInput<'d, T> {
type Future<'a>
where
Self: 'a,
= impl Future<Output = ()> + 'a;

fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
self.wait_for_high()
}
}

impl<'d, T: GpioPin> WaitForLow for ExtiInput<'d, T> {
type Future<'a>
where
Self: 'a,
= impl Future<Output = ()> + 'a;

fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
self.wait_for_low()
}
}

impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> {
type Future<'a>
where
Self: 'a,
= ExtiInputFuture<'a>;
= impl Future<Output = ()> + 'a;

fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> {
ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, false)
self.wait_for_rising_edge()
}
}

impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> {
type Future<'a>
where
Self: 'a,
= ExtiInputFuture<'a>;
= impl Future<Output = ()> + 'a;

fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> {
ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), false, true)
self.wait_for_falling_edge()
}
}

impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> {
type Future<'a>
where
Self: 'a,
= ExtiInputFuture<'a>;
= impl Future<Output = ()> + 'a;

fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, true)
self.wait_for_any_edge()
}
}

pub struct ExtiInputFuture<'a> {
struct ExtiInputFuture<'a> {
pin: u8,
phantom: PhantomData<&'a mut AnyPin>,
}

impl<'a> ExtiInputFuture<'a> {
fn new(pin: u8, port: u8, rising: bool, falling: bool) -> Self {
cortex_m::interrupt::free(|_| unsafe {
critical_section::with(|_| unsafe {
let pin = pin as usize;
exticr_regs()
.exticr(pin / 4)
Expand Down Expand Up @@ -177,7 +237,7 @@ impl<'a> ExtiInputFuture<'a> {

impl<'a> Drop for ExtiInputFuture<'a> {
fn drop(&mut self) {
cortex_m::interrupt::free(|_| unsafe {
critical_section::with(|_| unsafe {
let pin = self.pin as _;
cpu_regs().imr(0).modify(|w| w.set_line(pin, false));
});
Expand Down
Loading