Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
laeGpio.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelasp
4 //
5 // Library: liblaelaps
6 //
7 // File: laeGpio.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2016-01-21 16:50:25 -0700 (Thu, 21 Jan 2016) $
12  * $Rev: 4268 $
13  *
14  * \brief Laelaps GPIO class implementations.
15  * support functions.
16  *
17  * \author Robin Knight (robin.knight@roadnarrows.com)
18  *
19  * \par Copyright
20  * \h_copy 2015-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  *
27  * Unless otherwise stated explicitly, all materials contained are copyrighted
28  * and may not be used without RoadNarrows LLC's written consent,
29  * except as provided in these terms and conditions or in the copyright
30  * notice (documents and software) or other proprietary notice provided with
31  * the relevant materials.
32  *
33  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
34  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
35  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
36  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
37  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
38  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
41  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
42  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
43  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
44  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
45  *
46  * @EulaEnd@
47  */
48 ////////////////////////////////////////////////////////////////////////////////
49 
50 #include <sys/types.h>
51 #include <unistd.h>
52 
53 #include <string>
54 
55 #include "rnr/rnrconfig.h"
56 #include "rnr/gpio.h"
57 #include "rnr/log.h"
58 
59 #include "Laelaps/laelaps.h"
60 #include "Laelaps/laeSysDev.h"
61 #include "Laelaps/laeGpio.h"
62 
63 
64 using namespace std;
65 using namespace laelaps;
66 
67 
68 // -----------------------------------------------------------------------------
69 // LaeGpio Class
70 // -----------------------------------------------------------------------------
71 
72 LaeGpio::LaeGpio(const std::string &strTag,
73  const int gpio,
74  const LaeGpio::Direction dir) :
75  m_gpioTag(strTag), m_gpioNum(gpio), m_gpioDir(dir)
76 {
78  m_gpioCfg = false;
79 }
80 
82 {
84 
85  if( isConfigured() )
86  {
87  int value;
88  readValue(value);
89  }
90 }
91 
92 int LaeGpio::writeValue(const int value)
93 {
94  int rc;
95  int val = value? 1: 0;
96 
97  if( gpioWrite(m_gpioNum, val) == OK )
98  {
99  m_gpioVal = val;
100  rc = LAE_OK;
101 
102  LOGDIAG3("%s GPIO %d: new value is %d.",
103  m_gpioTag.c_str(), m_gpioNum, m_gpioVal);
104  }
105  else
106  {
107  LOGERROR("%s GPIO %d: Failed to write %d to pin.",
108  m_gpioTag.c_str(), m_gpioNum, value);
109  rc = -LAE_ECODE_IO;
110  }
111 
112  return rc;
113 }
114 
115 int LaeGpio::readValue(int &value)
116 {
117  int val;
118  int rc;
119 
120  if( (val = gpioRead(m_gpioNum)) != RC_ERROR )
121  {
122  value = val;
123  m_gpioVal = val;
124  rc = LAE_OK;
125 
126  LOGDIAG3("%s GPIO %d: current value is %d.",
127  m_gpioTag.c_str(), m_gpioNum, m_gpioVal);
128  }
129  else
130  {
131  LOGERROR("%s GPIO %d: Failed to read pin.", m_gpioTag.c_str(), m_gpioNum);
132  rc = -LAE_ECODE_IO;
133  }
134 
135  return rc;
136 }
137 
139 {
140  char buf[MAX_PATH];
141  int mode;
142 
143  gpioMakeDirname(m_gpioNum, buf, sizeof(buf));
144 
145  string strValFileName(buf);
146  string strDirFileName(buf);
147 
148  strValFileName += "/value";
149  strDirFileName += "/direction";
150 
151  if( m_gpioDir == LaeGpio::INPUT )
152  {
153  mode = R_OK;
154  }
155  else
156  {
157  mode = R_OK|W_OK;
158  }
159 
160  return access(strValFileName.c_str(), mode) == 0;
161 }
162 
163 
164 // -----------------------------------------------------------------------------
165 // LaeMotorCtlrEnable Class
166 // -----------------------------------------------------------------------------
167 
169 {
170  LaeGpio::sync();
171 
172  // version 2.0 has fixed power to motor controllers
173  if( !isConfigured() )
174  {
176  }
177 }
178 
180 {
181  bool wasEnabled;
182  bool bEnabled;
183 
184  // lazy one-time synchronization
185  if( m_gpioVal == LaeGpio::UNKNOWN )
186  {
187  sync();
188  }
189 
190  // versions 2.1+ have power enable to motor controllers
191  if( isConfigured() )
192  {
193  wasEnabled = isEnabled();
194 
195  writeValue(1);
196 
197  // give the motor controllers time to power up
198  if( !wasEnabled && isEnabled() )
199  {
200  usleep(TPowerUp);
201  }
202  }
203 
204  bEnabled = isEnabled();
205 
206  if( bEnabled )
207  {
208  LOGDIAG2("%s (GPIO %d) enabled.", m_gpioTag.c_str(), m_gpioNum);
209  }
210 
211  return bEnabled;
212 }
213 
215 {
216  bool bEnabled;
217 
218  // lazy one-time synchronization
219  if( m_gpioVal == LaeGpio::UNKNOWN )
220  {
221  sync();
222  }
223 
224  // versions 2.1+ have power enable to motor controllers
225  if( isConfigured() )
226  {
227  writeValue(0);
228  }
229 
230  bEnabled = isEnabled();
231 
232  if( !bEnabled )
233  {
234  LOGDIAG2("%s (GPIO %d) disabled.", m_gpioTag.c_str(), m_gpioNum);
235  }
236 
237  return bEnabled;
238 }
239 
241 {
242  // lazy one-time synchronization
243  if( m_gpioVal == LaeGpio::UNKNOWN )
244  {
245  sync();
246  }
247 
248  return hasValue() == LaeGpio::HIGH;
249 }
250 
251 
252 // -----------------------------------------------------------------------------
253 // LaeWatchDogReset Class
254 // -----------------------------------------------------------------------------
255 
257 {
258  LaeGpio::sync();
259 
260  // version 2.0 does not have a reset line
261  if( !isConfigured() )
262  {
264  }
265 }
266 
268 {
269  // lazy one-time synchronization
270  if( m_gpioVal == LaeGpio::UNKNOWN )
271  {
272  sync();
273  }
274 
275  // versions 2.1+ have reset line to watchdog sub-processor
276  if( isConfigured() )
277  {
278  // transition high to low
279  if( writeValue(1) == LAE_OK )
280  {
281  usleep(TTrans);
282  writeValue(0);
283  usleep(TTrans);
284 
285  if( hasValue() == LaeGpio::LOW )
286  {
287  usleep(TReboot);
288  }
289  }
290  }
291 }
292 
293 
294 // -----------------------------------------------------------------------------
295 // LaeI2CMuxReset Class
296 // -----------------------------------------------------------------------------
297 
299 {
300  LaeGpio::sync();
301 
302  // version 2.0 does not have a reset line
303  if( !isConfigured() )
304  {
306  }
307 }
308 
310 {
311  // lazy one-time synchronization
312  if( m_gpioVal == LaeGpio::UNKNOWN )
313  {
314  sync();
315  }
316 
317  // versions 2.1+ have reset line to watchdog sub-processor
318  if( isConfigured() )
319  {
320  // transition high to low
321  if( writeValue(1) == LAE_OK )
322  {
323  usleep(TTrans);
324  writeValue(0);
325  usleep(TTrans);
326 
327  if( hasValue() == LaeGpio::LOW )
328  {
329  usleep(TReboot);
330  }
331  }
332  }
333 }
334 
335 
336 // -----------------------------------------------------------------------------
337 // LaeAuxBattOutEnable Class
338 // -----------------------------------------------------------------------------
339 
341 {
342  LaeGpio::sync();
343 
344  // version 2.0 has fixed battery power to top deck
345  if( !isConfigured() )
346  {
348  }
349 }
350 
352 {
353  bool bEnabled;
354 
355  // lazy one-time synchronization
356  if( m_gpioVal == LaeGpio::UNKNOWN )
357  {
358  sync();
359  }
360 
361  // versions 2.1+ have battery power enable to top deck
362  if( isConfigured() )
363  {
364  writeValue(1);
365  }
366 
367  bEnabled = isEnabled();
368 
369  if( bEnabled )
370  {
371  LOGDIAG2("%s (GPIO %d) enabled.", m_gpioTag.c_str(), m_gpioNum);
372  }
373 
374  return bEnabled;
375 }
376 
378 {
379  bool bEnabled;
380 
381  // lazy one-time synchronization
382  if( m_gpioVal == LaeGpio::UNKNOWN )
383  {
384  sync();
385  }
386 
387  // versions 2.1+ have battery power enable to top deck
388  if( isConfigured() )
389  {
390  writeValue(0);
391  }
392 
393  bEnabled = isEnabled();
394 
395  if( !bEnabled )
396  {
397  LOGDIAG2("%s (GPIO %d) disabled.", m_gpioTag.c_str(), m_gpioNum);
398  }
399 
400  return bEnabled;
401 }
402 
404 {
405  // lazy one-time synchronization
406  if( m_gpioVal == LaeGpio::UNKNOWN )
407  {
408  sync();
409  }
410 
411  return hasValue() == LaeGpio::HIGH;
412 }
413 
414 
415 // -----------------------------------------------------------------------------
416 // LaeAux5VOutEnable Class
417 // -----------------------------------------------------------------------------
418 
420 {
421  LaeGpio::sync();
422 
423  // version 2.0 has fixed regulated 5V out to top deck
424  if( !isConfigured() )
425  {
427  }
428 }
429 
431 {
432  bool bEnabled;
433 
434  // lazy one-time synchronization
435  if( m_gpioVal == LaeGpio::UNKNOWN )
436  {
437  sync();
438  }
439 
440  // versions 2.1+ have regulated 5V power enable to top deck
441  if( isConfigured() )
442  {
443  writeValue(1);
444  }
445 
446  bEnabled = isEnabled();
447 
448  if( bEnabled )
449  {
450  LOGDIAG2("%s (GPIO %d) enabled.", m_gpioTag.c_str(), m_gpioNum);
451  }
452 
453  return bEnabled;
454 }
455 
457 {
458  bool bEnabled;
459 
460  // lazy one-time synchronization
461  if( m_gpioVal == LaeGpio::UNKNOWN )
462  {
463  sync();
464  }
465 
466  // versions 2.1+ have regulated 5V power enable to top deck
467  if( isConfigured() )
468  {
469  writeValue(0);
470  }
471 
472  bEnabled = isEnabled();
473 
474  if( !bEnabled )
475  {
476  LOGDIAG2("%s (GPIO %d) disabled.", m_gpioTag.c_str(), m_gpioNum);
477  }
478 
479  return bEnabled;
480 }
481 
483 {
484  // lazy one-time synchronization
485  if( m_gpioVal == LaeGpio::UNKNOWN )
486  {
487  sync();
488  }
489 
490  return hasValue() == LaeGpio::HIGH;
491 }
bool disable()
Disable regulated 5V power to top deck.
Definition: laeGpio.cxx:456
LaeGpio::Direction m_gpioDir
GPIO direction.
Definition: laeGpio.h:179
bool enable()
Enable battery power to top deck.
Definition: laeGpio.cxx:351
low value
Definition: laeGpio.h:84
bool isEnabled()
Test if power to motor controllers is enabled.
Definition: laeGpio.cxx:240
static const int LAE_ECODE_IO
I/O error.
Definition: laelaps.h:98
virtual void sync()
Synchronized this with GPIO hardware state.
Definition: laeGpio.cxx:419
virtual void sync()
Synchronized this with GPIO hardware state.
Definition: laeGpio.cxx:340
bool disable()
Disable power to motor controllers.
Definition: laeGpio.cxx:214
bool enable()
Enable power to motor controllers.
Definition: laeGpio.cxx:179
bool isEnabled()
Test if battery power to top deck is enabled.
Definition: laeGpio.cxx:403
bool enable()
Enable regulated 5V power to top deck.
Definition: laeGpio.cxx:430
int m_gpioNum
exported GPIO number
Definition: laeGpio.h:178
bool isEnabled()
Test if regulated 5V power to top deck is enabled.
Definition: laeGpio.cxx:482
Laelaps Odroid General Purpose I/O class interfaces.
virtual void sync()
Synchronized this with GPIO hardware state.
Definition: laeGpio.cxx:298
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
virtual void sync()
Synchronized this with GPIO hardware state.
Definition: laeGpio.cxx:81
void reset()
Reset the watchdog sub-processor.
Definition: laeGpio.cxx:267
int hasValue() const
Get the current shadowed gpio value.
Definition: laeGpio.h:157
bool isConfigured() const
Is the exported GPIO number configured to match this ojbect?
Definition: laeGpio.h:171
Laelaps system devices.
virtual int readValue(int &value)
Read current value of gpio.
Definition: laeGpio.cxx:115
unknown state value
Definition: laeGpio.h:83
bool checkConfig()
Check if the exported GPIO exists in /sys/class and that it has been configured to match this objects...
Definition: laeGpio.cxx:138
bool m_gpioCfg
GPIO is [not] configured (correctly)
Definition: laeGpio.h:181
bool disable()
Disable battery power to top deck.
Definition: laeGpio.cxx:377
input direction
Definition: laeGpio.h:93
virtual int writeValue(const LaeGpio::TriState value)
Write value to gpio.
Definition: laeGpio.h:129
high value
Definition: laeGpio.h:85
void reset()
Reset the I2C mulitplex chip.
Definition: laeGpio.cxx:309
int m_gpioVal
shadowed value
Definition: laeGpio.h:180
std::string m_gpioTag
identifying tag
Definition: laeGpio.h:177
virtual void sync()
Synchronized this with GPIO hardware state.
Definition: laeGpio.cxx:168
Top-level package include file.
virtual void sync()
Synchronized this with GPIO hardware state.
Definition: laeGpio.cxx:256
Direction
GPIO direction.
Definition: laeGpio.h:91
static const int LAE_OK
not an error, success
Definition: laelaps.h:71