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.

Parameters
  • app_data – A pointer to application specific data provided by the application. Used to share data between

  • out_buf – The buffer to send to the master

  • outbuf_len – The length in bytes of out_buf

  • in_buf – The buffer to receive into from the master

  • 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.

Parameters
  • app_data – A pointer to application specific data provided by the application. Used to share data between

  • out_buf – The buffer that had been provided to be sent to the master

  • bytes_written – The length in bytes of out_buf that had been written

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

  • bytes_read – The length in bytes of in_buf that has been read in to

  • 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.

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 – The spi_master_t context to de-initialize.

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.