gpio  1.4.2
General Purpose I/O Package
gpiobitbang.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: gpio
4 //
5 // Program: gpiobitbang
6 //
7 // File: gpiobitbang.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2015-04-08 17:22:10 -0600 (Wed, 08 Apr 2015) $
12  * $Rev: 3913 $
13  *
14  * \brief Bit bang pattern out GPIO pin.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \copyright
19  * \h_copy 2015-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 /*
24  * @EulaBegin@
25  * @EulaEnd@
26  */
27 ////////////////////////////////////////////////////////////////////////////////
28 
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 
34 #include <string>
35 
36 #include "rnr/rnrconfig.h"
37 #include "rnr/log.h"
38 #include "rnr/opts.h"
39 #include "rnr/pkg.h"
40 
41 #include "rnr/gpio.h"
42 
43 #include "version.h"
44 
45 using namespace std;
46 
47 /*!
48  * \ingroup cmds
49  * \defgroup gpiobitbang gpiobitbang
50  * \{
51  */
52 
53 #define APP_EC_OK 0 ///< success exit code
54 #define APP_EC_ARGS 2 ///< command-line options/arguments error exit code
55 #define APP_EC_EXEC 4 ///< execution exit code
56 
57 static char *Argv0; ///< the command
58 static char *OptsMethod = (char *)"sysfs"; ///< system file system
59 static int OptsIbd = 1000; ///< inter-bit delay
60 static int ArgsGpio; ///< gpio number
61 static byte_t *ArgsPattern; ///< bit pattern to write
62 static size_t PatByteCount; ///< pattern byte count
63 static size_t PatBitCount; ///< pattern bit count
64 
65 
66 /*!
67  * \brief Program information.
68  */
69 static OptsPgmInfo_T PgmInfo =
70 {
71  // usage_args
72  "<gpio> byte [byte...]",
73 
74  // synopsis
75  "Bit-bang bit pattern out GPIO pin.",
76 
77  // long_desc =
78  "The %P command writes the specified bit pattern to the GPIO at the given "
79  "exported number. "
80  "A bit value of 0 sets the pin low. "
81  "A bit value of 1 set the pin high."
82  "The byte pattern is specified as a series of byte arguments of any of the "
83  "format:\n"
84  " 0xH[H] hexidecimal examples: 0x5 0x3C 0xff\n"
85  " 0bB[B...] binary examples: 0b00000101 0b001111 0b11111111\n"
86  " D[D...] unsigned integer examples: 5 60 255",
87 
88  // diagnostics
89  NULL
90 };
91 
92 /*!
93  * \brief Command line options information.
94  */
95 static OptsInfo_T OptsInfo[] =
96 {
97  // -i, --ibd
98  {
99  "ibd", // long_opt
100  'i', // short_opt
101  required_argument, // has_arg
102  true, // has_default
103  &OptsIbd, // opt_addr
104  OptsCvtArgInt, // fn_cvt
105  OptsFmtInt, // fn_fmt
106  "<usec>", // arg_name
107  // opt desc
108  "Inter-bit delay in microseconds. A 0 value means no delay."
109  },
110 
111 #ifdef MMAP_GPIO
112  // -m, --method
113  {
114  "method", // long_opt
115  'm', // short_opt
116  required_argument, // has_arg
117  true, // has_default
118  &OptsMethod, // opt_addr
119  OptsCvtArgStr, // fn_cvt
120  OptsFmtStr, // fn_fmt
121  "<method>", // arg_name
122  // opt desc
123  "GPIO access method. One of: sysfs mmap."
124  },
125 #endif // MMAP_GPIO
126 
127  {NULL, }
128 };
129 
130 static int strToInt(const string &str, int &val)
131 {
132  long long int val1; // must use 64-bit for arm 32-bit compilers
133 
134  if( sscanf(str.c_str(), "%lli", &val1) != 1 )
135  {
136  return RC_ERROR;
137  }
138 
139  val = (int)val1;
140 
141  return OK;
142 }
143 
144 static int strToBits(const string &str, byte_t *p)
145 {
146  string s;
147  int bit;
148  size_t i;
149  int val = 0;
150 
151  if( str.substr(0, 2) == "0b" )
152  {
153  s = str.substr(2, str.size()-2);
154  bit = 0x80;
155  for(i=0; i<8 & i<s.size(); ++i)
156  {
157  if( s[i] == '1' )
158  {
159  val |= bit;
160  }
161  else if( s[i] != '0' )
162  {
163  return RC_ERROR;
164  }
165  bit >>= 1;
166  }
167  }
168  else
169  {
170  if( sscanf(str.c_str(), "%i", &val) != 1 )
171  {
172  return RC_ERROR;
173  }
174  }
175 
176  *p = (byte_t)val;
177 
178  return OK;
179 }
180 
181 /*!
182  * \brief Main initialization.
183  *
184  * \param argc Command-line argument count.
185  * \param argv Command-line argument list.
186  *
187  * \par Exits:
188  * Program terminates on conversion error.
189  */
190 static void mainInit(int argc, char *argv[])
191 {
192  int i;
193  byte_t *p;
194 
195  // name of this process
196  Argv0 = basename(argv[0]);
197 
198  // parse input options
199  argv = OptsGet(Argv0, &PkgInfo, &PgmInfo, OptsInfo, true, &argc, argv);
200 
201  if( argc == 0 )
202  {
203  fprintf(stderr, "%s: No GPIO pin number <gpio> specified.\n", Argv0);
204  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
205  exit(APP_EC_ARGS);
206  }
207 
208  else if( strToInt(argv[0], ArgsGpio) < 0 )
209  {
210  fprintf(stderr, "%s: '%s': Bad GPIO number.\n", Argv0, argv[0]);
211  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
212  exit(APP_EC_ARGS);
213  }
214 
215  if( argc == 1 )
216  {
217  fprintf(stderr, "%s: No bit pattern specified.\n", Argv0);
218  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
219  exit(APP_EC_ARGS);
220  }
221 
222  PatByteCount = argc - 1;
224  ArgsPattern = (byte_t *)malloc(sizeof(byte_t) * PatByteCount);
225 
226  for(i=1, p=ArgsPattern; i<argc; ++i, ++p)
227  {
228  if( strToBits(argv[i], p) < 0 )
229  {
230  fprintf(stderr, "%s: '%s': Bad bit pattern %d.\n", Argv0, argv[i], i);
231  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
232  exit(APP_EC_ARGS);
233  }
234  }
235 }
236 
237 /*!
238  * \brief Bit bang bit pattern.
239  *
240  * Method: sysfs
241  *
242  * \return Application exit code.
243  */
244 static int sysfsBitBang()
245 {
246  int fd;
247  int ec;
248 
249  if( (fd = gpioOpen(ArgsGpio)) < 0 )
250  {
251  return APP_EC_EXEC;
252  }
253 
254  if( gpioBitBang(fd, ArgsPattern, PatBitCount, OptsIbd) < 0 )
255  {
256  ec = APP_EC_EXEC;
257  }
258  else
259  {
260  ec = APP_EC_OK;
261  }
262 
263  gpioClose(fd);
264 
265  return ec;
266 }
267 
268 #ifdef MMAP_GPIO
269 /*!
270  * \brief Bit bang bit pattern.
271  *
272  * Method: mmap
273  *
274  * \return Application exit code.
275  */
276 static int mmapBitBang()
277 {
278  int ec;
279 
280  if( mmapGpioMap() < 0 )
281  {
282  return APP_EC_EXEC;
283  }
284 
285  if( mmapGpioBitBang(ArgsGpio, ArgsPattern, PatBitCount, OptsIbd) < 0 )
286  {
287  ec = APP_EC_EXEC;
288  }
289  else
290  {
291  ec = APP_EC_OK;
292  }
293 
294  mmapGpioUnmap();
295 
296  return ec;
297 }
298 #endif // MMAP_GPIO
299 
300 /*!
301  * \brief Main.
302  *
303  * \param argc Command-line argument count.
304  * \param argv Command-line argument list.
305  *
306  * \return Returns 0 on succes, non-zero on failure.
307  */
308 int main(int argc, char* argv[])
309 {
310  int pin;
311  int ec;
312 
313  mainInit(argc, argv);
314 
315 
316  printf("Bit banging pattern to GPIO %d.\n", ArgsGpio);
317  printf(" Pattern: ");
318  for(size_t i=0; i<PatByteCount; ++i)
319  {
320  printf("%02x ", ArgsPattern[i]);
321  }
322  printf("\n");
323  printf(" Ibd: %u usec\n", OptsIbd);
324 
325  if( !strcmp(OptsMethod, "sysfs") )
326  {
327  ec = sysfsBitBang();
328  }
329 #ifdef MMAP_GPIO
330  else if( !strcmp(OptsMethod, "mmap") )
331  {
332  ec = mmapBitBang();
333  }
334 #endif // MMAP_GPIO
335  else
336  {
337  fprintf(stderr,"%s: Unknown GPIO access method.", OptsMethod);
338  ec = APP_EC_ARGS;
339  }
340 
341  return ec;
342 }
343 
344 /*!
345  * \}
346  */
#define APP_EC_EXEC
execution exit code
Definition: gpiobitbang.cxx:55
static void mainInit(int argc, char *argv[])
Main initialization.
int main(int argc, char *argv[])
Main.
int gpioOpen(int gpio)
Open GPIO pin.
Definition: gpio.c:492
#define APP_EC_OK
success exit code
Definition: gpiobitbang.cxx:53
GPIO interface declarations and defines.
static OptsInfo_T OptsInfo[]
Command line options information.
Definition: gpiobitbang.cxx:95
#define APP_EC_ARGS
command-line options/arguments error exit code
Definition: gpiobitbang.cxx:54
static int sysfsBitBang()
Bit bang bit pattern.
static char * OptsMethod
system file system
Definition: gpiobitbang.cxx:58
int gpioBitBang(int fd, byte_t pattern[], size_t bitCount, unsigned int usecIbd)
Bit-bang bits out a GPIO pin.
Definition: gpio.c:558
static byte_t * ArgsPattern
bit pattern to write
Definition: gpiobitbang.cxx:61
static size_t PatByteCount
pattern byte count
Definition: gpiobitbang.cxx:62
int gpioClose(int fd)
Close GPIO pin.
Definition: gpio.c:510
static int ArgsGpio
gpio number
Definition: gpiobitbang.cxx:60
static size_t PatBitCount
pattern bit count
Definition: gpiobitbang.cxx:63
static const PkgInfo_T PkgInfo
Definition: version.h:45
static char * Argv0
the command
Definition: gpiobitbang.cxx:57
Package version information.
static int OptsIbd
inter-bit delay
Definition: gpiobitbang.cxx:59
static OptsPgmInfo_T PgmInfo
Program information.
Definition: gpiobitbang.cxx:69