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.

gpio.c 32 KiB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351
  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 if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0))
  352. fprintf (fd, "high\n") ;
  353. else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0))
  354. fprintf (fd, "low\n") ;
  355. else
  356. {
  357. fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
  358. exit (1) ;
  359. }
  360. fclose (fd) ;
  361. // Change ownership so the current user can actually use it
  362. sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
  363. changeOwner (argv [0], fName) ;
  364. sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
  365. changeOwner (argv [0], fName) ;
  366. }
  367. /*
  368. * doWfi:
  369. * gpio wfi pin mode
  370. * Wait for Interrupt on a given pin.
  371. * Slight cheat here - it's easier to actually use ISR now (which calls
  372. * gpio to set the pin modes!) then we simply sleep, and expect the thread
  373. * to exit the program. Crude but effective.
  374. *********************************************************************************
  375. */
  376. static void wfi (void)
  377. { exit (0) ; }
  378. void doWfi (int argc, char *argv [])
  379. {
  380. int pin, mode ;
  381. if (argc != 4)
  382. {
  383. fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
  384. exit (1) ;
  385. }
  386. pin = atoi (argv [2]) ;
  387. /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
  388. else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
  389. else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
  390. else
  391. {
  392. fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
  393. exit (1) ;
  394. }
  395. if (wiringPiISR (pin, mode, &wfi) < 0)
  396. {
  397. fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
  398. exit (1) ;
  399. }
  400. for (;;)
  401. delay (9999) ;
  402. }
  403. /*
  404. * doEdge:
  405. * gpio edge pin mode
  406. * Easy access to changing the edge trigger on a GPIO pin
  407. * This uses the /sys/class/gpio device interface.
  408. *********************************************************************************
  409. */
  410. void doEdge (int argc, char *argv [])
  411. {
  412. FILE *fd ;
  413. int pin ;
  414. char *mode ;
  415. char fName [128] ;
  416. if (argc != 4)
  417. {
  418. fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
  419. exit (1) ;
  420. }
  421. pin = atoi (argv [2]) ;
  422. mode = argv [3] ;
  423. // Export the pin and set direction to input
  424. if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
  425. {
  426. fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
  427. exit (1) ;
  428. }
  429. fprintf (fd, "%d\n", pin) ;
  430. fclose (fd) ;
  431. sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
  432. if ((fd = fopen (fName, "w")) == NULL)
  433. {
  434. fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
  435. exit (1) ;
  436. }
  437. fprintf (fd, "in\n") ;
  438. fclose (fd) ;
  439. sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
  440. if ((fd = fopen (fName, "w")) == NULL)
  441. {
  442. fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
  443. exit (1) ;
  444. }
  445. /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
  446. else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
  447. else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
  448. else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
  449. else
  450. {
  451. fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
  452. exit (1) ;
  453. }
  454. // Change ownership of the value and edge files, so the current user can actually use it!
  455. sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
  456. changeOwner (argv [0], fName) ;
  457. sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
  458. changeOwner (argv [0], fName) ;
  459. fclose (fd) ;
  460. }
  461. /*
  462. * doUnexport:
  463. * gpio unexport pin
  464. * This uses the /sys/class/gpio device interface.
  465. *********************************************************************************
  466. */
  467. void doUnexport (int argc, char *argv [])
  468. {
  469. FILE *fd ;
  470. int pin ;
  471. if (argc != 3)
  472. {
  473. fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
  474. exit (1) ;
  475. }
  476. pin = atoi (argv [2]) ;
  477. if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
  478. {
  479. fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
  480. exit (1) ;
  481. }
  482. fprintf (fd, "%d\n", pin) ;
  483. fclose (fd) ;
  484. }
  485. /*
  486. * doUnexportAll:
  487. * gpio unexportall
  488. * Un-Export all the GPIO pins.
  489. * This uses the /sys/class/gpio device interface.
  490. *********************************************************************************
  491. */
  492. void doUnexportall (char *progName)
  493. {
  494. FILE *fd ;
  495. int pin ;
  496. for (pin = 0 ; pin < 63 ; ++pin)
  497. {
  498. if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
  499. {
  500. fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
  501. exit (1) ;
  502. }
  503. fprintf (fd, "%d\n", pin) ;
  504. fclose (fd) ;
  505. }
  506. }
  507. /*
  508. * doReset:
  509. * Reset the GPIO pins - as much as we can do
  510. *********************************************************************************
  511. */
  512. static void doReset (char *progName)
  513. {
  514. printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
  515. printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
  516. printf (" that you need them in for your applications.\n") ;
  517. }
  518. /*
  519. * doMode:
  520. * gpio mode pin mode ...
  521. *********************************************************************************
  522. */
  523. void doMode (int argc, char *argv [])
  524. {
  525. int pin ;
  526. char *mode ;
  527. if (argc != 4)
  528. {
  529. fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
  530. exit (1) ;
  531. }
  532. pin = atoi (argv [2]) ;
  533. mode = argv [3] ;
  534. /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
  535. else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
  536. else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
  537. else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
  538. else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
  539. else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
  540. else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
  541. else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
  542. else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
  543. else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
  544. else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
  545. else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
  546. else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
  547. else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
  548. else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
  549. else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
  550. else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
  551. else
  552. {
  553. fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
  554. exit (1) ;
  555. }
  556. }
  557. /*
  558. * doPadDrive:
  559. * gpio drive group value
  560. *********************************************************************************
  561. */
  562. static void doPadDrive (int argc, char *argv [])
  563. {
  564. int group, val ;
  565. if (argc != 4)
  566. {
  567. fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
  568. exit (1) ;
  569. }
  570. group = atoi (argv [2]) ;
  571. val = atoi (argv [3]) ;
  572. if ((group < 0) || (group > 2))
  573. {
  574. fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
  575. exit (1) ;
  576. }
  577. if ((val < 0) || (val > 7))
  578. {
  579. fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
  580. exit (1) ;
  581. }
  582. setPadDrive (group, val) ;
  583. }
  584. /*
  585. * doUsbP:
  586. * Control USB Power - High (1.2A) or Low (600mA)
  587. * gpio usbp high/low
  588. *********************************************************************************
  589. */
  590. static void doUsbP (int argc, char *argv [])
  591. {
  592. int model, rev, mem, maker, overVolted ;
  593. if (argc != 3)
  594. {
  595. fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
  596. exit (1) ;
  597. }
  598. // Make sure we're on a B+
  599. piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
  600. if (model != PI_MODEL_BP)
  601. {
  602. fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ;
  603. exit (1) ;
  604. }
  605. // Need to force BCM_GPIO mode:
  606. wiringPiSetupGpio () ;
  607. if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
  608. {
  609. digitalWrite (PI_USB_POWER_CONTROL, 1) ;
  610. pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
  611. printf ("Switched to HIGH current USB (1.2A)\n") ;
  612. return ;
  613. }
  614. if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
  615. {
  616. digitalWrite (PI_USB_POWER_CONTROL, 0) ;
  617. pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
  618. printf ("Switched to LOW current USB (600mA)\n") ;
  619. return ;
  620. }
  621. fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
  622. exit (1) ;
  623. }
  624. /*
  625. * doGbw:
  626. * gpio gbw channel value
  627. * Gertboard Write - To the Analog output
  628. *********************************************************************************
  629. */
  630. static void doGbw (int argc, char *argv [])
  631. {
  632. int channel, value ;
  633. if (argc != 4)
  634. {
  635. fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
  636. exit (1) ;
  637. }
  638. channel = atoi (argv [2]) ;
  639. value = atoi (argv [3]) ;
  640. if ((channel < 0) || (channel > 1))
  641. {
  642. fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
  643. exit (1) ;
  644. }
  645. if ((value < 0) || (value > 255))
  646. {
  647. fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
  648. exit (1) ;
  649. }
  650. if (gertboardAnalogSetup (64) < 0)
  651. {
  652. fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
  653. exit (1) ;
  654. }
  655. analogWrite (64 + channel, value) ;
  656. }
  657. /*
  658. * doGbr:
  659. * gpio gbr channel
  660. * From the analog input
  661. *********************************************************************************
  662. */
  663. static void doGbr (int argc, char *argv [])
  664. {
  665. int channel ;
  666. if (argc != 3)
  667. {
  668. fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
  669. exit (1) ;
  670. }
  671. channel = atoi (argv [2]) ;
  672. if ((channel < 0) || (channel > 1))
  673. {
  674. fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\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. printf ("%d\n", analogRead (64 + channel)) ;
  683. }
  684. /*
  685. * doWrite:
  686. * gpio write pin value
  687. *********************************************************************************
  688. */
  689. static void doWrite (int argc, char *argv [])
  690. {
  691. int pin, val ;
  692. if (argc != 4)
  693. {
  694. fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
  695. exit (1) ;
  696. }
  697. pin = atoi (argv [2]) ;
  698. /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
  699. val = 1 ;
  700. else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
  701. val = 0 ;
  702. else
  703. val = atoi (argv [3]) ;
  704. /**/ if (val == 0)
  705. digitalWrite (pin, LOW) ;
  706. else
  707. digitalWrite (pin, HIGH) ;
  708. }
  709. /*
  710. * doAwriterite:
  711. * gpio awrite pin value
  712. *********************************************************************************
  713. */
  714. static void doAwrite (int argc, char *argv [])
  715. {
  716. int pin, val ;
  717. if (argc != 4)
  718. {
  719. fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
  720. exit (1) ;
  721. }
  722. pin = atoi (argv [2]) ;
  723. val = atoi (argv [3]) ;
  724. analogWrite (pin, val) ;
  725. }
  726. /*
  727. * doWriteByte:
  728. * gpio write value
  729. *********************************************************************************
  730. */
  731. static void doWriteByte (int argc, char *argv [])
  732. {
  733. int val ;
  734. if (argc != 3)
  735. {
  736. fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
  737. exit (1) ;
  738. }
  739. val = (int)strtol (argv [2], NULL, 0) ;
  740. digitalWriteByte (val) ;
  741. }
  742. /*
  743. * doRead:
  744. * Read a pin and return the value
  745. *********************************************************************************
  746. */
  747. void doRead (int argc, char *argv [])
  748. {
  749. int pin, val ;
  750. if (argc != 3)
  751. {
  752. fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
  753. exit (1) ;
  754. }
  755. pin = atoi (argv [2]) ;
  756. val = digitalRead (pin) ;
  757. printf ("%s\n", val == 0 ? "0" : "1") ;
  758. }
  759. /*
  760. * doAread:
  761. * Read an analog pin and return the value
  762. *********************************************************************************
  763. */
  764. void doAread (int argc, char *argv [])
  765. {
  766. if (argc != 3)
  767. {
  768. fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
  769. exit (1) ;
  770. }
  771. printf ("%d\n", analogRead (atoi (argv [2]))) ;
  772. }
  773. /*
  774. * doToggle:
  775. * Toggle an IO pin
  776. *********************************************************************************
  777. */
  778. void doToggle (int argc, char *argv [])
  779. {
  780. int pin ;
  781. if (argc != 3)
  782. {
  783. fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
  784. exit (1) ;
  785. }
  786. pin = atoi (argv [2]) ;
  787. digitalWrite (pin, !digitalRead (pin)) ;
  788. }
  789. /*
  790. * doPwmTone:
  791. * Output a tone in a PWM pin
  792. *********************************************************************************
  793. */
  794. void doPwmTone (int argc, char *argv [])
  795. {
  796. int pin, freq ;
  797. if (argc != 4)
  798. {
  799. fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
  800. exit (1) ;
  801. }
  802. pin = atoi (argv [2]) ;
  803. freq = atoi (argv [3]) ;
  804. pwmToneWrite (pin, freq) ;
  805. }
  806. /*
  807. * doClock:
  808. * Output a clock on a pin
  809. *********************************************************************************
  810. */
  811. void doClock (int argc, char *argv [])
  812. {
  813. int pin, freq ;
  814. if (argc != 4)
  815. {
  816. fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
  817. exit (1) ;
  818. }
  819. pin = atoi (argv [2]) ;
  820. freq = atoi (argv [3]) ;
  821. gpioClockSet (pin, freq) ;
  822. }
  823. /*
  824. * doPwm:
  825. * Output a PWM value on a pin
  826. *********************************************************************************
  827. */
  828. void doPwm (int argc, char *argv [])
  829. {
  830. int pin, val ;
  831. if (argc != 4)
  832. {
  833. fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
  834. exit (1) ;
  835. }
  836. pin = atoi (argv [2]) ;
  837. val = atoi (argv [3]) ;
  838. pwmWrite (pin, val) ;
  839. }
  840. /*
  841. * doPwmMode: doPwmRange: doPwmClock:
  842. * Change the PWM mode, range and clock divider values
  843. *********************************************************************************
  844. */
  845. static void doPwmMode (int mode)
  846. {
  847. pwmSetMode (mode) ;
  848. }
  849. static void doPwmRange (int argc, char *argv [])
  850. {
  851. unsigned int range ;
  852. if (argc != 3)
  853. {
  854. fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
  855. exit (1) ;
  856. }
  857. range = (unsigned int)strtoul (argv [2], NULL, 10) ;
  858. if (range == 0)
  859. {
  860. fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
  861. exit (1) ;
  862. }
  863. pwmSetRange (range) ;
  864. }
  865. static void doPwmClock (int argc, char *argv [])
  866. {
  867. unsigned int clock ;
  868. if (argc != 3)
  869. {
  870. fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
  871. exit (1) ;
  872. }
  873. clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
  874. if ((clock < 1) || (clock > 4095))
  875. {
  876. fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
  877. exit (1) ;
  878. }
  879. pwmSetClock (clock) ;
  880. }
  881. /*
  882. * main:
  883. * Start here
  884. *********************************************************************************
  885. */
  886. int main (int argc, char *argv [])
  887. {
  888. int i ;
  889. int model, rev, mem, maker, overVolted ;
  890. if (getenv ("WIRINGPI_DEBUG") != NULL)
  891. {
  892. printf ("gpio: wiringPi debug mode enabled\n") ;
  893. wiringPiDebug = TRUE ;
  894. }
  895. if (argc == 1)
  896. {
  897. fprintf (stderr, "%s\n", usage) ;
  898. return 1 ;
  899. }
  900. // Help
  901. if (strcasecmp (argv [1], "-h") == 0)
  902. {
  903. printf ("%s: %s\n", argv [0], usage) ;
  904. return 0 ;
  905. }
  906. // Sort of a special:
  907. if (strcmp (argv [1], "-R") == 0)
  908. {
  909. printf ("%d\n", piBoardRev ()) ;
  910. return 0 ;
  911. }
  912. // Version & Warranty
  913. if (strcmp (argv [1], "-V") == 0)
  914. {
  915. printf ("%d\n", piBoardRev ()) ;
  916. return 0 ;
  917. }
  918. if (strcmp (argv [1], "-v") == 0)
  919. {
  920. printf ("gpio version: %s\n", VERSION) ;
  921. printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
  922. printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
  923. printf ("For details type: %s -warranty\n", argv [0]) ;
  924. printf ("\n") ;
  925. piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
  926. if (model == PI_MODEL_UNKNOWN)
  927. {
  928. printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ;
  929. printf (" projects@drogon.net\n") ;
  930. printf ("with a copy of your /proc/cpuinfo if possible\n") ;
  931. }
  932. else
  933. {
  934. printf ("Raspberry Pi Details:\n") ;
  935. printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
  936. piModelNames [model], piRevisionNames [rev], mem, piMakerNames [maker], overVolted ? "[OV]" : "") ;
  937. }
  938. return 0 ;
  939. }
  940. if (strcasecmp (argv [1], "-warranty") == 0)
  941. {
  942. printf ("gpio version: %s\n", VERSION) ;
  943. printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
  944. printf ("\n") ;
  945. printf (" This program is free software; you can redistribute it and/or modify\n") ;
  946. printf (" it under the terms of the GNU Leser General Public License as published\n") ;
  947. printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
  948. printf (" (at your option) any later version.\n") ;
  949. printf ("\n") ;
  950. printf (" This program is distributed in the hope that it will be useful,\n") ;
  951. printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
  952. printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
  953. printf (" GNU Lesser General Public License for more details.\n") ;
  954. printf ("\n") ;
  955. printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
  956. printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
  957. printf ("\n") ;
  958. return 0 ;
  959. }
  960. if (geteuid () != 0)
  961. {
  962. fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
  963. return 1 ;
  964. }
  965. // Initial test for /sys/class/gpio operations:
  966. /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
  967. else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
  968. else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
  969. else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
  970. else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
  971. // Check for load command:
  972. if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
  973. if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
  974. // Gertboard commands
  975. if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
  976. if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
  977. // Check for -g argument
  978. /**/ if (strcasecmp (argv [1], "-g") == 0)
  979. {
  980. wiringPiSetupGpio () ;
  981. for (i = 2 ; i < argc ; ++i)
  982. argv [i - 1] = argv [i] ;
  983. --argc ;
  984. wpMode = WPI_MODE_GPIO ;
  985. }
  986. // Check for -1 argument
  987. else if (strcasecmp (argv [1], "-1") == 0)
  988. {
  989. wiringPiSetupPhys () ;
  990. for (i = 2 ; i < argc ; ++i)
  991. argv [i - 1] = argv [i] ;
  992. --argc ;
  993. wpMode = WPI_MODE_PHYS ;
  994. }
  995. // Check for -p argument for PiFace
  996. else if (strcasecmp (argv [1], "-p") == 0)
  997. {
  998. piFaceSetup (200) ;
  999. for (i = 2 ; i < argc ; ++i)
  1000. argv [i - 1] = argv [i] ;
  1001. --argc ;
  1002. wpMode = WPI_MODE_PIFACE ;
  1003. }
  1004. // Default to wiringPi mode
  1005. else
  1006. {
  1007. wiringPiSetup () ;
  1008. wpMode = WPI_MODE_PINS ;
  1009. }
  1010. // Check for -x argument to load in a new extension
  1011. if (strcasecmp (argv [1], "-x") == 0)
  1012. {
  1013. if (argc < 3)
  1014. {
  1015. fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
  1016. exit (EXIT_FAILURE) ;
  1017. }
  1018. if (!loadWPiExtension (argv [0], argv [2], TRUE)) // Prints its own error messages
  1019. exit (EXIT_FAILURE) ;
  1020. for (i = 3 ; i < argc ; ++i)
  1021. argv [i - 2] = argv [i] ;
  1022. argc -= 2 ;
  1023. }
  1024. if (argc <= 1)
  1025. {
  1026. fprintf (stderr, "%s: no command given\n", argv [0]) ;
  1027. exit (EXIT_FAILURE) ;
  1028. }
  1029. // Core wiringPi functions
  1030. /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
  1031. else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
  1032. else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
  1033. else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
  1034. else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
  1035. else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
  1036. // GPIO Nicies
  1037. else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
  1038. // Pi Specifics
  1039. else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
  1040. else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
  1041. else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
  1042. else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
  1043. else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
  1044. else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
  1045. else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ;
  1046. else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
  1047. else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
  1048. else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ;
  1049. else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
  1050. else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
  1051. else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
  1052. else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
  1053. else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
  1054. else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
  1055. else
  1056. {
  1057. fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
  1058. exit (EXIT_FAILURE) ;
  1059. }
  1060. return 0 ;
  1061. }