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.
 
 
 
 
 

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