You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1208 lines
28 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-2013 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 <gertboard.h>
  36. #include <piFace.h>
  37. #include "extensions.h"
  38. extern int wiringPiDebug ;
  39. extern void doReadall (void) ;
  40. extern void doReadallOld (void) ;
  41. #ifndef TRUE
  42. # define TRUE (1==1)
  43. # define FALSE (1==2)
  44. #endif
  45. #define VERSION "2.08"
  46. #define I2CDETECT "/usr/sbin/i2cdetect"
  47. int wpMode ;
  48. char *usage = "Usage: gpio -v\n"
  49. " gpio -h\n"
  50. " gpio [-g|-1] [-x extension:params] ...\n"
  51. " gpio [-p] <read/write/wb> ...\n"
  52. " gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
  53. " gpio readall/reset\n"
  54. " gpio unexportall/exports\n"
  55. " gpio export/edge/unexport ...\n"
  56. " gpio wfi <pin> <mode>\n"
  57. " gpio drive <group> <value>\n"
  58. " gpio pwm-bal/pwm-ms \n"
  59. " gpio pwmr <range> \n"
  60. " gpio pwmc <divider> \n"
  61. " gpio load spi/i2c\n"
  62. " gpio i2cd/i2cdetect\n"
  63. " gpio gbr <channel>\n"
  64. " gpio gbw <channel> <value>" ; // No trailing newline needed here.
  65. /*
  66. * changeOwner:
  67. * Change the ownership of the file to the real userId of the calling
  68. * program so we can access it.
  69. *********************************************************************************
  70. */
  71. static void changeOwner (char *cmd, char *file)
  72. {
  73. uid_t uid = getuid () ;
  74. uid_t gid = getgid () ;
  75. if (chown (file, uid, gid) != 0)
  76. {
  77. if (errno == ENOENT) // Warn that it's not there
  78. fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
  79. else
  80. {
  81. fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
  82. exit (1) ;
  83. }
  84. }
  85. }
  86. /*
  87. * moduleLoaded:
  88. * Return true/false if the supplied module is loaded
  89. *********************************************************************************
  90. */
  91. static int moduleLoaded (char *modName)
  92. {
  93. int len = strlen (modName) ;
  94. int found = FALSE ;
  95. FILE *fd = fopen ("/proc/modules", "r") ;
  96. char line [80] ;
  97. if (fd == NULL)
  98. {
  99. fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
  100. exit (1) ;
  101. }
  102. while (fgets (line, 80, fd) != NULL)
  103. {
  104. if (strncmp (line, modName, len) != 0)
  105. continue ;
  106. found = TRUE ;
  107. break ;
  108. }
  109. fclose (fd) ;
  110. return found ;
  111. }
  112. /*
  113. * doLoad:
  114. * Load either the spi or i2c modules and change device ownerships, etc.
  115. *********************************************************************************
  116. */
  117. static void _doLoadUsage (char *argv [])
  118. {
  119. fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
  120. exit (1) ;
  121. }
  122. static void doLoad (int argc, char *argv [])
  123. {
  124. char *module1, *module2 ;
  125. char cmd [80] ;
  126. char *file1, *file2 ;
  127. char args1 [32], args2 [32] ;
  128. if (argc < 3)
  129. _doLoadUsage (argv) ;
  130. args1 [0] = args2 [0] = 0 ;
  131. /**/ if (strcasecmp (argv [2], "spi") == 0)
  132. {
  133. module1 = "spidev" ;
  134. module2 = "spi_bcm2708" ;
  135. file1 = "/dev/spidev0.0" ;
  136. file2 = "/dev/spidev0.1" ;
  137. if (argc == 4)
  138. sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ;
  139. else if (argc > 4)
  140. _doLoadUsage (argv) ;
  141. }
  142. else if (strcasecmp (argv [2], "i2c") == 0)
  143. {
  144. module1 = "i2c_dev" ;
  145. module2 = "i2c_bcm2708" ;
  146. file1 = "/dev/i2c-0" ;
  147. file2 = "/dev/i2c-1" ;
  148. if (argc == 4)
  149. sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
  150. else if (argc > 4)
  151. _doLoadUsage (argv) ;
  152. }
  153. else
  154. _doLoadUsage (argv) ;
  155. if (!moduleLoaded (module1))
  156. {
  157. sprintf (cmd, "modprobe %s%s", module1, args1) ;
  158. system (cmd) ;
  159. }
  160. if (!moduleLoaded (module2))
  161. {
  162. sprintf (cmd, "modprobe %s%s", module2, args2) ;
  163. system (cmd) ;
  164. }
  165. if (!moduleLoaded (module2))
  166. {
  167. fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
  168. exit (1) ;
  169. }
  170. sleep (1) ; // To let things get settled
  171. changeOwner (argv [0], file1) ;
  172. changeOwner (argv [0], file2) ;
  173. }
  174. /*
  175. * doI2Cdetect:
  176. * Run the i2cdetect command with the right runes for this Pi revision
  177. *********************************************************************************
  178. */
  179. static void doI2Cdetect (int argc, char *argv [])
  180. {
  181. int port = piBoardRev () == 1 ? 0 : 1 ;
  182. char command [128] ;
  183. struct stat statBuf ;
  184. if (stat (I2CDETECT, &statBuf) < 0)
  185. {
  186. fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
  187. return ;
  188. }
  189. if (!moduleLoaded ("i2c_dev"))
  190. {
  191. fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
  192. return ;
  193. }
  194. sprintf (command, "%s -y %d", I2CDETECT, port) ;
  195. if (system (command) < 0)
  196. fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
  197. }
  198. /*
  199. * doExports:
  200. * List all GPIO exports
  201. *********************************************************************************
  202. */
  203. static void doExports (int argc, char *argv [])
  204. {
  205. int fd ;
  206. int i, l, first ;
  207. char fName [128] ;
  208. char buf [16] ;
  209. for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
  210. {
  211. // Try to read the direction
  212. sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
  213. if ((fd = open (fName, O_RDONLY)) == -1)
  214. continue ;
  215. if (first == 0)
  216. {
  217. ++first ;
  218. printf ("GPIO Pins exported:\n") ;
  219. }
  220. printf ("%4d: ", i) ;
  221. if ((l = read (fd, buf, 16)) == 0)
  222. sprintf (buf, "%s", "?") ;
  223. buf [l] = 0 ;
  224. if ((buf [strlen (buf) - 1]) == '\n')
  225. buf [strlen (buf) - 1] = 0 ;
  226. printf ("%-3s", buf) ;
  227. close (fd) ;
  228. // Try to Read the value
  229. sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
  230. if ((fd = open (fName, O_RDONLY)) == -1)
  231. {
  232. printf ("No Value file (huh?)\n") ;
  233. continue ;
  234. }
  235. if ((l = read (fd, buf, 16)) == 0)
  236. sprintf (buf, "%s", "?") ;
  237. buf [l] = 0 ;
  238. if ((buf [strlen (buf) - 1]) == '\n')
  239. buf [strlen (buf) - 1] = 0 ;
  240. printf (" %s", buf) ;
  241. // Read any edge trigger file
  242. sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
  243. if ((fd = open (fName, O_RDONLY)) == -1)
  244. {
  245. printf ("\n") ;
  246. continue ;
  247. }
  248. if ((l = read (fd, buf, 16)) == 0)
  249. sprintf (buf, "%s", "?") ;
  250. buf [l] = 0 ;
  251. if ((buf [strlen (buf) - 1]) == '\n')
  252. buf [strlen (buf) - 1] = 0 ;
  253. printf (" %-8s\n", buf) ;
  254. close (fd) ;
  255. }
  256. }
  257. /*
  258. * doExport:
  259. * gpio export pin mode
  260. * This uses the /sys/class/gpio device interface.
  261. *********************************************************************************
  262. */
  263. void doExport (int argc, char *argv [])
  264. {
  265. FILE *fd ;
  266. int pin ;
  267. char *mode ;
  268. char fName [128] ;
  269. if (argc != 4)
  270. {
  271. fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
  272. exit (1) ;
  273. }
  274. pin = atoi (argv [2]) ;
  275. mode = argv [3] ;
  276. if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
  277. {
  278. fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
  279. exit (1) ;
  280. }
  281. fprintf (fd, "%d\n", pin) ;
  282. fclose (fd) ;
  283. sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
  284. if ((fd = fopen (fName, "w")) == NULL)
  285. {
  286. fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
  287. exit (1) ;
  288. }
  289. /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
  290. fprintf (fd, "in\n") ;
  291. else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
  292. fprintf (fd, "out\n") ;
  293. else
  294. {
  295. fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
  296. exit (1) ;
  297. }
  298. fclose (fd) ;
  299. // Change ownership so the current user can actually use it!
  300. sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
  301. changeOwner (argv [0], fName) ;
  302. sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
  303. changeOwner (argv [0], fName) ;
  304. }
  305. /*
  306. * doWfi:
  307. * gpio wfi pin mode
  308. * Wait for Interrupt on a given pin.
  309. * Slight cheat here - it's easier to actually use ISR now (which calls
  310. * gpio to set the pin modes!) then we simply sleep, and expect the thread
  311. * to exit the program. Crude but effective.
  312. *********************************************************************************
  313. */
  314. static void wfi (void)
  315. { exit (0) ; }
  316. void doWfi (int argc, char *argv [])
  317. {
  318. int pin, mode ;
  319. if (argc != 4)
  320. {
  321. fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
  322. exit (1) ;
  323. }
  324. pin = atoi (argv [2]) ;
  325. /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
  326. else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
  327. else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
  328. else
  329. {
  330. fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
  331. exit (1) ;
  332. }
  333. if (wiringPiISR (pin, mode, &wfi) < 0)
  334. {
  335. fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
  336. exit (1) ;
  337. }
  338. for (;;)
  339. delay (9999) ;
  340. }
  341. /*
  342. * doEdge:
  343. * gpio edge pin mode
  344. * Easy access to changing the edge trigger on a GPIO pin
  345. * This uses the /sys/class/gpio device interface.
  346. *********************************************************************************
  347. */
  348. void doEdge (int argc, char *argv [])
  349. {
  350. FILE *fd ;
  351. int pin ;
  352. char *mode ;
  353. char fName [128] ;
  354. if (argc != 4)
  355. {
  356. fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
  357. exit (1) ;
  358. }
  359. pin = atoi (argv [2]) ;
  360. mode = argv [3] ;
  361. // Export the pin and set direction to input
  362. if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
  363. {
  364. fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
  365. exit (1) ;
  366. }
  367. fprintf (fd, "%d\n", pin) ;
  368. fclose (fd) ;
  369. sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
  370. if ((fd = fopen (fName, "w")) == NULL)
  371. {
  372. fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
  373. exit (1) ;
  374. }
  375. fprintf (fd, "in\n") ;
  376. fclose (fd) ;
  377. sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
  378. if ((fd = fopen (fName, "w")) == NULL)
  379. {
  380. fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
  381. exit (1) ;
  382. }
  383. /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
  384. else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
  385. else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
  386. else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
  387. else
  388. {
  389. fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
  390. exit (1) ;
  391. }
  392. // Change ownership of the value and edge files, so the current user can actually use it!
  393. sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
  394. changeOwner (argv [0], fName) ;
  395. sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
  396. changeOwner (argv [0], fName) ;
  397. fclose (fd) ;
  398. }
  399. /*
  400. * doUnexport:
  401. * gpio unexport pin
  402. * This uses the /sys/class/gpio device interface.
  403. *********************************************************************************
  404. */
  405. void doUnexport (int argc, char *argv [])
  406. {
  407. FILE *fd ;
  408. int pin ;
  409. if (argc != 3)
  410. {
  411. fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
  412. exit (1) ;
  413. }
  414. pin = atoi (argv [2]) ;
  415. if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
  416. {
  417. fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
  418. exit (1) ;
  419. }
  420. fprintf (fd, "%d\n", pin) ;
  421. fclose (fd) ;
  422. }
  423. /*
  424. * doUnexportAll:
  425. * gpio unexportall
  426. * Un-Export all the GPIO pins.
  427. * This uses the /sys/class/gpio device interface.
  428. *********************************************************************************
  429. */
  430. void doUnexportall (char *progName)
  431. {
  432. FILE *fd ;
  433. int pin ;
  434. for (pin = 0 ; pin < 63 ; ++pin)
  435. {
  436. if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
  437. {
  438. fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
  439. exit (1) ;
  440. }
  441. fprintf (fd, "%d\n", pin) ;
  442. fclose (fd) ;
  443. }
  444. }
  445. /*
  446. * doResetExternal:
  447. * Load readallExternal, we try to do this with an external device.
  448. *********************************************************************************
  449. */
  450. static void doResetExternal (void)
  451. {
  452. int pin ;
  453. for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin)
  454. {
  455. pinMode (pin, INPUT) ;
  456. pullUpDnControl (pin, PUD_OFF) ;
  457. }
  458. }
  459. /*
  460. * doReset:
  461. * Reset the GPIO pins - as much as we can do
  462. *********************************************************************************
  463. */
  464. static void doReset (char *progName)
  465. {
  466. int pin ;
  467. if (wiringPiNodes != NULL) // External reset
  468. doResetExternal () ;
  469. else
  470. {
  471. doUnexportall (progName) ;
  472. for (pin = 0 ; pin < 64 ; ++pin)
  473. {
  474. if (wpiPinToGpio (pin) == -1)
  475. continue ;
  476. digitalWrite (pin, LOW) ;
  477. pinMode (pin, INPUT) ;
  478. pullUpDnControl (pin, PUD_OFF) ;
  479. }
  480. }
  481. }
  482. /*
  483. * doMode:
  484. * gpio mode pin mode ...
  485. *********************************************************************************
  486. */
  487. void doMode (int argc, char *argv [])
  488. {
  489. int pin ;
  490. char *mode ;
  491. if (argc != 4)
  492. {
  493. fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
  494. exit (1) ;
  495. }
  496. pin = atoi (argv [2]) ;
  497. mode = argv [3] ;
  498. /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
  499. else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
  500. else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
  501. else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
  502. else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
  503. else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
  504. else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
  505. else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
  506. else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
  507. else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
  508. else
  509. {
  510. fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
  511. exit (1) ;
  512. }
  513. }
  514. /*
  515. * doPadDrive:
  516. * gpio drive group value
  517. *********************************************************************************
  518. */
  519. static void doPadDrive (int argc, char *argv [])
  520. {
  521. int group, val ;
  522. if (argc != 4)
  523. {
  524. fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
  525. exit (1) ;
  526. }
  527. group = atoi (argv [2]) ;
  528. val = atoi (argv [3]) ;
  529. if ((group < 0) || (group > 2))
  530. {
  531. fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
  532. exit (1) ;
  533. }
  534. if ((val < 0) || (val > 7))
  535. {
  536. fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
  537. exit (1) ;
  538. }
  539. setPadDrive (group, val) ;
  540. }
  541. /*
  542. * doGbw:
  543. * gpio gbw channel value
  544. * Gertboard Write - To the Analog output
  545. *********************************************************************************
  546. */
  547. static void doGbw (int argc, char *argv [])
  548. {
  549. int channel, value ;
  550. if (argc != 4)
  551. {
  552. fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
  553. exit (1) ;
  554. }
  555. channel = atoi (argv [2]) ;
  556. value = atoi (argv [3]) ;
  557. if ((channel < 0) || (channel > 1))
  558. {
  559. fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
  560. exit (1) ;
  561. }
  562. if ((value < 0) || (value > 1023))
  563. {
  564. fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
  565. exit (1) ;
  566. }
  567. if (gertboardAnalogSetup (64) < 0)
  568. {
  569. fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
  570. exit (1) ;
  571. }
  572. analogWrite (64 + channel, value) ;
  573. }
  574. /*
  575. * doGbr:
  576. * gpio gbr channel
  577. * From the analog input
  578. *********************************************************************************
  579. */
  580. static void doGbr (int argc, char *argv [])
  581. {
  582. int channel ;
  583. if (argc != 3)
  584. {
  585. fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
  586. exit (1) ;
  587. }
  588. channel = atoi (argv [2]) ;
  589. if ((channel < 0) || (channel > 1))
  590. {
  591. fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
  592. exit (1) ;
  593. }
  594. if (gertboardAnalogSetup (64) < 0)
  595. {
  596. fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
  597. exit (1) ;
  598. }
  599. printf ("%d\n", analogRead (64 + channel)) ;
  600. }
  601. /*
  602. * doWrite:
  603. * gpio write pin value
  604. *********************************************************************************
  605. */
  606. static void doWrite (int argc, char *argv [])
  607. {
  608. int pin, val ;
  609. if (argc != 4)
  610. {
  611. fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
  612. exit (1) ;
  613. }
  614. pin = atoi (argv [2]) ;
  615. /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
  616. val = 1 ;
  617. else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
  618. val = 0 ;
  619. else
  620. val = atoi (argv [3]) ;
  621. /**/ if (val == 0)
  622. digitalWrite (pin, LOW) ;
  623. else
  624. digitalWrite (pin, HIGH) ;
  625. }
  626. /*
  627. * doAwriterite:
  628. * gpio awrite pin value
  629. *********************************************************************************
  630. */
  631. static void doAwrite (int argc, char *argv [])
  632. {
  633. int pin, val ;
  634. if (argc != 4)
  635. {
  636. fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
  637. exit (1) ;
  638. }
  639. pin = atoi (argv [2]) ;
  640. val = atoi (argv [3]) ;
  641. analogWrite (pin, val) ;
  642. }
  643. /*
  644. * doWriteByte:
  645. * gpio write value
  646. *********************************************************************************
  647. */
  648. static void doWriteByte (int argc, char *argv [])
  649. {
  650. int val ;
  651. if (argc != 3)
  652. {
  653. fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
  654. exit (1) ;
  655. }
  656. val = (int)strtol (argv [2], NULL, 0) ;
  657. digitalWriteByte (val) ;
  658. }
  659. /*
  660. * doRead:
  661. * Read a pin and return the value
  662. *********************************************************************************
  663. */
  664. void doRead (int argc, char *argv [])
  665. {
  666. int pin, val ;
  667. if (argc != 3)
  668. {
  669. fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
  670. exit (1) ;
  671. }
  672. pin = atoi (argv [2]) ;
  673. val = digitalRead (pin) ;
  674. printf ("%s\n", val == 0 ? "0" : "1") ;
  675. }
  676. /*
  677. * doAread:
  678. * Read an analog pin and return the value
  679. *********************************************************************************
  680. */
  681. void doAread (int argc, char *argv [])
  682. {
  683. if (argc != 3)
  684. {
  685. fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
  686. exit (1) ;
  687. }
  688. printf ("%d\n", analogRead (atoi (argv [2]))) ;
  689. }
  690. /*
  691. * doToggle:
  692. * Toggle an IO pin
  693. *********************************************************************************
  694. */
  695. void doToggle (int argc, char *argv [])
  696. {
  697. int pin ;
  698. if (argc != 3)
  699. {
  700. fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
  701. exit (1) ;
  702. }
  703. pin = atoi (argv [2]) ;
  704. digitalWrite (pin, !digitalRead (pin)) ;
  705. }
  706. /*
  707. * doClock:
  708. * Output a clock on a pin
  709. *********************************************************************************
  710. */
  711. void doClock (int argc, char *argv [])
  712. {
  713. int pin, freq ;
  714. if (argc != 4)
  715. {
  716. fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
  717. exit (1) ;
  718. }
  719. pin = atoi (argv [2]) ;
  720. freq = atoi (argv [3]) ;
  721. gpioClockSet (pin, freq) ;
  722. }
  723. /*
  724. * doPwm:
  725. * Output a PWM value on a pin
  726. *********************************************************************************
  727. */
  728. void doPwm (int argc, char *argv [])
  729. {
  730. int pin, val ;
  731. if (argc != 4)
  732. {
  733. fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
  734. exit (1) ;
  735. }
  736. pin = atoi (argv [2]) ;
  737. val = atoi (argv [3]) ;
  738. pwmWrite (pin, val) ;
  739. }
  740. /*
  741. * doPwmMode: doPwmRange: doPwmClock:
  742. * Change the PWM mode, range and clock divider values
  743. *********************************************************************************
  744. */
  745. static void doPwmMode (int mode)
  746. {
  747. pwmSetMode (mode) ;
  748. }
  749. static void doPwmRange (int argc, char *argv [])
  750. {
  751. unsigned int range ;
  752. if (argc != 3)
  753. {
  754. fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
  755. exit (1) ;
  756. }
  757. range = (unsigned int)strtoul (argv [2], NULL, 10) ;
  758. if (range == 0)
  759. {
  760. fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
  761. exit (1) ;
  762. }
  763. pwmSetRange (range) ;
  764. }
  765. static void doPwmClock (int argc, char *argv [])
  766. {
  767. unsigned int clock ;
  768. if (argc != 3)
  769. {
  770. fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
  771. exit (1) ;
  772. }
  773. clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
  774. if ((clock < 1) || (clock > 4095))
  775. {
  776. fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
  777. exit (1) ;
  778. }
  779. pwmSetClock (clock) ;
  780. }
  781. /*
  782. * main:
  783. * Start here
  784. *********************************************************************************
  785. */
  786. int main (int argc, char *argv [])
  787. {
  788. int i ;
  789. if (getenv ("WIRINGPI_DEBUG") != NULL)
  790. {
  791. printf ("gpio: wiringPi debug mode enabled\n") ;
  792. wiringPiDebug = TRUE ;
  793. }
  794. if (argc == 1)
  795. {
  796. fprintf (stderr, "%s\n", usage) ;
  797. return 1 ;
  798. }
  799. // Help
  800. if (strcasecmp (argv [1], "-h") == 0)
  801. {
  802. printf ("%s: %s\n", argv [0], usage) ;
  803. return 0 ;
  804. }
  805. // Sort of a special:
  806. if (strcmp (argv [1], "-R") == 0)
  807. {
  808. printf ("%d\n", piBoardRev ()) ;
  809. return 0 ;
  810. }
  811. // Version & Warranty
  812. if (strcmp (argv [1], "-V") == 0)
  813. {
  814. printf ("%d\n", piBoardRev ()) ;
  815. return 0 ;
  816. }
  817. if (strcmp (argv [1], "-v") == 0)
  818. {
  819. printf ("gpio version: %s\n", VERSION) ;
  820. printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
  821. printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
  822. printf ("For details type: %s -warranty\n", argv [0]) ;
  823. printf ("\n") ;
  824. printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
  825. return 0 ;
  826. }
  827. if (strcasecmp (argv [1], "-warranty") == 0)
  828. {
  829. printf ("gpio version: %s\n", VERSION) ;
  830. printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
  831. printf ("\n") ;
  832. printf (" This program is free software; you can redistribute it and/or modify\n") ;
  833. printf (" it under the terms of the GNU Leser General Public License as published\n") ;
  834. printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
  835. printf (" (at your option) any later version.\n") ;
  836. printf ("\n") ;
  837. printf (" This program is distributed in the hope that it will be useful,\n") ;
  838. printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
  839. printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
  840. printf (" GNU Lesser General Public License for more details.\n") ;
  841. printf ("\n") ;
  842. printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
  843. printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
  844. printf ("\n") ;
  845. return 0 ;
  846. }
  847. if (geteuid () != 0)
  848. {
  849. fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
  850. return 1 ;
  851. }
  852. // Initial test for /sys/class/gpio operations:
  853. /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
  854. else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
  855. else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
  856. else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
  857. else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
  858. // Check for load command:
  859. if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
  860. // Gertboard commands
  861. if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
  862. if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
  863. // Check for -g argument
  864. /**/ if (strcasecmp (argv [1], "-g") == 0)
  865. {
  866. wiringPiSetupGpio () ;
  867. for (i = 2 ; i < argc ; ++i)
  868. argv [i - 1] = argv [i] ;
  869. --argc ;
  870. wpMode = WPI_MODE_GPIO ;
  871. }
  872. // Check for -1 argument
  873. else if (strcasecmp (argv [1], "-1") == 0)
  874. {
  875. wiringPiSetupPhys () ;
  876. for (i = 2 ; i < argc ; ++i)
  877. argv [i - 1] = argv [i] ;
  878. --argc ;
  879. wpMode = WPI_MODE_PHYS ;
  880. }
  881. // Check for -p argument for PiFace
  882. else if (strcasecmp (argv [1], "-p") == 0)
  883. {
  884. piFaceSetup (200) ;
  885. for (i = 2 ; i < argc ; ++i)
  886. argv [i - 1] = argv [i] ;
  887. --argc ;
  888. wpMode = WPI_MODE_PIFACE ;
  889. }
  890. // Default to wiringPi mode
  891. else
  892. {
  893. wiringPiSetup () ;
  894. wpMode = WPI_MODE_PINS ;
  895. }
  896. // Check for -x argument to load in a new extension
  897. if (strcasecmp (argv [1], "-x") == 0)
  898. {
  899. if (argc < 3)
  900. {
  901. fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
  902. exit (EXIT_FAILURE) ;
  903. }
  904. if (!doExtension (argv [0], argv [2])) // Prints its own error messages
  905. exit (EXIT_FAILURE) ;
  906. for (i = 3 ; i < argc ; ++i)
  907. argv [i - 2] = argv [i] ;
  908. argc -= 2 ;
  909. }
  910. if (argc <= 1)
  911. {
  912. fprintf (stderr, "%s: no command given\n", argv [0]) ;
  913. exit (EXIT_FAILURE) ;
  914. }
  915. // Core wiringPi functions
  916. /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
  917. else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
  918. else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
  919. else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
  920. else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
  921. else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
  922. // GPIO Nicies
  923. else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
  924. // Pi Specifics
  925. else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
  926. else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
  927. else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
  928. else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
  929. else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
  930. else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
  931. else if (strcasecmp (argv [1], "oreadall" ) == 0) doReadallOld () ;
  932. else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
  933. else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
  934. else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
  935. else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
  936. else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
  937. else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
  938. else
  939. {
  940. fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
  941. exit (EXIT_FAILURE) ;
  942. }
  943. return 0 ;
  944. }