PX4 Firmware
PX4 Autopilot Software http://px4.io
test_ppm.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2015, 2016 Airmind 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 Airmind 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 test_ppm.cpp
36  *
37  * @author sudragon
38  */
39 
40 #include <nuttx/config.h>
41 
42 #include <sys/types.h>
43 #include <stdint.h>
44 #include <stdbool.h>
45 #include <stddef.h>
46 #include <stdlib.h>
47 #include <semaphore.h>
48 #include <string.h>
49 #include <fcntl.h>
50 #include <poll.h>
51 #include <errno.h>
52 #include <stdio.h>
53 #include <math.h>
54 #include <unistd.h>
55 
56 #include <perf/perf_counter.h>
57 #include <systemlib/err.h>
58 #include <systemlib/conversions.h>
59 
60 #include <nuttx/arch.h>
61 #include <nuttx/clock.h>
62 
63 #include <board_config.h>
64 #include <drivers/drv_hrt.h>
65 
66 #define TEST_PPM_PIN (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN15)
67 
68 class TEST_PPM
69 {
70 public:
71  TEST_PPM(unsigned channels);
72  virtual ~TEST_PPM(void);
73  virtual int init();
74  unsigned _values[20];
75  unsigned _gaps[20];
76  unsigned _channels;
77  unsigned _plus_width;
78 protected:
79 
80 private:
81  struct hrt_call _call;
82  unsigned _call_times;
83  void start();
84 
85  void stop();
86  void do_out();
87  static void loops(void *arg);
88 
89 
90 };
91 
92 
93 /** driver 'main' command */
94 extern "C" { __EXPORT int test_ppm_main(int argc, char *argv[]); }
95 
96 TEST_PPM::TEST_PPM(unsigned channels) :
97  _channels(channels),
98  _plus_width(400),
99  _call{},
100  _call_times(0)
101 {
102  memset(&_call, 0, sizeof(_call));
103 
104  for (int i = 0; i < 20; i++) {
105  _values[i] = 1500;
106  }
107 
108  _values[0] = 5000;
109 }
110 
112 {
113  /* make sure we are truly inactive */
114  stop();
115 }
116 
117 int
119 {
120  px4_arch_configgpio(TEST_PPM_PIN);
121  start();
122  return OK;
123 }
124 
125 
126 void
128 {
129  stop();
130  _call_times = 0;
132 }
133 
134 void
136 {
137  hrt_cancel(&_call);
138 }
139 
140 void
142 {
143  TEST_PPM *dev = static_cast<TEST_PPM *>(arg);
144  dev->do_out();
145 }
146 void
148 {
149  if ((_call_times % 2) == 0) {
150  px4_arch_gpiowrite(TEST_PPM_PIN, false);
152 
153  } else {
154  px4_arch_gpiowrite(TEST_PPM_PIN, true);
156  }
157 
158  if ((_call_times / 2) < _channels + 1) { _call_times++; }
159 
160  else { _call_times = 0; }
161 }
162 
163 namespace test_ppm
164 {
165 
166 TEST_PPM *g_test = nullptr;
167 
168 void start(unsigned channels);
169 void stop();
170 void usage();
171 void set(unsigned ch, unsigned value);
172 
173 /**
174  * Start the driver.
175  *
176  * This function only returns if the driver is up and running
177  * or failed to detect the sensor.
178  */
179 void
180 start(unsigned channels)
181 {
182 
183  if (g_test != nullptr)
184  /* if already started, the still command succeeded */
185  {
186  errx(1, "already started");
187  }
188 
189  g_test = new TEST_PPM(channels);
190 
191  if (g_test == nullptr) {
192  goto fail;
193  }
194 
195  if (OK != g_test->init()) {
196  goto fail;
197  }
198 
199  exit(0);
200 fail:
201 
202  if (g_test != nullptr) {
203  delete (g_test);
204  g_test = nullptr;
205  }
206 
207  errx(1, "test_ppm start failed");
208 }
209 
210 void
212 {
213  if (g_test != nullptr) {
214  delete g_test;
215  g_test = nullptr;
216 
217  } else {
218  /* warn, but not an error */
219  warnx("test_ppm already stopped.");
220  }
221 
222  exit(0);
223 }
224 
225 void
226 set(unsigned ch, unsigned value)
227 {
228  if (ch > 18 || ch < 1) {warnx("channel is not valid.");}
229 
230  if (value > 2500 || value < 1) { warnx("value is not valid.");}
231 
232  g_test->_values[ch] = value;
233  g_test->_gaps[ch] = 2500 - value;
234 
235  if (ch == g_test->_channels) { g_test->_gaps[ch] = 5000; }
236 
237  return;
238 }
239 
240 void
242 {
243  warnx("missing command: try 'start', 'stop', 'set'\n");
244 }
245 
246 } // namespace
247 
248 int
249 test_ppm_main(int argc, char *argv[])
250 {
251  if (argc < 2) {
252  test_ppm::usage();
253  return -1;
254  }
255 
256  const char *verb = argv[1];
257  unsigned channels = 7;
258 
259  /*
260  * Start/load the driver.
261  */
262  if (!strcmp(verb, "start")) {
263  test_ppm::start(channels);
264  return 0;
265  }
266 
267  if (!strcmp(verb, "stop")) {
268 
269  test_ppm::stop();
270  return 0;
271  }
272 
273  /*
274  * Test the driver/device.
275  */
276  if (!strcmp(verb, "set")) {
277  if (argc < 4) {
278  errx(1, "Usage: test_ppm set <channel> <value>");
279  }
280 
281  unsigned channel = strtol(argv[2], NULL, 0);
282  unsigned value = strtol(argv[3], NULL, 0);
283 
284  test_ppm::set(channel, value);
285  return 0;
286  }
287 
288  test_ppm::usage();
289  return -1;
290 }
unsigned _call_times
Definition: test_ppm.cpp:82
void stop()
Stop the driver.
Definition: test_ppm.cpp:211
virtual int init()
Definition: test_ppm.cpp:118
static void loops(void *arg)
Definition: test_ppm.cpp:141
void(* hrt_callout)(void *arg)
Callout function type.
Definition: drv_hrt.h:67
void usage(const char *reason)
Print the correct usage.
Definition: Commander.cpp:4238
Definition: I2C.hpp:51
TEST_PPM * g_test
Definition: test_ppm.cpp:166
void start()
Definition: test_ppm.cpp:127
#define TEST_PPM_PIN
Definition: test_ppm.cpp:66
struct hrt_call _call
Definition: test_ppm.cpp:81
High-resolution timer with callouts and timekeeping.
void stop()
Definition: test_ppm.cpp:135
__EXPORT void hrt_call_after(struct hrt_call *entry, hrt_abstime delay, hrt_callout callout, void *arg)
Call callout(arg) after delay has elapsed.
unsigned _values[20]
Definition: test_ppm.cpp:74
void start(unsigned channels)
Start the driver.
Definition: test_ppm.cpp:180
unsigned _plus_width
Definition: test_ppm.cpp:77
TEST_PPM(unsigned channels)
Definition: test_ppm.cpp:96
void set(unsigned ch, unsigned value)
Definition: test_ppm.cpp:226
Definition of commonly used conversions.
void * arg
Definition: drv_hrt.h:78
#define warnx(...)
Definition: err.h:95
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
void usage()
Prints info about the driver argument usage.
Definition: test_ppm.cpp:241
unsigned _gaps[20]
Definition: test_ppm.cpp:75
unsigned _channels
Definition: test_ppm.cpp:76
#define errx(eval,...)
Definition: err.h:89
virtual ~TEST_PPM(void)
Definition: test_ppm.cpp:111
Callout record.
Definition: drv_hrt.h:72
void do_out()
Definition: test_ppm.cpp:147
#define OK
Definition: uavcan_main.cpp:71
__EXPORT int test_ppm_main(int argc, char *argv[])
driver &#39;main&#39; command
Definition: test_ppm.cpp:249
__EXPORT void hrt_cancel(struct hrt_call *entry)
Remove the entry from the callout list.
Performance measuring tools.