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_BUS_LOCKED, /* SPI bus is already locked */
84  SPI_DEV_STATUS_BUS_NOT_OWNED, /* SPI bus is locked by someone else */
85  SPI_DEV_STATUS_CLOSED /* SPI bus has not opened properly */
86 } spi_status_t;
87 /** @} */
88 /*---------------------------------------------------------------------------*/
89 /**
90  * \brief SPI Device Configuration
91  *
92  * This is a structure to an architecture-independent SPI configuration.
93  *
94  * @{
95  */
96 
97 typedef struct spi_device {
98  gpio_hal_pin_t pin_spi_sck; /* SPI SCK pin */
99  gpio_hal_pin_t pin_spi_miso; /* SPI MISO pin */
100  gpio_hal_pin_t pin_spi_mosi; /* SPI MOSI pin */
101  gpio_hal_pin_t pin_spi_cs; /* SPI Chip Select pin */
102  uint32_t spi_bit_rate; /* SPI bit rate */
103  uint8_t spi_pha; /* SPI mode phase */
104  uint8_t spi_pol; /* SPI mode polarity */
105  uint8_t spi_controller; /* ID of SPI controller to use */
106 } spi_device_t;
107 /** @} */
108 /*---------------------------------------------------------------------------*/
109 /* These are architecture-independent functions to be used by SPI devices. */
110 /*---------------------------------------------------------------------------*/
111 /**
112  * \brief Locks and then opens an SPI controller
113  * \param dev An SPI device configuration which defines the controller
114  * to be locked and the opening configuration.
115  * \return SPI return code
116  */
118 
119 /**
120  * \brief Closes and then unlocks an SPI controller
121  * \param dev An SPI device configuration which defines the controller
122  * to be closed and unlocked.
123  * \return SPI return code
124  *
125  * Releasing an SPI controller should put it in low-power mode.
126  * This should work only if the device has already locked the SPI
127  * controller.
128  */
130 
131 /**
132  * \brief Selects the SPI peripheral
133  * \param dev An SPI device configuration which defines the CS pin.
134  * \return SPI return code
135  *
136  * Clears the CS pin. This should work only if the device has
137  * already locked the SPI controller.
138  */
140 
141 /**
142  * \brief Deselects the SPI peripheral
143  * \param dev An SPI device configuration which defines the CS pin.
144  * \return SPI return code
145  *
146  * Sets the CS pin. Lock is not required.
147  */
149 
150 /**
151  * \brief Checks if a device has locked an SPI controller
152  * \param dev An SPI device configuration which defines the controller.
153  * \return true if the device has the lock, false otherwise.
154  */
155 bool spi_has_bus(spi_device_t *dev);
156 
157 /**
158  * \brief Writes a single byte to an SPI device
159  * \param dev An SPI device configuration.
160  * \param data A byte of data
161  * \return SPI return code
162  *
163  * It should work only if the device has already locked the SPI controller.
164  */
165 spi_status_t spi_write_byte(spi_device_t *dev, uint8_t data);
166 
167 /**
168  * \brief Reads a single byte from an SPI device
169  * \param dev An SPI device configuration.
170  * \param data A pointer to a byte of data
171  * \return SPI return code
172  *
173  * It should work only if the device has already locked the SPI controller.
174  */
175 spi_status_t spi_read_byte(spi_device_t *dev, uint8_t *data);
176 
177 /**
178  * \brief Writes a buffer to an SPI device
179  * \param dev An SPI device configuration.
180  * \param data A pointer to the data
181  * \param size Size of the data to write
182  * \return SPI return code
183  *
184  * It should work only if the device has already locked the SPI controller.
185  */
187  const uint8_t *data, int size);
188 
189 /**
190  * \brief Reads a buffer from an SPI device
191  * \param dev An SPI device configuration.
192  * \param data A pointer to the data
193  * \param size Size of the data to read
194  * \return SPI return code
195  *
196  * It should work only if the device has already locked the SPI controller.
197  */
198 spi_status_t spi_read(spi_device_t *dev, uint8_t *data, int size);
199 
200 /**
201  * \brief Reads and ignores data from an SPI device
202  * \param dev An SPI device configuration.
203  * \param size Size of the data to read and ignore
204  * \return SPI return code
205  *
206  * Reads size bytes from the SPI and throws them away.
207  * It should work only if the device has already locked the SPI controller.
208  */
209 spi_status_t spi_read_skip(spi_device_t *dev, int size);
210 
211 /**
212  * \brief Performs a generic SPI transfer
213  * \param dev An SPI device configuration.
214  * \param data A pointer to the data to be written. Set it to NULL to
215  * skip writing.
216  * \param wsize Size of data to write.
217  * \param buf A pointer to buffer to copy the data read. Set to NULL
218  * to skip reading.
219  * \param rsize Size of data to read.
220  * \param ignore Size of data to read and ignore.
221  * \return SPI return code
222  *
223  * It should work only if the device has already locked the SPI controller.
224  * A total of rlen+ignore_len bytes will be read. The first rlen bytes will
225  * be copied to buf. The remaining ignore_len bytes won't be copied to the
226  * buffer. The maximum of wlen and rlen+ignore_len of bytes will be transfered.
227  */
229  const uint8_t *data, int wsize,
230  uint8_t *buf, int rsize, int ignore);
231 
232 /**
233  * \brief Reads and Writes one byte from/to an SPI device
234  * \param dev An SPI device configuration.
235  * \param strobe Byte to write
236  * \param status Pointer to byte to read
237  * \return SPI return code
238  *
239  * It should work only if the device has already locked the SPI controller.
240  */
241 spi_status_t spi_strobe(spi_device_t *dev, uint8_t strobe,
242  uint8_t *status);
243 
244 /**
245  * \brief Reads a buffer of bytes from a register of an SPI device
246  * \param dev An SPI device configuration.
247  * \param reg Register
248  * \param data A pointer to the data
249  * \param size Size of the data to read
250  * \return SPI return code
251  *
252  * It should work only if the device has already locked the SPI controller.
253  */
255  uint8_t *data, int size);
256 
257 /*---------------------------------------------------------------------------*/
258 /* These are architecture-specific functions to be implemented by each CPU. */
259 /*---------------------------------------------------------------------------*/
260 
261 /**
262  * \brief Checks if a device has locked an SPI controller
263  * \param dev An SPI device configuration which defines the controller
264  * to be checked if it is locked and the respective device.
265  * \return 1 if the device has the lock, 0 otherwise.
266  *
267  */
269 
270 /**
271  * \brief Checks if an SPI controller is locked by any device
272  * \param dev An SPI device configuration which defines the controller
273  * to be checked.
274  * \return 1 if the controller is locked, 0 otherwise.
275  *
276  */
278 
279 /**
280  * \brief Locks and opens an SPI controller to the configuration specified.
281  * \param dev An SPI device configuration.
282  * \return SPI return code
283  *
284  * This should work only if the device has already locked the SPI
285  * controller.
286  *
287  */
289 
290 /**
291  * \brief Closes and unlocks an SPI controller
292  * \param dev An SPI device configuration that specifies the controller.
293  * \return SPI return code
294  *
295  * This should turn off the SPI controller to put it in low power mode
296  * and unlock it.
297  * It should work only if the device has already locked the SPI
298  * controller.
299  *
300  */
302 
303 /**
304  * \brief Performs an SPI transfer
305  * \param dev An SPI device configuration that specifies the controller.
306  * \param data A pointer to the data to be written. Set it to NULL to
307  * skip writing.
308  * \param wlen Length of data to write.
309  * \param buf A pointer to buffer to copy the data read. Set to NULL
310  * to skip reading.
311  * \param rlen Length of data to read.
312  * \param ignore_len Length of data to read and ignore.
313  * \return SPI return code
314  *
315  * It should work only if the device has already locked the SPI controller.
316  * A total of rlen+ignore_len bytes will be read. The first rlen bytes will
317  * be copied to buf. The remaining ignore_len bytes won't be copied to the
318  * buffer. The maximum of wlen and rlen+ignore_len of bytes will be transfered.
319  */
321  const uint8_t *data, int wlen,
322  uint8_t *buf, int rlen,
323  int ignore_len);
324 
325 /**
326  * \brief Selects an SPI device
327  * \param dev An SPI device configuration that specifies the CS pin.
328  * \return SPI return code
329  *
330  * Clears the CS pin. It should work only if the device has already
331  * locked the SPI controller.
332  */
334 
335 /**
336  * \brief Deselects an SPI device
337  * \param dev An SPI device configuration that specifies the CS pin.
338  * \return SPI return code
339  *
340  * Set the CS pin. Locking the SPI controller is not needed.
341  */
343 
344 #endif /* SPI_H_ */
345 /*---------------------------------------------------------------------------*/
346 /**
347  * @}
348  * @}
349  */
spi_status_t spi_arch_lock_and_open(spi_device_t *dev)
Locks and opens an SPI controller to the configuration specified.
Definition: spi-arch.c:171
struct spi_device spi_device_t
SPI Device Configuration.
bool spi_has_bus(spi_device_t *dev)
Checks if a device has locked an SPI controller.
Definition: spi.c:80
spi_status_t spi_read(spi_device_t *dev, uint8_t *buf, int size)
Reads a buffer from an SPI device.
Definition: spi.c:132
spi_status_t spi_write(spi_device_t *dev, const uint8_t *data, int size)
Writes a buffer to an SPI device.
Definition: spi.c:104
spi_status_t spi_read_register(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:184
bool spi_arch_has_lock(spi_device_t *dev)
Checks if a device has locked an SPI controller.
Definition: spi-arch.c:151
bool spi_arch_is_bus_locked(spi_device_t *dev)
Checks if an SPI controller is locked by any device.
Definition: spi-arch.c:161
spi_status_t
SPI return codes.
Definition: spi.h:80
spi_status_t spi_write_byte(spi_device_t *dev, uint8_t data)
Writes a single byte to an SPI device.
Definition: spi.c:90
spi_status_t spi_read_skip(spi_device_t *dev, int size)
Reads and ignores data from an SPI device.
Definition: spi.c:146
spi_status_t spi_strobe(spi_device_t *dev, uint8_t strobe, uint8_t *result)
Reads and Writes one byte from/to an SPI device.
Definition: spi.c:207
spi_status_t spi_deselect(spi_device_t *dev)
Deselects the SPI peripheral.
Definition: spi.c:74
spi_status_t spi_arch_deselect(spi_device_t *dev)
Deselects an SPI device.
Definition: spi-arch.c:298
spi_status_t spi_release(spi_device_t *dev)
Closes and then unlocks an SPI controller.
Definition: spi.c:57
uint8_t gpio_hal_pin_t
GPIO pin number representation.
Definition: gpio-hal.h:77
spi_status_t spi_acquire(spi_device_t *dev)
Locks and then opens an SPI controller.
Definition: spi.c:46
spi_status_t spi_arch_transfer(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:307
spi_status_t spi_select(spi_device_t *dev)
Selects the SPI peripheral.
Definition: spi.c:68
spi_status_t spi_transfer(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:160
SPI Device Configuration.
Definition: spi.h:97
spi_status_t spi_arch_select(spi_device_t *dev)
Selects an SPI device.
Definition: spi-arch.c:285
Header file for the GPIO HAL.
spi_status_t spi_read_byte(spi_device_t *dev, uint8_t *buf)
Reads a single byte from an SPI device.
Definition: spi.c:118
spi_status_t spi_arch_close_and_unlock(spi_device_t *dev)
Closes and unlocks an SPI controller.
Definition: spi-arch.c:268