XCORE SDK
XCORE Software Development Kit
spi.h
Go to the documentation of this file.
1 // Copyright 2021 XMOS LIMITED.
2 // This Software is subject to the terms of the XMOS Public Licence: Version 1.
3 #pragma once
4 
13 #define SPI_MASTER_MINIMUM_DELAY 10
14 
15 #include <stdlib.h> /* for size_t */
16 #include <stdint.h>
17 #include <xclib.h> /* for byterev() */
18 #include <xcore/assert.h>
19 #include <xcore/port.h>
20 #include <xcore/clock.h>
21 
22 /* The SETC constant for pad delay is missing from xs2a_user.h */
23 #define SPI_IO_SETC_PAD_DELAY(n) (0x7007 | ((n) << 3))
24 
25 /* These appear to be missing from the public API of lib_xcore */
26 #define SPI_IO_RESOURCE_SETCI(res, c) asm volatile( "setc res[%0], %1" :: "r" (res), "n" (c))
27 #define SPI_IO_RESOURCE_SETC(res, r) asm volatile( "setc res[%0], %1" :: "r" (res), "r" (r))
28 #define SPI_IO_SETSR(c) asm volatile("setsr %0" : : "n"(c));
29 #define SPI_IO_CLRSR(c) asm volatile("clrsr %0" : : "n"(c));
30 
31 /* is setpsc available in lib_xcore or anywhere else..??? */
32 __attribute__((always_inline))
33 inline void spi_io_port_outpw(
34  resource_t __p,
35  uint32_t __w,
36  uint32_t __bpw)
37 {
38  asm volatile("outpw res[%0], %1, %2" : : "r" (__p), "r" (__w), "r" (__bpw));
39 }
40 
52 typedef enum {
59 
63 typedef enum {
67 
72 #define SPI_MODE_0 0,0
73 
78 #define SPI_MODE_1 0,1
79 
84 #define SPI_MODE_2 1,0
85 
90 #define SPI_MODE_3 1,1
91 
97 typedef struct {
98  xclock_t clock_block;
99  port_t cs_port;
100  port_t sclk_port;
101  port_t mosi_port;
102  port_t miso_port;
103  uint32_t current_device;
104  int delay_before_transfer;
105 } spi_master_t;
106 
113 typedef struct {
114  spi_master_t *spi_master_ctx;
115  spi_master_source_clock_t source_clock;
116  int clock_divisor;
117  spi_master_sample_delay_t miso_sample_delay;
118  uint32_t miso_pad_delay;
119  uint32_t miso_initial_trigger_delay;
120  uint32_t cs_assert_val;
121  uint32_t clock_delay;
122  uint32_t clock_bits;
123  uint32_t cs_to_clk_delay_ticks;
124  uint32_t clk_to_cs_delay_ticks;
125  uint32_t cs_to_cs_delay_ticks;
127 
139  spi_master_t *spi,
140  xclock_t clock_block,
141  port_t cs_port,
142  port_t sclk_port,
143  port_t mosi_port,
144  port_t miso_port);
145 
174  spi_master_device_t *dev,
175  spi_master_t *spi,
176  uint32_t cs_pin,
177  int cpol,
178  int cpha,
179  spi_master_source_clock_t source_clock,
180  uint32_t clock_divisor,
181  spi_master_sample_delay_t miso_sample_delay,
182  uint32_t miso_pad_delay,
183  uint32_t cs_to_clk_delay_ticks,
184  uint32_t clk_to_cs_delay_ticks,
185  uint32_t cs_to_cs_delay_ticks);
186 
193  spi_master_device_t *dev);
194 
208  spi_master_device_t *dev,
209  uint8_t *data_out,
210  uint8_t *data_in,
211  size_t len);
212 
222  spi_master_device_t *dev,
223  uint32_t delay_ticks)
224 {
225  spi_master_t *spi = dev->spi_master_ctx;
226 
227  spi->delay_before_transfer = 1;
228 
229  port_clear_trigger_time(spi->cs_port);
230 
231  /* Assert CS now */
232  port_out(spi->cs_port, dev->cs_assert_val);
233  port_sync(spi->cs_port);
234 
235  /*
236  * Assert CS again, scheduled for earliest time the
237  * next transfer is allowed to start.
238  */
239  if (delay_ticks >= SPI_MASTER_MINIMUM_DELAY) {
240  port_out_at_time(spi->cs_port, port_get_trigger_time(spi->cs_port) + delay_ticks, dev->cs_assert_val);
241  }
242 }
243 
250  spi_master_device_t *dev);
251 
259  spi_master_t *spi);
260 
277 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);
278 
297 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);
298 
303 #define SPI_CALLBACK_ATTR __attribute__((fptrgroup("spi_callback")))
304  // END: addtogroup hil_spi_master
306 
319 typedef struct {
322 
328 
330  void *app_data;
332 
350  const spi_slave_callback_group_t *spi_cbg,
351  port_t p_sclk,
352  port_t p_mosi,
353  port_t p_miso,
354  port_t p_cs,
355  xclock_t clk,
356  int cpol,
357  int cpha);
358  // END: addtogroup hil_spi_slave
void spi_master_deinit(spi_master_t *spi)
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)
Definition: spi.h:297
void spi_master_transfer(spi_master_device_t *dev, uint8_t *data_out, uint8_t *data_in, size_t len)
void spi_master_delay_before_next_transfer(spi_master_device_t *dev, uint32_t delay_ticks)
Definition: spi.h:221
void spi_master_end_transaction(spi_master_device_t *dev)
void spi_master_start_transaction(spi_master_device_t *dev)
#define SPI_CALLBACK_ATTR
Definition: spi.h:303
spi_master_source_clock_t
Definition: spi.h:63
spi_master_sample_delay_t
Definition: spi.h:52
void(* slave_transaction_started_t)(void *app_data, uint8_t **out_buf, size_t *outbuf_len, uint8_t **in_buf, size_t *inbuf_len)
Definition: spi.h:277
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)
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)
@ spi_master_source_clock_ref
Definition: spi.h:64
@ spi_master_source_clock_xcore
Definition: spi.h:65
@ spi_master_sample_delay_0
Definition: spi.h:53
@ spi_master_sample_delay_1
Definition: spi.h:54
@ spi_master_sample_delay_3
Definition: spi.h:56
@ spi_master_sample_delay_2
Definition: spi.h:55
@ spi_master_sample_delay_4
Definition: spi.h:57
void spi_slave(const spi_slave_callback_group_t *spi_cbg, port_t p_sclk, port_t p_mosi, port_t p_miso, port_t p_cs, xclock_t clk, int cpol, int cpha)
#define SPI_MASTER_MINIMUM_DELAY
Definition: spi.h:13
Definition: spi.h:113
Definition: spi.h:97
Definition: spi.h:319
void * app_data
Definition: spi.h:330
SPI_CALLBACK_ATTR slave_transaction_ended_t slave_transaction_ended
Definition: spi.h:327
SPI_CALLBACK_ATTR slave_transaction_started_t slave_transaction_started
Definition: spi.h:321