Robot Control Library
spi.h
Go to the documentation of this file.
1/**
2 * <rc/spi.h>
3 *
4 * @brief General purpose C interface to the Linux SPI driver.
5 *
6 * It allows use of both dedicated hardware slave-select pins as well as GPIO
7 * pins for slave select. While this was developed on the BeagleBone platform,
8 * it should also work on Raspberry Pi and other embedded Linux systems.
9 *
10 * For the Robotics Cape and BeagleBone blue, the SPI bus 1 is broken out on two
11 * JST SH 6-pin sockets labeled SPI1.1 and SPI1.2 These share clock and serial
12 * IO signals, but have independent slave select lines so two devices can share
13 * the same bus. Note that these ports labeled for slaves 1 and 2 correspond to
14 * slaves 0 and 1 in software. To make source code more clear, the macros
15 * RC_BB_SPI1_SS1 and RC_BB_SPI1_SS2 are provided in this header which are
16 * defined as 1,0 and 1,1. the GPIO channels corresponding to these slave select
17 * pins are also provided as macros in this header.For example:
18 *
19 * ```C
20 * rc_spi_init_manual_slave(RC_BB_SPI1_SS1, SPI_MODE_0, \
21 * RC_SPI_MAX_SPEED, RC_BLUE_SS1_GPIO);
22 * ```
23 *
24 * pinout on Robotics Cape and BeagleBone Blue:
25 * 1. GND
26 * 2. 3.3V
27 * 3. MOSI (P9_30)
28 * 4. MISO (P9_29)
29 * 5. SCK (P9_31)
30 * 6. Slave Select
31 *
32 *
33 * The slaves can be selected automatically by the SPI Linux driver or manually
34 * with rc_spi_select() function. On the Robotics Cape, slave 1 can be used in
35 * either mode, but slave 2 must be selected manually. On the BB Blue either
36 * slave can be used in manual or automatic modes. Only initialize once with
37 * either mode.
38 *
39 * @author James Strawson
40 * @date 1/19/2018
41 *
42 * @addtogroup SPI
43 * @ingroup IO
44 * @{
45 */
46
47
48#ifndef RC_SPI_H
49#define RC_SPI_H
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55#include <stdint.h>
56#include <linux/spi/spidev.h> // for xfer and ioctl calls
57
58
59#define RC_SPI_MAX_SPEED 24000000 ///< 24mhz
60#define RC_SPI_MIN_SPEED 1000 ///< 1khz
61#define RC_SPI_BITS_PER_WORD 8 ///< only allow for 8-bit words
62
63
64#define RC_BB_SPI1_SS1 1,0 ///< bus and slave to use for Robotics Cape and BeagleBone Blue SPI1.1 port
65#define RC_BB_SPI1_SS2 1,1 ///< bus and slave to use for Robotics Cape and BeagleBone Blue SPI1.2 port
66
67#define RC_CAPE_SS1_GPIO 3,17 ///< Robotics Cape SPI1 SS1 gpio P9_28, normally AUTO mode
68#define RC_CAPE_SS2_GPIO 1,17 ///< Robotics Cape SPI1 SS2 gpio P9_23, normally MANUAL GPIO mode
69
70#define RC_BLUE_SS1_GPIO 0,29 ///< BeagleBone Blue SPI1 SS1 gpio 0_29 pin H18
71#define RC_BLUE_SS2_GPIO 0,7 ///< BeagleBone Blue SPI1 SS2 gpio 0_7 pin H18
72
73
74/**
75 * @brief Initializes an SPI bus
76 *
77 * For description of the 4 SPI modes, see
78 * <https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers>
79 *
80 * @param[in] bus The bus
81 * @param[in] slave The slave
82 * @param[in] bus_mode SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, or SPI_MODE_3
83 * @param[in] speed_hz The speed hz
84 *
85 * @return 0 on succcess or -1 on failure
86 */
87int rc_spi_init_auto_slave(int bus, int slave, int bus_mode, int speed_hz);
88
89
90/**
91 * @brief Initializes an SPI bus and GPIO pin for use as a manual SPI slave
92 * select pin.
93 *
94 * The provided gpio chip/pin will then be remembered and tied to the provided
95 * slave number and bus. Note that on the BeagleBone and probably other
96 * platforms, there are only two files provided by the driver for interfacing to
97 * the bus, /dev/spi1.0 and /dev/spi1.1. When using a slave in manual mode, the
98 * first interface (slave 0 in software) will be used to talk to the manual
99 * slaves. Therefore this slave can not be used as an automatic slave.
100 *
101 * For the BeagleBone Blue and RoboticsCape, this will also ensure that the
102 * pinmux is set correctly for that pin. The available manual slave select pins
103 * for these two boards are defined in this header for convenience. If using
104 * other boards it's up to the user to make sure the pin they are using is set
105 * up correctly in the device tree.
106 *
107 * @param[in] bus The spi bus
108 * @param[in] slave The slave identifier (up to 16)
109 * @param[in] bus_mode The bus mode
110 * @param[in] speed_hz The speed hz
111 * @param[in] chip The gpio chip
112 * @param[in] pin The gpio pin
113 *
114 * @return 0 on succcess or -1 on failure
115 */
116int rc_spi_init_manual_slave(int bus, int slave, int bus_mode, int speed_hz, int chip, int pin);
117
118
119/**
120 * @brief fetches the file descriptor for a specified slave so the user can
121 * do more advanced IO operations than what's presented here
122 *
123 * @param[in] bus The bus
124 * @param[in] slave 0 or 1
125 *
126 * @return fd or -1 on failure
127 */
128int rc_spi_get_fd(int bus, int slave);
129
130
131/**
132 * @brief Closes and cleans up the bus for specified slave
133 *
134 * @param[in] bus SPI bus to close
135 *
136 * @return 0 on succcess or -1 on failure
137 */
138int rc_spi_close(int bus);
139
140
141/**
142 * @brief Manually selects or deselects a slave
143 *
144 * Only works if slave was initialized with SPI_SLAVE_MODE_MANUAL. If
145 * SPI_SLAVE_MODE_AUTO was selected then the SPI driver will handle this
146 * automatically when reading or writing.
147 *
148 * @param[in] bus SPI bus to use
149 * @param[in] slave slave id
150 * @param[in] select 0 to deselect, otherwise selects
151 *
152 * @return 0 on succcess or -1 on failure
153 */
154int rc_spi_manual_select(int bus, int slave, int select);
155
156
157/**
158 * @brief Send any sequence of bytes and read the response.
159 *
160 * This is a wrapper for the ioctl spi transfer function and is generally what
161 * you will use for reading/writing device registers.
162 *
163 * @param[in] bus SPI bus to use
164 * @param[in] slave slave id
165 * @param[in] tx_data pointer to data to send
166 * @param[in] tx_bytes number of bytes to send
167 * @param rx_data pointer to put response data
168 *
169 * @return number of bytes received or -1 on failure
170 */
171int rc_spi_transfer(int bus, int slave, uint8_t* tx_data, size_t tx_bytes, uint8_t* rx_data);
172
173
174/**
175 * @brief Writes data to specified slave
176 *
177 * @param[in] bus SPI bus to use
178 * @param[in] slave slave id
179 * @param data data pointer
180 * @param[in] bytes number of bytes to send
181 *
182 * @return returns number of bytes written or -1 on failure
183 */
184int rc_spi_write(int bus, int slave, uint8_t* data, size_t bytes);
185
186
187/**
188 * @brief Reads data from a specified slave
189 *
190 * @param[in] bus SPI bus to use
191 * @param[in] slave slave id
192 * @param data data poitner
193 * @param[in] bytes number of bytes to read
194 *
195 * @return number of bytes read or -1 on failure
196 */
197int rc_spi_read(int bus, int slave, uint8_t* data, size_t bytes);
198
199
200#ifdef __cplusplus
201}
202#endif
203
204#endif // RC_SPI_H
205
206///@} end group SPI
207
int rc_spi_init_auto_slave(int bus, int slave, int bus_mode, int speed_hz)
Initializes an SPI bus.
int rc_spi_close(int bus)
Closes and cleans up the bus for specified slave.
int rc_spi_read(int bus, int slave, uint8_t *data, size_t bytes)
Reads data from a specified slave.
int rc_spi_init_manual_slave(int bus, int slave, int bus_mode, int speed_hz, int chip, int pin)
Initializes an SPI bus and GPIO pin for use as a manual SPI slave select pin.
int rc_spi_get_fd(int bus, int slave)
fetches the file descriptor for a specified slave so the user can do more advanced IO operations than...
int rc_spi_transfer(int bus, int slave, uint8_t *tx_data, size_t tx_bytes, uint8_t *rx_data)
Send any sequence of bytes and read the response.
int rc_spi_write(int bus, int slave, uint8_t *data, size_t bytes)
Writes data to specified slave.
int rc_spi_manual_select(int bus, int slave, int select)
Manually selects or deselects a slave.