選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

gpio.c 35 KiB

8ヶ月前
8ヶ月前
6ヶ月前
8ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
6ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
8ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
9ヶ月前
9ヶ月前
9ヶ月前
8ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
6ヶ月前
8ヶ月前
8ヶ月前
6ヶ月前
6ヶ月前
9ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431
  1. /*
  2. * gpio.c:
  3. * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
  4. * Pi's GPIO.
  5. * Copyright (c) 2012-2024 Gordon Henderson and contributors
  6. ***********************************************************************
  7. * This file is part of wiringPi:
  8. * https://github.com/WiringPi/WiringPi/
  9. *
  10. * wiringPi is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Lesser General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * wiringPi is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <stdint.h>
  27. #include <ctype.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30. #include <errno.h>
  31. #include <fcntl.h>
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #include <wiringPi.h>
  35. #include <wpiExtensions.h>
  36. #include <gertboard.h>
  37. #include <piFace.h>
  38. #include "../version.h"
  39. extern int wiringPiDebug ;
  40. int gpioDebug ;
  41. // External functions I can't be bothered creating a separate .h file for:
  42. extern void doReadall (void) ;
  43. extern void doAllReadall (void) ;
  44. extern void doQmode (int argc, char *argv []) ;
  45. #ifndef TRUE
  46. # define TRUE (1==1)
  47. # define FALSE (1==2)
  48. #endif
  49. #define PI_USB_POWER_CONTROL 38
  50. #define I2CDETECT "i2cdetect"
  51. #define MODPROBE "modprobe"
  52. #define RMMOD "rmmod"
  53. int wpMode ;
  54. char *usage = "Usage: gpio -v\n"
  55. " gpio -h\n"
  56. " gpio [-g|-1] ...\n"
  57. " gpio [-d] ...\n"
  58. " [-x extension:params] [[ -x ...]] ...\n"
  59. " gpio [-p] <read/write/wb> ...\n"
  60. " gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n"
  61. " gpio <toggle/blink> <pin>\n"
  62. " gpio readall\n"
  63. // " gpio unexportall/exports\n"
  64. // " gpio export/edge/unexport ...\n"
  65. " gpio wfi <pin> <mode>\n"
  66. " gpio drive <group> <value>\n"
  67. " gpio pwm-bal/pwm-ms \n"
  68. " gpio pwmr <range> \n"
  69. " gpio pwmc <divider> \n"
  70. " gpio load spi/i2c\n"
  71. " gpio unload spi/i2c\n"
  72. " gpio i2cd/i2cdetect\n"
  73. " gpio rbx/rbd\n"
  74. " gpio wb <value>\n"
  75. " gpio usbp high/low\n"
  76. " gpio gbr <channel>\n"
  77. " gpio gbw <channel> <value>" ; // No trailing newline needed here.
  78. #ifdef NOT_FOR_NOW
  79. /*
  80. * decodePin:
  81. * Decode a pin "number" which can actually be a pin name to represent
  82. * one of the Pi's on-board pins.
  83. *********************************************************************************
  84. */
  85. static int decodePin (const char *str)
  86. {
  87. // The first case - see if it's a number:
  88. if (isdigit (str [0]))
  89. return atoi (str) ;
  90. return 0 ;
  91. }
  92. #endif
  93. /*
  94. * findExecutable:
  95. * Code to locate the path to the given executable. We have a fixed list
  96. * of locations to try which completely overrides any $PATH environment.
  97. * This may be detrimental, however it avoids the reliance on $PATH
  98. * which may be a security issue when this program is run a set-uid-root.
  99. *********************************************************************************
  100. */
  101. static const char *searchPath [] =
  102. {
  103. "/sbin",
  104. "/usr/sbin",
  105. "/bin",
  106. "/usr/bin",
  107. NULL,
  108. } ;
  109. static char *findExecutable (const char *progName)
  110. {
  111. static char *path = NULL ;
  112. int len = strlen (progName) ;
  113. int i = 0 ;
  114. struct stat statBuf ;
  115. for (i = 0 ; searchPath [i] != NULL ; ++i)
  116. {
  117. path = malloc (strlen (searchPath [i]) + len + 2) ;
  118. sprintf (path, "%s/%s", searchPath [i], progName) ;
  119. if (stat (path, &statBuf) == 0)
  120. return path ;
  121. free (path) ;
  122. }
  123. return NULL ;
  124. }
  125. /*
  126. * changeOwner:
  127. * Change the ownership of the file to the real userId of the calling
  128. * program so we can access it.
  129. *********************************************************************************
  130. */
  131. static void changeOwner (char *cmd, char *file)
  132. {
  133. uid_t uid = getuid () ;
  134. uid_t gid = getgid () ;
  135. if (chown (file, uid, gid) != 0)
  136. {
  137. // Removed (ignoring) the check for not existing as I'm fed-up with morons telling me that
  138. // the warning message is an error.
  139. if (errno != ENOENT)
  140. fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
  141. }
  142. }
  143. /*
  144. * moduleLoaded:
  145. * Return true/false if the supplied module is loaded
  146. *********************************************************************************
  147. */
  148. static int moduleLoaded (char *modName)
  149. {
  150. int len = strlen (modName) ;
  151. int found = FALSE ;
  152. FILE *fd = fopen ("/proc/modules", "r") ;
  153. char line [80] ;
  154. if (fd == NULL)
  155. {
  156. fprintf (stderr, "gpio: Unable to check /proc/modules: %s\n", strerror (errno)) ;
  157. exit (1) ;
  158. }
  159. while (fgets (line, 80, fd) != NULL)
  160. {
  161. if (strncmp (line, modName, len) != 0)
  162. continue ;
  163. found = TRUE ;
  164. break ;
  165. }
  166. fclose (fd) ;
  167. return found ;
  168. }
  169. /*
  170. * doLoad:
  171. * Load either the spi or i2c modules and change device ownerships, etc.
  172. *********************************************************************************
  173. */
  174. static void checkDevTree (char *argv [])
  175. {
  176. struct stat statBuf ;
  177. if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
  178. {
  179. fprintf (stderr,
  180. "%s: Unable to load/unload modules as this Pi has the device tree enabled.\n"
  181. " You need to run the raspi-config program (as root) and select the\n"
  182. " modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ;
  183. exit (1) ;
  184. }
  185. }
  186. static void _doLoadUsage (char *argv [])
  187. {
  188. fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
  189. exit (1) ;
  190. }
  191. static void doLoad (int argc, char *argv [])
  192. {
  193. char *module1, *module2 ;
  194. char cmd [80] ;
  195. char *file1, *file2 ;
  196. char args1 [32], args2 [32] ;
  197. checkDevTree (argv) ;
  198. if (argc < 3)
  199. _doLoadUsage (argv) ;
  200. args1 [0] = args2 [0] = 0 ;
  201. /**/ if (strcasecmp (argv [2], "spi") == 0)
  202. {
  203. module1 = "spidev" ;
  204. module2 = "spi_bcm2708" ;
  205. file1 = "/dev/spidev0.0" ;
  206. file2 = "/dev/spidev0.1" ;
  207. if (argc == 4)
  208. {
  209. fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
  210. exit (1) ;
  211. }
  212. else if (argc > 4)
  213. _doLoadUsage (argv) ;
  214. }
  215. else if (strcasecmp (argv [2], "i2c") == 0)
  216. {
  217. module1 = "i2c_dev" ;
  218. module2 = "i2c_bcm2708" ;
  219. file1 = "/dev/i2c-0" ;
  220. file2 = "/dev/i2c-1" ;
  221. if (argc == 4)
  222. sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
  223. else if (argc > 4)
  224. _doLoadUsage (argv) ;
  225. }
  226. else
  227. _doLoadUsage (argv) ;
  228. if (findExecutable ("modprobe") == NULL)
  229. printf ("No found\n") ;
  230. if (!moduleLoaded (module1))
  231. {
  232. sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
  233. int ret = system(cmd);
  234. if (ret == -1) {
  235. perror("Error executing command");
  236. } else if (WIFEXITED(ret)) {
  237. int exit_status = WEXITSTATUS(ret);
  238. if (exit_status != 0) {
  239. fprintf(stderr, "Command failed with exit status %d\n", exit_status);
  240. }
  241. } else {
  242. fprintf(stderr, "Command terminated by signal\n");
  243. }
  244. }
  245. if (!moduleLoaded (module2))
  246. {
  247. sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
  248. int ret = system(cmd);
  249. if (ret == -1) {
  250. perror("Error executing command");
  251. } else if (WIFEXITED(ret)) {
  252. int exit_status = WEXITSTATUS(ret);
  253. if (exit_status != 0) {
  254. fprintf(stderr, "Command failed with exit status %d\n", exit_status);
  255. }
  256. } else {
  257. fprintf(stderr, "Command terminated by signal\n");
  258. }
  259. }
  260. if (!moduleLoaded (module2))
  261. {
  262. fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
  263. exit (1) ;
  264. }
  265. sleep (1) ; // To let things get settled
  266. changeOwner (argv [0], file1) ;
  267. changeOwner (argv [0], file2) ;
  268. }
  269. /*
  270. * doUnLoad:
  271. * Un-Load either the spi or i2c modules and change device ownerships, etc.
  272. *********************************************************************************
  273. */
  274. static void _doUnLoadUsage (char *argv [])
  275. {
  276. fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
  277. exit (1) ;
  278. }
  279. static void doUnLoad (int argc, char *argv [])
  280. {
  281. char *module1, *module2 ;
  282. char cmd [80] ;
  283. checkDevTree (argv) ;
  284. if (argc != 3)
  285. _doUnLoadUsage (argv) ;
  286. /**/ if (strcasecmp (argv [2], "spi") == 0)
  287. {
  288. module1 = "spidev" ;
  289. module2 = "spi_bcm2708" ;
  290. }
  291. else if (strcasecmp (argv [2], "i2c") == 0)
  292. {
  293. module1 = "i2c_dev" ;
  294. module2 = "i2c_bcm2708" ;
  295. }
  296. else
  297. _doUnLoadUsage (argv) ;
  298. if (moduleLoaded (module1))
  299. {
  300. sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
  301. int ret = system(cmd);
  302. if (ret == -1) {
  303. perror("Error executing command");
  304. } else if (WIFEXITED(ret)) {
  305. int exit_status = WEXITSTATUS(ret);
  306. if (exit_status != 0) {
  307. fprintf(stderr, "Command failed with exit status %d\n", exit_status);
  308. }
  309. } else {
  310. fprintf(stderr, "Command terminated by signal\n");
  311. }
  312. }
  313. if (moduleLoaded (module2))
  314. {
  315. sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
  316. int ret = system(cmd);
  317. if (ret == -1) {
  318. perror("Error executing command");
  319. } else if (WIFEXITED(ret)) {
  320. int exit_status = WEXITSTATUS(ret);
  321. if (exit_status != 0) {
  322. fprintf(stderr, "Command failed with exit status %d\n", exit_status);
  323. }
  324. } else {
  325. fprintf(stderr, "Command terminated by signal\n");
  326. }
  327. }
  328. }
  329. /*
  330. * doI2Cdetect:
  331. * Run the i2cdetect command with the right runes for this Pi revision
  332. *********************************************************************************
  333. */
  334. static void doI2Cdetect (UNU int argc, char *argv [])
  335. {
  336. int port = piGpioLayout () == GPIO_LAYOUT_PI1_REV1 ? 0 : 1 ;
  337. char *c, *command ;
  338. if ((c = findExecutable (I2CDETECT)) == NULL)
  339. {
  340. fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
  341. return ;
  342. }
  343. if (!moduleLoaded ("i2c_dev"))
  344. {
  345. fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
  346. return ;
  347. }
  348. command = malloc (strlen (c) + 16) ;
  349. sprintf (command, "%s -y %d", c, port) ;
  350. if (system (command) < 0)
  351. fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
  352. }
  353. void SYSFS_DEPRECATED(const char *progName) {
  354. fprintf(stderr, "%s: GPIO Sysfs Interface for Userspace is deprecated (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).\n Function is now useless and empty.\n\n", progName);
  355. }
  356. /*
  357. * doExports: -> deprecated, removed
  358. * List all GPIO exports
  359. *********************************************************************************
  360. */
  361. /*
  362. * doExport: -> deprecated, removed
  363. * gpio export pin mode
  364. * This uses the /sys/class/gpio device interface.
  365. *********************************************************************************
  366. */
  367. /*
  368. * doWfi:
  369. * gpio wfi pin mode
  370. * Wait for Interrupt on a given pin.
  371. * Slight cheat here - it's easier to actually use ISR now (which calls
  372. * gpio to set the pin modes!) then we simply sleep, and expect the thread
  373. * to exit the program. Crude but effective.
  374. *********************************************************************************
  375. */
  376. static volatile int iterations ;
  377. static volatile int globalCounter ;
  378. void printgpioflush(const char* text) {
  379. if (gpioDebug) {
  380. printf("%s", text);
  381. fflush(stdout);
  382. }
  383. }
  384. void printgpio(const char* text) {
  385. if (gpioDebug) {
  386. printf("%s", text);
  387. }
  388. }
  389. static void wfi (void) {
  390. globalCounter++;
  391. if(globalCounter>=iterations) {
  392. printgpio("finished\n");
  393. exit (0) ;
  394. } else {
  395. printgpioflush("I");
  396. }
  397. }
  398. void doWfi (int argc, char *argv [])
  399. {
  400. int pin, mode;
  401. int timeoutSec = 2147483647;
  402. iterations = 1;
  403. globalCounter = 0;
  404. if (argc != 4 && argc != 5 && argc != 6)
  405. {
  406. fprintf (stderr, "Usage: %s wfi pin mode [interations] [timeout sec.]\n", argv [0]) ;
  407. exit (1) ;
  408. }
  409. pin = atoi (argv [2]) ;
  410. /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
  411. else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
  412. else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
  413. else
  414. {
  415. fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
  416. exit (1) ;
  417. }
  418. if (argc>=5) {
  419. iterations = atoi(argv [4]);
  420. }
  421. if (argc>=6) {
  422. timeoutSec = atoi(argv [5]);
  423. }
  424. if (wiringPiISR (pin, mode, &wfi) < 0)
  425. {
  426. fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
  427. exit (1) ;
  428. }
  429. printgpio("wait for interrupt function call\n");
  430. for (int Sec=0; Sec<timeoutSec; ++Sec) {
  431. printgpioflush(".");
  432. delay (999);
  433. }
  434. printgpio("\nstopping wait for interrupt\n");
  435. wiringPiISRStop (pin);
  436. }
  437. /*
  438. * doEdge: -> deprecated, removed
  439. * gpio edge pin mode
  440. * Easy access to changing the edge trigger on a GPIO pin
  441. * This uses the /sys/class/gpio device interface.
  442. *********************************************************************************
  443. */
  444. /*
  445. * doUnexport: -> deprecated, removed
  446. * gpio unexport pin
  447. * This uses the /sys/class/gpio device interface.
  448. *********************************************************************************
  449. */
  450. /*
  451. * doUnexportAll: -> deprecated, removed
  452. * gpio unexportall
  453. * Un-Export all the GPIO pins.
  454. * This uses the /sys/class/gpio device interface.
  455. *********************************************************************************
  456. */
  457. /*
  458. * doReset:
  459. * Reset the GPIO pins - as much as we can do
  460. *********************************************************************************
  461. */
  462. static void doReset (UNU char *progName)
  463. {
  464. printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
  465. printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
  466. printf (" that you need them in for your applications.\n") ;
  467. }
  468. /*
  469. * doMode:
  470. * gpio mode pin mode ...
  471. *********************************************************************************
  472. */
  473. void doMode (int argc, char *argv [])
  474. {
  475. int pin ;
  476. char *mode ;
  477. if (argc != 4)
  478. {
  479. fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
  480. exit (1) ;
  481. }
  482. pin = atoi (argv [2]) ;
  483. mode = argv [3] ;
  484. /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
  485. else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
  486. else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
  487. else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
  488. else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
  489. else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
  490. else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
  491. else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
  492. else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
  493. else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
  494. else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
  495. else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
  496. else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
  497. else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
  498. else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
  499. else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
  500. else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
  501. else
  502. {
  503. fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
  504. exit (1) ;
  505. }
  506. }
  507. /*
  508. * doPadDrive:
  509. * gpio drive group value
  510. *********************************************************************************
  511. */
  512. static void doPadDrivePin (int argc, char *argv [])
  513. {
  514. if (argc != 4) {
  515. fprintf (stderr, "Usage: %s drivepin pin value\n", argv [0]) ;
  516. exit (1) ;
  517. }
  518. int pin = atoi (argv [2]) ;
  519. int val = atoi (argv [3]) ;
  520. if ((pin < 0) || (pin > 27)) {
  521. fprintf (stderr, "%s: drive pin not 0-27: %d\n", argv [0], pin) ;
  522. exit (1) ;
  523. }
  524. if ((val < 0) || (val > 3)) {
  525. fprintf (stderr, "%s: drive value not 0-3: %d\n", argv [0], val) ;
  526. exit (1) ;
  527. }
  528. setPadDrivePin (pin, val) ;
  529. }
  530. static void doPadDrive (int argc, char *argv [])
  531. {
  532. int group, val ;
  533. if (argc != 4)
  534. {
  535. fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
  536. exit (1) ;
  537. }
  538. group = atoi (argv [2]) ;
  539. val = atoi (argv [3]) ;
  540. if ((group < -1) || (group > 2)) //-1 hidden feature for read and print values
  541. {
  542. fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
  543. exit (1) ;
  544. }
  545. if ((val < 0) || (val > 7))
  546. {
  547. fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
  548. exit (1) ;
  549. }
  550. setPadDrive (group, val) ;
  551. }
  552. /*
  553. * doUsbP:
  554. * Control USB Power - High (1.2A) or Low (600mA)
  555. * gpio usbp high/low
  556. *********************************************************************************
  557. */
  558. static void doUsbP (int argc, char *argv [])
  559. {
  560. int model, rev, mem, maker, overVolted ;
  561. if (argc != 3)
  562. {
  563. fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
  564. exit (1) ;
  565. }
  566. // Make sure we're on a B+
  567. piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
  568. if (!((model == PI_MODEL_BP) || (model == PI_MODEL_2)))
  569. {
  570. fprintf (stderr, "USB power contol is applicable to B+ and v2 boards only.\n") ;
  571. exit (1) ;
  572. }
  573. // Make sure we start in BCM_GPIO mode
  574. wiringPiSetupGpio () ;
  575. if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
  576. {
  577. digitalWrite (PI_USB_POWER_CONTROL, 1) ;
  578. pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
  579. printf ("Switched to HIGH current USB (1.2A)\n") ;
  580. return ;
  581. }
  582. if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
  583. {
  584. digitalWrite (PI_USB_POWER_CONTROL, 0) ;
  585. pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
  586. printf ("Switched to LOW current USB (600mA)\n") ;
  587. return ;
  588. }
  589. fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
  590. exit (1) ;
  591. }
  592. /*
  593. * doGbw:
  594. * gpio gbw channel value
  595. * Gertboard Write - To the Analog output
  596. *********************************************************************************
  597. */
  598. static void doGbw (int argc, char *argv [])
  599. {
  600. int channel, value ;
  601. if (argc != 4)
  602. {
  603. fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
  604. exit (1) ;
  605. }
  606. channel = atoi (argv [2]) ;
  607. value = atoi (argv [3]) ;
  608. if ((channel < 0) || (channel > 1))
  609. {
  610. fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
  611. exit (1) ;
  612. }
  613. if ((value < 0) || (value > 255))
  614. {
  615. fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
  616. exit (1) ;
  617. }
  618. if (gertboardAnalogSetup (64) < 0)
  619. {
  620. fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
  621. exit (1) ;
  622. }
  623. analogWrite (64 + channel, value) ;
  624. }
  625. /*
  626. * doGbr:
  627. * gpio gbr channel
  628. * From the analog input
  629. *********************************************************************************
  630. */
  631. static void doGbr (int argc, char *argv [])
  632. {
  633. int channel ;
  634. if (argc != 3)
  635. {
  636. fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
  637. exit (1) ;
  638. }
  639. channel = atoi (argv [2]) ;
  640. if ((channel < 0) || (channel > 1))
  641. {
  642. fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
  643. exit (1) ;
  644. }
  645. if (gertboardAnalogSetup (64) < 0)
  646. {
  647. fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
  648. exit (1) ;
  649. }
  650. printf ("%d\n", analogRead (64 + channel)) ;
  651. }
  652. /*
  653. * doWrite:
  654. * gpio write pin value
  655. *********************************************************************************
  656. */
  657. static void doWrite (int argc, char *argv [])
  658. {
  659. int pin, val ;
  660. if (argc != 4)
  661. {
  662. fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
  663. exit (1) ;
  664. }
  665. pin = atoi (argv [2]) ;
  666. /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
  667. val = 1 ;
  668. else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
  669. val = 0 ;
  670. else
  671. val = atoi (argv [3]) ;
  672. /**/ if (val == 0)
  673. digitalWrite (pin, LOW) ;
  674. else
  675. digitalWrite (pin, HIGH) ;
  676. }
  677. /*
  678. * doAwriterite:
  679. * gpio awrite pin value
  680. *********************************************************************************
  681. */
  682. static void doAwrite (int argc, char *argv [])
  683. {
  684. int pin, val ;
  685. if (argc != 4)
  686. {
  687. fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
  688. exit (1) ;
  689. }
  690. pin = atoi (argv [2]) ;
  691. val = atoi (argv [3]) ;
  692. analogWrite (pin, val) ;
  693. }
  694. /*
  695. * doWriteByte:
  696. * gpio wb value
  697. *********************************************************************************
  698. */
  699. static void doWriteByte (int argc, char *argv [])
  700. {
  701. int val ;
  702. if (argc != 3)
  703. {
  704. fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
  705. exit (1) ;
  706. }
  707. val = (int)strtol (argv [2], NULL, 0) ;
  708. digitalWriteByte (val) ;
  709. }
  710. /*
  711. * doReadByte:
  712. * gpio rbx|rbd value
  713. *********************************************************************************
  714. */
  715. static void doReadByte (int argc, char *argv [], int printHex)
  716. {
  717. int val ;
  718. if (argc != 2)
  719. {
  720. fprintf (stderr, "Usage: %s rbx|rbd\n", argv [0]) ;
  721. exit (1) ;
  722. }
  723. val = digitalReadByte () ;
  724. if (printHex)
  725. printf ("%02X\n", val) ;
  726. else
  727. printf ("%d\n", val) ;
  728. }
  729. /*
  730. * doRead:
  731. * Read a pin and return the value
  732. *********************************************************************************
  733. */
  734. void doRead (int argc, char *argv [])
  735. {
  736. int pin, val ;
  737. if (argc != 3)
  738. {
  739. fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
  740. exit (1) ;
  741. }
  742. pin = atoi (argv [2]) ;
  743. val = digitalRead (pin) ;
  744. printf ("%s\n", val == 0 ? "0" : "1") ;
  745. }
  746. /*
  747. * doAread:
  748. * Read an analog pin and return the value
  749. *********************************************************************************
  750. */
  751. void doAread (int argc, char *argv [])
  752. {
  753. if (argc != 3)
  754. {
  755. fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
  756. exit (1) ;
  757. }
  758. printf ("%d\n", analogRead (atoi (argv [2]))) ;
  759. }
  760. /*
  761. * doToggle:
  762. * Toggle an IO pin
  763. *********************************************************************************
  764. */
  765. void doToggle (int argc, char *argv [])
  766. {
  767. int pin ;
  768. if (argc != 3)
  769. {
  770. fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
  771. exit (1) ;
  772. }
  773. pin = atoi (argv [2]) ;
  774. digitalWrite (pin, !digitalRead (pin)) ;
  775. }
  776. /*
  777. * doBlink:
  778. * Blink an IO pin
  779. *********************************************************************************
  780. */
  781. void doBlink (int argc, char *argv [])
  782. {
  783. int pin ;
  784. if (argc != 3)
  785. {
  786. fprintf (stderr, "Usage: %s blink pin\n", argv [0]) ;
  787. exit (1) ;
  788. }
  789. pin = atoi (argv [2]) ;
  790. pinMode (pin, OUTPUT) ;
  791. for (;;)
  792. {
  793. digitalWrite (pin, !digitalRead (pin)) ;
  794. delay (500) ;
  795. }
  796. }
  797. /*
  798. * doPwmTone:
  799. * Output a tone in a PWM pin
  800. *********************************************************************************
  801. */
  802. void doPwmTone (int argc, char *argv [])
  803. {
  804. int pin, freq ;
  805. if (argc != 4)
  806. {
  807. fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
  808. exit (1) ;
  809. }
  810. pin = atoi (argv [2]) ;
  811. freq = atoi (argv [3]) ;
  812. pwmToneWrite (pin, freq) ;
  813. }
  814. /*
  815. * doClock:
  816. * Output a clock on a pin
  817. *********************************************************************************
  818. */
  819. void doClock (int argc, char *argv [])
  820. {
  821. int pin, freq ;
  822. if (argc != 4)
  823. {
  824. fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
  825. exit (1) ;
  826. }
  827. pin = atoi (argv [2]) ;
  828. freq = atoi (argv [3]) ;
  829. gpioClockSet (pin, freq) ;
  830. }
  831. /*
  832. * doPwm:
  833. * Output a PWM value on a pin
  834. *********************************************************************************
  835. */
  836. void doPwm (int argc, char *argv [])
  837. {
  838. int pin, val ;
  839. if (argc != 4)
  840. {
  841. fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
  842. exit (1) ;
  843. }
  844. pin = atoi (argv [2]) ;
  845. val = atoi (argv [3]) ;
  846. pwmWrite (pin, val) ;
  847. }
  848. /*
  849. * doPwmMode: doPwmRange: doPwmClock:
  850. * Change the PWM mode, range and clock divider values
  851. *********************************************************************************
  852. */
  853. static void doPwmMode (int mode)
  854. {
  855. pwmSetMode (mode) ;
  856. }
  857. static void doPwmRange (int argc, char *argv [])
  858. {
  859. unsigned int range ;
  860. if (argc != 3)
  861. {
  862. fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
  863. exit (1) ;
  864. }
  865. range = (unsigned int)strtoul (argv [2], NULL, 10) ;
  866. if (range == 0)
  867. {
  868. fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
  869. exit (1) ;
  870. }
  871. pwmSetRange (range) ;
  872. }
  873. static void doPwmClock (int argc, char *argv [])
  874. {
  875. unsigned int clock ;
  876. if (argc != 3)
  877. {
  878. fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
  879. exit (1) ;
  880. }
  881. clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
  882. if ((clock < 1) || (clock > 4095))
  883. {
  884. fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
  885. exit (1) ;
  886. }
  887. pwmSetClock (clock) ;
  888. }
  889. /*
  890. * doVersion:
  891. * Handle the ever more complicated version command and print out
  892. * some usefull information.
  893. *********************************************************************************
  894. */
  895. static void doVersion (char *argv [])
  896. {
  897. int model, rev, mem, maker, warranty ;
  898. struct stat statBuf ;
  899. char name [80] ;
  900. FILE *fd ;
  901. int vMaj, vMin ;
  902. wiringPiVersion (&vMaj, &vMin) ;
  903. printf ("gpio version: %d.%d\n", vMaj, vMin) ;
  904. printf ("Copyright (c) 2012-2024 Gordon Henderson and contributors\n") ;
  905. printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
  906. printf ("For details type: %s -warranty\n", argv [0]) ;
  907. printf ("\n") ;
  908. piBoardId (&model, &rev, &mem, &maker, &warranty) ;
  909. printf ("Hardware details:\n") ;
  910. printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
  911. piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ;
  912. // Check for device tree
  913. printf ("\nSystem details:\n") ;
  914. if (stat ("/proc/device-tree", &statBuf) == 0) { // We're on a devtree system ...
  915. printf (" * Device tree present.\n") ;
  916. }
  917. if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type
  918. {
  919. if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL)
  920. {
  921. if (fgets(name, sizeof(name), fd) == NULL) {
  922. // Handle error or end of file condition
  923. perror("Error reading /proc/device-tree/model");
  924. }
  925. fclose (fd) ;
  926. printf (" Model: %s\n", name) ;
  927. }
  928. }
  929. int bGlobalAccess = wiringPiGlobalMemoryAccess(); // User level GPIO is GO
  930. switch(bGlobalAccess) {
  931. case 0:
  932. printf (" * Does not support basic user-level GPIO access via memory.\n") ;
  933. break;
  934. case 1:
  935. printf (" * Supports basic user-level GPIO access via /dev/mem.\n") ;
  936. break;
  937. case 2:
  938. printf (" * Supports full user-level GPIO access via memory.\n") ;
  939. break;
  940. }
  941. if (wiringPiUserLevelAccess()) {
  942. printf (" * Supports basic user-level GPIO access via /dev/gpiomem.\n") ;
  943. } else {
  944. printf (" * Does not support basic user-level GPIO access via /dev/gpiomem.\n") ;
  945. if(0==bGlobalAccess) {
  946. printf (" * root or sudo may be required for direct GPIO access.\n") ;
  947. }
  948. }
  949. if (wiringPiGpioDeviceGetFd()>0) {
  950. printf (" * Supports basic user-level GPIO access via /dev/gpiochip (slow).\n") ;
  951. }
  952. }
  953. /*
  954. * main:
  955. * Start here
  956. *********************************************************************************
  957. */
  958. int main (int argc, char *argv [])
  959. {
  960. int i ;
  961. if (getenv ("WIRINGPI_DEBUG") != NULL)
  962. {
  963. printf ("gpio: wiringPi debug mode enabled\n") ;
  964. wiringPiDebug = TRUE ;
  965. }
  966. if (getenv ("GPIO_DEBUG") != NULL)
  967. {
  968. printf ("gpio: gpio debug mode enabled\n") ;
  969. gpioDebug = TRUE ;
  970. }
  971. if (argc == 1)
  972. {
  973. fprintf (stderr,
  974. "%s: At your service!\n"
  975. " Type: gpio -h for full details and\n"
  976. " gpio readall for a quick printout of your connector details\n", argv [0]) ;
  977. exit (EXIT_FAILURE) ;
  978. }
  979. // Help
  980. if (strcasecmp (argv [1], "-h") == 0)
  981. {
  982. printf ("%s: %s\n", argv [0], usage) ;
  983. exit (EXIT_SUCCESS) ;
  984. }
  985. // Version & Warranty
  986. // Wish I could remember why I have both -R and -V ...
  987. if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
  988. {
  989. printf ("%d\n", piGpioLayout ()) ;
  990. exit (EXIT_SUCCESS) ;
  991. }
  992. // Version and information
  993. if (strcmp (argv [1], "-v") == 0)
  994. {
  995. doVersion (argv) ;
  996. exit (EXIT_SUCCESS) ;
  997. }
  998. if (strcasecmp (argv [1], "-warranty") == 0)
  999. {
  1000. printf ("gpio version: %s\n", VERSION) ;
  1001. printf ("Copyright (c) 2012-2024 Gordon Henderson and contributors\n") ;
  1002. printf ("\n") ;
  1003. printf (" This program is free software; you can redistribute it and/or modify\n") ;
  1004. printf (" it under the terms of the GNU Leser General Public License as published\n") ;
  1005. printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
  1006. printf (" (at your option) any later version.\n") ;
  1007. printf ("\n") ;
  1008. printf (" This program is distributed in the hope that it will be useful,\n") ;
  1009. printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
  1010. printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
  1011. printf (" GNU Lesser General Public License for more details.\n") ;
  1012. printf ("\n") ;
  1013. printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
  1014. printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
  1015. printf ("\n") ;
  1016. exit (EXIT_SUCCESS) ;
  1017. }
  1018. if (geteuid () != 0)
  1019. {
  1020. fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
  1021. exit (EXIT_FAILURE) ;
  1022. }
  1023. // Initial test for /sys/class/gpio operations: - -> deprecated, empty but still there
  1024. /**/ if (strcasecmp (argv [1], "exports" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
  1025. else if (strcasecmp (argv [1], "export" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
  1026. else if (strcasecmp (argv [1], "edge" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
  1027. else if (strcasecmp (argv [1], "unexport" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
  1028. else if (strcasecmp (argv [1], "unexportall") == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
  1029. // Check for load command:
  1030. if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
  1031. if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
  1032. // Check for usb power command
  1033. if (strcasecmp (argv [1], "usbp" ) == 0) { doUsbP (argc, argv) ; return 0 ; }
  1034. // Gertboard commands
  1035. if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
  1036. if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
  1037. // Check for allreadall command, force Gpio mode
  1038. if (strcasecmp (argv [1], "allreadall") == 0)
  1039. {
  1040. wiringPiSetupGpio () ;
  1041. doAllReadall () ;
  1042. return 0 ;
  1043. }
  1044. // Check for -g argument
  1045. /**/ if (strcasecmp (argv [1], "-g") == 0)
  1046. {
  1047. wiringPiSetupGpio () ;
  1048. for (i = 2 ; i < argc ; ++i)
  1049. argv [i - 1] = argv [i] ;
  1050. --argc ;
  1051. wpMode = WPI_MODE_GPIO ;
  1052. }
  1053. // Check for -1 argument
  1054. else if (strcasecmp (argv [1], "-1") == 0)
  1055. {
  1056. wiringPiSetupPhys () ;
  1057. for (i = 2 ; i < argc ; ++i)
  1058. argv [i - 1] = argv [i] ;
  1059. --argc ;
  1060. wpMode = WPI_MODE_PHYS ;
  1061. }
  1062. // Check for -p argument for PiFace
  1063. else if (strcasecmp (argv [1], "-p") == 0)
  1064. {
  1065. piFaceSetup (200) ;
  1066. for (i = 2 ; i < argc ; ++i)
  1067. argv [i - 1] = argv [i] ;
  1068. --argc ;
  1069. wpMode = WPI_MODE_PIFACE ;
  1070. }
  1071. // Check for -z argument so we don't actually initialise wiringPi
  1072. else if (strcasecmp (argv [1], "-z") == 0)
  1073. {
  1074. for (i = 2 ; i < argc ; ++i)
  1075. argv [i - 1] = argv [i] ;
  1076. --argc ;
  1077. wpMode = WPI_MODE_UNINITIALISED ;
  1078. }
  1079. // Default to wiringPi mode
  1080. else
  1081. {
  1082. wiringPiSetup () ;
  1083. wpMode = WPI_MODE_PINS ;
  1084. }
  1085. // Check for -x argument to load in a new extension
  1086. // -x extension:base:args
  1087. // Can load many modules, but unless daemon mode we can only send one
  1088. // command at a time.
  1089. while (strcasecmp (argv [1], "-x") == 0)
  1090. {
  1091. if (argc < 3)
  1092. {
  1093. fprintf (stderr, "%s: -x missing extension command.\n", argv [0]) ;
  1094. exit (EXIT_FAILURE) ;
  1095. }
  1096. if (!loadWPiExtension (argv [0], argv [2], TRUE))
  1097. {
  1098. fprintf (stderr, "%s: Extension load failed: %s\n", argv [0], strerror (errno)) ;
  1099. exit (EXIT_FAILURE) ;
  1100. }
  1101. // Shift args down by 2
  1102. for (i = 3 ; i < argc ; ++i)
  1103. argv [i - 2] = argv [i] ;
  1104. argc -= 2 ;
  1105. }
  1106. if (argc <= 1)
  1107. {
  1108. fprintf (stderr, "%s: no command given\n", argv [0]) ;
  1109. exit (EXIT_FAILURE) ;
  1110. }
  1111. // Core wiringPi functions
  1112. /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
  1113. else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
  1114. else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
  1115. else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
  1116. else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
  1117. else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
  1118. // GPIO Nicies
  1119. else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
  1120. else if (strcasecmp (argv [1], "blink" ) == 0) doBlink (argc, argv) ;
  1121. // Pi Specifics
  1122. else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
  1123. else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
  1124. else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
  1125. else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
  1126. else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
  1127. else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
  1128. else if (strcasecmp (argv [1], "drivepin" ) == 0) doPadDrivePin(argc, argv) ;
  1129. else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
  1130. else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
  1131. else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ;
  1132. else if (strcasecmp (argv [1], "qmode" ) == 0) doQmode (argc, argv) ;
  1133. else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
  1134. else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
  1135. else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
  1136. else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
  1137. else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ;
  1138. else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ;
  1139. else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
  1140. else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
  1141. else
  1142. {
  1143. fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
  1144. exit (EXIT_FAILURE) ;
  1145. }
  1146. return 0 ;
  1147. }