No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 

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