wiringPi.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. /*
  2. * wiringPi:
  3. * Arduino compatable (ish) Wiring library for the Raspberry Pi
  4. * Copyright (c) 2012 Gordon Henderson
  5. *
  6. * Thanks to code samples from Gert Jan van Loo and the
  7. * BCM2835 ARM Peripherals manual, however it's missing
  8. * the clock section /grr/mutter/
  9. ***********************************************************************
  10. * This file is part of wiringPi:
  11. * https://projects.drogon.net/raspberry-pi/wiringpi/
  12. *
  13. * wiringPi is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Lesser General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * wiringPi is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Lesser General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Lesser General Public
  24. * License along with wiringPi.
  25. * If not, see <http://www.gnu.org/licenses/>.
  26. ***********************************************************************
  27. */
  28. // Revisions:
  29. // 19 Jul 2012:
  30. // Moved to the LGPL
  31. // Added an abstraction layer to the main routines to save a tiny
  32. // bit of run-time and make the clode a little cleaner (if a little
  33. // larger)
  34. // Added waitForInterrupt code
  35. // Added piHiPri code
  36. //
  37. // 9 Jul 2012:
  38. // Added in support to use the /sys/class/gpio interface.
  39. // 2 Jul 2012:
  40. // Fixed a few more bugs to do with range-checking when in GPIO mode.
  41. // 11 Jun 2012:
  42. // Fixed some typos.
  43. // Added c++ support for the .h file
  44. // Added a new function to allow for using my "pin" numbers, or native
  45. // GPIO pin numbers.
  46. // Removed my busy-loop delay and replaced it with a call to delayMicroseconds
  47. //
  48. // 02 May 2012:
  49. // Added in the 2 UART pins
  50. // Change maxPins to numPins to more accurately reflect purpose
  51. // Pad drive current fiddling
  52. #undef DEBUG_PADS
  53. #include <stdio.h>
  54. #include <stdint.h>
  55. #include <poll.h>
  56. #include <unistd.h>
  57. #include <errno.h>
  58. #include <string.h>
  59. #include <time.h>
  60. #include <fcntl.h>
  61. #include <sys/time.h>
  62. #include <sys/mman.h>
  63. #include <sys/types.h>
  64. #include <sys/stat.h>
  65. #include "wiringPi.h"
  66. // Function stubs
  67. void (*pinMode) (int pin, int mode) ;
  68. void (*pullUpDnControl) (int pin, int pud) ;
  69. void (*digitalWrite) (int pin, int value) ;
  70. void (*pwmWrite) (int pin, int value) ;
  71. int (*digitalRead) (int pin) ;
  72. int (*waitForInterrupt) (int pin, int mS) ;
  73. #ifndef TRUE
  74. #define TRUE (1==1)
  75. #define FALSE (1==2)
  76. #endif
  77. // Port function select bits
  78. #define FSEL_INPT 0b000
  79. #define FSEL_OUTP 0b001
  80. #define FSEL_ALT0 0b100
  81. #define FSEL_ALT0 0b100
  82. #define FSEL_ALT1 0b101
  83. #define FSEL_ALT2 0b110
  84. #define FSEL_ALT3 0b111
  85. #define FSEL_ALT4 0b011
  86. #define FSEL_ALT5 0b010
  87. // Access from ARM Running Linux
  88. // Take from Gert/Doms code. Some of this is not in the manual
  89. // that I can find )-:
  90. #define BCM2708_PERI_BASE 0x20000000
  91. #define GPIO_PADS (BCM2708_PERI_BASE + 0x100000)
  92. #define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000)
  93. #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
  94. #define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000)
  95. #define PAGE_SIZE (4*1024)
  96. #define BLOCK_SIZE (4*1024)
  97. // PWM
  98. #define PWM_CONTROL 0
  99. #define PWM_STATUS 1
  100. #define PWM0_RANGE 4
  101. #define PWM0_DATA 5
  102. #define PWM1_RANGE 8
  103. #define PWM1_DATA 9
  104. #define PWMCLK_CNTL 40
  105. #define PWMCLK_DIV 41
  106. #define PWM1_MS_MODE 0x8000 // Run in MS mode
  107. #define PWM1_USEFIFO 0x2000 // Data from FIFO
  108. #define PWM1_REVPOLAR 0x1000 // Reverse polarity
  109. #define PWM1_OFFSTATE 0x0800 // Ouput Off state
  110. #define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty
  111. #define PWM1_SERIAL 0x0200 // Run in serial mode
  112. #define PWM1_ENABLE 0x0100 // Channel Enable
  113. #define PWM0_MS_MODE 0x0080 // Run in MS mode
  114. #define PWM0_USEFIFO 0x0020 // Data from FIFO
  115. #define PWM0_REVPOLAR 0x0010 // Reverse polarity
  116. #define PWM0_OFFSTATE 0x0008 // Ouput Off state
  117. #define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty
  118. #define PWM0_SERIAL 0x0002 // Run in serial mode
  119. #define PWM0_ENABLE 0x0001 // Channel Enable
  120. // Locals to hold pointers to the hardware
  121. static volatile uint32_t *gpio ;
  122. static volatile uint32_t *pwm ;
  123. static volatile uint32_t *clk ;
  124. // The BCM2835 has 54 GPIO pins.
  125. // BCM2835 data sheet, Page 90 onwards.
  126. // There are 6 control registers, each control the functions of a block
  127. // of 10 pins.
  128. // Each control register has 10 sets of 3 bits per GPIO pin:
  129. //
  130. // 000 = GPIO Pin X is an input
  131. // 001 = GPIO Pin X is an output
  132. // 100 = GPIO Pin X takes alternate function 0
  133. // 101 = GPIO Pin X takes alternate function 1
  134. // 110 = GPIO Pin X takes alternate function 2
  135. // 111 = GPIO Pin X takes alternate function 3
  136. // 011 = GPIO Pin X takes alternate function 4
  137. // 010 = GPIO Pin X takes alternate function 5
  138. //
  139. // So the 3 bits for port X are:
  140. // X / 10 + ((X % 10) * 3)
  141. // sysFds:
  142. // Map a file descriptor from the /sys/class/gpio/gpioX/value
  143. static int sysFds [64] ;
  144. // Doing it the Arduino way with lookup tables...
  145. // Yes, it's probably more innefficient than all the bit-twidling, but it
  146. // does tend to make it all a bit clearer. At least to me!
  147. // pinToGpio:
  148. // Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
  149. static int pinToGpio [64] =
  150. {
  151. 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7
  152. 0, 1, // I2C - SDA0, SCL0
  153. 8, 7, // SPI - CE1, CE0
  154. 10, 9, 11, // SPI - MOSI, MISO, SCLK
  155. 14, 15, // UART - Tx, Rx
  156. // Padding:
  157. -1, -1, -1,-1,-1,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
  158. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
  159. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
  160. } ;
  161. // gpioToGPFSEL:
  162. // Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
  163. static uint8_t gpioToGPFSEL [] =
  164. {
  165. 0,0,0,0,0,0,0,0,0,0,
  166. 1,1,1,1,1,1,1,1,1,1,
  167. 2,2,2,2,2,2,2,2,2,2,
  168. 3,3,3,3,3,3,3,3,3,3,
  169. 4,4,4,4,4,4,4,4,4,4,
  170. 5,5,5,5,5,5,5,5,5,5,
  171. } ;
  172. // gpioToShift
  173. // Define the shift up for the 3 bits per pin in each GPFSEL port
  174. static uint8_t gpioToShift [] =
  175. {
  176. 0,3,6,9,12,15,18,21,24,27,
  177. 0,3,6,9,12,15,18,21,24,27,
  178. 0,3,6,9,12,15,18,21,24,27,
  179. 0,3,6,9,12,15,18,21,24,27,
  180. 0,3,6,9,12,15,18,21,24,27,
  181. } ;
  182. // gpioToGPSET:
  183. // (Word) offset to the GPIO Set registers for each GPIO pin
  184. static uint8_t gpioToGPSET [] =
  185. {
  186. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  187. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  188. } ;
  189. // gpioToGPCLR:
  190. // (Word) offset to the GPIO Clear registers for each GPIO pin
  191. static uint8_t gpioToGPCLR [] =
  192. {
  193. 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  194. 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
  195. } ;
  196. // gpioToGPLEV:
  197. // (Word) offset to the GPIO Input level registers for each GPIO pin
  198. static uint8_t gpioToGPLEV [] =
  199. {
  200. 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
  201. 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
  202. } ;
  203. #ifdef notYetReady
  204. // gpioToEDS
  205. // (Word) offset to the Event Detect Status
  206. static uint8_t gpioToEDS [] =
  207. {
  208. 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
  209. 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
  210. } ;
  211. // gpioToREN
  212. // (Word) offset to the Rising edgde ENable register
  213. static uint8_t gpioToREN [] =
  214. {
  215. 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
  216. 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
  217. } ;
  218. // gpioToFEN
  219. // (Word) offset to the Falling edgde ENable register
  220. static uint8_t gpioToFEN [] =
  221. {
  222. 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
  223. 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
  224. } ;
  225. #endif
  226. // gpioToPUDCLK
  227. // (Word) offset to the Pull Up Down Clock regsiter
  228. static uint8_t gpioToPUDCLK [] =
  229. {
  230. 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
  231. 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
  232. } ;
  233. // gpioToPwmALT
  234. // the ALT value to put a GPIO pin into PWM mode
  235. static uint8_t gpioToPwmALT [] =
  236. {
  237. 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
  238. 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15
  239. 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23
  240. 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
  241. 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
  242. FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47
  243. 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
  244. 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
  245. } ;
  246. static uint8_t gpioToPwmPort [] =
  247. {
  248. 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
  249. 0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15
  250. 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23
  251. 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
  252. 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
  253. PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47
  254. 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
  255. 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
  256. } ;
  257. // Time for easy calculations
  258. static unsigned long long epoch ;
  259. //////////////////////////////////////////////////////////////////////////////////
  260. /*
  261. * pinMode:
  262. * Sets the mode of a pin to be input, output or PWM output
  263. *********************************************************************************
  264. */
  265. void pinModeGpio (int pin, int mode)
  266. {
  267. static int pwmRunning = FALSE ;
  268. int fSel, shift, alt ;
  269. pin &= 63 ;
  270. fSel = gpioToGPFSEL [pin] ;
  271. shift = gpioToShift [pin] ;
  272. /**/ if (mode == INPUT)
  273. *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
  274. else if (mode == OUTPUT)
  275. *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
  276. else if (mode == PWM_OUTPUT)
  277. {
  278. if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
  279. return ;
  280. // Set pin to PWM mode
  281. *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
  282. // We didn't initialise the PWM hardware at setup time - because it's possible that
  283. // something else is using the PWM - e.g. the Audio systems! So if we use PWM
  284. // here, then we're assuming that nothing else is, otherwise things are going
  285. // to sound a bit funny...
  286. if (!pwmRunning)
  287. {
  288. // Gert/Doms Values
  289. *(clk + PWMCLK_DIV) = 0x5A000000 | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz)
  290. *(clk + PWMCLK_CNTL) = 0x5A000011 ; // Source=osc and enable
  291. digitalWrite (pin, LOW) ;
  292. *(pwm + PWM_CONTROL) = 0 ; // Disable PWM
  293. delayMicroseconds (10) ;
  294. *(pwm + PWM0_RANGE) = 0x400 ;
  295. delayMicroseconds (10) ;
  296. *(pwm + PWM1_RANGE) = 0x400 ;
  297. delayMicroseconds (10) ;
  298. // Enable PWMs
  299. *(pwm + PWM0_DATA) = 512 ;
  300. *(pwm + PWM1_DATA) = 512 ;
  301. *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
  302. }
  303. }
  304. // When we change mode of any pin, we remove the pull up/downs
  305. pullUpDnControl (pin, PUD_OFF) ;
  306. }
  307. void pinModeWPi (int pin, int mode)
  308. {
  309. pinModeGpio (pinToGpio [pin & 63], mode) ;
  310. }
  311. void pinModeSys (int pin, int mode)
  312. {
  313. return ;
  314. }
  315. #ifdef notYetReady
  316. /*
  317. * pinED01:
  318. * pinED10:
  319. * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
  320. * Pin must already be in input mode with appropriate pull up/downs set.
  321. *********************************************************************************
  322. */
  323. void pinEnableED01Pi (int pin)
  324. {
  325. pin = pinToGpio [pin & 63] ;
  326. }
  327. #endif
  328. /*
  329. * digitalWrite:
  330. * Set an output bit
  331. *********************************************************************************
  332. */
  333. void digitalWriteWPi (int pin, int value)
  334. {
  335. int gpioPin = pinToGpio [pin & 63] ;
  336. if (value == LOW)
  337. *(gpio + gpioToGPCLR [gpioPin]) = 1 << gpioPin ;
  338. else
  339. *(gpio + gpioToGPSET [gpioPin]) = 1 << gpioPin ;
  340. }
  341. void digitalWriteGpio (int pin, int value)
  342. {
  343. pin &= 63 ;
  344. if (value == LOW)
  345. *(gpio + gpioToGPCLR [pin]) = 1 << pin ;
  346. else
  347. *(gpio + gpioToGPSET [pin]) = 1 << pin ;
  348. }
  349. void digitalWriteSys (int pin, int value)
  350. {
  351. pin &= 63 ;
  352. if (sysFds [pin] != -1)
  353. {
  354. if (value == LOW)
  355. write (sysFds [pin], "0\n", 2) ;
  356. else
  357. write (sysFds [pin], "1\n", 2) ;
  358. }
  359. }
  360. /*
  361. * pwnWrite:
  362. * Set an output PWM value
  363. *********************************************************************************
  364. */
  365. void pwmWriteWPi (int pin, int value)
  366. {
  367. int port, gpioPin ;
  368. gpioPin = pinToGpio [pin & 63] ;
  369. port = gpioToPwmPort [gpioPin] ;
  370. *(pwm + port) = value & 0x3FF ;
  371. }
  372. void pwmWriteGpio (int pin, int value)
  373. {
  374. int port, gpioPin ;
  375. gpioPin = pin & 63 ;
  376. port = gpioToPwmPort [gpioPin] ;
  377. *(pwm + port) = value & 0x3FF ;
  378. }
  379. void pwmWriteSys (int pin, int value)
  380. {
  381. return ;
  382. }
  383. /*
  384. * digitalRead:
  385. * Read the value of a given Pin, returning HIGH or LOW
  386. *********************************************************************************
  387. */
  388. int digitalReadWPi (int pin)
  389. {
  390. int gpioPin ;
  391. pin &= 63 ;
  392. gpioPin = pinToGpio [pin] ;
  393. if ((*(gpio + gpioToGPLEV [gpioPin]) & (1 << gpioPin)) != 0)
  394. return HIGH ;
  395. else
  396. return LOW ;
  397. }
  398. int digitalReadGpio (int pin)
  399. {
  400. pin &= 63 ;
  401. if ((*(gpio + gpioToGPLEV [pin]) & (1 << pin)) != 0)
  402. return HIGH ;
  403. else
  404. return LOW ;
  405. }
  406. int digitalReadSys (int pin)
  407. {
  408. char c ;
  409. pin &= 63 ;
  410. if (sysFds [pin] == -1)
  411. return 0 ;
  412. lseek (sysFds [pin], 0L, SEEK_SET) ;
  413. read (sysFds [pin], &c, 1) ;
  414. return (c == '0') ? 0 : 1 ;
  415. }
  416. /*
  417. * pullUpDownCtrl:
  418. * Control the internal pull-up/down resistors on a GPIO pin
  419. * The Arduino only has pull-ups and these are enabled by writing 1
  420. * to a port when in input mode - this paradigm doesn't quite apply
  421. * here though.
  422. *********************************************************************************
  423. */
  424. void pullUpDnControlWPi (int pin, int pud)
  425. {
  426. pin = pinToGpio [pin & 63] ;
  427. *(gpio + 37) = pud ;
  428. delayMicroseconds (10) ;
  429. *(gpio + gpioToPUDCLK [pin]) = 1 << pin ;
  430. delayMicroseconds (10) ;
  431. *(gpio + 37) = 0 ;
  432. *(gpio + gpioToPUDCLK [pin]) = 0 ;
  433. }
  434. void pullUpDnControlGpio (int pin, int pud)
  435. {
  436. pin &= 63 ;
  437. *(gpio + 37) = pud ;
  438. delayMicroseconds (10) ;
  439. *(gpio + gpioToPUDCLK [pin]) = 1 << pin ;
  440. delayMicroseconds (10) ;
  441. *(gpio + 37) = 0 ;
  442. *(gpio + gpioToPUDCLK [pin]) = 0 ;
  443. }
  444. void pullUpDnControlSys (int pin, int pud)
  445. {
  446. return ;
  447. }
  448. /*
  449. * waitForInterrupt:
  450. * Wait for Interrupt on a GPIO pin.
  451. * This is actually done via the /sys/class/gpio interface regardless of
  452. * the wiringPi access mode in-use. Maybe sometime it might get a better
  453. * way for a bit more efficiency.
  454. *********************************************************************************
  455. */
  456. int waitForInterruptSys (int pin, int mS)
  457. {
  458. int fd, x ;
  459. char buf [8] ;
  460. struct pollfd polls ;
  461. if ((fd = sysFds [pin & 63]) == -1)
  462. return -2 ;
  463. // Do a dummy read
  464. x = read (fd, buf, 6) ;
  465. if (x < 0)
  466. return x ;
  467. // And seek
  468. lseek (fd, 0, SEEK_SET) ;
  469. // Setup poll structure
  470. polls.fd = fd ;
  471. polls.events = POLLPRI ; // Urgent data!
  472. // Wait for it ...
  473. return poll (&polls, 1, mS) ;
  474. }
  475. int waitForInterruptWPi (int pin, int mS)
  476. {
  477. return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
  478. }
  479. int waitForInterruptGpio (int pin, int mS)
  480. {
  481. return waitForInterruptSys (pin, mS) ;
  482. }
  483. /*
  484. * wiringPiSetup:
  485. * Must be called once at the start of your program execution.
  486. *
  487. * Default setup: Initialises the system into wiringPi Pin mode and uses the
  488. * memory mapped hardware directly.
  489. *********************************************************************************
  490. */
  491. int wiringPiSetup (void)
  492. {
  493. int fd ;
  494. uint8_t *gpioMem, *pwmMem, *clkMem ;
  495. struct timeval tv ;
  496. #ifdef DEBUG_PADS
  497. uint8_t *gpioMem, *padsMem, *pwmMem, *clkMem ;
  498. uint32_t *pads ;
  499. #endif
  500. pinMode = pinModeWPi ;
  501. pullUpDnControl = pullUpDnControlWPi ;
  502. digitalWrite = digitalWriteWPi ;
  503. pwmWrite = pwmWriteWPi ;
  504. digitalRead = digitalReadWPi ;
  505. waitForInterrupt = waitForInterruptWPi ;
  506. // Open the master /dev/memory device
  507. if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
  508. {
  509. fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
  510. return -1 ;
  511. }
  512. // GPIO:
  513. // Allocate 2 pages - 1 ...
  514. if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
  515. {
  516. fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
  517. return -1 ;
  518. }
  519. // ... presumably to make sure we can round it up to a whole page size
  520. if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
  521. gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
  522. gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
  523. if ((int32_t)gpio < 0)
  524. {
  525. fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
  526. return -1 ;
  527. }
  528. // PWM
  529. if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
  530. {
  531. fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
  532. return -1 ;
  533. }
  534. if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
  535. pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;
  536. pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;
  537. if ((int32_t)pwm < 0)
  538. {
  539. fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
  540. return -1 ;
  541. }
  542. // Clock control (needed for PWM)
  543. if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
  544. {
  545. fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
  546. return -1 ;
  547. }
  548. if (((uint32_t)clkMem % PAGE_SIZE) != 0)
  549. clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;
  550. clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;
  551. if ((int32_t)clk < 0)
  552. {
  553. fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
  554. return -1 ;
  555. }
  556. #ifdef DEBUG_PADS
  557. if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
  558. {
  559. fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
  560. return -1 ;
  561. }
  562. if (((uint32_t)padsMem % PAGE_SIZE) != 0)
  563. padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;
  564. pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;
  565. if ((int32_t)pads < 0)
  566. {
  567. fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
  568. return -1 ;
  569. }
  570. printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
  571. printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
  572. // *(pads + 11) = 0x1F ;
  573. printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
  574. #endif
  575. gettimeofday (&tv, NULL) ;
  576. epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
  577. return 0 ;
  578. }
  579. /*
  580. * wiringPiSetupGpio:
  581. * Must be called once at the start of your program execution.
  582. *
  583. * GPIO setup: Initialises the system into GPIO Pin mode and uses the
  584. * memory mapped hardware directly.
  585. *********************************************************************************
  586. */
  587. int wiringPiSetupGpio (void)
  588. {
  589. int x = wiringPiSetup () ;
  590. if (x != 0)
  591. return x ;
  592. pinMode = pinModeGpio ;
  593. pullUpDnControl = pullUpDnControlGpio ;
  594. digitalWrite = digitalWriteGpio ;
  595. pwmWrite = pwmWriteGpio ;
  596. digitalRead = digitalReadGpio ;
  597. waitForInterrupt = waitForInterruptGpio ;
  598. return 0 ;
  599. }
  600. /*
  601. * wiringPiSetupSys:
  602. * Must be called once at the start of your program execution.
  603. *
  604. * Initialisation (again), however this time we are using the /sys/class/gpio
  605. * interface to the GPIO systems - slightly slower, but always usable as
  606. * a non-root user, assuming the devices are already exported and setup correctly.
  607. */
  608. int wiringPiSetupSys (void)
  609. {
  610. int pin ;
  611. struct timeval tv ;
  612. char fName [128] ;
  613. pinMode = pinModeSys ;
  614. pullUpDnControl = pullUpDnControlSys ;
  615. digitalWrite = digitalWriteSys ;
  616. pwmWrite = pwmWriteSys ;
  617. digitalRead = digitalReadSys ;
  618. waitForInterrupt = waitForInterruptSys ;
  619. // Open and scan the directory, looking for exported GPIOs, and pre-open
  620. // the 'value' interface to speed things up for later
  621. for (pin = 0 ; pin < 64 ; ++pin)
  622. {
  623. sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
  624. sysFds [pin] = open (fName, O_RDWR) ;
  625. }
  626. // Initialise the epoch for mills() ...
  627. gettimeofday (&tv, NULL) ;
  628. epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
  629. return 0 ;
  630. }
  631. /*
  632. * delay: delayMicroseconds
  633. * Wait for some number of milli/micro seconds
  634. *********************************************************************************
  635. */
  636. void delay (unsigned int howLong)
  637. {
  638. struct timespec sleeper, dummy ;
  639. sleeper.tv_sec = (time_t)(howLong / 1000) ;
  640. sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
  641. nanosleep (&sleeper, &dummy) ;
  642. }
  643. void delayMicroseconds (unsigned int howLong)
  644. {
  645. struct timespec sleeper, dummy ;
  646. sleeper.tv_sec = 0 ;
  647. sleeper.tv_nsec = (long)(howLong * 1000) ;
  648. nanosleep (&sleeper, &dummy) ;
  649. }
  650. /*
  651. * millis:
  652. * Return a number of milliseconds as an unsigned int.
  653. *********************************************************************************
  654. */
  655. unsigned int millis (void)
  656. {
  657. struct timeval tv ;
  658. unsigned long long t1 ;
  659. gettimeofday (&tv, NULL) ;
  660. t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
  661. return (uint32_t)(t1 - epoch) ;
  662. }