PX4 Firmware
PX4 Autopilot Software http://px4.io
bmp280_main.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2016-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 #include <px4_platform_common/px4_config.h>
35 #include <px4_platform_common/getopt.h>
36 
37 #include "BMP280.hpp"
38 
39 enum class BMP280_BUS {
40  ALL = 0,
45 };
46 
47 namespace bmp280
48 {
49 
50 // list of supported bus configurations
54  uint8_t busnum;
55  uint32_t address;
57 } bus_options[] = {
58 #if defined(PX4_SPI_BUS_EXT) && defined(PX4_SPIDEV_EXT_BARO)
59  { BMP280_BUS::SPI_EXTERNAL, &bmp280_spi_interface, PX4_SPI_BUS_EXT, PX4_SPIDEV_EXT_BARO, nullptr },
60 #endif
61 #if defined(PX4_SPIDEV_BARO_BUS) && defined(PX4_SPIDEV_BARO)
62  { BMP280_BUS::SPI_INTERNAL, &bmp280_spi_interface, PX4_SPIDEV_BARO_BUS, PX4_SPIDEV_BARO, nullptr },
63 #elif defined(PX4_SPI_BUS_SENSORS) && defined(PX4_SPIDEV_BARO)
64  { BMP280_BUS::SPI_INTERNAL, &bmp280_spi_interface, PX4_SPI_BUS_SENSORS, PX4_SPIDEV_BARO, nullptr },
65 #endif
66 #if defined(PX4_I2C_BUS_ONBOARD) && defined(PX4_I2C_OBDEV_BMP280)
67  { BMP280_BUS::I2C_INTERNAL, &bmp280_i2c_interface, PX4_I2C_BUS_ONBOARD, PX4_I2C_OBDEV_BMP280, nullptr },
68 #endif
69 #if defined(PX4_I2C_BUS_EXPANSION) && defined(PX4_I2C_OBDEV_BMP280)
70  { BMP280_BUS::I2C_EXTERNAL, &bmp280_i2c_interface, PX4_I2C_BUS_EXPANSION, PX4_I2C_OBDEV_BMP280, nullptr },
71 #endif
72 };
73 
74 // find a bus structure for a busid
75 static struct bmp280_bus_option *find_bus(BMP280_BUS busid)
76 {
77  for (bmp280_bus_option &bus_option : bus_options) {
78  if ((busid == BMP280_BUS::ALL ||
79  busid == bus_option.busid) && bus_option.dev != nullptr) {
80 
81  return &bus_option;
82  }
83  }
84 
85  return nullptr;
86 }
87 
88 static bool start_bus(bmp280_bus_option &bus)
89 {
90  bmp280::IBMP280 *interface = bus.interface_constructor(bus.busnum, bus.address);
91 
92  if ((interface == nullptr) || (interface->init() != PX4_OK)) {
93  PX4_WARN("no device on bus %u", (unsigned)bus.busid);
94  delete interface;
95  return false;
96  }
97 
98  BMP280 *dev = new BMP280(interface);
99 
100  if (dev == nullptr) {
101  PX4_ERR("driver allocate failed");
102  delete interface;
103  return false;
104  }
105 
106  if (dev->init() != PX4_OK) {
107  PX4_ERR("driver start failed");
108  delete dev; // BMP280 deletes the interface
109  return false;
110  }
111 
112  bus.dev = dev;
113 
114  return true;
115 }
116 
117 static int start(BMP280_BUS busid)
118 {
119  for (bmp280_bus_option &bus_option : bus_options) {
120  if (bus_option.dev != nullptr) {
121  // this device is already started
122  PX4_WARN("already started");
123  continue;
124  }
125 
126  if (busid != BMP280_BUS::ALL && bus_option.busid != busid) {
127  // not the one that is asked for
128  continue;
129  }
130 
131  if (start_bus(bus_option)) {
132  return PX4_OK;
133  }
134  }
135 
136  return PX4_ERROR;
137 }
138 
139 static int stop(BMP280_BUS busid)
140 {
141  bmp280_bus_option *bus = find_bus(busid);
142 
143  if (bus != nullptr && bus->dev != nullptr) {
144  delete bus->dev;
145  bus->dev = nullptr;
146 
147  } else {
148  PX4_WARN("driver not running");
149  return PX4_ERROR;
150  }
151 
152  return PX4_OK;
153 }
154 
155 static int status(BMP280_BUS busid)
156 {
157  bmp280_bus_option *bus = find_bus(busid);
158 
159  if (bus != nullptr && bus->dev != nullptr) {
160  bus->dev->print_info();
161  return PX4_OK;
162  }
163 
164  PX4_WARN("driver not running");
165  return PX4_ERROR;
166 }
167 
168 static int usage()
169 {
170  PX4_INFO("missing command: try 'start', 'stop', 'status'");
171  PX4_INFO("options:");
172  PX4_INFO(" -X (i2c external bus)");
173  PX4_INFO(" -I (i2c internal bus)");
174  PX4_INFO(" -s (spi internal bus)");
175  PX4_INFO(" -S (spi external bus)");
176 
177  return 0;
178 }
179 
180 } // namespace
181 
182 extern "C" int bmp280_main(int argc, char *argv[])
183 {
184  int myoptind = 1;
185  int ch;
186  const char *myoptarg = nullptr;
187 
188  BMP280_BUS busid = BMP280_BUS::ALL;
189 
190  while ((ch = px4_getopt(argc, argv, "XISs:", &myoptind, &myoptarg)) != EOF) {
191  switch (ch) {
192  case 'X':
193  busid = BMP280_BUS::I2C_EXTERNAL;
194  break;
195 
196  case 'I':
197  busid = BMP280_BUS::I2C_INTERNAL;
198  break;
199 
200  case 'S':
201  busid = BMP280_BUS::SPI_EXTERNAL;
202  break;
203 
204  case 's':
205  busid = BMP280_BUS::SPI_INTERNAL;
206  break;
207 
208  default:
209  return bmp280::usage();
210  }
211  }
212 
213  if (myoptind >= argc) {
214  return bmp280::usage();
215  }
216 
217  const char *verb = argv[myoptind];
218 
219  if (!strcmp(verb, "start")) {
220  return bmp280::start(busid);
221 
222  } else if (!strcmp(verb, "stop")) {
223  return bmp280::stop(busid);
224 
225  } else if (!strcmp(verb, "status")) {
226  return bmp280::status(busid);
227  }
228 
229  return bmp280::usage();
230 }
BMP280_constructor interface_constructor
Definition: bmp280_main.cpp:53
void print_info()
Definition: BMP280.cpp:196
bmp280::IBMP280 * bmp280_spi_interface(uint8_t busnum, uint32_t device)
static struct bmp280_bus_option * find_bus(BMP280_BUS busid)
Definition: bmp280_main.cpp:75
static int start(BMP280_BUS busid)
Definition: bmp280.h:84
static int stop(BMP280_BUS busid)
void usage(const char *reason)
Print the correct usage.
Definition: Commander.cpp:4238
static void stop()
Definition: dataman.cpp:1491
int bmp280_main(int argc, char *argv[])
static int usage()
bmp280::IBMP280 * bmp280_i2c_interface(uint8_t busnum, uint32_t device)
int init()
Definition: BMP280.cpp:60
struct bmp280::bmp280_bus_option bus_options[]
static int status(BMP280_BUS busid)
bmp280::IBMP280 *(* BMP280_constructor)(uint8_t, uint32_t)
Definition: bmp280.h:160
static bool start_bus(bmp280_bus_option &bus)
Definition: bmp280_main.cpp:88
static int start()
Definition: dataman.cpp:1452
BMP280_BUS
Definition: bmp280_main.cpp:39