blob: 3240ac90db4f6feef4f85011efdaaddcbb464181 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
use anyhow::Result;
use thiserror::Error;
/// Errors related to the SPI interface and SPI transactions.
#[derive(Error, Debug)]
pub enum SpiError {
#[error("Invalid word size: {0}")]
InvalidWordSize(u32),
#[error("Invalid speed: {0}")]
InvalidSpeed(u32),
}
/// Represents the SPI transfer mode.
/// See https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#Clock_polarity_and_phase
/// for details about SPI transfer modes.
#[derive(Debug, Clone, Copy)]
pub enum TransferMode {
/// `Mode0` is CPOL=0, CPHA=0.
Mode0,
/// `Mode1` is CPOL=0, CPHA=1.
Mode1,
/// `Mode2` is CPOL=1, CPHA=0.
Mode2,
/// `Mode3` is CPOL=1, CPHA=1.
Mode3,
}
#[derive(Debug, Clone, Copy)]
pub enum ClockPhase {
SampleLeading,
SampleTrailing,
}
#[derive(Debug, Clone, Copy)]
pub enum ClockPolarity {
IdleLow,
IdleHigh,
}
impl TransferMode {
pub fn phase(&self) -> ClockPhase {
match self {
TransferMode::Mode0 | TransferMode::Mode2 => ClockPhase::SampleLeading,
TransferMode::Mode1 | TransferMode::Mode3 => ClockPhase::SampleTrailing,
}
}
pub fn polarity(&self) -> ClockPolarity {
match self {
TransferMode::Mode0 | TransferMode::Mode1 => ClockPolarity::IdleLow,
TransferMode::Mode2 | TransferMode::Mode3 => ClockPolarity::IdleHigh,
}
}
}
/// Represents a SPI transfer.
pub enum Transfer<'rd, 'wr> {
Read(&'rd mut [u8]),
Write(&'wr [u8]),
Both(&'wr [u8], &'rd mut [u8]),
}
/// A trait which represents a SPI Target.
pub trait Target {
/// Gets the current SPI transfer mode.
fn get_transfer_mode(&self) -> Result<TransferMode>;
/// Sets the current SPI transfer mode.
fn set_transfer_mode(&mut self, mode: TransferMode) -> Result<()>;
/// Gets the current number of bits per word.
fn get_bits_per_word(&self) -> Result<u32>;
/// Sets the current number of bits per word.
fn set_bits_per_word(&mut self, bits_per_word: u32) -> Result<()>;
/// Gets the maximum allowed speed of the SPI bus.
fn get_max_speed(&self) -> Result<u32>;
/// Sets the maximum allowed speed of the SPI bus.
fn set_max_speed(&mut self, max_speed: u32) -> Result<()>;
/// Returns the maximum number of transfers allowed in a single transaction.
fn get_max_transfer_count(&self) -> usize;
/// Maximum chunksize handled by this SPI device.
fn max_chunk_size(&self) -> usize;
/// Runs a SPI transaction composed from the slice of [`Transfer`] objects.
fn run_transaction(&self, transaction: &mut [Transfer]) -> Result<()>;
}