chiark / gitweb /
Updated wiringPi to check the the hardware board revision, to
[wiringPi.git] / wiringPi / wiringPi.c
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
29 // Revisions:
30 //      19 Jul 2012:
31 //              Moved to the LGPL
32 //              Added an abstraction layer to the main routines to save a tiny
33 //              bit of run-time and make the clode a little cleaner (if a little
34 //              larger)
35 //              Added waitForInterrupt code
36 //              Added piHiPri code
37 //
38 //       9 Jul 2012:
39 //              Added in support to use the /sys/class/gpio interface.
40 //       2 Jul 2012:
41 //              Fixed a few more bugs to do with range-checking when in GPIO mode.
42 //      11 Jun 2012:
43 //              Fixed some typos.
44 //              Added c++ support for the .h file
45 //              Added a new function to allow for using my "pin" numbers, or native
46 //                      GPIO pin numbers.
47 //              Removed my busy-loop delay and replaced it with a call to delayMicroseconds
48 //
49 //      02 May 2012:
50 //              Added in the 2 UART pins
51 //              Change maxPins to numPins to more accurately reflect purpose
52
53 // Pad drive current fiddling
54
55 #undef  DEBUG_PADS
56
57 #include <stdio.h>
58 #include <stdint.h>
59 #include <stdlib.h>
60 #include <ctype.h>
61 #include <poll.h>
62 #include <unistd.h>
63 #include <errno.h>
64 #include <string.h>
65 #include <time.h>
66 #include <fcntl.h>
67 #include <sys/time.h>
68 #include <sys/mman.h>
69 #include <sys/types.h>
70 #include <sys/stat.h>
71
72 #include "wiringPi.h"
73
74 // Function stubs
75
76 void (*pinMode)           (int pin, int mode) ;
77 void (*pullUpDnControl)   (int pin, int pud) ;
78 void (*digitalWrite)      (int pin, int value) ;
79 void (*pwmWrite)          (int pin, int value) ;
80 void (*setPadDrive)       (int group, int value) ;
81 int  (*digitalRead)       (int pin) ;
82 int  (*waitForInterrupt)  (int pin, int mS) ;
83 void (*delayMicroseconds) (unsigned int howLong) ;
84 void (*pwmSetMode)        (int mode) ;
85 void (*pwmSetRange)       (unsigned int range) ;
86
87
88 #ifndef TRUE
89 #define TRUE    (1==1)
90 #define FALSE   (1==2)
91 #endif
92
93 // BCM Magic
94
95 #define BCM_PASSWORD            0x5A000000
96
97
98 // Port function select bits
99
100 #define FSEL_INPT               0b000
101 #define FSEL_OUTP               0b001
102 #define FSEL_ALT0               0b100
103 #define FSEL_ALT0               0b100
104 #define FSEL_ALT1               0b101
105 #define FSEL_ALT2               0b110
106 #define FSEL_ALT3               0b111
107 #define FSEL_ALT4               0b011
108 #define FSEL_ALT5               0b010
109
110 // Access from ARM Running Linux
111 //      Take from Gert/Doms code. Some of this is not in the manual
112 //      that I can find )-:
113
114 #define BCM2708_PERI_BASE                          0x20000000
115 #define GPIO_PADS               (BCM2708_PERI_BASE + 0x100000)
116 #define CLOCK_BASE              (BCM2708_PERI_BASE + 0x101000)
117 #define GPIO_BASE               (BCM2708_PERI_BASE + 0x200000)
118 #define GPIO_TIMER              (BCM2708_PERI_BASE + 0x00B000)
119 #define GPIO_PWM                (BCM2708_PERI_BASE + 0x20C000)
120
121 #define PAGE_SIZE               (4*1024)
122 #define BLOCK_SIZE              (4*1024)
123
124 // PWM
125
126 #define PWM_CONTROL 0
127 #define PWM_STATUS  1
128 #define PWM0_RANGE  4
129 #define PWM0_DATA   5
130 #define PWM1_RANGE  8
131 #define PWM1_DATA   9
132
133 #define PWMCLK_CNTL     40
134 #define PWMCLK_DIV      41
135
136 #define PWM1_MS_MODE    0x8000  // Run in MS mode
137 #define PWM1_USEFIFO    0x2000  // Data from FIFO
138 #define PWM1_REVPOLAR   0x1000  // Reverse polarity
139 #define PWM1_OFFSTATE   0x0800  // Ouput Off state
140 #define PWM1_REPEATFF   0x0400  // Repeat last value if FIFO empty
141 #define PWM1_SERIAL     0x0200  // Run in serial mode
142 #define PWM1_ENABLE     0x0100  // Channel Enable
143
144 #define PWM0_MS_MODE    0x0080  // Run in MS mode
145 #define PWM0_USEFIFO    0x0020  // Data from FIFO
146 #define PWM0_REVPOLAR   0x0010  // Reverse polarity
147 #define PWM0_OFFSTATE   0x0008  // Ouput Off state
148 #define PWM0_REPEATFF   0x0004  // Repeat last value if FIFO empty
149 #define PWM0_SERIAL     0x0002  // Run in serial mode
150 #define PWM0_ENABLE     0x0001  // Channel Enable
151
152 // Timer
153
154 #define TIMER_LOAD      (0x400 >> 2)
155 #define TIMER_VALUE     (0x404 >> 2)
156 #define TIMER_CONTROL   (0x408 >> 2)
157 #define TIMER_IRQ_CLR   (0x40C >> 2)
158 #define TIMER_IRQ_RAW   (0x410 >> 2)
159 #define TIMER_IRQ_MASK  (0x414 >> 2)
160 #define TIMER_RELOAD    (0x418 >> 2)
161 #define TIMER_PRE_DIV   (0x41C >> 2)
162 #define TIMER_COUNTER   (0x420 >> 2)
163
164 // Locals to hold pointers to the hardware
165
166 static volatile uint32_t *gpio ;
167 static volatile uint32_t *pwm ;
168 static volatile uint32_t *clk ;
169 static volatile uint32_t *pads ;
170 static volatile uint32_t *timer ;
171
172 static volatile uint32_t *timerIrqRaw ;
173
174 // Raspberry Pi board revision
175
176 static int boardRevision = -1 ;
177
178 // Debugging
179
180 static int wiringPiDebug = FALSE ;
181
182 // The BCM2835 has 54 GPIO pins.
183 //      BCM2835 data sheet, Page 90 onwards.
184 //      There are 6 control registers, each control the functions of a block
185 //      of 10 pins.
186 //      Each control register has 10 sets of 3 bits per GPIO pin:
187 //
188 //      000 = GPIO Pin X is an input
189 //      001 = GPIO Pin X is an output
190 //      100 = GPIO Pin X takes alternate function 0
191 //      101 = GPIO Pin X takes alternate function 1
192 //      110 = GPIO Pin X takes alternate function 2
193 //      111 = GPIO Pin X takes alternate function 3
194 //      011 = GPIO Pin X takes alternate function 4
195 //      010 = GPIO Pin X takes alternate function 5
196 //
197 // So the 3 bits for port X are:
198 //      X / 10 + ((X % 10) * 3)
199
200 // sysFds:
201 //      Map a file descriptor from the /sys/class/gpio/gpioX/value
202
203 static int sysFds [64] ;
204
205 // Doing it the Arduino way with lookup tables...
206 //      Yes, it's probably more innefficient than all the bit-twidling, but it
207 //      does tend to make it all a bit clearer. At least to me!
208
209 // pinToGpio:
210 //      Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
211 //      Cope for 2 different board revieions here
212
213 static int *pinToGpio ;
214
215 static int pinToGpioR1 [64] =
216 {
217   17, 18, 21, 22, 23, 24, 25, 4,        // From the Original Wiki - GPIO 0 through 7
218    0,  1,                               // I2C  - SDA0, SCL0
219    8,  7,                               // SPI  - CE1, CE0
220   10,  9, 11,                           // SPI  - MOSI, MISO, SCLK
221   14, 15,                               // UART - Tx, Rx
222
223 // Padding:
224
225       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 31
226   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 47
227   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 63
228 } ;
229
230 static int pinToGpioR2 [64] =
231 {
232   17, 18, 27, 22, 23, 24, 25, 4,        // From the Original Wiki - GPIO 0 through 7
233    2,  3,                               // I2C  - SDA0, SCL0
234    8,  7,                               // SPI  - CE1, CE0
235   10,  9, 11,                           // SPI  - MOSI, MISO, SCLK
236   14, 15,                               // UART - Tx, Rx
237   28, 29, 30, 31,                       // New GPIOs 8 though 11
238
239 // Padding:
240
241                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 31
242   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 47
243   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 63
244 } ;
245
246 // gpioToGPFSEL:
247 //      Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
248
249 static uint8_t gpioToGPFSEL [] =
250 {
251   0,0,0,0,0,0,0,0,0,0,
252   1,1,1,1,1,1,1,1,1,1,
253   2,2,2,2,2,2,2,2,2,2,
254   3,3,3,3,3,3,3,3,3,3,
255   4,4,4,4,4,4,4,4,4,4,
256   5,5,5,5,5,5,5,5,5,5,
257 } ;
258
259 // gpioToShift
260 //      Define the shift up for the 3 bits per pin in each GPFSEL port
261
262 static uint8_t gpioToShift [] =
263 {
264   0,3,6,9,12,15,18,21,24,27,
265   0,3,6,9,12,15,18,21,24,27,
266   0,3,6,9,12,15,18,21,24,27,
267   0,3,6,9,12,15,18,21,24,27,
268   0,3,6,9,12,15,18,21,24,27,
269 } ;
270
271 // gpioToGPSET:
272 //      (Word) offset to the GPIO Set registers for each GPIO pin
273
274 static uint8_t gpioToGPSET [] =
275 {
276    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,
277    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,
278 } ;
279
280 // gpioToGPCLR:
281 //      (Word) offset to the GPIO Clear registers for each GPIO pin
282
283 static uint8_t gpioToGPCLR [] =
284 {
285   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,
286   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,
287 } ;
288
289 // gpioToGPLEV:
290 //      (Word) offset to the GPIO Input level registers for each GPIO pin
291
292 static uint8_t gpioToGPLEV [] =
293 {
294   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,
295   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,
296 } ;
297
298 #ifdef notYetReady
299 // gpioToEDS
300 //      (Word) offset to the Event Detect Status
301
302 static uint8_t gpioToEDS [] =
303 {
304   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,
305   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,
306 } ;
307
308 // gpioToREN
309 //      (Word) offset to the Rising edgde ENable register
310
311 static uint8_t gpioToREN [] =
312 {
313   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,
314   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,
315 } ;
316
317 // gpioToFEN
318 //      (Word) offset to the Falling edgde ENable register
319
320 static uint8_t gpioToFEN [] =
321 {
322   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,
323   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,
324 } ;
325 #endif
326
327 // gpioToPUDCLK
328 //      (Word) offset to the Pull Up Down Clock regsiter
329
330 #define GPPUD   37
331
332 static uint8_t gpioToPUDCLK [] =
333 {
334   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,
335   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,
336 } ;
337
338 // gpioToPwmALT
339 //      the ALT value to put a GPIO pin into PWM mode
340
341 static uint8_t gpioToPwmALT [] =
342 {
343           0,         0,         0,         0,         0,         0,         0,         0,       //  0 ->  7
344           0,         0,         0,         0, FSEL_ALT0, FSEL_ALT0,         0,         0,       //  8 -> 15
345           0,         0, FSEL_ALT5, FSEL_ALT5,         0,         0,         0,         0,       // 16 -> 23
346           0,         0,         0,         0,         0,         0,         0,         0,       // 24 -> 31
347           0,         0,         0,         0,         0,         0,         0,         0,       // 32 -> 39
348   FSEL_ALT0, FSEL_ALT0,         0,         0,         0, FSEL_ALT0,         0,         0,       // 40 -> 47
349           0,         0,         0,         0,         0,         0,         0,         0,       // 48 -> 55
350           0,         0,         0,         0,         0,         0,         0,         0,       // 56 -> 63
351 } ;
352
353 static uint8_t gpioToPwmPort [] =
354 {
355           0,         0,         0,         0,         0,         0,         0,         0,       //  0 ->  7
356           0,         0,         0,         0, PWM0_DATA, PWM1_DATA,         0,         0,       //  8 -> 15
357           0,         0, PWM0_DATA, PWM1_DATA,         0,         0,         0,         0,       // 16 -> 23
358           0,         0,         0,         0,         0,         0,         0,         0,       // 24 -> 31
359           0,         0,         0,         0,         0,         0,         0,         0,       // 32 -> 39
360   PWM0_DATA, PWM1_DATA,         0,         0,         0, PWM1_DATA,         0,         0,       // 40 -> 47
361           0,         0,         0,         0,         0,         0,         0,         0,       // 48 -> 55
362           0,         0,         0,         0,         0,         0,         0,         0,       // 56 -> 63
363
364 } ;
365
366
367 // Time for easy calculations
368
369 static unsigned long long epoch ;
370
371 //////////////////////////////////////////////////////////////////////////////////
372
373
374 /*
375  * pinMode:
376  *      Sets the mode of a pin to be input, output or PWM output
377  *********************************************************************************
378  */
379
380 void pinModeGpio (int pin, int mode)
381 {
382   static int pwmRunning  = FALSE ;
383   int fSel, shift, alt ;
384
385   pin &= 63 ;
386
387   fSel    = gpioToGPFSEL [pin] ;
388   shift   = gpioToShift  [pin] ;
389
390   /**/ if (mode == INPUT)
391     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
392   else if (mode == OUTPUT)
393     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
394   else if (mode == PWM_OUTPUT)
395   {
396     if ((alt = gpioToPwmALT [pin]) == 0)        // Not a PWM pin
397       return ;
398
399 // Set pin to PWM mode
400
401     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
402
403 // We didn't initialise the PWM hardware at setup time - because it's possible that
404 //      something else is using the PWM - e.g. the Audio systems! So if we use PWM
405 //      here, then we're assuming that nothing else is, otherwise things are going
406 //      to sound a bit funny...
407
408     if (!pwmRunning)
409     {
410
411       *(pwm + PWM_CONTROL) = 0 ;                        // Stop PWM
412       delayMicroseconds (10) ;
413         
414 //      Gert/Doms Values
415       *(clk + PWMCLK_DIV)  = BCM_PASSWORD | (32<<12) ;  // set pwm div to 32 (19.2/32 = 600KHz)
416       *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ;      // Source=osc and enable
417
418       delayMicroseconds (10) ;
419
420       *(pwm + PWM0_RANGE) = 0x400 ; delayMicroseconds (10) ;
421       *(pwm + PWM1_RANGE) = 0x400 ; delayMicroseconds (10) ;
422
423 // Enable PWMs
424
425       *(pwm + PWM0_DATA) = 512 ;
426       *(pwm + PWM1_DATA) = 512 ;
427
428 // Balanced mode (default)
429
430       *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
431
432       pwmRunning = TRUE ;
433     }
434
435   }
436
437 // When we change mode of any pin, we remove the pull up/downs
438 //      Or we used to... Hm. Commented out now because for some wieird reason,
439 //      it seems to block subsequent attempts to set the pull up/downs and I've
440 //      not quite gotten to the bottom of why this happens
441 //      The down-side is that the pull up/downs are rememberd in the SoC between
442 //      power cycles, so it's going to be a good idea to explicitly set them in
443 //      any new code.
444 //
445 //  pullUpDnControl (pin, PUD_OFF) ;
446
447 }
448
449 void pinModeWPi (int pin, int mode)
450 {
451   pinModeGpio (pinToGpio [pin & 63], mode) ;
452 }
453
454 void pinModeSys (int pin, int mode)
455 {
456   return ;
457 }
458
459
460 /*
461  * pwmControl:
462  *      Allow the user to control some of the PWM functions
463  *********************************************************************************
464  */
465
466 void pwmSetModeWPi (int mode)
467 {
468   if (mode == PWM_MODE_MS)
469     *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
470   else
471     *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
472 }
473
474 void pwmSetModeSys (int mode)
475 {
476   return ;
477 }
478
479
480 void pwmSetRangeWPi (unsigned int range)
481 {
482   *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
483   *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
484 }
485
486 void pwmSetRangeSys (unsigned int range)
487 {
488   return ;
489 }
490
491
492 #ifdef notYetReady
493 /*
494  * pinED01:
495  * pinED10:
496  *      Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
497  *      Pin must already be in input mode with appropriate pull up/downs set.
498  *********************************************************************************
499  */
500
501 void pinEnableED01Pi (int pin)
502 {
503   pin = pinToGpio [pin & 63] ;
504 }
505 #endif
506
507
508
509 /*
510  * digitalWrite:
511  *      Set an output bit
512  *********************************************************************************
513  */
514
515 void digitalWriteWPi (int pin, int value)
516 {
517   pin = pinToGpio [pin & 63] ;
518
519   if (value == LOW)
520     *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
521   else
522     *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
523 }
524
525 void digitalWriteGpio (int pin, int value)
526 {
527   pin &= 63 ;
528
529   if (value == LOW)
530     *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
531   else
532     *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
533 }
534
535 void digitalWriteSys (int pin, int value)
536 {
537   pin &= 63 ;
538
539   if (sysFds [pin] != -1)
540   {
541     if (value == LOW)
542       write (sysFds [pin], "0\n", 2) ;
543     else
544       write (sysFds [pin], "1\n", 2) ;
545   }
546 }
547
548
549 /*
550  * pwnWrite:
551  *      Set an output PWM value
552  *********************************************************************************
553  */
554
555 void pwmWriteGpio (int pin, int value)
556 {
557   int port ;
558
559   pin  = pin & 63 ;
560   port = gpioToPwmPort [pin] ;
561
562   *(pwm + port) = value ;
563 }
564
565 void pwmWriteWPi (int pin, int value)
566 {
567   pwmWriteGpio (pinToGpio [pin & 63], value) ;
568 }
569
570 void pwmWriteSys (int pin, int value)
571 {
572   return ;
573 }
574
575
576 /*
577  * setPadDrive:
578  *      Set the PAD driver value
579  *********************************************************************************
580  */
581
582 void setPadDriveWPi (int group, int value)
583 {
584   uint32_t wrVal ;
585
586   if ((group < 0) || (group > 2))
587     return ;
588
589   wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
590   *(pads + group + 11) = wrVal ;
591
592 #ifdef  DEBUG_PADS
593   printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
594   printf ("Read : %08X\n", *(pads + group + 11)) ;
595 #endif
596 }
597
598 void setPadDriveGpio (int group, int value)
599 {
600   setPadDriveWPi (group, value) ;
601 }
602
603 void setPadDriveSys (int group, int value)
604 {
605   return ;
606 }
607
608
609 /*
610  * digitalRead:
611  *      Read the value of a given Pin, returning HIGH or LOW
612  *********************************************************************************
613  */
614
615 int digitalReadWPi (int pin)
616 {
617   pin = pinToGpio [pin & 63] ;
618
619   if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
620     return HIGH ;
621   else
622     return LOW ;
623 }
624
625 int digitalReadGpio (int pin)
626 {
627   pin &= 63 ;
628
629   if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
630     return HIGH ;
631   else
632     return LOW ;
633 }
634
635 int digitalReadSys (int pin)
636 {
637   char c ;
638
639   pin &= 63 ;
640
641   if (sysFds [pin] == -1)
642     return 0 ;
643
644   lseek (sysFds [pin], 0L, SEEK_SET) ;
645   read  (sysFds [pin], &c, 1) ;
646   return (c == '0') ? 0 : 1 ;
647 }
648
649
650 /*
651  * pullUpDownCtrl:
652  *      Control the internal pull-up/down resistors on a GPIO pin
653  *      The Arduino only has pull-ups and these are enabled by writing 1
654  *      to a port when in input mode - this paradigm doesn't quite apply
655  *      here though.
656  *********************************************************************************
657  */
658
659 void pullUpDnControlGpio (int pin, int pud)
660 {
661   pin &= 63 ;
662   pud &=  3 ;
663
664   *(gpio + GPPUD)              = pud ;                  delayMicroseconds (5) ;
665   *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;      delayMicroseconds (5) ;
666   
667   *(gpio + GPPUD)              = 0 ;                    delayMicroseconds (5) ;
668   *(gpio + gpioToPUDCLK [pin]) = 0 ;                    delayMicroseconds (5) ;
669 }
670
671 void pullUpDnControlWPi (int pin, int pud)
672 {
673   pullUpDnControlGpio (pinToGpio [pin & 63], pud) ;
674 }
675
676 void pullUpDnControlSys (int pin, int pud)
677 {
678   return ;
679 }
680
681
682 /*
683  * waitForInterrupt:
684  *      Wait for Interrupt on a GPIO pin.
685  *      This is actually done via the /sys/class/gpio interface regardless of
686  *      the wiringPi access mode in-use. Maybe sometime it might get a better
687  *      way for a bit more efficiency.
688  *********************************************************************************
689  */
690
691 int waitForInterruptSys (int pin, int mS)
692 {
693   int fd, x ;
694   char buf [8] ;
695   struct pollfd polls ;
696
697   if ((fd = sysFds [pin & 63]) == -1)
698     return -2 ;
699
700 // Do a dummy read
701
702   x = read (fd, buf, 6) ;
703   if (x < 0)
704     return x ;
705
706 // And seek
707
708   lseek (fd, 0, SEEK_SET) ;
709
710 // Setup poll structure
711
712   polls.fd     = fd ;
713   polls.events = POLLPRI ;      // Urgent data!
714
715 // Wait for it ...
716
717   return poll (&polls, 1, mS) ;
718 }
719
720 int waitForInterruptWPi (int pin, int mS)
721 {
722   return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
723 }
724
725 int waitForInterruptGpio (int pin, int mS)
726 {
727   return waitForInterruptSys (pin, mS) ;
728 }
729
730
731
732
733 /*
734  * delay:
735  *      Wait for some number of milli seconds
736  *********************************************************************************
737  */
738
739 void delay (unsigned int howLong)
740 {
741   struct timespec sleeper, dummy ;
742
743   sleeper.tv_sec  = (time_t)(howLong / 1000) ;
744   sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
745
746   nanosleep (&sleeper, &dummy) ;
747 }
748
749
750 /*
751  * delayMicroseconds:
752  *      This is somewhat intersting. It seems that on the Pi, a single call
753  *      to nanosleep takes some 80 to 130 microseconds anyway, so while
754  *      obeying the standards (may take longer), it's not always what we
755  *      want!
756  *
757  *      So what I'll do now is if the delay is less than 100uS we'll do it
758  *      in a hard loop, watching a built-in counter on the ARM chip. This is
759  *      somewhat sub-optimal in that it uses 100% CPU, something not an issue
760  *      in a microcontroller, but under a multi-tasking, multi-user OS, it's
761  *      wastefull, however we've no real choice )-:
762  *********************************************************************************
763  */
764
765 void delayMicrosecondsSys (unsigned int howLong)
766 {
767   struct timespec sleeper, dummy ;
768
769   sleeper.tv_sec  = 0 ;
770   sleeper.tv_nsec = (long)(howLong * 1000) ;
771
772   nanosleep (&sleeper, &dummy) ;
773 }
774
775 void delayMicrosecondsHard (unsigned int howLong)
776 {
777   *(timer + TIMER_LOAD)    = howLong ;
778   *(timer + TIMER_IRQ_CLR) = 0 ;
779
780   while (*timerIrqRaw == 0)
781     ;
782 }
783
784 void delayMicrosecondsWPi (unsigned int howLong)
785 {
786   struct timespec sleeper, dummy ;
787
788   /**/ if (howLong ==   0)
789     return ;
790   else if (howLong  < 100)
791     delayMicrosecondsHard (howLong) ;
792   else
793   {
794     sleeper.tv_sec  = 0 ;
795     sleeper.tv_nsec = (long)(howLong * 1000) ;
796     nanosleep (&sleeper, &dummy) ;
797   }
798 }
799
800
801 /*
802  * millis:
803  *      Return a number of milliseconds as an unsigned int.
804  *********************************************************************************
805  */
806
807 unsigned int millis (void)
808 {
809   struct timeval tv ;
810   unsigned long long t1 ;
811
812   gettimeofday (&tv, NULL) ;
813
814   t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
815
816   return (uint32_t)(t1 - epoch) ;
817 }
818
819
820 /*
821  * wiringPiSetup:
822  *      Must be called once at the start of your program execution.
823  *
824  * Default setup: Initialises the system into wiringPi Pin mode and uses the
825  *      memory mapped hardware directly.
826  *********************************************************************************
827  */
828
829 int wiringPiSetup (void)
830 {
831   int      fd ;
832   FILE    *cpuFd ;
833   char     line [80] ;
834   char    *c ;
835   int      revision = -1 ;
836   uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
837   struct timeval tv ;
838
839   if (getenv ("WIRINGPI_DEBUG") != NULL)
840     wiringPiDebug = TRUE ;
841
842   if (wiringPiDebug)
843     printf ("wiringPiSetup called\n") ;
844
845             pinMode =           pinModeWPi ;
846     pullUpDnControl =   pullUpDnControlWPi ;
847        digitalWrite =      digitalWriteWPi ;
848            pwmWrite =          pwmWriteWPi ;
849         setPadDrive =       setPadDriveWPi ;
850         digitalRead =       digitalReadWPi ;
851    waitForInterrupt =  waitForInterruptWPi ;
852   delayMicroseconds = delayMicrosecondsWPi ;
853          pwmSetMode =        pwmSetModeWPi ;
854         pwmSetRange =       pwmSetRangeWPi ;
855   
856 // Find board revision
857
858   if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
859   {
860     fprintf (stderr, "wiringPiSetup: Unable to open /proc/cpuinfo: %s\n", strerror (errno)) ;
861     return -1 ;
862   }
863
864   while (fgets (line, 80, cpuFd) != NULL)
865     if (strncmp (line, "Revision", 8) == 0)
866       for (c = line ; *c ; ++c)
867       {
868         if (!isdigit (*c))
869           continue ;
870         revision = atoi (c) ;
871         break ;
872       }
873
874   fclose (cpuFd) ;
875   if (revision == -1)
876   {
877     fprintf (stderr, "wiringPiSetup: Unable to determine board revision\n") ;
878     errno = 0 ;
879     return -1 ;
880   }
881
882   /**/ if ((revision == 2) || (revision == 3))
883     boardRevision = 1 ;
884   else if ((revision == 4) || (revision == 5) || (revision == 6))
885     boardRevision = 2 ;
886   else
887   {
888     fprintf (stderr, "wiringPiSetup: Unable to determine board revision: %d\n", revision) ;
889     errno = 0 ;
890     return -1 ;
891   }
892
893
894   if (boardRevision == 1)
895     pinToGpio = pinToGpioR1 ;
896   else
897     pinToGpio = pinToGpioR2 ;
898
899   if (wiringPiDebug)
900     printf ("Revision: %d, board revision: %d\n", revision, boardRevision) ;
901
902 // Open the master /dev/memory device
903
904   if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
905   {
906     fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
907     return -1 ;
908   }
909
910 // GPIO:
911
912 // Allocate 2 pages - 1 ...
913
914   if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
915   {
916     fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
917     return -1 ;
918   }
919
920 // ... presumably to make sure we can round it up to a whole page size
921
922   if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
923     gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
924
925   gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
926
927   if ((int32_t)gpio < 0)
928   {
929     fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
930     return -1 ;
931   }
932
933 // PWM
934
935   if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
936   {
937     fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
938     return -1 ;
939   }
940
941   if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
942     pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;
943
944   pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;
945
946   if ((int32_t)pwm < 0)
947   {
948     fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
949     return -1 ;
950   }
951  
952 // Clock control (needed for PWM)
953
954   if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
955   {
956     fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
957     return -1 ;
958   }
959
960   if (((uint32_t)clkMem % PAGE_SIZE) != 0)
961     clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;
962
963   clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;
964
965   if ((int32_t)clk < 0)
966   {
967     fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
968     return -1 ;
969   }
970  
971 // The drive pads
972
973   if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
974   {
975     fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
976     return -1 ;
977   }
978
979   if (((uint32_t)padsMem % PAGE_SIZE) != 0)
980     padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;
981
982   pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;
983
984   if ((int32_t)pads < 0)
985   {
986     fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
987     return -1 ;
988   }
989
990 #ifdef  DEBUG_PADS
991   printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
992   printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
993 #endif
994
995 // The system timer
996
997   if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
998   {
999     fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ;
1000     return -1 ;
1001   }
1002
1003   if (((uint32_t)timerMem % PAGE_SIZE) != 0)
1004     timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ;
1005
1006   timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ;
1007
1008   if ((int32_t)timer < 0)
1009   {
1010     fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
1011     return -1 ;
1012   }
1013
1014 // Set the timer to free-running, 1MHz.
1015 //      0xF9 is 249, the timer divide is base clock / (divide+1)
1016 //      so base clock is 250MHz / 250 = 1MHz.
1017
1018   *(timer + TIMER_CONTROL) = 0x0000280 ;
1019   *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
1020   timerIrqRaw = timer + TIMER_IRQ_RAW ;
1021
1022 // Initialise our epoch for millis()
1023
1024   gettimeofday (&tv, NULL) ;
1025   epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
1026
1027   return 0 ;
1028 }
1029
1030
1031 /*
1032  * wiringPiSetupGpio:
1033  *      Must be called once at the start of your program execution.
1034  *
1035  * GPIO setup: Initialises the system into GPIO Pin mode and uses the
1036  *      memory mapped hardware directly.
1037  *********************************************************************************
1038  */
1039
1040 int wiringPiSetupGpio (void)
1041 {
1042   int x  ;
1043
1044   if (wiringPiDebug)
1045     printf ("wiringPiSetupGpio called\n") ;
1046
1047   if ((x = wiringPiSetup ()) < 0)
1048     return x ;
1049
1050             pinMode =           pinModeGpio ;
1051     pullUpDnControl =   pullUpDnControlGpio ;
1052        digitalWrite =      digitalWriteGpio ;
1053            pwmWrite =          pwmWriteGpio ;
1054         setPadDrive =       setPadDriveGpio ;
1055         digitalRead =       digitalReadGpio ;
1056    waitForInterrupt =  waitForInterruptGpio ;
1057   delayMicroseconds = delayMicrosecondsWPi ;    // Same
1058          pwmSetMode =        pwmSetModeWPi ;
1059         pwmSetRange =       pwmSetRangeWPi ;
1060
1061   return 0 ;
1062 }
1063
1064
1065 /*
1066  * wiringPiSetupSys:
1067  *      Must be called once at the start of your program execution.
1068  *
1069  * Initialisation (again), however this time we are using the /sys/class/gpio
1070  *      interface to the GPIO systems - slightly slower, but always usable as
1071  *      a non-root user, assuming the devices are already exported and setup correctly.
1072  */
1073
1074 int wiringPiSetupSys (void)
1075 {
1076   int pin ;
1077   struct timeval tv ;
1078   char fName [128] ;
1079
1080   if (wiringPiDebug)
1081     printf ("wiringPiSetupSys called\n") ;
1082
1083             pinMode =           pinModeSys ;
1084     pullUpDnControl =   pullUpDnControlSys ;
1085        digitalWrite =      digitalWriteSys ;
1086            pwmWrite =          pwmWriteSys ;
1087         setPadDrive =       setPadDriveSys ;
1088         digitalRead =       digitalReadSys ;
1089    waitForInterrupt =  waitForInterruptSys ;
1090   delayMicroseconds = delayMicrosecondsSys ;
1091          pwmSetMode =        pwmSetModeSys ;
1092         pwmSetRange =       pwmSetRangeSys ;
1093
1094
1095 // Open and scan the directory, looking for exported GPIOs, and pre-open
1096 //      the 'value' interface to speed things up for later
1097   
1098   for (pin = 0 ; pin < 64 ; ++pin)
1099   {
1100     sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
1101     sysFds [pin] = open (fName, O_RDWR) ;
1102   }
1103
1104 // Initialise the epoch for mills() ...
1105
1106   gettimeofday (&tv, NULL) ;
1107   epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
1108
1109   return 0 ;
1110 }