nrf: docs.
This commit is contained in:
@ -1,3 +1,5 @@
|
||||
//! Serial Peripheral Instance in slave mode (SPIS) driver.
|
||||
|
||||
#![macro_use]
|
||||
use core::future::poll_fn;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
@ -14,28 +16,43 @@ use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
/// SPIS error
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[non_exhaustive]
|
||||
pub enum Error {
|
||||
/// TX buffer was too long.
|
||||
TxBufferTooLong,
|
||||
/// RX buffer was too long.
|
||||
RxBufferTooLong,
|
||||
/// EasyDMA can only read from data memory, read only buffers in flash will fail.
|
||||
DMABufferNotInDataMemory,
|
||||
BufferNotInRAM,
|
||||
}
|
||||
|
||||
/// Interface for the SPIS peripheral using EasyDMA to offload the transmission and reception workload.
|
||||
///
|
||||
/// For more details about EasyDMA, consult the module documentation.
|
||||
/// SPIS driver.
|
||||
pub struct Spis<'d, T: Instance> {
|
||||
_p: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
/// SPIS configuration.
|
||||
#[non_exhaustive]
|
||||
pub struct Config {
|
||||
/// SPI mode
|
||||
pub mode: Mode,
|
||||
|
||||
/// Overread character.
|
||||
///
|
||||
/// If the master keeps clocking the bus after all the bytes in the TX buffer have
|
||||
/// already been transmitted, this byte will be constantly transmitted in the MISO line.
|
||||
pub orc: u8,
|
||||
|
||||
/// Default byte.
|
||||
///
|
||||
/// This is the byte clocked out in the MISO line for ignored transactions (if the master
|
||||
/// sets CSN low while the semaphore is owned by the firmware)
|
||||
pub def: u8,
|
||||
|
||||
/// Automatically make the firmware side acquire the semaphore on transfer end.
|
||||
pub auto_acquire: bool,
|
||||
}
|
||||
|
||||
@ -51,6 +68,7 @@ impl Default for Config {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Spis<'d, T> {
|
||||
/// Create a new SPIS driver.
|
||||
pub fn new(
|
||||
spis: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
@ -72,6 +90,7 @@ impl<'d, T: Instance> Spis<'d, T> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new SPIS driver, capable of TX only (MISO only).
|
||||
pub fn new_txonly(
|
||||
spis: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
@ -92,6 +111,7 @@ impl<'d, T: Instance> Spis<'d, T> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new SPIS driver, capable of RX only (MOSI only).
|
||||
pub fn new_rxonly(
|
||||
spis: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
@ -212,7 +232,7 @@ impl<'d, T: Instance> Spis<'d, T> {
|
||||
}
|
||||
|
||||
fn prepare(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
|
||||
slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?;
|
||||
slice_in_ram_or(tx, Error::BufferNotInRAM)?;
|
||||
// NOTE: RAM slice check for rx is not necessary, as a mutable
|
||||
// slice can only be built from data located in RAM.
|
||||
|
||||
@ -267,7 +287,7 @@ impl<'d, T: Instance> Spis<'d, T> {
|
||||
fn blocking_inner(&mut self, rx: &mut [u8], tx: &[u8]) -> Result<(usize, usize), Error> {
|
||||
match self.blocking_inner_from_ram(rx, tx) {
|
||||
Ok(n) => Ok(n),
|
||||
Err(Error::DMABufferNotInDataMemory) => {
|
||||
Err(Error::BufferNotInRAM) => {
|
||||
trace!("Copying SPIS tx buffer into RAM for DMA");
|
||||
let tx_ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..tx.len()];
|
||||
tx_ram_buf.copy_from_slice(tx);
|
||||
@ -330,7 +350,7 @@ impl<'d, T: Instance> Spis<'d, T> {
|
||||
async fn async_inner(&mut self, rx: &mut [u8], tx: &[u8]) -> Result<(usize, usize), Error> {
|
||||
match self.async_inner_from_ram(rx, tx).await {
|
||||
Ok(n) => Ok(n),
|
||||
Err(Error::DMABufferNotInDataMemory) => {
|
||||
Err(Error::BufferNotInRAM) => {
|
||||
trace!("Copying SPIS tx buffer into RAM for DMA");
|
||||
let tx_ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..tx.len()];
|
||||
tx_ram_buf.copy_from_slice(tx);
|
||||
@ -468,7 +488,9 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
/// SPIS peripheral instance
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
|
||||
/// Interrupt for this peripheral.
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user