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  */
80 typedef 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 */
87 } spi_status_t;
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 
100 typedef 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 */
115 } spi_device_t;
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  */
180 bool 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  */
190 spi_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  */
200 spi_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  */
223 spi_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  */
234 spi_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  */
266 spi_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  */
279 spi_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  */
293 bool 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  */
302 bool 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  */
bool spi_arch_has_lock(const spi_device_t *dev)
Checks if a device has locked an SPI controller.
Definition: spi-arch.c:151
struct spi_device spi_device_t
SPI Device Configuration.
spi_status_t spi_select(const spi_device_t *dev)
Selects the SPI peripheral.
Definition: spi.c:68
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_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_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_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
uint8_t gpio_hal_port_t
A data structure that represents ports.
Definition: gpio-hal.h:110
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
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
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_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
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_read_byte(const spi_device_t *dev, uint8_t *buf)
Reads a single byte from an SPI device.
Definition: spi.c:126
uint8_t gpio_hal_pin_t
GPIO pin number representation.
Definition: gpio-hal.h:103
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_acquire(const spi_device_t *dev)
Locks and then opens an SPI controller.
Definition: spi.c:46
spi_status_t spi_deselect(const spi_device_t *dev)
Deselects the SPI peripheral.
Definition: spi.c:80
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 Device Configuration.
Definition: spi.h:100
spi_status_t spi_release(const spi_device_t *dev)
Closes and then unlocks an SPI controller.
Definition: spi.c:57
Header file for the GPIO HAL.
spi_status_t spi_arch_close_and_unlock(const spi_device_t *dev)
Closes and unlocks an SPI controller.
Definition: spi-arch.c:268