Contiki-NG
spi.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016-2017, Yanzi Networks.
3 * Copyright (c) 2017, University of Bristol - http://www.bristol.ac.uk/
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the copyright holder nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31/*---------------------------------------------------------------------------*/
32/**
33 * \addtogroup dev
34 * @{
35 *
36 * \defgroup spi-hal SPI Hardware Abstraction Layer
37 *
38 * The SPI HAL provides a set of common functions that can be used in a
39 * platform-independent fashion.
40 *
41 *
42 * @{
43 *
44 * \file
45 * Header file for the SPI HAL
46 */
47/*---------------------------------------------------------------------------*/
48#ifndef SPI_H_
49#define SPI_H_
50/*---------------------------------------------------------------------------*/
51#include "contiki.h"
52#include "gpio-hal.h"
53
54#include <stdint.h>
55#include <stdbool.h>
56/*---------------------------------------------------------------------------*/
57/* Include Arch-Specific conf */
58#ifdef SPI_HAL_CONF_ARCH_HDR_PATH
59#include SPI_HAL_CONF_ARCH_HDR_PATH
60#endif /* SPI_HAL_CONF_ARCH_HDR_PATH */
61/*---------------------------------------------------------------------------*/
62#ifdef SPI_CONF_CONTROLLER_COUNT
63/**
64 * \brief Number of SPI module instances on a chip
65 */
66#define SPI_CONTROLLER_COUNT SPI_CONF_CONTROLLER_COUNT
67#else
68#define SPI_CONTROLLER_COUNT 0
69#endif
70/*---------------------------------------------------------------------------*/
71/* Convenience macros to enumerate SPI module instances on a chip */
72#define SPI_CONTROLLER_SPI0 0
73#define SPI_CONTROLLER_SPI1 1
74/*---------------------------------------------------------------------------*/
75/**
76 * \brief SPI return codes
77 *
78 * @{
79 */
80typedef enum {
81 SPI_DEV_STATUS_OK, /* Everything OK */
82 SPI_DEV_STATUS_EINVAL, /* Erroneous input value */
83 SPI_DEV_STATUS_TRANSFER_ERR, /* Error during SPI transfer */
84 SPI_DEV_STATUS_BUS_LOCKED, /* SPI bus is already locked */
85 SPI_DEV_STATUS_BUS_NOT_OWNED, /* SPI bus is locked by someone else */
86 SPI_DEV_STATUS_CLOSED /* SPI bus has not opened properly */
88/** @} */
89/*---------------------------------------------------------------------------*/
90/**
91 * \brief SPI Device Configuration
92 *
93 * This is a structure to an architecture-independent SPI configuration.
94 *
95 * \note Do not access the port_spi_foo members directly. Access them by using
96 * the SPI_DEVICE_PORT() macro instead
97 * @{
98 */
99
100typedef struct spi_device {
101#if GPIO_HAL_PORT_PIN_NUMBERING
102 gpio_hal_port_t port_spi_sck; /* SPI SCK port */
103 gpio_hal_port_t port_spi_miso; /* SPI MISO port */
104 gpio_hal_port_t port_spi_mosi; /* SPI MOSI port */
105 gpio_hal_port_t port_spi_cs; /* SPI Chip Select port */
106#endif
107 gpio_hal_pin_t pin_spi_sck; /* SPI SCK pin */
108 gpio_hal_pin_t pin_spi_miso; /* SPI MISO pin */
109 gpio_hal_pin_t pin_spi_mosi; /* SPI MOSI pin */
110 gpio_hal_pin_t pin_spi_cs; /* SPI Chip Select pin */
111 uint32_t spi_bit_rate; /* SPI bit rate */
112 uint8_t spi_pha; /* SPI mode phase */
113 uint8_t spi_pol; /* SPI mode polarity */
114 uint8_t spi_controller; /* ID of SPI controller to use */
116/** @} */
117/*---------------------------------------------------------------------------*/
118/**
119 * \brief Retrieve the SPI device's port number if applicable
120 * \param member Retrieve struct member port_spi_member (e.g. port_spi_miso)
121 * \param device A pointer the a variable of type spi_device_t
122 *
123 * The same macro is used for all four port_spi_foo members of the struct. So
124 * to retrieve port_spi_cs, use SPI_DEVICE_PORT(cs, device). Replace cs with
125 * mosi to retrieve port_spi_mosi.
126 *
127 */
128#if GPIO_HAL_PORT_PIN_NUMBERING
129#define SPI_DEVICE_PORT(member, device) (device)->port_spi_##member
130#else
131#define SPI_DEVICE_PORT(member, device) GPIO_HAL_NULL_PORT
132#endif
133/*---------------------------------------------------------------------------*/
134/* These are architecture-independent functions to be used by SPI devices. */
135/*---------------------------------------------------------------------------*/
136/**
137 * \brief Locks and then opens an SPI controller
138 * \param dev An SPI device configuration which defines the controller
139 * to be locked and the opening configuration.
140 * \return SPI return code
141 */
143
144/**
145 * \brief Closes and then unlocks an SPI controller
146 * \param dev An SPI device configuration which defines the controller
147 * to be closed and unlocked.
148 * \return SPI return code
149 *
150 * Releasing an SPI controller should put it in low-power mode.
151 * This should work only if the device has already locked the SPI
152 * controller.
153 */
155
156/**
157 * \brief Selects the SPI peripheral
158 * \param dev An SPI device configuration which defines the CS pin.
159 * \return SPI return code
160 *
161 * Clears the CS pin. This should work only if the device has
162 * already locked the SPI controller.
163 */
165
166/**
167 * \brief Deselects the SPI peripheral
168 * \param dev An SPI device configuration which defines the CS pin.
169 * \return SPI return code
170 *
171 * Sets the CS pin. Lock is not required.
172 */
174
175/**
176 * \brief Checks if a device has locked an SPI controller
177 * \param dev An SPI device configuration which defines the controller.
178 * \return true if the device has the lock, false otherwise.
179 */
180bool spi_has_bus(const spi_device_t *dev);
181
182/**
183 * \brief Writes a single byte to an SPI device
184 * \param dev An SPI device configuration.
185 * \param data A byte of data
186 * \return SPI return code
187 *
188 * It should work only if the device has already locked the SPI controller.
189 */
190spi_status_t spi_write_byte(const spi_device_t *dev, uint8_t data);
191
192/**
193 * \brief Reads a single byte from an SPI device
194 * \param dev An SPI device configuration.
195 * \param data A pointer to a byte of data
196 * \return SPI return code
197 *
198 * It should work only if the device has already locked the SPI controller.
199 */
200spi_status_t spi_read_byte(const spi_device_t *dev, uint8_t *data);
201
202/**
203 * \brief Writes a buffer to an SPI device
204 * \param dev An SPI device configuration.
205 * \param data A pointer to the data
206 * \param size Size of the data to write
207 * \return SPI return code
208 *
209 * It should work only if the device has already locked the SPI controller.
210 */
212 const uint8_t *data, int size);
213
214/**
215 * \brief Reads a buffer from an SPI device
216 * \param dev An SPI device configuration.
217 * \param data A pointer to the data
218 * \param size Size of the data to read
219 * \return SPI return code
220 *
221 * It should work only if the device has already locked the SPI controller.
222 */
223spi_status_t spi_read(const spi_device_t *dev, uint8_t *data, int size);
224
225/**
226 * \brief Reads and ignores data from an SPI device
227 * \param dev An SPI device configuration.
228 * \param size Size of the data to read and ignore
229 * \return SPI return code
230 *
231 * Reads size bytes from the SPI and throws them away.
232 * It should work only if the device has already locked the SPI controller.
233 */
234spi_status_t spi_read_skip(const spi_device_t *dev, int size);
235
236/**
237 * \brief Performs a generic SPI transfer
238 * \param dev An SPI device configuration.
239 * \param data A pointer to the data to be written. Set it to NULL to
240 * skip writing.
241 * \param wsize Size of data to write.
242 * \param buf A pointer to buffer to copy the data read. Set to NULL
243 * to skip reading.
244 * \param rsize Size of data to read.
245 * \param ignore Size of data to read and ignore.
246 * \return SPI return code
247 *
248 * It should work only if the device has already locked the SPI controller.
249 * A total of rlen+ignore_len bytes will be read. The first rlen bytes will
250 * be copied to buf. The remaining ignore_len bytes won't be copied to the
251 * buffer. The maximum of wlen and rlen+ignore_len of bytes will be transfered.
252 */
254 const uint8_t *data, int wsize,
255 uint8_t *buf, int rsize, int ignore);
256
257/**
258 * \brief Reads and Writes one byte from/to an SPI device
259 * \param dev An SPI device configuration.
260 * \param strobe Byte to write
261 * \param status Pointer to byte to read
262 * \return SPI return code
263 *
264 * It should work only if the device has already locked the SPI controller.
265 */
266spi_status_t spi_strobe(const spi_device_t *dev, uint8_t strobe,
267 uint8_t *status);
268
269/**
270 * \brief Reads a buffer of bytes from a register of an SPI device
271 * \param dev An SPI device configuration.
272 * \param reg Register
273 * \param data A pointer to the data
274 * \param size Size of the data to read
275 * \return SPI return code
276 *
277 * It should work only if the device has already locked the SPI controller.
278 */
279spi_status_t spi_read_register(const spi_device_t *dev, uint8_t reg,
280 uint8_t *data, int size);
281
282/*---------------------------------------------------------------------------*/
283/* These are architecture-specific functions to be implemented by each CPU. */
284/*---------------------------------------------------------------------------*/
285
286/**
287 * \brief Checks if a device has locked an SPI controller
288 * \param dev An SPI device configuration which defines the controller
289 * to be checked if it is locked and the respective device.
290 * \return 1 if the device has the lock, 0 otherwise.
291 *
292 */
293bool spi_arch_has_lock(const spi_device_t *dev);
294
295/**
296 * \brief Checks if an SPI controller is locked by any device
297 * \param dev An SPI device configuration which defines the controller
298 * to be checked.
299 * \return 1 if the controller is locked, 0 otherwise.
300 *
301 */
302bool spi_arch_is_bus_locked(const spi_device_t *dev);
303
304/**
305 * \brief Locks and opens an SPI controller to the configuration specified.
306 * \param dev An SPI device configuration.
307 * \return SPI return code
308 *
309 * This should work only if the device has already locked the SPI
310 * controller.
311 *
312 */
314
315/**
316 * \brief Closes and unlocks an SPI controller
317 * \param dev An SPI device configuration that specifies the controller.
318 * \return SPI return code
319 *
320 * This should turn off the SPI controller to put it in low power mode
321 * and unlock it.
322 * It should work only if the device has already locked the SPI
323 * controller.
324 *
325 */
327
328/**
329 * \brief Performs an SPI transfer
330 * \param dev An SPI device configuration that specifies the controller.
331 * \param data A pointer to the data to be written. Set it to NULL to
332 * skip writing.
333 * \param wlen Length of data to write.
334 * \param buf A pointer to buffer to copy the data read. Set to NULL
335 * to skip reading.
336 * \param rlen Length of data to read.
337 * \param ignore_len Length of data to read and ignore.
338 * \return SPI return code
339 *
340 * It should work only if the device has already locked the SPI controller.
341 * A total of rlen+ignore_len bytes will be read. The first rlen bytes will
342 * be copied to buf. The remaining ignore_len bytes won't be copied to the
343 * buffer. The maximum of wlen and rlen+ignore_len of bytes will be transfered.
344 */
346 const uint8_t *data, int wlen,
347 uint8_t *buf, int rlen,
348 int ignore_len);
349
350#endif /* SPI_H_ */
351/*---------------------------------------------------------------------------*/
352/**
353 * @}
354 * @}
355 */
Header file for the GPIO HAL.
uint8_t gpio_hal_port_t
A data structure that represents ports.
Definition: gpio-hal.h:110
uint8_t gpio_hal_pin_t
GPIO pin number representation.
Definition: gpio-hal.h:103
spi_status_t spi_read_byte(const spi_device_t *dev, uint8_t *buf)
Reads a single byte from an SPI device.
Definition: spi.c:126
struct spi_device spi_device_t
SPI Device Configuration.
spi_status_t spi_transfer(const spi_device_t *dev, const uint8_t *wdata, int wsize, uint8_t *rbuf, int rsize, int ignore)
Performs a generic SPI transfer.
Definition: spi.c:168
spi_status_t spi_release(const spi_device_t *dev)
Closes and then unlocks an SPI controller.
Definition: spi.c:57
spi_status_t spi_arch_close_and_unlock(const spi_device_t *dev)
Closes and unlocks an SPI controller.
Definition: spi-arch.c:268
spi_status_t spi_read(const spi_device_t *dev, uint8_t *buf, int size)
Reads a buffer from an SPI device.
Definition: spi.c:140
spi_status_t spi_arch_transfer(const spi_device_t *dev, const uint8_t *data, int wlen, uint8_t *buf, int rlen, int ignore_len)
Performs an SPI transfer.
Definition: spi-arch.c:286
spi_status_t
SPI return codes.
Definition: spi.h:80
spi_status_t spi_arch_lock_and_open(const spi_device_t *dev)
Locks and opens an SPI controller to the configuration specified.
Definition: spi-arch.c:171
bool spi_has_bus(const spi_device_t *dev)
Checks if a device has locked an SPI controller.
Definition: spi.c:88
spi_status_t spi_deselect(const spi_device_t *dev)
Deselects the SPI peripheral.
Definition: spi.c:80
bool spi_arch_has_lock(const spi_device_t *dev)
Checks if a device has locked an SPI controller.
Definition: spi-arch.c:151
spi_status_t spi_read_skip(const spi_device_t *dev, int size)
Reads and ignores data from an SPI device.
Definition: spi.c:154
bool spi_arch_is_bus_locked(const spi_device_t *dev)
Checks if an SPI controller is locked by any device.
Definition: spi-arch.c:161
spi_status_t spi_acquire(const spi_device_t *dev)
Locks and then opens an SPI controller.
Definition: spi.c:46
spi_status_t spi_write_byte(const spi_device_t *dev, uint8_t data)
Writes a single byte to an SPI device.
Definition: spi.c:98
spi_status_t spi_read_register(const spi_device_t *dev, uint8_t reg, uint8_t *data, int size)
Reads a buffer of bytes from a register of an SPI device.
Definition: spi.c:192
spi_status_t spi_write(const spi_device_t *dev, const uint8_t *data, int size)
Writes a buffer to an SPI device.
Definition: spi.c:112
spi_status_t spi_strobe(const spi_device_t *dev, uint8_t strobe, uint8_t *result)
Reads and Writes one byte from/to an SPI device.
Definition: spi.c:215
spi_status_t spi_select(const spi_device_t *dev)
Selects the SPI peripheral.
Definition: spi.c:68
SPI Device Configuration.
Definition: spi.h:100