SPI Master#

SPI Master Usage#

The following code snippet demonstrates the basic usage of an SPI master device.

#include <xs1.h>
#include <spi.h>

spi_master_t spi_ctx;
spi_master_device_t spi_dev;

port_t p_miso = XS1_PORT_1A;
port_t p_ss[1] = {XS1_PORT_1B};
port_t p_sclk = XS1_PORT_1C;
port_t p_mosi = XS1_PORT_1D;
xclock_t cb = XS1_CLKBLK_1;

uint8_t tx[4] = {0x01, 0x02, 0x04, 0x08};
uint8_t rx[4];

// Initialize the master device
spi_master_init(&spi_ctx, cb, p_ss[0], p_sclk, p_mosi, p_miso);
spi_master_device_init(&spi_dev, &spi_ctx,
     1,
     SPI_MODE_0,
     spi_master_source_clock_ref,
     0,
     spi_master_sample_delay_0,
     0, 0 ,0 ,0 );

// Transfer some data
spi_master_start_transaction(&spi_ctx);
spi_master_transfer(&spi_ctx, (uint8_t *)tx, (uint8_t *)rx, 4);
spi_master_end_transaction(&spi_ctx);

SPI Master API#

The following structures and functions are used to initialize and start an SPI master instance.

enum spi_master_sample_delay_t#

Enum type representing the different options for the SPI master sample delay.

Values:

enumerator spi_master_sample_delay_0#

Samples 1/2 clock cycle after output from device

enumerator spi_master_sample_delay_1#

Samples 3/4 clock cycle after output from device

enumerator spi_master_sample_delay_2#

Samples 1 clock cycle after output from device

enumerator spi_master_sample_delay_3#

Samples 1 and 1/4 clock cycle after output from device

enumerator spi_master_sample_delay_4#

Samples 1 and 1/2 clock cycle after output from device

enum spi_master_source_clock_t#

Enum type used to set which of the two clock sources SCLK is derived from.

Values:

enumerator spi_master_source_clock_ref#

SCLK is derived from the 100 MHz reference clock

enumerator spi_master_source_clock_xcore#

SCLK is derived from the core clock

typedef void (*slave_transaction_started_t)(void *app_data, uint8_t **out_buf, size_t *outbuf_len, uint8_t **in_buf, size_t *inbuf_len)#

Master has started a transaction

This callback function will be called when the SPI master has asserted this slave’s chip select.

The input and output buffer may be the same; however, partial byte/incomplete reads will result in out_buf bits being masked off due to a partial bit output.

Param app_data:

A pointer to application specific data provided by the application. Used to share data between

Param out_buf:

The buffer to send to the master

Param outbuf_len:

The length in bytes of out_buf

Param in_buf:

The buffer to receive into from the master

Param inbuf_len:

The length in bytes of in_buf

typedef void (*slave_transaction_ended_t)(void *app_data, uint8_t **out_buf, size_t bytes_written, uint8_t **in_buf, size_t bytes_read, size_t read_bits)#

Master has ended a transaction

This callback function will be called when the SPI master has de-asserted this slave’s chip select.

The value of bytes_read contains the number of full bytes that are in in_buf. When read_bits is greater than 0, the byte after the last full byte contains the partial bits read.

Param app_data:

A pointer to application specific data provided by the application. Used to share data between

Param out_buf:

The buffer that had been provided to be sent to the master

Param bytes_written:

The length in bytes of out_buf that had been written

Param in_buf:

The buffer that had been provided to be received into from the master

Param bytes_read:

The length in bytes of in_buf that has been read in to

Param read_bits:

The length in bits of in_buf

void spi_master_init(spi_master_t *spi, xclock_t clock_block, port_t cs_port, port_t sclk_port, port_t mosi_port, port_t miso_port)#

Initializes a SPI master I/O interface.

Note: To guarantee timing in all situations, the SPI I/O interface implicitly sets the fast mode and high priority status register bits for the duration of SPI operations. This may reduce the MIPS of other threads based on overall system setup.

Parameters:
  • spi – The spi_master_t context to initialize.

  • clock_block – The clock block to use for the SPI master interface.

  • cs_port – The SPI interface’s chip select port. This may be a multi-bit port.

  • sclk_port – The SPI interface’s SCLK port. Must be a 1-bit port.

  • mosi_port – The SPI interface’s MOSI port. Must be a 1-bit port.

  • miso_port – The SPI interface’s MISO port. Must be a 1-bit port.

void spi_master_device_init(spi_master_device_t *dev, spi_master_t *spi, uint32_t cs_pin, int cpol, int cpha, spi_master_source_clock_t source_clock, uint32_t clock_divisor, spi_master_sample_delay_t miso_sample_delay, uint32_t miso_pad_delay, uint32_t cs_to_clk_delay_ticks, uint32_t clk_to_cs_delay_ticks, uint32_t cs_to_cs_delay_ticks)#

Initialize a SPI device. Multiple SPI devices may be initialized per SPI interface. Each must be on a unique pin of the interface’s chip select port.

Parameters:
  • dev – The context representing the device to initialize.

  • spi – The context representing the SPI master interface that the device is connected to.

  • cs_pin – The bit number of the chip select port that is connected to the device’s chip select pin.

  • cpol – The clock polarity required by the device.

  • cpha – The clock phase required by the device.

  • source_clock – The source clock to derive SCLK from. See spi_master_source_clock_t.

  • clock_divisor – The value to divide the source clock by. The frequency of SCLK will be set to:

    • (F_src) / (4 * clock_divisor) when clock_divisor > 0

    • (F_src) / (2) when clock_divisor = 0 Where F_src is the frequency of the source clock.

  • miso_sample_delay – When to sample MISO. See spi_master_sample_delay_t.

  • miso_pad_delay – The number of core clock cycles to delay sampling the MISO pad during a transaction. This allows for more fine grained adjustment of sampling time. The value may be between 0 and 5.

  • cs_to_clk_delay_ticks – The minimum number of reference clock ticks between assertion of chip select and the first clock edge.

  • clk_to_cs_delay_ticks – The minimum number of reference clock ticks between the last clock edge and de-assertion of chip select.

  • cs_to_cs_delay_ticks – The minimum number of reference clock ticks between transactions, which is between de-assertion of chip select and the end of one transaction, and its re-assertion at the beginning of the next.

void spi_master_start_transaction(spi_master_device_t *dev)#

Starts a SPI transaction with the specified SPI device. This leaves chip select asserted.

Parameters:
  • dev – The SPI device with which to start a transaction.

void spi_master_transfer(spi_master_device_t *dev, uint8_t *data_out, uint8_t *data_in, size_t len)#

Transfers data to/from the specified SPI device. This may be called multiple times during a single transaction.

Parameters:
  • dev – The SPI device with which to transfer data.

  • data_out – Buffer containing the data to send to the device. May be NULL if no data needs to be sent.

  • data_in – Buffer to save the data received from the device. May be NULL if the data received is not needed.

  • len – The length in bytes of the data to transfer. Both buffers must be at least this large if not NULL.

inline void spi_master_delay_before_next_transfer(spi_master_device_t *dev, uint32_t delay_ticks)#

Enforces a minimum delay between the time this is called and the next transfer. It must be called during a transaction. It returns immediately.

Parameters:
  • dev – The active SPI device.

  • delay_ticks – The number of reference clock ticks to delay.

void spi_master_end_transaction(spi_master_device_t *dev)#

Ends a SPI transaction with the specified SPI device. This leaves chip select de-asserted.

Parameters:
  • dev – The SPI device with which to end a transaction.

void spi_master_deinit(spi_master_t *spi)#

De-initializes the specified SPI master interface. This disables the ports and clock block.

Parameters:
SPI_MODE_0#

Convenience macro that may be used to specify SPI Mode 0 to spi_master_device_init() or spi_slave() in place of cpol and cpha.

SPI_MODE_1#

Convenience macro that may be used to specify SPI Mode 1 to spi_master_device_init() or spi_slave() in place of cpol and cpha.

SPI_MODE_2#

Convenience macro that may be used to specify SPI Mode 2 to spi_master_device_init() or spi_slave() in place of cpol and cpha.

SPI_MODE_3#

Convenience macro that may be used to specify SPI Mode 3 to spi_master_device_init() or spi_slave() in place of cpol and cpha.

SPI_CALLBACK_ATTR#

This attribute must be specified on all SPI callback functions provided by the application.

struct spi_master_t#
#include <spi.h>

Struct to hold a SPI master context.

The members in this struct should not be accessed directly.

struct spi_master_device_t#
#include <spi.h>

Struct type representing a SPI device connected to a SPI master interface.

The members in this struct should not be accessed directly.