Firmware
Device.hpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2012-2017 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 
40 #ifndef _DEVICE_DEVICE_HPP
41 #define _DEVICE_DEVICE_HPP
42 
43 /*
44  * Includes here should only cover the needs of the framework definitions.
45  */
46 #include <px4_config.h>
47 #include <px4_posix.h>
48 
49 #include <drivers/drv_device.h>
50 
51 #define DEVICE_LOG(FMT, ...) PX4_LOG_NAMED(_name, FMT, ##__VA_ARGS__)
52 #define DEVICE_DEBUG(FMT, ...) PX4_LOG_NAMED_COND(_name, _debug_enabled, FMT, ##__VA_ARGS__)
53 
57 namespace device
58 {
59 
66 {
67 public:
73  virtual ~Device() = default;
74 
75  /*
76  * Direct access methods.
77  */
78 
84  virtual int init() { return PX4_OK; }
85 
96  virtual int read(unsigned address, void *data, unsigned count) { return -ENODEV; }
97 
108  virtual int write(unsigned address, void *data, unsigned count) { return -ENODEV; }
109 
117  virtual int ioctl(unsigned operation, unsigned &arg)
118  {
119  switch (operation) {
120  case DEVIOCGDEVICEID:
121  return (int)_device_id.devid;
122  }
123 
124  return -ENODEV;
125  }
126 
129  DeviceBusType_UNKNOWN = 0,
130  DeviceBusType_I2C = 1,
131  DeviceBusType_SPI = 2,
132  DeviceBusType_UAVCAN = 3,
133  };
134 
140  uint8_t get_device_bus() const { return _device_id.devid_s.bus; }
141 
142  uint32_t get_device_id() const { return _device_id.devid; }
143 
149  DeviceBusType get_device_bus_type() const { return _device_id.devid_s.bus_type; }
150 
151  static const char *get_device_bus_string(DeviceBusType bus)
152  {
153  switch (bus) {
154  case DeviceBusType_I2C:
155  return "I2C";
156 
157  case DeviceBusType_SPI:
158  return "SPI";
159 
160  case DeviceBusType_UAVCAN:
161  return "UAVCAN";
162 
163  case DeviceBusType_UNKNOWN:
164  default:
165  return "UNKNOWN";
166  }
167  }
168 
174  uint8_t get_device_address() const { return _device_id.devid_s.address; }
175 
176  void set_device_address(int address) { _device_id.devid_s.address = address; }
177 
183  void set_device_type(uint8_t devtype) { _device_id.devid_s.devtype = devtype; }
184 
185  virtual bool external() { return false; }
186 
187  /*
188  broken out device elements. The bitfields are used to keep
189  the overall value small enough to fit in a float accurately,
190  which makes it possible to transport over the MAVLink
191  parameter protocol without loss of information.
192  */
194  enum DeviceBusType bus_type : 3;
195  uint8_t bus: 5; // which instance of the bus type
196  uint8_t address; // address on the bus (eg. I2C address)
197  uint8_t devtype; // device class specific device type
198  };
199 
200  union DeviceId {
201  struct DeviceStructure devid_s;
202  uint32_t devid;
203  };
204 
213  static int device_id_print_buffer(char *buffer, int length, uint32_t id)
214  {
215  DeviceId dev_id;
216  dev_id.devid = id;
217 
218  int num_written = snprintf(buffer, length, "Type: 0x%02X, %s:%d (0x%02X)", dev_id.devid_s.devtype,
219  get_device_bus_string(dev_id.devid_s.bus_type), dev_id.devid_s.bus, dev_id.devid_s.address);
220 
221  buffer[length - 1] = 0; // ensure 0-termination
222 
223  return num_written;
224  }
225 
226 protected:
227  union DeviceId _device_id;
229  const char *_name;
230  bool _debug_enabled{false};
232  Device(const char *name) : _name(name)
233  {
234  /* setup a default device ID. When bus_type is UNKNOWN the
235  other fields are invalid */
236  _device_id.devid = 0;
237  _device_id.devid_s.bus_type = DeviceBusType_UNKNOWN;
238  _device_id.devid_s.bus = 0;
239  _device_id.devid_s.address = 0;
240  _device_id.devid_s.devtype = 0;
241  }
242 
243  Device(DeviceBusType bus_type, uint8_t bus, uint8_t address, uint8_t devtype = 0)
244  {
245  _device_id.devid = 0;
246  _device_id.devid_s.bus_type = bus_type;
247  _device_id.devid_s.bus = bus;
248  _device_id.devid_s.address = address;
249  _device_id.devid_s.devtype = devtype;
250  }
251 
252  // no copy, assignment, move, move assignment
253  Device(const Device &) = delete;
254  Device &operator=(const Device &) = delete;
255  Device(Device &&) = delete;
256  Device &operator=(Device &&) = delete;
257 
258 };
259 
260 } // namespace device
261 
262 #endif /* _DEVICE_DEVICE_HPP */
uint8_t get_device_address() const
Return the bus address of the device.
Definition: Device.hpp:174
virtual int ioctl(unsigned operation, unsigned &arg)
Perform a device-specific operation.
Definition: Device.hpp:117
virtual int read(unsigned address, void *data, unsigned count)
Read directly from the device.
Definition: Device.hpp:96
DeviceBusType get_device_bus_type() const
Return the bus type the device is connected to.
Definition: Device.hpp:149
Configuration flags used in code.
Includes POSIX-like functions for virtual character devices.
Namespace encapsulating all device framework classes, functions and data.
Definition: CDev.cpp:47
virtual int write(unsigned address, void *data, unsigned count)
Write directly to the device.
Definition: Device.hpp:108
Generic device / sensor interface.
Definition: I2C.hpp:51
Fundamental base class for all physical drivers (I2C, SPI).
Definition: Device.hpp:65
void set_device_type(uint8_t devtype)
Set the device type.
Definition: Device.hpp:183
virtual int init()
Initialise the driver and make it ready for use.
Definition: Device.hpp:84
uint8_t get_device_bus() const
Return the bus ID the device is connected to.
Definition: Device.hpp:140
Definition: video_device.h:50
Definition: Device.hpp:193
static int device_id_print_buffer(char *buffer, int length, uint32_t id)
Print decoded device id string to a buffer.
Definition: Device.hpp:213
DeviceBusType
Device bus types for DEVID.
Definition: Device.hpp:128
const char * _name
driver name
Definition: Device.hpp:229
Definition: Device.hpp:200