stm32/spi: expose all functionality as inherent methods.
This commit is contained in:
parent
3d27a0e7cb
commit
889d757ab8
12 changed files with 203 additions and 174 deletions
|
@ -1,5 +1,13 @@
|
|||
#![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::NoDma;
|
||||
use crate::gpio::sealed::{AFType, Pin};
|
||||
|
@ -8,19 +16,14 @@ use crate::pac::spi::{regs, vals};
|
|||
use crate::peripherals;
|
||||
use crate::rcc::RccPeripheral;
|
||||
use crate::time::Hertz;
|
||||
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;
|
||||
|
||||
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
|
||||
#[cfg_attr(spi_v1, path = "v1.rs")]
|
||||
#[cfg_attr(spi_f1, path = "v1.rs")]
|
||||
#[cfg_attr(spi_v2, path = "v2.rs")]
|
||||
#[cfg_attr(spi_v3, path = "v3.rs")]
|
||||
mod _version;
|
||||
pub use _version::*;
|
||||
|
||||
type Regs = &'static crate::pac::spi::Spi;
|
||||
|
||||
|
@ -40,54 +43,6 @@ pub enum BitOrder {
|
|||
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]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Config {
|
||||
|
@ -379,6 +334,47 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
|
||||
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> {
|
||||
|
@ -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> {
|
||||
spin_until_tx_ready(regs)?;
|
||||
|
||||
|
@ -572,14 +557,7 @@ macro_rules! impl_blocking {
|
|||
type Error = Error;
|
||||
|
||||
fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
|
||||
self.set_word_size($w::WORDSIZE);
|
||||
let regs = T::regs();
|
||||
|
||||
for word in words.iter() {
|
||||
let _ = transfer_word(regs, *word)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
self.blocking_write(words)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,13 +567,7 @@ macro_rules! impl_blocking {
|
|||
type Error = Error;
|
||||
|
||||
fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> {
|
||||
self.set_word_size($w::WORDSIZE);
|
||||
let regs = T::regs();
|
||||
|
||||
for word in words.iter_mut() {
|
||||
*word = transfer_word(regs, *word)?;
|
||||
}
|
||||
|
||||
self.blocking_transfer_in_place(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;
|
||||
|
||||
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;
|
||||
|
||||
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],
|
||||
write: &'a [u8],
|
||||
) -> 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> {
|
||||
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 SckPin<T: Instance>: sealed::SckPin<T> {}
|
||||
pub trait MosiPin<T: Instance>: sealed::MosiPin<T> {}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#![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 super::*;
|
||||
use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
|
||||
|
||||
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
|
||||
Tx: TxDmaChannel<T>,
|
||||
{
|
||||
|
@ -18,9 +17,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
}
|
||||
self.set_word_size(WordSize::EightBit);
|
||||
|
||||
let request = self.txdma.request();
|
||||
let dst = T::regs().tx_ptr();
|
||||
let f = crate::dma::write(&mut self.txdma, request, write, dst);
|
||||
let tx_request = self.txdma.request();
|
||||
let tx_dst = T::regs().tx_ptr();
|
||||
unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
|
||||
let tx_f = Transfer::new(&mut self.txdma);
|
||||
|
||||
unsafe {
|
||||
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());
|
||||
|
||||
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
|
||||
Tx: TxDmaChannel<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);
|
||||
|
||||
let clock_byte_count = read.len();
|
||||
let (_, clock_byte_count) = slice_ptr_parts_mut(read);
|
||||
|
||||
let rx_request = self.rxdma.request();
|
||||
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_dst = T::regs().tx_ptr();
|
||||
|
@ -86,16 +87,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn read_write_dma_u8(
|
||||
pub(super) async fn transfer_dma_u8(
|
||||
&mut self,
|
||||
read: &mut [u8],
|
||||
write: &[u8],
|
||||
read: *mut [u8],
|
||||
write: *const [u8],
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
Tx: TxDmaChannel<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 {
|
||||
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_src = T::regs().rx_ptr();
|
||||
let rx_f = crate::dma::read(
|
||||
&mut self.rxdma,
|
||||
rx_request,
|
||||
rx_src,
|
||||
&mut read[0..write.len()],
|
||||
);
|
||||
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_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 {
|
||||
T::regs().cr2().modify(|reg| {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#![macro_use]
|
||||
|
||||
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
use futures::future::join;
|
||||
|
||||
use super::*;
|
||||
use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
|
||||
|
||||
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
|
||||
Tx: TxDmaChannel<T>,
|
||||
{
|
||||
|
@ -22,9 +22,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
}
|
||||
self.set_word_size(WordSize::EightBit);
|
||||
|
||||
let request = self.txdma.request();
|
||||
let dst = T::regs().tx_ptr();
|
||||
let f = crate::dma::write(&mut self.txdma, request, write, dst);
|
||||
let tx_request = self.txdma.request();
|
||||
let tx_dst = T::regs().tx_ptr();
|
||||
unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
|
||||
let tx_f = Transfer::new(&mut self.txdma);
|
||||
|
||||
unsafe {
|
||||
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());
|
||||
|
||||
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
|
||||
Tx: TxDmaChannel<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);
|
||||
|
||||
let clock_byte_count = read.len();
|
||||
let (_, clock_byte_count) = slice_ptr_parts_mut(read);
|
||||
|
||||
let rx_request = self.rxdma.request();
|
||||
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_dst = T::regs().tx_ptr();
|
||||
|
@ -90,16 +92,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn read_write_dma_u8(
|
||||
pub(super) async fn transfer_dma_u8(
|
||||
&mut self,
|
||||
read: &mut [u8],
|
||||
write: &[u8],
|
||||
read: *mut [u8],
|
||||
write: *const [u8],
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
Tx: TxDmaChannel<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 {
|
||||
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_src = T::regs().rx_ptr();
|
||||
let rx_f = crate::dma::read(
|
||||
&mut self.rxdma,
|
||||
rx_request,
|
||||
rx_src,
|
||||
&mut read[0..write.len()],
|
||||
);
|
||||
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_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 {
|
||||
T::regs().cr2().modify(|reg| {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#![macro_use]
|
||||
|
||||
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
use futures::future::join;
|
||||
|
||||
use super::*;
|
||||
use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
|
||||
|
||||
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
|
||||
Tx: TxDmaChannel<T>,
|
||||
{
|
||||
|
@ -22,9 +22,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
}
|
||||
}
|
||||
|
||||
let request = self.txdma.request();
|
||||
let dst = T::regs().tx_ptr();
|
||||
let f = crate::dma::write(&mut self.txdma, request, write, dst);
|
||||
let tx_request = self.txdma.request();
|
||||
let tx_dst = T::regs().tx_ptr();
|
||||
unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
|
||||
let tx_f = Transfer::new(&mut self.txdma);
|
||||
|
||||
unsafe {
|
||||
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());
|
||||
|
||||
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
|
||||
Tx: TxDmaChannel<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_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_dst = T::regs().tx_ptr();
|
||||
|
@ -96,16 +98,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn read_write_dma_u8(
|
||||
pub(super) async fn transfer_dma_u8(
|
||||
&mut self,
|
||||
read: &mut [u8],
|
||||
write: &[u8],
|
||||
read: *mut [u8],
|
||||
write: *const [u8],
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
Tx: TxDmaChannel<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);
|
||||
unsafe {
|
||||
|
@ -124,16 +128,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||
|
||||
let rx_request = self.rxdma.request();
|
||||
let rx_src = T::regs().rx_ptr();
|
||||
let rx_f = crate::dma::read(
|
||||
&mut self.rxdma,
|
||||
rx_request,
|
||||
rx_src,
|
||||
&mut read[0..write.len()],
|
||||
);
|
||||
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_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 {
|
||||
T::regs().cfg1().modify(|reg| {
|
||||
|
|
|
@ -82,14 +82,10 @@ use crate::{
|
|||
pac,
|
||||
peripherals::SUBGHZSPI,
|
||||
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,
|
||||
};
|
||||
use embassy::util::Unborrow;
|
||||
use embedded_hal::{
|
||||
blocking::spi::{Transfer, Write},
|
||||
spi::MODE_0,
|
||||
};
|
||||
|
||||
/// Passthrough for SPI errors (for now)
|
||||
pub type Error = crate::spi::Error;
|
||||
|
@ -255,8 +251,8 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
|
|||
self.poll_not_busy();
|
||||
{
|
||||
let _nss: Nss = Nss::new();
|
||||
self.spi.write(&[opcode as u8])?;
|
||||
self.spi.transfer(data)?;
|
||||
self.spi.blocking_write(&[opcode as u8])?;
|
||||
self.spi.blocking_transfer_in_place(data)?;
|
||||
}
|
||||
self.poll_not_busy();
|
||||
Ok(())
|
||||
|
@ -280,7 +276,7 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
|
|||
self.poll_not_busy();
|
||||
{
|
||||
let _nss: Nss = Nss::new();
|
||||
self.spi.write(data)?;
|
||||
self.spi.blocking_write(data)?;
|
||||
}
|
||||
self.poll_not_busy();
|
||||
Ok(())
|
||||
|
@ -290,8 +286,9 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
|
|||
self.poll_not_busy();
|
||||
{
|
||||
let _nss: Nss = Nss::new();
|
||||
self.spi.write(&[OpCode::WriteBuffer as u8, offset])?;
|
||||
self.spi.write(data)?;
|
||||
self.spi
|
||||
.blocking_write(&[OpCode::WriteBuffer as u8, offset])?;
|
||||
self.spi.blocking_write(data)?;
|
||||
}
|
||||
self.poll_not_busy();
|
||||
|
||||
|
@ -308,9 +305,10 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
|
|||
self.poll_not_busy();
|
||||
{
|
||||
let _nss: Nss = Nss::new();
|
||||
self.spi.write(&[OpCode::ReadBuffer as u8, offset])?;
|
||||
self.spi.transfer(&mut status_buf)?;
|
||||
self.spi.transfer(buf)?;
|
||||
self.spi
|
||||
.blocking_write(&[OpCode::ReadBuffer as u8, offset])?;
|
||||
self.spi.blocking_transfer_in_place(&mut status_buf)?;
|
||||
self.spi.blocking_transfer_in_place(buf)?;
|
||||
}
|
||||
self.poll_not_busy();
|
||||
|
||||
|
@ -342,8 +340,8 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
|
|||
{
|
||||
let _nss: Nss = Nss::new();
|
||||
self.spi
|
||||
.write(&[OpCode::WriteRegister as u8, addr[0], addr[1]])?;
|
||||
self.spi.write(data)?;
|
||||
.blocking_write(&[OpCode::WriteRegister as u8, addr[0], addr[1]])?;
|
||||
self.spi.blocking_write(data)?;
|
||||
}
|
||||
self.poll_not_busy();
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ use embassy_stm32::dma::NoDma;
|
|||
use embassy_stm32::gpio::{Level, Output, Speed};
|
||||
use embassy_stm32::spi::{Config, Spi};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embedded_hal::blocking::spi::Transfer;
|
||||
use example_common::*;
|
||||
|
||||
#[entry]
|
||||
|
@ -35,7 +34,7 @@ fn main() -> ! {
|
|||
loop {
|
||||
let mut buf = [0x0Au8; 4];
|
||||
cs.set_low();
|
||||
unwrap!(spi.transfer(&mut buf));
|
||||
unwrap!(spi.blocking_transfer_in_place(&mut buf));
|
||||
cs.set_high();
|
||||
info!("xfer {=[u8]:x}", buf);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use embassy::executor::Spawner;
|
|||
use embassy_stm32::spi::{Config, Spi};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::Peripherals;
|
||||
use embassy_traits::spi::FullDuplex;
|
||||
use example_common::*;
|
||||
use heapless::String;
|
||||
|
||||
|
@ -33,7 +32,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||
let mut write: String<128> = String::new();
|
||||
let mut read = [0; 128];
|
||||
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
|
||||
.ok();
|
||||
info!("read via spi+dma: {}", from_utf8(&read).unwrap());
|
||||
|
|
|
@ -10,7 +10,6 @@ use embassy::executor::Executor;
|
|||
use embassy::util::Forever;
|
||||
use embassy_stm32::dma::NoDma;
|
||||
use embassy_stm32::spi;
|
||||
use embedded_hal::blocking::spi::Transfer;
|
||||
use example_common::*;
|
||||
|
||||
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();
|
||||
core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
|
||||
unsafe {
|
||||
let result = spi.transfer(write.as_bytes_mut());
|
||||
let result = spi.blocking_transfer_in_place(write.as_bytes_mut());
|
||||
if let Err(_) = result {
|
||||
defmt::panic!("crap");
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use embassy_stm32::dma::NoDma;
|
|||
use embassy_stm32::spi::{Config, Spi};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::Peripherals;
|
||||
use embedded_hal::blocking::spi::Transfer;
|
||||
|
||||
#[embassy::main]
|
||||
async fn main(_spawner: Spawner, p: Peripherals) {
|
||||
|
@ -35,7 +34,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||
loop {
|
||||
let mut buf = [0x0Au8; 4];
|
||||
cs.set_low();
|
||||
unwrap!(spi.transfer(&mut buf));
|
||||
unwrap!(spi.blocking_transfer_in_place(&mut buf));
|
||||
cs.set_high();
|
||||
info!("xfer {=[u8]:x}", buf);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use embassy_stm32::dma::NoDma;
|
|||
use embassy_stm32::spi::{Config, Spi};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::Peripherals;
|
||||
use embedded_hal::blocking::spi::Transfer;
|
||||
|
||||
#[embassy::main]
|
||||
async fn main(_spawner: Spawner, p: Peripherals) {
|
||||
|
@ -35,7 +34,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||
loop {
|
||||
let mut buf = [0x0Au8; 4];
|
||||
cs.set_low();
|
||||
unwrap!(spi.transfer(&mut buf));
|
||||
unwrap!(spi.blocking_transfer_in_place(&mut buf));
|
||||
cs.set_high();
|
||||
info!("xfer {=[u8]:x}", buf);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use embassy_stm32::dma::NoDma;
|
|||
use embassy_stm32::gpio::{Level, Output, Speed};
|
||||
use embassy_stm32::spi::{Config, Spi};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embedded_hal::blocking::spi::Transfer;
|
||||
use example_common::*;
|
||||
|
||||
#[cortex_m_rt::entry]
|
||||
|
@ -34,7 +33,7 @@ fn main() -> ! {
|
|||
loop {
|
||||
let mut buf = [0x0Au8; 4];
|
||||
cs.set_low();
|
||||
unwrap!(spi.transfer(&mut buf));
|
||||
unwrap!(spi.blocking_transfer_in_place(&mut buf));
|
||||
cs.set_high();
|
||||
info!("xfer {=[u8]:x}", buf);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use embassy_stm32::dma::NoDma;
|
|||
use embassy_stm32::spi::{self, Spi};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::Peripherals;
|
||||
use embedded_hal::blocking::spi::Transfer;
|
||||
use example_common::*;
|
||||
|
||||
#[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.
|
||||
// so we should get the data we sent back.
|
||||
let mut buf = data;
|
||||
spi.transfer(&mut buf).unwrap();
|
||||
spi.blocking_transfer_in_place(&mut buf).unwrap();
|
||||
assert_eq!(buf, data);
|
||||
|
||||
info!("Test OK");
|
||||
|
|
Loading…
Reference in a new issue