stm32/spi: expose all functionality as inherent methods.

This commit is contained in:
Dario Nieuwenhuis 2022-01-19 17:29:47 +01:00
parent 3d27a0e7cb
commit 889d757ab8
12 changed files with 203 additions and 174 deletions

View File

@ -1,5 +1,13 @@
#![macro_use] #![macro_use]
use core::future::Future;
use core::marker::PhantomData;
use core::ptr;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embassy_traits::spi as traits;
use self::sealed::WordSize;
use crate::dma; use crate::dma;
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::{AFType, Pin}; use crate::gpio::sealed::{AFType, Pin};
@ -8,19 +16,14 @@ use crate::pac::spi::{regs, vals};
use crate::peripherals; use crate::peripherals;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
use core::future::Future;
use core::marker::PhantomData; pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
use core::ptr;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embassy_traits::spi as traits;
#[cfg_attr(spi_v1, path = "v1.rs")] #[cfg_attr(spi_v1, path = "v1.rs")]
#[cfg_attr(spi_f1, path = "v1.rs")] #[cfg_attr(spi_f1, path = "v1.rs")]
#[cfg_attr(spi_v2, path = "v2.rs")] #[cfg_attr(spi_v2, path = "v2.rs")]
#[cfg_attr(spi_v3, path = "v3.rs")] #[cfg_attr(spi_v3, path = "v3.rs")]
mod _version; mod _version;
pub use _version::*;
type Regs = &'static crate::pac::spi::Spi; type Regs = &'static crate::pac::spi::Spi;
@ -40,54 +43,6 @@ pub enum BitOrder {
MsbFirst, MsbFirst,
} }
#[derive(Copy, Clone, PartialOrd, PartialEq)]
enum WordSize {
EightBit,
SixteenBit,
}
impl WordSize {
#[cfg(any(spi_v1, spi_f1))]
fn dff(&self) -> vals::Dff {
match self {
WordSize::EightBit => vals::Dff::EIGHTBIT,
WordSize::SixteenBit => vals::Dff::SIXTEENBIT,
}
}
#[cfg(spi_v2)]
fn ds(&self) -> vals::Ds {
match self {
WordSize::EightBit => vals::Ds::EIGHTBIT,
WordSize::SixteenBit => vals::Ds::SIXTEENBIT,
}
}
#[cfg(spi_v2)]
fn frxth(&self) -> vals::Frxth {
match self {
WordSize::EightBit => vals::Frxth::QUARTER,
WordSize::SixteenBit => vals::Frxth::HALF,
}
}
#[cfg(spi_v3)]
fn dsize(&self) -> u8 {
match self {
WordSize::EightBit => 0b0111,
WordSize::SixteenBit => 0b1111,
}
}
#[cfg(spi_v3)]
fn _frxth(&self) -> vals::Fthlv {
match self {
WordSize::EightBit => vals::Fthlv::ONEFRAME,
WordSize::SixteenBit => vals::Fthlv::ONEFRAME,
}
}
}
#[non_exhaustive] #[non_exhaustive]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Config { pub struct Config {
@ -379,6 +334,47 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
self.current_word_size = word_size; self.current_word_size = word_size;
} }
pub async fn write(&mut self, data: &[u8]) -> Result<(), Error>
where
Tx: TxDmaChannel<T>,
{
self.write_dma_u8(data).await
}
pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error>
where
Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>,
{
self.read_dma_u8(data).await
}
pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error>
where
Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>,
{
self.transfer_dma_u8(read, write).await
}
pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> {
self.set_word_size(W::WORDSIZE);
let regs = T::regs();
for word in words.iter() {
let _ = transfer_word(regs, *word)?;
}
Ok(())
}
pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
self.set_word_size(W::WORDSIZE);
let regs = T::regs();
for word in words.iter_mut() {
*word = transfer_word(regs, *word)?;
}
Ok(())
}
} }
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
@ -537,17 +533,6 @@ fn finish_dma(regs: Regs) {
} }
} }
trait Word {
const WORDSIZE: WordSize;
}
impl Word for u8 {
const WORDSIZE: WordSize = WordSize::EightBit;
}
impl Word for u16 {
const WORDSIZE: WordSize = WordSize::SixteenBit;
}
fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> { fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> {
spin_until_tx_ready(regs)?; spin_until_tx_ready(regs)?;
@ -572,14 +557,7 @@ macro_rules! impl_blocking {
type Error = Error; type Error = Error;
fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
self.set_word_size($w::WORDSIZE); self.blocking_write(words)
let regs = T::regs();
for word in words.iter() {
let _ = transfer_word(regs, *word)?;
}
Ok(())
} }
} }
@ -589,13 +567,7 @@ macro_rules! impl_blocking {
type Error = Error; type Error = Error;
fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> {
self.set_word_size($w::WORDSIZE); self.blocking_transfer_in_place(words)?;
let regs = T::regs();
for word in words.iter_mut() {
*word = transfer_word(regs, *word)?;
}
Ok(words) Ok(words)
} }
} }
@ -616,7 +588,7 @@ impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> traits::Write<u8> for Spi<'d, T,
= impl Future<Output = Result<(), Self::Error>> + 'a; = impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
self.write_dma_u8(data) self.write(data)
} }
} }
@ -629,7 +601,7 @@ impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::Read<u8>
= impl Future<Output = Result<(), Self::Error>> + 'a; = impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.read_dma_u8(data) self.read(data)
} }
} }
@ -646,7 +618,7 @@ impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::FullDupl
read: &'a mut [u8], read: &'a mut [u8],
write: &'a [u8], write: &'a [u8],
) -> Self::WriteReadFuture<'a> { ) -> Self::WriteReadFuture<'a> {
self.read_write_dma_u8(read, write) self.transfer(read, write)
} }
} }
@ -676,8 +648,72 @@ pub(crate) mod sealed {
pub trait RxDmaChannel<T: Instance> { pub trait RxDmaChannel<T: Instance> {
fn request(&self) -> dma::Request; fn request(&self) -> dma::Request;
} }
pub trait Word: Copy + 'static {
const WORDSIZE: WordSize;
}
impl Word for u8 {
const WORDSIZE: WordSize = WordSize::EightBit;
}
impl Word for u16 {
const WORDSIZE: WordSize = WordSize::SixteenBit;
}
#[derive(Copy, Clone, PartialOrd, PartialEq)]
pub enum WordSize {
EightBit,
SixteenBit,
}
impl WordSize {
#[cfg(any(spi_v1, spi_f1))]
pub fn dff(&self) -> vals::Dff {
match self {
WordSize::EightBit => vals::Dff::EIGHTBIT,
WordSize::SixteenBit => vals::Dff::SIXTEENBIT,
}
}
#[cfg(spi_v2)]
pub fn ds(&self) -> vals::Ds {
match self {
WordSize::EightBit => vals::Ds::EIGHTBIT,
WordSize::SixteenBit => vals::Ds::SIXTEENBIT,
}
}
#[cfg(spi_v2)]
pub fn frxth(&self) -> vals::Frxth {
match self {
WordSize::EightBit => vals::Frxth::QUARTER,
WordSize::SixteenBit => vals::Frxth::HALF,
}
}
#[cfg(spi_v3)]
pub fn dsize(&self) -> u8 {
match self {
WordSize::EightBit => 0b0111,
WordSize::SixteenBit => 0b1111,
}
}
#[cfg(spi_v3)]
pub fn _frxth(&self) -> vals::Fthlv {
match self {
WordSize::EightBit => vals::Fthlv::ONEFRAME,
WordSize::SixteenBit => vals::Fthlv::ONEFRAME,
}
}
}
} }
pub trait Word: Copy + 'static + sealed::Word {}
impl Word for u8 {}
impl Word for u16 {}
pub trait Instance: sealed::Instance + RccPeripheral {} pub trait Instance: sealed::Instance + RccPeripheral {}
pub trait SckPin<T: Instance>: sealed::SckPin<T> {} pub trait SckPin<T: Instance>: sealed::SckPin<T> {}
pub trait MosiPin<T: Instance>: sealed::MosiPin<T> {} pub trait MosiPin<T: Instance>: sealed::MosiPin<T> {}

View File

@ -1,13 +1,12 @@
#![macro_use] #![macro_use]
pub use embedded_hal::blocking;
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
use futures::future::join; use futures::future::join;
use super::*; use super::*;
use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
{ {
@ -18,9 +17,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
self.set_word_size(WordSize::EightBit); self.set_word_size(WordSize::EightBit);
let request = self.txdma.request(); let tx_request = self.txdma.request();
let dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
let f = crate::dma::write(&mut self.txdma, request, write, dst); unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
let tx_f = Transfer::new(&mut self.txdma);
unsafe { unsafe {
T::regs().cr2().modify(|reg| { T::regs().cr2().modify(|reg| {
@ -31,14 +31,14 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
}); });
} }
f.await; tx_f.await;
finish_dma(T::regs()); finish_dma(T::regs());
Ok(()) Ok(())
} }
pub(super) async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>, Rx: RxDmaChannel<T>,
@ -53,11 +53,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
self.set_word_size(WordSize::EightBit); self.set_word_size(WordSize::EightBit);
let clock_byte_count = read.len(); let (_, clock_byte_count) = slice_ptr_parts_mut(read);
let rx_request = self.rxdma.request(); let rx_request = self.rxdma.request();
let rx_src = T::regs().rx_ptr(); let rx_src = T::regs().rx_ptr();
let rx_f = crate::dma::read(&mut self.rxdma, rx_request, rx_src, read); unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
let rx_f = Transfer::new(&mut self.rxdma);
let tx_request = self.txdma.request(); let tx_request = self.txdma.request();
let tx_dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
@ -86,16 +87,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
Ok(()) Ok(())
} }
pub(super) async fn read_write_dma_u8( pub(super) async fn transfer_dma_u8(
&mut self, &mut self,
read: &mut [u8], read: *mut [u8],
write: &[u8], write: *const [u8],
) -> Result<(), Error> ) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>, Rx: RxDmaChannel<T>,
{ {
assert!(read.len() >= write.len()); let (_, rx_len) = slice_ptr_parts(read);
let (_, tx_len) = slice_ptr_parts(write);
assert_eq!(rx_len, tx_len);
unsafe { unsafe {
T::regs().cr1().modify(|w| { T::regs().cr1().modify(|w| {
@ -109,16 +112,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
let rx_request = self.rxdma.request(); let rx_request = self.rxdma.request();
let rx_src = T::regs().rx_ptr(); let rx_src = T::regs().rx_ptr();
let rx_f = crate::dma::read( unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
&mut self.rxdma, let rx_f = Transfer::new(&mut self.rxdma);
rx_request,
rx_src,
&mut read[0..write.len()],
);
let tx_request = self.txdma.request(); let tx_request = self.txdma.request();
let tx_dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
let tx_f = crate::dma::write(&mut self.txdma, tx_request, write, tx_dst); unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
let tx_f = Transfer::new(&mut self.txdma);
unsafe { unsafe {
T::regs().cr2().modify(|reg| { T::regs().cr2().modify(|reg| {

View File

@ -1,12 +1,12 @@
#![macro_use] #![macro_use]
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
use futures::future::join; use futures::future::join;
use super::*; use super::*;
use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
{ {
@ -22,9 +22,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
self.set_word_size(WordSize::EightBit); self.set_word_size(WordSize::EightBit);
let request = self.txdma.request(); let tx_request = self.txdma.request();
let dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
let f = crate::dma::write(&mut self.txdma, request, write, dst); unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
let tx_f = Transfer::new(&mut self.txdma);
unsafe { unsafe {
T::regs().cr2().modify(|reg| { T::regs().cr2().modify(|reg| {
@ -35,14 +36,14 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
}); });
} }
f.await; tx_f.await;
finish_dma(T::regs()); finish_dma(T::regs());
Ok(()) Ok(())
} }
pub(super) async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>, Rx: RxDmaChannel<T>,
@ -57,11 +58,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
self.set_word_size(WordSize::EightBit); self.set_word_size(WordSize::EightBit);
let clock_byte_count = read.len(); let (_, clock_byte_count) = slice_ptr_parts_mut(read);
let rx_request = self.rxdma.request(); let rx_request = self.rxdma.request();
let rx_src = T::regs().rx_ptr(); let rx_src = T::regs().rx_ptr();
let rx_f = crate::dma::read(&mut self.rxdma, rx_request, rx_src, read); unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
let rx_f = Transfer::new(&mut self.rxdma);
let tx_request = self.txdma.request(); let tx_request = self.txdma.request();
let tx_dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
@ -90,16 +92,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
Ok(()) Ok(())
} }
pub(super) async fn read_write_dma_u8( pub(super) async fn transfer_dma_u8(
&mut self, &mut self,
read: &mut [u8], read: *mut [u8],
write: &[u8], write: *const [u8],
) -> Result<(), Error> ) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>, Rx: RxDmaChannel<T>,
{ {
assert!(read.len() >= write.len()); let (_, rx_len) = slice_ptr_parts(read);
let (_, tx_len) = slice_ptr_parts(write);
assert_eq!(rx_len, tx_len);
unsafe { unsafe {
T::regs().cr1().modify(|w| { T::regs().cr1().modify(|w| {
@ -118,16 +122,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
let rx_request = self.rxdma.request(); let rx_request = self.rxdma.request();
let rx_src = T::regs().rx_ptr(); let rx_src = T::regs().rx_ptr();
let rx_f = crate::dma::read( unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
&mut self.rxdma, let rx_f = Transfer::new(&mut self.rxdma);
rx_request,
rx_src,
&mut read[0..write.len()],
);
let tx_request = self.txdma.request(); let tx_request = self.txdma.request();
let tx_dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
let tx_f = crate::dma::write(&mut self.txdma, tx_request, write, tx_dst); unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
let tx_f = Transfer::new(&mut self.txdma);
unsafe { unsafe {
T::regs().cr2().modify(|reg| { T::regs().cr2().modify(|reg| {

View File

@ -1,12 +1,12 @@
#![macro_use] #![macro_use]
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
use futures::future::join; use futures::future::join;
use super::*; use super::*;
use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
{ {
@ -22,9 +22,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
} }
let request = self.txdma.request(); let tx_request = self.txdma.request();
let dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
let f = crate::dma::write(&mut self.txdma, request, write, dst); unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
let tx_f = Transfer::new(&mut self.txdma);
unsafe { unsafe {
T::regs().cfg1().modify(|reg| { T::regs().cfg1().modify(|reg| {
@ -38,14 +39,14 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
}); });
} }
f.await; tx_f.await;
finish_dma(T::regs()); finish_dma(T::regs());
Ok(()) Ok(())
} }
pub(super) async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>, Rx: RxDmaChannel<T>,
@ -60,11 +61,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
}); });
} }
let clock_byte_count = read.len(); let (_, clock_byte_count) = slice_ptr_parts_mut(read);
let rx_request = self.rxdma.request(); let rx_request = self.rxdma.request();
let rx_src = T::regs().rx_ptr(); let rx_src = T::regs().rx_ptr();
let rx_f = crate::dma::read(&mut self.rxdma, rx_request, rx_src, read); unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
let rx_f = Transfer::new(&mut self.rxdma);
let tx_request = self.txdma.request(); let tx_request = self.txdma.request();
let tx_dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
@ -96,16 +98,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
Ok(()) Ok(())
} }
pub(super) async fn read_write_dma_u8( pub(super) async fn transfer_dma_u8(
&mut self, &mut self,
read: &mut [u8], read: *mut [u8],
write: &[u8], write: *const [u8],
) -> Result<(), Error> ) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDmaChannel<T>,
Rx: RxDmaChannel<T>, Rx: RxDmaChannel<T>,
{ {
assert!(read.len() >= write.len()); let (_, rx_len) = slice_ptr_parts(read);
let (_, tx_len) = slice_ptr_parts(write);
assert_eq!(rx_len, tx_len);
self.set_word_size(WordSize::EightBit); self.set_word_size(WordSize::EightBit);
unsafe { unsafe {
@ -124,16 +128,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
let rx_request = self.rxdma.request(); let rx_request = self.rxdma.request();
let rx_src = T::regs().rx_ptr(); let rx_src = T::regs().rx_ptr();
let rx_f = crate::dma::read( unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
&mut self.rxdma, let rx_f = Transfer::new(&mut self.rxdma);
rx_request,
rx_src,
&mut read[0..write.len()],
);
let tx_request = self.txdma.request(); let tx_request = self.txdma.request();
let tx_dst = T::regs().tx_ptr(); let tx_dst = T::regs().tx_ptr();
let tx_f = crate::dma::write(&mut self.txdma, tx_request, write, tx_dst); unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
let tx_f = Transfer::new(&mut self.txdma);
unsafe { unsafe {
T::regs().cfg1().modify(|reg| { T::regs().cfg1().modify(|reg| {

View File

@ -82,14 +82,10 @@ use crate::{
pac, pac,
peripherals::SUBGHZSPI, peripherals::SUBGHZSPI,
rcc::sealed::RccPeripheral, rcc::sealed::RccPeripheral,
spi::{BitOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi}, spi::{BitOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi, MODE_0},
time::Hertz, time::Hertz,
}; };
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embedded_hal::{
blocking::spi::{Transfer, Write},
spi::MODE_0,
};
/// Passthrough for SPI errors (for now) /// Passthrough for SPI errors (for now)
pub type Error = crate::spi::Error; pub type Error = crate::spi::Error;
@ -255,8 +251,8 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
self.poll_not_busy(); self.poll_not_busy();
{ {
let _nss: Nss = Nss::new(); let _nss: Nss = Nss::new();
self.spi.write(&[opcode as u8])?; self.spi.blocking_write(&[opcode as u8])?;
self.spi.transfer(data)?; self.spi.blocking_transfer_in_place(data)?;
} }
self.poll_not_busy(); self.poll_not_busy();
Ok(()) Ok(())
@ -280,7 +276,7 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
self.poll_not_busy(); self.poll_not_busy();
{ {
let _nss: Nss = Nss::new(); let _nss: Nss = Nss::new();
self.spi.write(data)?; self.spi.blocking_write(data)?;
} }
self.poll_not_busy(); self.poll_not_busy();
Ok(()) Ok(())
@ -290,8 +286,9 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
self.poll_not_busy(); self.poll_not_busy();
{ {
let _nss: Nss = Nss::new(); let _nss: Nss = Nss::new();
self.spi.write(&[OpCode::WriteBuffer as u8, offset])?; self.spi
self.spi.write(data)?; .blocking_write(&[OpCode::WriteBuffer as u8, offset])?;
self.spi.blocking_write(data)?;
} }
self.poll_not_busy(); self.poll_not_busy();
@ -308,9 +305,10 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
self.poll_not_busy(); self.poll_not_busy();
{ {
let _nss: Nss = Nss::new(); let _nss: Nss = Nss::new();
self.spi.write(&[OpCode::ReadBuffer as u8, offset])?; self.spi
self.spi.transfer(&mut status_buf)?; .blocking_write(&[OpCode::ReadBuffer as u8, offset])?;
self.spi.transfer(buf)?; self.spi.blocking_transfer_in_place(&mut status_buf)?;
self.spi.blocking_transfer_in_place(buf)?;
} }
self.poll_not_busy(); self.poll_not_busy();
@ -342,8 +340,8 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
{ {
let _nss: Nss = Nss::new(); let _nss: Nss = Nss::new();
self.spi self.spi
.write(&[OpCode::WriteRegister as u8, addr[0], addr[1]])?; .blocking_write(&[OpCode::WriteRegister as u8, addr[0], addr[1]])?;
self.spi.write(data)?; self.spi.blocking_write(data)?;
} }
self.poll_not_busy(); self.poll_not_busy();

View File

@ -10,7 +10,6 @@ use embassy_stm32::dma::NoDma;
use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::spi::{Config, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embedded_hal::blocking::spi::Transfer;
use example_common::*; use example_common::*;
#[entry] #[entry]
@ -35,7 +34,7 @@ fn main() -> ! {
loop { loop {
let mut buf = [0x0Au8; 4]; let mut buf = [0x0Au8; 4];
cs.set_low(); cs.set_low();
unwrap!(spi.transfer(&mut buf)); unwrap!(spi.blocking_transfer_in_place(&mut buf));
cs.set_high(); cs.set_high();
info!("xfer {=[u8]:x}", buf); info!("xfer {=[u8]:x}", buf);
} }

View File

@ -10,7 +10,6 @@ use embassy::executor::Spawner;
use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::spi::{Config, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::Peripherals; use embassy_stm32::Peripherals;
use embassy_traits::spi::FullDuplex;
use example_common::*; use example_common::*;
use heapless::String; use heapless::String;
@ -33,7 +32,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
let mut write: String<128> = String::new(); let mut write: String<128> = String::new();
let mut read = [0; 128]; let mut read = [0; 128];
core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
spi.read_write(&mut read[0..write.len()], write.as_bytes()) spi.transfer(&mut read[0..write.len()], write.as_bytes())
.await .await
.ok(); .ok();
info!("read via spi+dma: {}", from_utf8(&read).unwrap()); info!("read via spi+dma: {}", from_utf8(&read).unwrap());

View File

@ -10,7 +10,6 @@ use embassy::executor::Executor;
use embassy::util::Forever; use embassy::util::Forever;
use embassy_stm32::dma::NoDma; use embassy_stm32::dma::NoDma;
use embassy_stm32::spi; use embassy_stm32::spi;
use embedded_hal::blocking::spi::Transfer;
use example_common::*; use example_common::*;
use core::str::from_utf8; use core::str::from_utf8;
@ -25,7 +24,7 @@ async fn main_task(mut spi: spi::Spi<'static, SPI3, NoDma, NoDma>) {
let mut write: String<128> = String::new(); let mut write: String<128> = String::new();
core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
unsafe { unsafe {
let result = spi.transfer(write.as_bytes_mut()); let result = spi.blocking_transfer_in_place(write.as_bytes_mut());
if let Err(_) = result { if let Err(_) = result {
defmt::panic!("crap"); defmt::panic!("crap");
} }

View File

@ -13,7 +13,6 @@ use embassy_stm32::dma::NoDma;
use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::spi::{Config, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::Peripherals; use embassy_stm32::Peripherals;
use embedded_hal::blocking::spi::Transfer;
#[embassy::main] #[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) { async fn main(_spawner: Spawner, p: Peripherals) {
@ -35,7 +34,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
loop { loop {
let mut buf = [0x0Au8; 4]; let mut buf = [0x0Au8; 4];
cs.set_low(); cs.set_low();
unwrap!(spi.transfer(&mut buf)); unwrap!(spi.blocking_transfer_in_place(&mut buf));
cs.set_high(); cs.set_high();
info!("xfer {=[u8]:x}", buf); info!("xfer {=[u8]:x}", buf);
} }

View File

@ -13,7 +13,6 @@ use embassy_stm32::dma::NoDma;
use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::spi::{Config, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::Peripherals; use embassy_stm32::Peripherals;
use embedded_hal::blocking::spi::Transfer;
#[embassy::main] #[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) { async fn main(_spawner: Spawner, p: Peripherals) {
@ -35,7 +34,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
loop { loop {
let mut buf = [0x0Au8; 4]; let mut buf = [0x0Au8; 4];
cs.set_low(); cs.set_low();
unwrap!(spi.transfer(&mut buf)); unwrap!(spi.blocking_transfer_in_place(&mut buf));
cs.set_high(); cs.set_high();
info!("xfer {=[u8]:x}", buf); info!("xfer {=[u8]:x}", buf);
} }

View File

@ -9,7 +9,6 @@ use embassy_stm32::dma::NoDma;
use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::spi::{Config, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embedded_hal::blocking::spi::Transfer;
use example_common::*; use example_common::*;
#[cortex_m_rt::entry] #[cortex_m_rt::entry]
@ -34,7 +33,7 @@ fn main() -> ! {
loop { loop {
let mut buf = [0x0Au8; 4]; let mut buf = [0x0Au8; 4];
cs.set_low(); cs.set_low();
unwrap!(spi.transfer(&mut buf)); unwrap!(spi.blocking_transfer_in_place(&mut buf));
cs.set_high(); cs.set_high();
info!("xfer {=[u8]:x}", buf); info!("xfer {=[u8]:x}", buf);
} }

View File

@ -10,7 +10,6 @@ use embassy_stm32::dma::NoDma;
use embassy_stm32::spi::{self, Spi}; use embassy_stm32::spi::{self, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::Peripherals; use embassy_stm32::Peripherals;
use embedded_hal::blocking::spi::Transfer;
use example_common::*; use example_common::*;
#[embassy::main(config = "config()")] #[embassy::main(config = "config()")]
@ -38,7 +37,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
// Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor.
// so we should get the data we sent back. // so we should get the data we sent back.
let mut buf = data; let mut buf = data;
spi.transfer(&mut buf).unwrap(); spi.blocking_transfer_in_place(&mut buf).unwrap();
assert_eq!(buf, data); assert_eq!(buf, data);
info!("Test OK"); info!("Test OK");