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
52 extern "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  */
87 int 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  */
116 int 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  */
128 int 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  */
138 int 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  */
154 int 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  */
171 int 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  */
184 int 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  */
197 int 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_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_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_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_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.
int rc_spi_read(int bus, int slave, uint8_t *data, size_t bytes)
Reads data from a specified slave.