Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 

1412 строки
34 KiB

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