spi.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_SPI_H
8#define _HARDWARE_SPI_H
9
10#include "pico.h"
11#include "pico/time.h"
12#include "hardware/structs/spi.h"
13#include "hardware/regs/dreq.h"
14
15// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_SPI, Enable/disable assertions in the SPI module, type=bool, default=0, group=hardware_spi
16#ifndef PARAM_ASSERTIONS_ENABLED_SPI
17#define PARAM_ASSERTIONS_ENABLED_SPI 0
18#endif
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
39// PICO_CONFIG: PICO_DEFAULT_SPI, Define the default SPI for a board, min=0, max=1, group=hardware_spi
40// PICO_CONFIG: PICO_DEFAULT_SPI_SCK_PIN, Define the default SPI SCK pin, min=0, max=29, group=hardware_spi
41// PICO_CONFIG: PICO_DEFAULT_SPI_TX_PIN, Define the default SPI TX pin, min=0, max=29, group=hardware_spi
42// PICO_CONFIG: PICO_DEFAULT_SPI_RX_PIN, Define the default SPI RX pin, min=0, max=29, group=hardware_spi
43// PICO_CONFIG: PICO_DEFAULT_SPI_CSN_PIN, Define the default SPI CSN pin, min=0, max=29, group=hardware_spi
44
48typedef struct spi_inst spi_inst_t;
49
56#define spi0 ((spi_inst_t * const)spi0_hw)
57
64#define spi1 ((spi_inst_t * const)spi1_hw)
65
66#if !defined(PICO_DEFAULT_SPI_INSTANCE) && defined(PICO_DEFAULT_SPI)
67#define PICO_DEFAULT_SPI_INSTANCE (__CONCAT(spi,PICO_DEFAULT_SPI))
68#endif
69
70#ifdef PICO_DEFAULT_SPI_INSTANCE
71#define spi_default PICO_DEFAULT_SPI_INSTANCE
72#endif
73
77typedef enum {
78 SPI_CPHA_0 = 0,
79 SPI_CPHA_1 = 1
81
85typedef enum {
86 SPI_CPOL_0 = 0,
87 SPI_CPOL_1 = 1
89
93typedef enum {
94 SPI_LSB_FIRST = 0,
95 SPI_MSB_FIRST = 1
97
98// ----------------------------------------------------------------------------
99// Setup
100
113uint spi_init(spi_inst_t *spi, uint baudrate);
114
122void spi_deinit(spi_inst_t *spi);
123
134uint spi_set_baudrate(spi_inst_t *spi, uint baudrate);
135
144uint spi_get_baudrate(const spi_inst_t *spi);
145
152static inline uint spi_get_index(const spi_inst_t *spi) {
153 invalid_params_if(SPI, spi != spi0 && spi != spi1);
154 return spi == spi1 ? 1 : 0;
155}
156
157static inline spi_hw_t *spi_get_hw(spi_inst_t *spi) {
158 spi_get_index(spi); // check it is a hw spi
159 return (spi_hw_t *)spi;
160}
161
162static inline const spi_hw_t *spi_get_const_hw(const spi_inst_t *spi) {
163 spi_get_index(spi); // check it is a hw spi
164 return (const spi_hw_t *)spi;
165}
166
178static inline void spi_set_format(spi_inst_t *spi, uint data_bits, spi_cpol_t cpol, spi_cpha_t cpha, __unused spi_order_t order) {
179 invalid_params_if(SPI, data_bits < 4 || data_bits > 16);
180 // LSB-first not supported on PL022:
181 invalid_params_if(SPI, order != SPI_MSB_FIRST);
182 invalid_params_if(SPI, cpol != SPI_CPOL_0 && cpol != SPI_CPOL_1);
183 invalid_params_if(SPI, cpha != SPI_CPHA_0 && cpha != SPI_CPHA_1);
184 hw_write_masked(&spi_get_hw(spi)->cr0,
185 ((uint)(data_bits - 1)) << SPI_SSPCR0_DSS_LSB |
186 ((uint)cpol) << SPI_SSPCR0_SPO_LSB |
187 ((uint)cpha) << SPI_SSPCR0_SPH_LSB,
188 SPI_SSPCR0_DSS_BITS |
189 SPI_SSPCR0_SPO_BITS |
190 SPI_SSPCR0_SPH_BITS);
191}
192
202static inline void spi_set_slave(spi_inst_t *spi, bool slave) {
203 if (slave)
204 hw_set_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_MS_BITS);
205 else
206 hw_clear_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_MS_BITS);
207}
208
209// ----------------------------------------------------------------------------
210// Generic input/output
211
218static inline bool spi_is_writable(const spi_inst_t *spi) {
219 return (spi_get_const_hw(spi)->sr & SPI_SSPSR_TNF_BITS);
220}
221
228static inline bool spi_is_readable(const spi_inst_t *spi) {
229 return (spi_get_const_hw(spi)->sr & SPI_SSPSR_RNE_BITS);
230}
231
238static inline bool spi_is_busy(const spi_inst_t *spi) {
239 return (spi_get_const_hw(spi)->sr & SPI_SSPSR_BSY_BITS);
240}
241
254int spi_write_read_blocking(spi_inst_t *spi, const uint8_t *src, uint8_t *dst, size_t len);
255
267int spi_write_blocking(spi_inst_t *spi, const uint8_t *src, size_t len);
268
284int spi_read_blocking(spi_inst_t *spi, uint8_t repeated_tx_data, uint8_t *dst, size_t len);
285
286// ----------------------------------------------------------------------------
287// SPI-specific operations and aliases
288
289// FIXME need some instance-private data for select() and deselect() if we are going that route
290
305int spi_write16_read16_blocking(spi_inst_t *spi, const uint16_t *src, uint16_t *dst, size_t len);
306
320int spi_write16_blocking(spi_inst_t *spi, const uint16_t *src, size_t len);
321
339int spi_read16_blocking(spi_inst_t *spi, uint16_t repeated_tx_data, uint16_t *dst, size_t len);
340
347static inline uint spi_get_dreq(spi_inst_t *spi, bool is_tx) {
348 static_assert(DREQ_SPI0_RX == DREQ_SPI0_TX + 1, "");
349 static_assert(DREQ_SPI1_RX == DREQ_SPI1_TX + 1, "");
350 static_assert(DREQ_SPI1_TX == DREQ_SPI0_TX + 2, "");
351 return DREQ_SPI0_TX + spi_get_index(spi) * 2 + !is_tx;
352}
353
354#ifdef __cplusplus
355}
356#endif
357
358#endif
static __force_inline void hw_set_bits(io_rw_32 *addr, uint32_t mask)
Atomically set the specified bits to 1 in a HW register.
Definition: address_mapped.h:121
static __force_inline void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask)
Set new values for a sub-set of the bits in a HW register.
Definition: address_mapped.h:157
static __force_inline void hw_clear_bits(io_rw_32 *addr, uint32_t mask)
Atomically clear the specified bits to 0 in a HW register.
Definition: address_mapped.h:131
static bool spi_is_writable(const spi_inst_t *spi)
Check whether a write can be done on SPI device.
Definition: spi.h:218
static void spi_set_slave(spi_inst_t *spi, bool slave)
Set SPI master/slave.
Definition: spi.h:202
static void spi_set_format(spi_inst_t *spi, uint data_bits, spi_cpol_t cpol, spi_cpha_t cpha, __unused spi_order_t order)
Configure SPI.
Definition: spi.h:178
uint spi_init(spi_inst_t *spi, uint baudrate)
Initialise SPI instancesPuts the SPI into a known state, and enable it. Must be called before other f...
Definition: spi.c:21
static bool spi_is_readable(const spi_inst_t *spi)
Check whether a read can be done on SPI device.
Definition: spi.h:228
uint spi_set_baudrate(spi_inst_t *spi, uint baudrate)
Set SPI baudrate.
Definition: spi.c:41
#define spi1
Identifier for the second (SPI 1) hardware SPI instance (for use in SPI functions).
Definition: spi.h:64
int spi_read_blocking(spi_inst_t *spi, uint8_t repeated_tx_data, uint8_t *dst, size_t len)
Read from an SPI device.
Definition: spi.c:128
spi_cpol_t
Enumeration of SPI CPOL (clock polarity) values.
Definition: spi.h:85
int spi_write_blocking(spi_inst_t *spi, const uint8_t *src, size_t len)
Write to an SPI device, blocking.
Definition: spi.c:99
static bool spi_is_busy(const spi_inst_t *spi)
Check whether SPI is busy.
Definition: spi.h:238
static uint spi_get_dreq(spi_inst_t *spi, bool is_tx)
Return the DREQ to use for pacing transfers to/from a particular SPI instance.
Definition: spi.h:347
int spi_read16_blocking(spi_inst_t *spi, uint16_t repeated_tx_data, uint16_t *dst, size_t len)
Read from an SPI device.
Definition: spi.c:195
static uint spi_get_index(const spi_inst_t *spi)
Convert SPI instance to hardware instance number.
Definition: spi.h:152
spi_cpha_t
Enumeration of SPI CPHA (clock phase) values.
Definition: spi.h:77
#define spi0
Identifier for the first (SPI 0) hardware SPI instance (for use in SPI functions).
Definition: spi.h:56
uint spi_get_baudrate(const spi_inst_t *spi)
Get SPI baudrate.
Definition: spi.c:68
spi_order_t
Enumeration of SPI bit-order values.
Definition: spi.h:93
int spi_write_read_blocking(spi_inst_t *spi, const uint8_t *src, uint8_t *dst, size_t len)
Write/Read to/from an SPI device.
Definition: spi.c:76
int spi_write16_blocking(spi_inst_t *spi, const uint16_t *src, size_t len)
Write to an SPI device.
Definition: spi.c:170
int spi_write16_read16_blocking(spi_inst_t *spi, const uint16_t *src, uint16_t *dst, size_t len)
Write/Read half words to/from an SPI device.
Definition: spi.c:148
void spi_deinit(spi_inst_t *spi)
Deinitialise SPI instancesPuts the SPI into a disabled state. Init will need to be called to reenable...
Definition: spi.c:35
struct spi_inst spi_inst_t
Opaque type representing an SPI instance.
Definition: spi.h:48
Definition: spi.h:23