PX4 Firmware
PX4 Autopilot Software http://px4.io
bmi160_main.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2018 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 "bmi160.hpp"
35 
36 /** driver 'main' command */
37 extern "C" { __EXPORT int bmi160_main(int argc, char *argv[]); }
38 
39 /**
40  * Local functions in support of the shell command.
41  */
42 namespace bmi160
43 {
44 
45 BMI160 *g_dev_int; // on internal bus
46 BMI160 *g_dev_ext; // on external bus
47 
48 void start(bool, enum Rotation);
49 void stop(bool);
50 void info(bool);
51 void regdump(bool);
52 void testerror(bool);
53 void usage();
54 
55 
56 /**
57  * Start the driver.
58  *
59  * This function only returns if the driver is up and running
60  * or failed to detect the sensor.
61  */
62 void
63 start(bool external_bus, enum Rotation rotation)
64 {
65  BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int;
66 
67  if (*g_dev_ptr != nullptr)
68  /* if already started, the still command succeeded */
69  {
70  errx(0, "already started");
71  }
72 
73  /* create the driver */
74  if (external_bus) {
75 #if defined(PX4_SPI_BUS_EXT) && defined(PX4_SPIDEV_EXT_BMI)
76  *g_dev_ptr = new BMI160(PX4_SPI_BUS_EXT, PX4_SPIDEV_EXT_BMI, rotation);
77 #else
78  errx(0, "External SPI not available");
79 #endif
80 
81  } else {
82 #if defined(PX4_SPIDEV_BMI)
83  *g_dev_ptr = new BMI160(PX4_SPI_BUS_SENSORS, PX4_SPIDEV_BMI, rotation);
84 #else
85  errx(0, "No Internal SPI CS");
86 #endif
87  }
88 
89  if (*g_dev_ptr == nullptr) {
90  goto fail;
91  }
92 
93  if (OK != (*g_dev_ptr)->init()) {
94  goto fail;
95  }
96 
97  exit(0);
98 fail:
99 
100  if (*g_dev_ptr != nullptr) {
101  delete (*g_dev_ptr);
102  *g_dev_ptr = nullptr;
103  }
104 
105  errx(1, "driver start failed");
106 }
107 
108 void
109 stop(bool external_bus)
110 {
111  BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int;
112 
113  if (*g_dev_ptr != nullptr) {
114  delete *g_dev_ptr;
115  *g_dev_ptr = nullptr;
116 
117  } else {
118  /* warn, but not an error */
119  warnx("already stopped.");
120  }
121 
122  exit(0);
123 }
124 
125 /**
126  * Print a little info about the driver.
127  */
128 void
129 info(bool external_bus)
130 {
131  BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int;
132 
133  if (*g_dev_ptr == nullptr) {
134  errx(1, "driver not running");
135  }
136 
137  printf("state @ %p\n", *g_dev_ptr);
138  (*g_dev_ptr)->print_info();
139 
140  exit(0);
141 }
142 
143 /**
144  * Dump the register information
145  */
146 void
147 regdump(bool external_bus)
148 {
149  BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int;
150 
151  if (*g_dev_ptr == nullptr) {
152  errx(1, "driver not running");
153  }
154 
155  printf("regdump @ %p\n", *g_dev_ptr);
156  (*g_dev_ptr)->print_registers();
157 
158  exit(0);
159 }
160 
161 
162 /**
163  * deliberately produce an error to test recovery
164  */
165 void
166 testerror(bool external_bus)
167 {
168  BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int;
169 
170  if (*g_dev_ptr == nullptr) {
171  errx(1, "driver not running");
172  }
173 
174  (*g_dev_ptr)->test_error();
175 
176  exit(0);
177 }
178 
179 void
181 {
182  warnx("missing command: try 'start', 'info', 'stop', 'regdump', 'testerror'");
183  warnx("options:");
184  warnx(" -X (external bus)");
185  warnx(" -R rotation");
186 }
187 
188 } // namespace
189 
190 int
191 bmi160_main(int argc, char *argv[])
192 {
193  int myoptind = 1;
194  int ch;
195  const char *myoptarg = nullptr;
196  bool external_bus = false;
197  enum Rotation rotation = ROTATION_NONE;
198 
199  while ((ch = px4_getopt(argc, argv, "XR:", &myoptind, &myoptarg)) != EOF) {
200  switch (ch) {
201  case 'X':
202  external_bus = true;
203  break;
204 
205  case 'R':
206  rotation = (enum Rotation)atoi(myoptarg);
207  break;
208 
209  default:
210  bmi160::usage();
211  return 0;
212  }
213  }
214 
215  if (myoptind >= argc) {
216  bmi160::usage();
217  return -1;
218  }
219 
220  const char *verb = argv[myoptind];
221 
222  /*
223  * Start/load the driver.
224  */
225  if (!strcmp(verb, "start")) {
226  bmi160::start(external_bus, rotation);
227  }
228 
229  if (!strcmp(verb, "stop")) {
230  bmi160::stop(external_bus);
231  }
232 
233  /*
234  * Print driver information.
235  */
236  if (!strcmp(verb, "info")) {
237  bmi160::info(external_bus);
238  }
239 
240  /*
241  * Print register information.
242  */
243  if (!strcmp(verb, "regdump")) {
244  bmi160::regdump(external_bus);
245  }
246 
247  if (!strcmp(verb, "testerror")) {
248  bmi160::testerror(external_bus);
249  }
250 
251  bmi160::usage();
252  return -1;
253 }
void testerror(bool)
deliberately produce an error to test recovery
Local functions in support of the shell command.
Definition: bmi160_main.cpp:42
void start(bool, enum Rotation)
Start the driver.
Definition: bmi160_main.cpp:63
Definition: I2C.hpp:51
void stop(bool)
void regdump(bool)
Dump the register information.
Rotation
Enum for board and external compass rotations.
Definition: rotation.h:51
#define warnx(...)
Definition: err.h:95
BMI160 * g_dev_int
Definition: bmi160_main.cpp:45
void info(bool)
Print a little info about the driver.
BMI160 * g_dev_ext
Definition: bmi160_main.cpp:46
#define errx(eval,...)
Definition: err.h:89
#define OK
Definition: uavcan_main.cpp:71
void usage()
Prints info about the driver argument usage.
__EXPORT int bmi160_main(int argc, char *argv[])
driver 'main' command