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