PX4 Firmware
PX4 Autopilot Software http://px4.io
SPI.hpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (C) 2019 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
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
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file SPI.hpp
36  *
37  * Base class for devices connected via SPI.
38  */
39 
40 #ifndef _DEVICE_SPI_H
41 #define _DEVICE_SPI_H
42 
43 #include "../CDev.hpp"
44 
45 #ifdef __PX4_LINUX
46 
47 #include <fcntl.h>
48 #include <unistd.h>
49 #include <sys/ioctl.h>
50 #include <linux/types.h>
51 #include <linux/spi/spidev.h>
52 
53 enum spi_mode_e {
54  SPIDEV_MODE0 = SPI_MODE_0, /* CPOL=0 CHPHA=0 */
55  SPIDEV_MODE1 = SPI_MODE_1, /* CPOL=0 CHPHA=1 */
56  SPIDEV_MODE2 = SPI_MODE_2, /* CPOL=1 CHPHA=0 */
57  SPIDEV_MODE3 = SPI_MODE_3 /* CPOL=1 CHPHA=1 */
58 };
59 
60 namespace device __EXPORT
61 {
62 
63 /**
64  * Abstract class for character device on SPI
65  */
66 class __EXPORT SPI : public CDev
67 {
68 public:
69  // no copy, assignment, move, move assignment
70  SPI(const SPI &) = delete;
71  SPI &operator=(const SPI &) = delete;
72  SPI(SPI &&) = delete;
73  SPI &operator=(SPI &&) = delete;
74 
75 protected:
76  /**
77  * Constructor
78  *
79  * @param name Driver name
80  * @param devname Device node name
81  * @param bus SPI bus on which the device lives
82  * @param device Device handle (used by SPI_SELECT)
83  * @param mode SPI clock/data mode
84  * @param frequency SPI clock frequency
85  */
86  SPI(const char *name, const char *devname, int bus, uint32_t device, enum spi_mode_e mode, uint32_t frequency);
87  virtual ~SPI();
88 
89  /**
90  * Locking modes supported by the driver.
91  */
92  enum LockMode {
93  LOCK_PREEMPTION, /**< the default; lock against all forms of preemption. */
94  LOCK_THREADS, /**< lock only against other threads, using SPI_LOCK */
95  LOCK_NONE /**< perform no locking, only safe if the bus is entirely private */
96  };
97 
98  virtual int init() override;
99 
100  /**
101  * Check for the presence of the device on the bus.
102  */
103  virtual int probe() { return PX4_OK; }
104 
105  /**
106  * Perform a SPI transfer.
107  *
108  * If called from interrupt context, this interface does not lock
109  * the bus and may interfere with non-interrupt-context callers.
110  *
111  * Clients in a mixed interrupt/non-interrupt configuration must
112  * ensure appropriate interlocking.
113  *
114  * At least one of send or recv must be non-null.
115  *
116  * @param send Bytes to send to the device, or nullptr if
117  * no data is to be sent.
118  * @param recv Buffer for receiving bytes from the device,
119  * or nullptr if no bytes are to be received.
120  * @param len Number of bytes to transfer.
121  * @return OK if the exchange was successful, -errno
122  * otherwise.
123  */
124  int transfer(uint8_t *send, uint8_t *recv, unsigned len);
125 
126  /**
127  * Perform a SPI 16 bit transfer.
128  *
129  * If called from interrupt context, this interface does not lock
130  * the bus and may interfere with non-interrupt-context callers.
131  *
132  * Clients in a mixed interrupt/non-interrupt configuration must
133  * ensure appropriate interlocking.
134  *
135  * At least one of send or recv must be non-null.
136  *
137  * @param send Words to send to the device, or nullptr if
138  * no data is to be sent.
139  * @param recv Words for receiving bytes from the device,
140  * or nullptr if no bytes are to be received.
141  * @param len Number of words to transfer.
142  * @return OK if the exchange was successful, -errno
143  * otherwise.
144  */
145  int transferhword(uint16_t *send, uint16_t *recv, unsigned len);
146 
147  /**
148  * Set the SPI bus frequency
149  * This is used to change frequency on the fly. Some sensors
150  * (such as the MPU6000) need a lower frequency for setup
151  * registers and can handle higher frequency for sensor
152  * value registers
153  *
154  * @param frequency Frequency to set (Hz)
155  */
156  void set_frequency(uint32_t frequency) { _frequency = frequency; }
157  uint32_t get_frequency() { return _frequency; }
158 
159  /**
160  * Set the SPI bus locking mode
161  *
162  * This set the SPI locking mode. For devices competing with NuttX SPI
163  * drivers on a bus the right lock mode is LOCK_THREADS.
164  *
165  * @param mode Locking mode
166  */
167  void set_lockmode(enum LockMode mode) { _locking_mode = mode; }
168 
169 private:
170  uint32_t _device;
171  enum spi_mode_e _mode;
172  uint32_t _frequency;
173  int _fd{-1};
174 
175  LockMode _locking_mode{LOCK_THREADS}; /**< selected locking mode */
176 
177 protected:
178  int _transfer(uint8_t *send, uint8_t *recv, unsigned len);
179 
180  int _transferhword(uint16_t *send, uint16_t *recv, unsigned len);
181 
182  virtual bool external() const override { return px4_spi_bus_external(get_device_bus()); }
183 
184 };
185 
186 } // namespace device
187 
188 #endif // __PX4_LINUX
189 
190 #endif /* _DEVICE_SPI_H */
spi_mode_e
Definition: SPI.hpp:46
void * send(void *data)
Definition: I2C.hpp:51
static Mode _mode
Definition: motor_ramp.cpp:81
Namespace encapsulating all device framework classes, functions and data.
Definition: CDev.cpp:47
void init()
Activates/configures the hardware registers.
static char _device[64]
const char * name
Definition: tests_main.c:58
mode
Definition: vtol_type.h:76