Soft SPI

Software implemented Serial Peripheral Interface bus This module provides a software implemented Serial Peripheral Interface bus. More...

Detailed Description

Software implemented Serial Peripheral Interface bus This module provides a software implemented Serial Peripheral Interface bus.

It is intended to be used in situation where hardware spi is not available. The signatures of the functions are similar to the functions declared in spi.h The clock speed is approximated by using xtimer_nanosleep. Currently only the use of MOSI in master mode is implemented. Therefore receiving data from a slave is currently not possible.

Files

file  soft_spi.h
 Software SPI port descriptor definition.
 

Data Structures

struct  soft_spi_conf_t
 Software SPI port descriptor. More...
 

Macros

#define SOFT_SPI_DEV(x)   (x)
 Default SPI device access macro.
 
#define SOFT_SPI_UNDEF   (UINT_MAX)
 Define global value for undefined SPI device.
 
#define SOFT_SPI_CS_UNDEF   (GPIO_UNDEF)
 Define value for unused CS line.
 

Typedefs

typedef unsigned int soft_spi_t
 Default type for SPI devices.
 
typedef gpio_t soft_spi_cs_t
 Chip select pin type overlaps with gpio_t so it can be casted to this.
 

Enumerations

enum  {
  SOFT_SPI_OK = 0, SOFT_SPI_NODEV = -1, SOFT_SPI_NOCS = -2, SOFT_SPI_NOMODE = -3,
  SOFT_SPI_NOCLK = -4
}
 Status codes used by the SPI driver interface. More...
 
enum  soft_spi_mode_t { SOFT_SPI_MODE_0 = 0, SOFT_SPI_MODE_1, SOFT_SPI_MODE_2, SOFT_SPI_MODE_3 }
 Available SPI modes, defining the configuration of clock polarity and clock phase. More...
 
enum  soft_spi_clk_t { SOFT_SPI_CLK_100KHZ = 5000, SOFT_SPI_CLK_400KHZ = 1250, SOFT_SPI_CLK_DEFAULT = 0 }
 Available SPI clock speeds. More...
 

Functions

void soft_spi_init (soft_spi_t bus)
 Basic initialization of the given SPI bus. More...
 
void soft_spi_init_pins (soft_spi_t bus)
 Initialize the used SPI bus pins, i.e. More...
 
int soft_spi_init_cs (soft_spi_t bus, soft_spi_cs_t cs)
 Initialize the given chip select pin. More...
 
int soft_spi_acquire (soft_spi_t bus, soft_spi_cs_t cs, soft_spi_mode_t mode, soft_spi_clk_t clk)
 Start a new SPI transaction. More...
 
void soft_spi_release (soft_spi_t bus)
 Finish an ongoing SPI transaction by releasing the given SPI bus. More...
 
uint8_t soft_spi_transfer_byte (soft_spi_t bus, soft_spi_cs_t cs, bool cont, uint8_t out)
 Transfer one byte on the given SPI bus Currently only the use of MOSI in master mode is implemented. More...
 
void soft_spi_transfer_bytes (soft_spi_t bus, soft_spi_cs_t cs, bool cont, const void *out, void *in, size_t len)
 Transfer a number bytes using the given SPI bus. More...
 
uint8_t soft_spi_transfer_reg (soft_spi_t bus, soft_spi_cs_t cs, uint8_t reg, uint8_t out)
 Transfer one byte to/from a given register address. More...
 
void soft_spi_transfer_regs (soft_spi_t bus, soft_spi_cs_t cs, uint8_t reg, const void *out, void *in, size_t len)
 Transfer a number of bytes to/from a given register address. More...
 

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Status codes used by the SPI driver interface.

Enumerator
SOFT_SPI_OK 

everything went as planned

SOFT_SPI_NODEV 

invalid SPI bus specified

SOFT_SPI_NOCS 

invalid chip select line specified

SOFT_SPI_NOMODE 

selected mode is not supported

SOFT_SPI_NOCLK 

selected clock value is not supported

Definition at line 73 of file soft_spi.h.

◆ soft_spi_clk_t

Available SPI clock speeds.

The actual speed of the bus varies between CPUs and depends on the speed of the processing. The values of the enum entries represent the approximate delay between two clock edges.

Enumerator
SOFT_SPI_CLK_100KHZ 

drive the SPI bus with less than 100kHz

SOFT_SPI_CLK_400KHZ 

drive the SPI bus with less than 400kHz

SOFT_SPI_CLK_DEFAULT 

drive the SPI bus with maximum speed possible

Definition at line 111 of file soft_spi.h.

◆ soft_spi_mode_t

Available SPI modes, defining the configuration of clock polarity and clock phase.

RIOT is using the mode numbers as commonly defined by most vendors (https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers):

  • MODE_0: CPOL=0, CPHA=0 - The first data bit is sampled by the receiver on the first SCK rising SCK edge (this mode is used most often).
  • MODE_1: CPOL=0, CPHA=1 - The first data bit is sampled by the receiver on the second rising SCK edge.
  • MODE_2: CPOL=1, CPHA=0 - The first data bit is sampled by the receiver on the first falling SCK edge.
  • MODE_3: CPOL=1, CPHA=1 - The first data bit is sampled by the receiver on the second falling SCK edge.
Enumerator
SOFT_SPI_MODE_0 

CPOL=0, CPHA=0.

SOFT_SPI_MODE_1 

CPOL=0, CPHA=1.

SOFT_SPI_MODE_2 

CPOL=1, CPHA=0.

SOFT_SPI_MODE_3 

CPOL=1, CPHA=1.

Definition at line 97 of file soft_spi.h.

Function Documentation

◆ soft_spi_acquire()

int soft_spi_acquire ( soft_spi_t  bus,
soft_spi_cs_t  cs,
soft_spi_mode_t  mode,
soft_spi_clk_t  clk 
)

Start a new SPI transaction.

Starting a new SPI transaction will get exclusive access to the SPI bus and configure it according to the given values. If another SPI transaction is active when this function is called, this function will block until the other transaction is complete (soft_spi_relase was called).

Note
This function expects the bus and the cs parameters to be valid (they are checked in soft_spi_init and soft_spi_init_cs before)
Parameters
[in]busSPI device to access
[in]cschip select pin/line to use
[in]modemode to use for the new transaction
[in]clkbus clock speed to use for the transaction
Returns
SOFT_SPI_OK on success
SOFT_SPI_NOMODE if given mode is not supported
SOFT_SPI_NOCLK if given clock speed is not supported

◆ soft_spi_init()

void soft_spi_init ( soft_spi_t  bus)

Basic initialization of the given SPI bus.

This function does the basic initialization including pin configuration for MISO, MOSI, and CLK pins.

Errors (e.g. invalid bus parameter) are not signaled through a return value, but should be signaled using the assert() function internally.

Note
This function MUST not be called more than once per bus!
Parameters
[in]busSPI device to initialize

◆ soft_spi_init_cs()

int soft_spi_init_cs ( soft_spi_t  bus,
soft_spi_cs_t  cs 
)

Initialize the given chip select pin.

The chip select must be any generic GPIO pin (e.g. GPIO_PIN(x,y)). It must be called once before the use of the chip select pin in transaction.

Parameters
[in]busSPI device that is used with the given CS line
[in]cschip select pin to initialize
Returns
SOFT_SPI_OK on success
SOFT_SPI_NODEV on invalid device
SOFT_SPI_NOCS on invalid CS pin/line

◆ soft_spi_init_pins()

void soft_spi_init_pins ( soft_spi_t  bus)

Initialize the used SPI bus pins, i.e.

MISO, MOSI, and CLK

After calling soft_spi_init, the pins must be initialized. In normal cases, this function will not be used.

The pins used are configured in the board's periph_conf.h.

Parameters
[in]busSPI device the pins are configure for

◆ soft_spi_release()

void soft_spi_release ( soft_spi_t  bus)

Finish an ongoing SPI transaction by releasing the given SPI bus.

After release, the given SPI bus should be fully powered down until acquired again.

Parameters
[in]busSPI device to release

◆ soft_spi_transfer_byte()

uint8_t soft_spi_transfer_byte ( soft_spi_t  bus,
soft_spi_cs_t  cs,
bool  cont,
uint8_t  out 
)

Transfer one byte on the given SPI bus Currently only the use of MOSI in master mode is implemented.

Therefore receiving data from a slave is currently not possible.

Parameters
[in]busSPI device to use
[in]cschip select pin/line to use
[in]contif true, keep device selected after transfer
[in]outbyte to send out, set NULL if only receiving
Returns
the received byte

◆ soft_spi_transfer_bytes()

void soft_spi_transfer_bytes ( soft_spi_t  bus,
soft_spi_cs_t  cs,
bool  cont,
const void *  out,
void *  in,
size_t  len 
)

Transfer a number bytes using the given SPI bus.

Parameters
[in]busSPI device to use
[in]cschip select pin/line to use
[in]contif true, keep device selected after transfer
[in]outbuffer to send data from, set NULL if only receiving
[out]inbuffer to read into, set NULL if only sending
[in]lennumber of bytes to transfer

◆ soft_spi_transfer_reg()

uint8_t soft_spi_transfer_reg ( soft_spi_t  bus,
soft_spi_cs_t  cs,
uint8_t  reg,
uint8_t  out 
)

Transfer one byte to/from a given register address.

This function is a shortcut function for easier handling of SPI devices that implement a register based access scheme.

Parameters
[in]busSPI device to use
[in]cschip select pin/line to use
[in]regregister address to transfer data to/from
[in]outbyte to send, set NULL if only receiving data
Returns
value that was read from the given register address

◆ soft_spi_transfer_regs()

void soft_spi_transfer_regs ( soft_spi_t  bus,
soft_spi_cs_t  cs,
uint8_t  reg,
const void *  out,
void *  in,
size_t  len 
)

Transfer a number of bytes to/from a given register address.

This function is a shortcut function for easier handling of SPI devices that implement a register based access scheme.

Parameters
[in]busSPI device to use
[in]cschip select pin/line to use
[in]regregister address to transfer data to/from
[in]outbuffer to send data from, set NULL if only receiving
[out]inbuffer to read into, set NULL if only sending
[in]lennumber of bytes to transfer