diff --git a/README.md b/README.md
index 374133c4b..ee5c42245 100644
--- a/README.md
+++ b/README.md
@@ -18,6 +18,7 @@ Rust's async/await allows
- esp-rs, for the Espressif Systems ESP32 series of chips.
- Embassy HAL support for Espressif chips, as well as Async WiFi, Bluetooth and ESP-NOW, is being developed in the [esp-rs/esp-hal](https://github.com/esp-rs/esp-hal) repository.
- ch32-hal, for the WCH 32-bit RISC-V(CH32V) series of chips.
+ - mpfs-hal, for the Microchip PolarFire SoC.
- **Time that Just Works** -
No more messing with hardware timers. embassy_time provides Instant, Duration and Timer types that are globally available and never overflow.
diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs
index d0d504395..c1b301547 100644
--- a/cyw43-pio/src/lib.rs
+++ b/cyw43-pio/src/lib.rs
@@ -169,12 +169,12 @@ where
self.sm.set_enable(true);
- self.sm.tx().dma_push(self.dma.reborrow(), write).await;
+ self.sm.tx().dma_push(self.dma.reborrow(), write, false).await;
let mut status = 0;
self.sm
.rx()
- .dma_pull(self.dma.reborrow(), slice::from_mut(&mut status))
+ .dma_pull(self.dma.reborrow(), slice::from_mut(&mut status), false)
.await;
status
}
@@ -201,13 +201,16 @@ where
// self.cs.set_low();
self.sm.set_enable(true);
- self.sm.tx().dma_push(self.dma.reborrow(), slice::from_ref(&cmd)).await;
- self.sm.rx().dma_pull(self.dma.reborrow(), read).await;
+ self.sm
+ .tx()
+ .dma_push(self.dma.reborrow(), slice::from_ref(&cmd), false)
+ .await;
+ self.sm.rx().dma_pull(self.dma.reborrow(), read, false).await;
let mut status = 0;
self.sm
.rx()
- .dma_pull(self.dma.reborrow(), slice::from_mut(&mut status))
+ .dma_pull(self.dma.reborrow(), slice::from_mut(&mut status), false)
.await;
#[cfg(feature = "defmt")]
diff --git a/docs/pages/hal.adoc b/docs/pages/hal.adoc
index 14b85e1f1..e1a29751e 100644
--- a/docs/pages/hal.adoc
+++ b/docs/pages/hal.adoc
@@ -12,3 +12,5 @@ async traits in `embedded-hal` and `embedded-hal-async`. You can also use these
For the ESP32 series, there is an link:https://github.com/esp-rs/esp-hal[esp-hal] which you can use.
For the WCH 32-bit RISC-V series, there is an link:https://github.com/ch32-rs/ch32-hal[ch32-hal], which you can use.
+
+For the Microchip PolarFire SoC, there is link:https://github.com/AlexCharlton/mpfs-hal[mpfs-hal].
\ No newline at end of file
diff --git a/docs/pages/overview.adoc b/docs/pages/overview.adoc
index a1bf180cd..9b93ba10c 100644
--- a/docs/pages/overview.adoc
+++ b/docs/pages/overview.adoc
@@ -31,6 +31,7 @@ The Embassy project maintains HALs for select hardware, but you can still use HA
* link:https://docs.embassy.dev/embassy-rp/[embassy-rp], for the Raspberry Pi RP2040 microcontroller.
* link:https://github.com/esp-rs[esp-rs], for the Espressif Systems ESP32 series of chips.
* link:https://github.com/ch32-rs/ch32-hal[ch32-hal], for the WCH 32-bit RISC-V(CH32V) series of chips.
+* link:https://github.com/AlexCharlton/mpfs-hal[mpfs-hal], for the Microchip PolarFire SoC.
NOTE: A common question is if one can use the Embassy HALs standalone. Yes, it is possible! There are no dependency on the executor within the HALs. You can even use them without async,
as they implement both the link:https://github.com/rust-embedded/embedded-hal[Embedded HAL] blocking and async traits.
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs
index 880d6effd..fd09d4bba 100644
--- a/embassy-rp/src/pio/mod.rs
+++ b/embassy-rp/src/pio/mod.rs
@@ -362,6 +362,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
&'a mut self,
ch: PeripheralRef<'a, C>,
data: &'a mut [W],
+ bswap: bool,
) -> Transfer<'a, C> {
let pio_no = PIO::PIO_NO;
let p = ch.regs();
@@ -379,6 +380,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
w.set_chain_to(ch.number());
w.set_incr_read(false);
w.set_incr_write(true);
+ w.set_bswap(bswap);
w.set_en(true);
});
compiler_fence(Ordering::SeqCst);
@@ -447,7 +449,12 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
}
/// Prepare a DMA transfer to TX FIFO.
- pub fn dma_push<'a, C: Channel, W: Word>(&'a mut self, ch: PeripheralRef<'a, C>, data: &'a [W]) -> Transfer<'a, C> {
+ pub fn dma_push<'a, C: Channel, W: Word>(
+ &'a mut self,
+ ch: PeripheralRef<'a, C>,
+ data: &'a [W],
+ bswap: bool,
+ ) -> Transfer<'a, C> {
let pio_no = PIO::PIO_NO;
let p = ch.regs();
p.read_addr().write_value(data.as_ptr() as u32);
@@ -464,6 +471,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
w.set_chain_to(ch.number());
w.set_incr_read(true);
w.set_incr_write(false);
+ w.set_bswap(bswap);
w.set_en(true);
});
compiler_fence(Ordering::SeqCst);
diff --git a/embassy-rp/src/pio_programs/hd44780.rs b/embassy-rp/src/pio_programs/hd44780.rs
index 70129318b..6997b91f3 100644
--- a/embassy-rp/src/pio_programs/hd44780.rs
+++ b/embassy-rp/src/pio_programs/hd44780.rs
@@ -173,7 +173,7 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
sm.set_enable(true);
// display on and cursor on and blinking, reset display
- sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1]).await;
+ sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await;
Self {
dma: dma.map_into(),
@@ -198,6 +198,6 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
// set cursor to 1:15
self.buf[38..].copy_from_slice(&[0x80, 0xcf]);
- self.sm.tx().dma_push(self.dma.reborrow(), &self.buf).await;
+ self.sm.tx().dma_push(self.dma.reborrow(), &self.buf, false).await;
}
}
diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs
index a7b4f46a6..17e321405 100644
--- a/embassy-rp/src/pio_programs/i2s.rs
+++ b/embassy-rp/src/pio_programs/i2s.rs
@@ -90,6 +90,6 @@ impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> {
/// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer.
pub fn write<'b>(&'b mut self, buff: &'b [u32]) -> Transfer<'b, AnyChannel> {
- self.sm.tx().dma_push(self.dma.reborrow(), buff)
+ self.sm.tx().dma_push(self.dma.reborrow(), buff, false)
}
}
diff --git a/embassy-rp/src/pio_programs/ws2812.rs b/embassy-rp/src/pio_programs/ws2812.rs
index 875f0209f..2462a64e6 100644
--- a/embassy-rp/src/pio_programs/ws2812.rs
+++ b/embassy-rp/src/pio_programs/ws2812.rs
@@ -111,7 +111,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
}
// DMA transfer
- self.sm.tx().dma_push(self.dma.reborrow(), &words).await;
+ self.sm.tx().dma_push(self.dma.reborrow(), &words, false).await;
Timer::after_micros(55).await;
}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index de7b3c8df..568067360 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -85,6 +85,7 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) {
compiler_fence(Ordering::SeqCst);
s.rx_waker.wake();
+ s.tx_waker.wake();
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -592,7 +593,7 @@ async fn flush(info: &Info, state: &State) -> Result<(), Error> {
// future which completes when Transmission complete is detected
let abort = poll_fn(move |cx| {
- state.rx_waker.register(cx.waker());
+ state.tx_waker.register(cx.waker());
let sr = sr(r).read();
if sr.tc() {
@@ -2019,6 +2020,7 @@ enum Kind {
struct State {
rx_waker: AtomicWaker,
+ tx_waker: AtomicWaker,
tx_rx_refcount: AtomicU8,
}
@@ -2026,6 +2028,7 @@ impl State {
const fn new() -> Self {
Self {
rx_waker: AtomicWaker::new(),
+ tx_waker: AtomicWaker::new(),
tx_rx_refcount: AtomicU8::new(0),
}
}
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index 560ce4e8f..3631888e4 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -8,12 +8,12 @@ use embassy_hal_internal::PeripheralRef;
use embedded_io_async::ReadReady;
use futures_util::future::{select, Either};
-use super::{
- clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx,
-};
+use super::{rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx};
use crate::dma::ReadableRingBuffer;
use crate::gpio::{AnyPin, SealedPin as _};
use crate::mode::Async;
+#[cfg(any(usart_v3, usart_v4))]
+use crate::pac::usart::regs;
use crate::time::Hertz;
use crate::usart::{Regs, Sr};
@@ -254,7 +254,12 @@ fn clear_idle_flag(r: Regs) -> Sr {
// This read also clears the error and idle interrupt flags on v1.
unsafe { rdr(r).read_volatile() };
- clear_interrupt_flags(r, sr);
+ #[cfg(any(usart_v3, usart_v4))]
+ {
+ let mut clear_idle = regs::Icr(0);
+ clear_idle.set_idle(true);
+ r.icr().write_value(clear_idle);
+ }
r.cr1().modify(|w| w.set_idleie(true));
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs
index d00ed2142..da6e47a1b 100644
--- a/examples/rp/src/bin/pio_dma.rs
+++ b/examples/rp/src/bin/pio_dma.rs
@@ -72,8 +72,8 @@ async fn main(_spawner: Spawner) {
loop {
let (rx, tx) = sm.rx_tx();
join(
- tx.dma_push(dma_out_ref.reborrow(), &dout),
- rx.dma_pull(dma_in_ref.reborrow(), &mut din),
+ tx.dma_push(dma_out_ref.reborrow(), &dout, false),
+ rx.dma_pull(dma_in_ref.reborrow(), &mut din, false),
)
.await;
for i in 0..din.len() {
diff --git a/examples/rp235x/src/bin/pio_dma.rs b/examples/rp235x/src/bin/pio_dma.rs
index d00ed2142..da6e47a1b 100644
--- a/examples/rp235x/src/bin/pio_dma.rs
+++ b/examples/rp235x/src/bin/pio_dma.rs
@@ -72,8 +72,8 @@ async fn main(_spawner: Spawner) {
loop {
let (rx, tx) = sm.rx_tx();
join(
- tx.dma_push(dma_out_ref.reborrow(), &dout),
- rx.dma_pull(dma_in_ref.reborrow(), &mut din),
+ tx.dma_push(dma_out_ref.reborrow(), &dout, false),
+ rx.dma_pull(dma_in_ref.reborrow(), &mut din, false),
)
.await;
for i in 0..din.len() {