chiark / gitweb /
Big update here.
[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  *      Additional code for pwmSetClock by Chris Hall <chris@kchall.plus.com>
6  *
7  *      Thanks to code samples from Gert Jan van Loo and the
8  *      BCM2835 ARM Peripherals manual, however it's missing
9  *      the clock section /grr/mutter/
10  ***********************************************************************
11  * This file is part of wiringPi:
12  *      https://projects.drogon.net/raspberry-pi/wiringpi/
13  *
14  *    wiringPi is free software: you can redistribute it and/or modify
15  *    it under the terms of the GNU Lesser General Public License as
16  *    published by the Free Software Foundation, either version 3 of the
17  *    License, or (at your option) any later version.
18  *
19  *    wiringPi is distributed in the hope that it will be useful,
20  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *    GNU Lesser General Public License for more details.
23  *
24  *    You should have received a copy of the GNU Lesser General Public
25  *    License along with wiringPi.
26  *    If not, see <http://www.gnu.org/licenses/>.
27  ***********************************************************************
28  */
29
30 // Revisions:
31 //      19 Jul 2012:
32 //              Moved to the LGPL
33 //              Added an abstraction layer to the main routines to save a tiny
34 //              bit of run-time and make the clode a little cleaner (if a little
35 //              larger)
36 //              Added waitForInterrupt code
37 //              Added piHiPri code
38 //
39 //       9 Jul 2012:
40 //              Added in support to use the /sys/class/gpio interface.
41 //       2 Jul 2012:
42 //              Fixed a few more bugs to do with range-checking when in GPIO mode.
43 //      11 Jun 2012:
44 //              Fixed some typos.
45 //              Added c++ support for the .h file
46 //              Added a new function to allow for using my "pin" numbers, or native
47 //                      GPIO pin numbers.
48 //              Removed my busy-loop delay and replaced it with a call to delayMicroseconds
49 //
50 //      02 May 2012:
51 //              Added in the 2 UART pins
52 //              Change maxPins to numPins to more accurately reflect purpose
53
54 // Pad drive current fiddling
55
56 #undef  DEBUG_PADS
57
58 #include <stdio.h>
59 #include <stdint.h>
60 #include <stdlib.h>
61 #include <ctype.h>
62 #include <poll.h>
63 #include <unistd.h>
64 #include <errno.h>
65 #include <string.h>
66 #include <time.h>
67 #include <fcntl.h>
68 #include <sys/time.h>
69 #include <sys/mman.h>
70 #include <sys/types.h>
71 #include <sys/stat.h>
72
73 #include "wiringPi.h"
74
75 // Function stubs
76
77 void (*pinMode)           (int pin, int mode) ;
78 void (*pullUpDnControl)   (int pin, int pud) ;
79 void (*digitalWrite)      (int pin, int value) ;
80 void (*digitalWriteByte)  (int value) ;
81 void (*pwmWrite)          (int pin, int value) ;
82 void (*setPadDrive)       (int group, int value) ;
83 int  (*digitalRead)       (int pin) ;
84 int  (*waitForInterrupt)  (int pin, int mS) ;
85 void (*delayMicroseconds) (unsigned int howLong) ;
86 void (*pwmSetMode)        (int mode) ;
87 void (*pwmSetRange)       (unsigned int range) ;
88 void (*pwmSetClock)       (int divisor) ;
89
90
91 #ifndef TRUE
92 #define TRUE    (1==1)
93 #define FALSE   (1==2)
94 #endif
95
96 // BCM Magic
97
98 #define BCM_PASSWORD            0x5A000000
99
100
101 // Port function select bits
102
103 #define FSEL_INPT               0b000
104 #define FSEL_OUTP               0b001
105 #define FSEL_ALT0               0b100
106 #define FSEL_ALT0               0b100
107 #define FSEL_ALT1               0b101
108 #define FSEL_ALT2               0b110
109 #define FSEL_ALT3               0b111
110 #define FSEL_ALT4               0b011
111 #define FSEL_ALT5               0b010
112
113 // Access from ARM Running Linux
114 //      Take from Gert/Doms code. Some of this is not in the manual
115 //      that I can find )-:
116
117 #define BCM2708_PERI_BASE                          0x20000000
118 #define GPIO_PADS               (BCM2708_PERI_BASE + 0x100000)
119 #define CLOCK_BASE              (BCM2708_PERI_BASE + 0x101000)
120 #define GPIO_BASE               (BCM2708_PERI_BASE + 0x200000)
121 #define GPIO_TIMER              (BCM2708_PERI_BASE + 0x00B000)
122 #define GPIO_PWM                (BCM2708_PERI_BASE + 0x20C000)
123
124 #define PAGE_SIZE               (4*1024)
125 #define BLOCK_SIZE              (4*1024)
126
127 // PWM
128
129 #define PWM_CONTROL 0
130 #define PWM_STATUS  1
131 #define PWM0_RANGE  4
132 #define PWM0_DATA   5
133 #define PWM1_RANGE  8
134 #define PWM1_DATA   9
135
136 #define PWMCLK_CNTL     40
137 #define PWMCLK_DIV      41
138
139 #define PWM1_MS_MODE    0x8000  // Run in MS mode
140 #define PWM1_USEFIFO    0x2000  // Data from FIFO
141 #define PWM1_REVPOLAR   0x1000  // Reverse polarity
142 #define PWM1_OFFSTATE   0x0800  // Ouput Off state
143 #define PWM1_REPEATFF   0x0400  // Repeat last value if FIFO empty
144 #define PWM1_SERIAL     0x0200  // Run in serial mode
145 #define PWM1_ENABLE     0x0100  // Channel Enable
146
147 #define PWM0_MS_MODE    0x0080  // Run in MS mode
148 #define PWM0_USEFIFO    0x0020  // Data from FIFO
149 #define PWM0_REVPOLAR   0x0010  // Reverse polarity
150 #define PWM0_OFFSTATE   0x0008  // Ouput Off state
151 #define PWM0_REPEATFF   0x0004  // Repeat last value if FIFO empty
152 #define PWM0_SERIAL     0x0002  // Run in serial mode
153 #define PWM0_ENABLE     0x0001  // Channel Enable
154
155 // Timer
156
157 #define TIMER_LOAD      (0x400 >> 2)
158 #define TIMER_VALUE     (0x404 >> 2)
159 #define TIMER_CONTROL   (0x408 >> 2)
160 #define TIMER_IRQ_CLR   (0x40C >> 2)
161 #define TIMER_IRQ_RAW   (0x410 >> 2)
162 #define TIMER_IRQ_MASK  (0x414 >> 2)
163 #define TIMER_RELOAD    (0x418 >> 2)
164 #define TIMER_PRE_DIV   (0x41C >> 2)
165 #define TIMER_COUNTER   (0x420 >> 2)
166
167 // Locals to hold pointers to the hardware
168
169 static volatile uint32_t *gpio ;
170 static volatile uint32_t *pwm ;
171 static volatile uint32_t *clk ;
172 static volatile uint32_t *pads ;
173 static volatile uint32_t *timer ;
174 static volatile uint32_t *timerIrqRaw ;
175
176 // Debugging
177
178 static int wiringPiDebug = FALSE ;
179
180 // The BCM2835 has 54 GPIO pins.
181 //      BCM2835 data sheet, Page 90 onwards.
182 //      There are 6 control registers, each control the functions of a block
183 //      of 10 pins.
184 //      Each control register has 10 sets of 3 bits per GPIO pin:
185 //
186 //      000 = GPIO Pin X is an input
187 //      001 = GPIO Pin X is an output
188 //      100 = GPIO Pin X takes alternate function 0
189 //      101 = GPIO Pin X takes alternate function 1
190 //      110 = GPIO Pin X takes alternate function 2
191 //      111 = GPIO Pin X takes alternate function 3
192 //      011 = GPIO Pin X takes alternate function 4
193 //      010 = GPIO Pin X takes alternate function 5
194 //
195 // So the 3 bits for port X are:
196 //      X / 10 + ((X % 10) * 3)
197
198 // sysFds:
199 //      Map a file descriptor from the /sys/class/gpio/gpioX/value
200
201 static int sysFds [64] ;
202
203 // Doing it the Arduino way with lookup tables...
204 //      Yes, it's probably more innefficient than all the bit-twidling, but it
205 //      does tend to make it all a bit clearer. At least to me!
206
207 // pinToGpio:
208 //      Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
209 //      Cope for 2 different board revieions here
210
211 static int *pinToGpio ;
212
213 static int pinToGpioR1 [64] =
214 {
215   17, 18, 21, 22, 23, 24, 25, 4,        // From the Original Wiki - GPIO 0 through 7
216    0,  1,                               // I2C  - SDA0, SCL0
217    8,  7,                               // SPI  - CE1, CE0
218   10,  9, 11,                           // SPI  - MOSI, MISO, SCLK
219   14, 15,                               // UART - Tx, Rx
220
221 // Padding:
222
223       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 31
224   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 47
225   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 63
226 } ;
227
228 static int pinToGpioR2 [64] =
229 {
230   17, 18, 27, 22, 23, 24, 25, 4,        // From the Original Wiki - GPIO 0 through 7:   wpi  0 -  7
231    2,  3,                               // I2C  - SDA0, SCL0                            wpi  8 -  9
232    8,  7,                               // SPI  - CE1, CE0                              wpi 10 - 11
233   10,  9, 11,                           // SPI  - MOSI, MISO, SCLK                      wpi 12 - 14
234   14, 15,                               // UART - Tx, Rx                                wpi 15 - 16
235   28, 29, 30, 31,                       // New GPIOs 8 though 11                        wpi 17 - 20
236
237 // Padding:
238
239                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 31
240   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 47
241   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,       // ... 63
242 } ;
243
244
245 // gpioToGPFSEL:
246 //      Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
247
248 static uint8_t gpioToGPFSEL [] =
249 {
250   0,0,0,0,0,0,0,0,0,0,
251   1,1,1,1,1,1,1,1,1,1,
252   2,2,2,2,2,2,2,2,2,2,
253   3,3,3,3,3,3,3,3,3,3,
254   4,4,4,4,4,4,4,4,4,4,
255   5,5,5,5,5,5,5,5,5,5,
256 } ;
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
272 // gpioToGPSET:
273 //      (Word) offset to the GPIO Set registers for each GPIO pin
274
275 static uint8_t gpioToGPSET [] =
276 {
277    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,
278    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,
279 } ;
280
281
282 // gpioToGPCLR:
283 //      (Word) offset to the GPIO Clear registers for each GPIO pin
284
285 static uint8_t gpioToGPCLR [] =
286 {
287   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,
288   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,
289 } ;
290
291
292 // gpioToGPLEV:
293 //      (Word) offset to the GPIO Input level registers for each GPIO pin
294
295 static uint8_t gpioToGPLEV [] =
296 {
297   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,
298   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,
299 } ;
300
301
302 #ifdef notYetReady
303 // gpioToEDS
304 //      (Word) offset to the Event Detect Status
305
306 static uint8_t gpioToEDS [] =
307 {
308   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,
309   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,
310 } ;
311
312 // gpioToREN
313 //      (Word) offset to the Rising edgde ENable register
314
315 static uint8_t gpioToREN [] =
316 {
317   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,
318   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,
319 } ;
320
321 // gpioToFEN
322 //      (Word) offset to the Falling edgde ENable register
323
324 static uint8_t gpioToFEN [] =
325 {
326   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,
327   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,
328 } ;
329 #endif
330
331
332 // gpioToPUDCLK
333 //      (Word) offset to the Pull Up Down Clock regsiter
334
335 #define GPPUD   37
336
337 static uint8_t gpioToPUDCLK [] =
338 {
339   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,
340   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,
341 } ;
342
343
344 // gpioToPwmALT
345 //      the ALT value to put a GPIO pin into PWM mode
346
347 static uint8_t gpioToPwmALT [] =
348 {
349           0,         0,         0,         0,         0,         0,         0,         0,       //  0 ->  7
350           0,         0,         0,         0, FSEL_ALT0, FSEL_ALT0,         0,         0,       //  8 -> 15
351           0,         0, FSEL_ALT5, FSEL_ALT5,         0,         0,         0,         0,       // 16 -> 23
352           0,         0,         0,         0,         0,         0,         0,         0,       // 24 -> 31
353           0,         0,         0,         0,         0,         0,         0,         0,       // 32 -> 39
354   FSEL_ALT0, FSEL_ALT0,         0,         0,         0, FSEL_ALT0,         0,         0,       // 40 -> 47
355           0,         0,         0,         0,         0,         0,         0,         0,       // 48 -> 55
356           0,         0,         0,         0,         0,         0,         0,         0,       // 56 -> 63
357 } ;
358
359 static uint8_t gpioToPwmPort [] =
360 {
361           0,         0,         0,         0,         0,         0,         0,         0,       //  0 ->  7
362           0,         0,         0,         0, PWM0_DATA, PWM1_DATA,         0,         0,       //  8 -> 15
363           0,         0, PWM0_DATA, PWM1_DATA,         0,         0,         0,         0,       // 16 -> 23
364           0,         0,         0,         0,         0,         0,         0,         0,       // 24 -> 31
365           0,         0,         0,         0,         0,         0,         0,         0,       // 32 -> 39
366   PWM0_DATA, PWM1_DATA,         0,         0,         0, PWM1_DATA,         0,         0,       // 40 -> 47
367           0,         0,         0,         0,         0,         0,         0,         0,       // 48 -> 55
368           0,         0,         0,         0,         0,         0,         0,         0,       // 56 -> 63
369
370 } ;
371
372
373 // Time for easy calculations
374
375 static unsigned long long epoch ;
376
377 /*
378  * Functions
379  *********************************************************************************
380  */
381
382
383 /*
384  * wpiPinToGpio:
385  *      Translate a wiringPi Pin number to native GPIO pin number.
386  *      (We don't use this here, prefering to just do the lookup directly,
387  *      but it's been requested!)
388  *********************************************************************************
389  */
390
391 int wpiPinToGpio (int wpiPin)
392 {
393   return pinToGpio [wpiPin & 63] ;
394 }
395
396
397 /*
398  * piBoardRev:
399  *      Return a number representing the hardware revision of the board.
400  *      Revision is currently 1 or 2. -1 is returned on error.
401  *
402  *      Much confusion here )-:
403  *      Seems there are some boards with 0000 in them (mistake in manufacture)
404  *      and some board with 0005 in them (another mistake in manufacture?)
405  *      So the distinction between boards that I can see is:
406  *      0000 - Error
407  *      0001 - Not used
408  *      0002 - Rev 1
409  *      0003 - Rev 1
410  *      0004 - Rev 2
411  *      0005 - Rev 2 (but error)
412  *      0006 - Rev 2
413  *      000f - Rev 2 + 512MB
414  *
415  *      A small thorn is the olde style overvolting - that will add in
416  *              1000000
417  *
418  *********************************************************************************
419  */
420
421 int piBoardRev (void)
422 {
423   FILE *cpuFd ;
424   char line [120] ;
425   char *c, lastChar ;
426   static int  boardRev = -1 ;
427
428 // No point checking twice...
429
430   if (boardRev != -1)
431     return boardRev ;
432
433   if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
434     return -1 ;
435
436   while (fgets (line, 120, cpuFd) != NULL)
437     if (strncmp (line, "Revision", 8) == 0)
438       break ;
439
440   fclose (cpuFd) ;
441
442   if (line == NULL)
443   {
444     fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
445     fprintf (stderr, "  (No \"Revision\" line)\n") ;
446     errno = 0 ;
447     return -1 ;
448   }
449   
450   for (c = line ; *c ; ++c)
451     if (isdigit (*c))
452       break ;
453
454   if (!isdigit (*c))
455   {
456     fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
457     fprintf (stderr, "  (No numeric revision string in: \"%s\"\n", line) ;
458     errno = 0 ;
459     return -1 ;
460   }
461
462 // If you have overvolted the Pi, then it appears that the revision
463 //      has 100000 added to it!
464
465   if (wiringPiDebug)
466     if (strlen (c) != 4)
467       printf ("piboardRev: This Pi has/is overvolted!\n") ;
468
469   lastChar = c [strlen (c) - 2] ;
470
471   /**/ if ((lastChar == '2') || (lastChar == '3'))
472     boardRev = 1 ;
473   else
474     boardRev = 2 ;
475
476 #ifdef  DO_WE_CARE_ABOUT_THIS_NOW
477   else
478   {
479     fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ;
480     fprintf (stderr, " -> You may want to check:\n") ;
481     fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
482     fprintf (stderr, " -> Assuming a Rev 1 board\n") ;
483     boardRev = 1 ;
484   }
485 #endif
486
487   if (wiringPiDebug)
488     printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ;
489
490   return boardRev ;
491 }
492
493
494
495 /*
496  * pinMode:
497  *      Sets the mode of a pin to be input, output or PWM output
498  *********************************************************************************
499  */
500
501 void pinModeGpio (int pin, int mode)
502 {
503 //  register int barrier ;
504
505   int fSel, shift, alt ;
506
507   pin &= 63 ;
508
509   fSel    = gpioToGPFSEL [pin] ;
510   shift   = gpioToShift  [pin] ;
511
512   /**/ if (mode == INPUT)
513     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
514   else if (mode == OUTPUT)
515     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
516   else if (mode == PWM_OUTPUT)
517   {
518     if ((alt = gpioToPwmALT [pin]) == 0)        // Not a PWM pin
519       return ;
520
521 // Set pin to PWM mode
522
523     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
524
525     delayMicroseconds (110) ;                           // See comments in pwmSetClockWPi
526     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
527
528 //  Page 107 of the BCM Peripherals manual talks about the GPIO clocks,
529 //      but I'm assuming (hoping!) that this applies to other clocks too.
530
531     *(pwm + PWM_CONTROL) = 0 ;                          // Stop PWM
532
533     *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ;        // Stop PWM Clock
534     delayMicroseconds (110) ;                           // See comments in pwmSetClockWPi
535
536     while ((*(clk + PWMCLK_CNTL) & 0x80) != 0)          // Wait for clock to be !BUSY
537       delayMicroseconds (1) ;
538
539     *(clk + PWMCLK_DIV)  = BCM_PASSWORD | (32 << 12) ;  // set pwm div to 32 (19.2/32 = 600KHz)
540     *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ;        // enable clk
541
542     delayMicroseconds (110) ;                           // See comments in pwmSetClockWPi
543
544 // Default range register of 1024
545
546     *(pwm + PWM0_RANGE) = 1024 ; delayMicroseconds (10) ;
547     *(pwm + PWM1_RANGE) = 1024 ; delayMicroseconds (10) ;
548     *(pwm + PWM0_DATA)  =    0 ; delayMicroseconds (10) ;
549     *(pwm + PWM1_DATA)  =    0 ; delayMicroseconds (10) ;
550
551 // Enable PWMs in balanced mode (default)
552
553     *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
554
555     delay (100) ;
556   }
557
558
559 // When we change mode of any pin, we remove the pull up/downs
560 //      Or we used to... Hm. Commented out now because for some wieird reason,
561 //      it seems to block subsequent attempts to set the pull up/downs and I've
562 //      not quite gotten to the bottom of why this happens
563 //      The down-side is that the pull up/downs are rememberd in the SoC between
564 //      power cycles, so it's going to be a good idea to explicitly set them in
565 //      any new code.
566 //
567 //  pullUpDnControl (pin, PUD_OFF) ;
568
569 }
570
571 void pinModeWPi (int pin, int mode)
572 {
573   pinModeGpio (pinToGpio [pin & 63], mode) ;
574 }
575
576 void pinModeSys (int pin, int mode)
577 {
578   return ;
579 }
580
581
582 /*
583  * pwmControl:
584  *      Allow the user to control some of the PWM functions
585  *********************************************************************************
586  */
587
588 void pwmSetModeWPi (int mode)
589 {
590   if (mode == PWM_MODE_MS)
591     *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
592   else
593     *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
594 }
595
596 void pwmSetModeSys (int mode)
597 {
598   return ;
599 }
600
601
602 void pwmSetRangeWPi (unsigned int range)
603 {
604   *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
605   *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
606 }
607
608 void pwmSetRangeSys (unsigned int range)
609 {
610   return ;
611 }
612
613 /*
614  * pwmSetClockWPi:
615  *      Set/Change the PWM clock. Originally my code, but changed
616  *      (for the better!) by Chris Hall, <chris@kchall.plus.com>
617  *      after further study of the manual and testing with a 'scope
618  *********************************************************************************
619  */
620
621 void pwmSetClockWPi (int divisor)
622 {
623   unsigned int pwm_control ;
624   divisor &= 4095 ;
625
626   if (wiringPiDebug)
627     printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
628
629   pwm_control = *(pwm + PWM_CONTROL) ;          // preserve PWM_CONTROL
630
631 // We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
632 // stays high.
633
634   *(pwm + PWM_CONTROL) = 0 ;                    // Stop PWM
635
636 // Stop PWM clock before changing divisor. The delay after this does need to
637 // this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY
638 // flag is not working properly in balanced mode. Without the delay when DIV is
639 // adjusted the clock sometimes switches to very slow, once slow further DIV
640 // adjustments do nothing and it's difficult to get out of this mode.
641
642   *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ;  // Stop PWM Clock
643     delayMicroseconds (110) ;                   // prevents clock going sloooow
644
645   while ((*(clk + PWMCLK_CNTL) & 0x80) != 0)    // Wait for clock to be !BUSY
646     delayMicroseconds (1) ;
647
648   *(clk + PWMCLK_DIV)  = BCM_PASSWORD | (divisor << 12) ;
649
650   *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ;  // Start PWM clock
651   *(pwm + PWM_CONTROL) = pwm_control ;          // restore PWM_CONTROL
652
653   if (wiringPiDebug)
654     printf ("Set     to: %d. Now    : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
655 }
656
657 void pwmSetClockSys (int divisor)
658 {
659   return ;
660 }
661
662
663 #ifdef notYetReady
664 /*
665  * pinED01:
666  * pinED10:
667  *      Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
668  *      Pin must already be in input mode with appropriate pull up/downs set.
669  *********************************************************************************
670  */
671
672 void pinEnableED01Pi (int pin)
673 {
674   pin = pinToGpio [pin & 63] ;
675 }
676 #endif
677
678
679
680 /*
681  * digitalWrite:
682  *      Set an output bit
683  *********************************************************************************
684  */
685
686 void digitalWriteWPi (int pin, int value)
687 {
688   pin = pinToGpio [pin & 63] ;
689
690   if (value == LOW)
691     *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
692   else
693     *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
694 }
695
696 void digitalWriteGpio (int pin, int value)
697 {
698   pin &= 63 ;
699
700   if (value == LOW)
701     *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
702   else
703     *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
704 }
705
706 void digitalWriteSys (int pin, int value)
707 {
708   pin &= 63 ;
709
710   if (sysFds [pin] != -1)
711   {
712     if (value == LOW)
713       write (sysFds [pin], "0\n", 2) ;
714     else
715       write (sysFds [pin], "1\n", 2) ;
716   }
717 }
718
719
720 /*
721  * digitalWriteByte:
722  *      Write an 8-bit byte to the first 8 GPIO pins - try to do it as
723  *      fast as possible.
724  *      However it still needs 2 operations to set the bits, so any external
725  *      hardware must not rely on seeing a change as there will be a change 
726  *      to set the outputs bits to zero, then another change to set the 1's
727  *********************************************************************************
728  */
729
730 void digitalWriteByteGpio (int value)
731 {
732   uint32_t pinSet = 0 ;
733   uint32_t pinClr = 0 ;
734   int mask = 1 ;
735   int pin ;
736
737   for (pin = 0 ; pin < 8 ; ++pin)
738   {
739     if ((value & mask) == 0)
740       pinClr |= (1 << pinToGpio [pin]) ;
741     else
742       pinSet |= (1 << pinToGpio [pin]) ;
743
744     *(gpio + gpioToGPCLR [0]) = pinClr ;
745     *(gpio + gpioToGPSET [0]) = pinSet ;
746
747     mask <<= 1 ;
748   }
749 }
750
751 void digitalWriteByteSys (int value)
752 {
753   int mask = 1 ;
754   int pin ;
755
756   for (pin = 0 ; pin < 8 ; ++pin)
757   {
758     digitalWriteSys (pinToGpio [pin], value & mask) ;
759     mask <<= 1 ;
760   }
761 }
762
763
764 /*
765  * pwmWrite:
766  *      Set an output PWM value
767  *********************************************************************************
768  */
769
770 void pwmWriteGpio (int pin, int value)
771 {
772   int port ;
773
774   pin  = pin & 63 ;
775   port = gpioToPwmPort [pin] ;
776
777   *(pwm + port) = value ;
778 }
779
780 void pwmWriteWPi (int pin, int value)
781 {
782   pwmWriteGpio (pinToGpio [pin & 63], value) ;
783 }
784
785 void pwmWriteSys (int pin, int value)
786 {
787   return ;
788 }
789
790
791 /*
792  * setPadDrive:
793  *      Set the PAD driver value
794  *********************************************************************************
795  */
796
797 void setPadDriveWPi (int group, int value)
798 {
799   uint32_t wrVal ;
800
801   if ((group < 0) || (group > 2))
802     return ;
803
804   wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
805   *(pads + group + 11) = wrVal ;
806
807 #ifdef  DEBUG_PADS
808   printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
809   printf ("Read : %08X\n", *(pads + group + 11)) ;
810 #endif
811 }
812
813 void setPadDriveGpio (int group, int value)
814 {
815   setPadDriveWPi (group, value) ;
816 }
817
818 void setPadDriveSys (int group, int value)
819 {
820   return ;
821 }
822
823
824 /*
825  * digitalRead:
826  *      Read the value of a given Pin, returning HIGH or LOW
827  *********************************************************************************
828  */
829
830 int digitalReadWPi (int pin)
831 {
832   pin = pinToGpio [pin & 63] ;
833
834   if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
835     return HIGH ;
836   else
837     return LOW ;
838 }
839
840 int digitalReadGpio (int pin)
841 {
842   pin &= 63 ;
843
844   if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
845     return HIGH ;
846   else
847     return LOW ;
848 }
849
850 int digitalReadSys (int pin)
851 {
852   char c ;
853
854   pin &= 63 ;
855
856   if (sysFds [pin] == -1)
857     return 0 ;
858
859   lseek (sysFds [pin], 0L, SEEK_SET) ;
860   read  (sysFds [pin], &c, 1) ;
861   return (c == '0') ? 0 : 1 ;
862 }
863
864
865 /*
866  * pullUpDownCtrl:
867  *      Control the internal pull-up/down resistors on a GPIO pin
868  *      The Arduino only has pull-ups and these are enabled by writing 1
869  *      to a port when in input mode - this paradigm doesn't quite apply
870  *      here though.
871  *********************************************************************************
872  */
873
874 void pullUpDnControlGpio (int pin, int pud)
875 {
876   pin &= 63 ;
877   pud &=  3 ;
878
879   *(gpio + GPPUD)              = pud ;                  delayMicroseconds (5) ;
880   *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;      delayMicroseconds (5) ;
881   
882   *(gpio + GPPUD)              = 0 ;                    delayMicroseconds (5) ;
883   *(gpio + gpioToPUDCLK [pin]) = 0 ;                    delayMicroseconds (5) ;
884 }
885
886 void pullUpDnControlWPi (int pin, int pud)
887 {
888   pullUpDnControlGpio (pinToGpio [pin & 63], pud) ;
889 }
890
891 void pullUpDnControlSys (int pin, int pud)
892 {
893   return ;
894 }
895
896
897 /*
898  * waitForInterrupt:
899  *      Wait for Interrupt on a GPIO pin.
900  *      This is actually done via the /sys/class/gpio interface regardless of
901  *      the wiringPi access mode in-use. Maybe sometime it might get a better
902  *      way for a bit more efficiency.
903  *********************************************************************************
904  */
905
906 int waitForInterruptSys (int pin, int mS)
907 {
908   int fd, x ;
909   char buf [8] ;
910   struct pollfd polls ;
911
912   if ((fd = sysFds [pin & 63]) == -1)
913     return -2 ;
914
915 // Do a dummy read
916
917   x = read (fd, buf, 6) ;
918   if (x < 0)
919     return x ;
920
921 // And seek
922
923   lseek (fd, 0, SEEK_SET) ;
924
925 // Setup poll structure
926
927   polls.fd     = fd ;
928   polls.events = POLLPRI ;      // Urgent data!
929
930 // Wait for it ...
931
932   return poll (&polls, 1, mS) ;
933 }
934
935 int waitForInterruptWPi (int pin, int mS)
936 {
937   return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
938 }
939
940 int waitForInterruptGpio (int pin, int mS)
941 {
942   return waitForInterruptSys (pin, mS) ;
943 }
944
945
946 /*
947  * delay:
948  *      Wait for some number of milli seconds
949  *********************************************************************************
950  */
951
952 void delay (unsigned int howLong)
953 {
954   struct timespec sleeper, dummy ;
955
956   sleeper.tv_sec  = (time_t)(howLong / 1000) ;
957   sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
958
959   nanosleep (&sleeper, &dummy) ;
960 }
961
962
963 /*
964  * delayMicroseconds:
965  *      This is somewhat intersting. It seems that on the Pi, a single call
966  *      to nanosleep takes some 80 to 130 microseconds anyway, so while
967  *      obeying the standards (may take longer), it's not always what we
968  *      want!
969  *
970  *      So what I'll do now is if the delay is less than 100uS we'll do it
971  *      in a hard loop, watching a built-in counter on the ARM chip. This is
972  *      somewhat sub-optimal in that it uses 100% CPU, something not an issue
973  *      in a microcontroller, but under a multi-tasking, multi-user OS, it's
974  *      wastefull, however we've no real choice )-:
975  *
976  *      Plan B: It seems all might not be well with that plan, so changing it
977  *      to use gettimeofday () and poll on that instead...
978  *********************************************************************************
979  */
980
981 void delayMicrosecondsSys (unsigned int howLong)
982 {
983   struct timespec sleeper, dummy ;
984
985   sleeper.tv_sec  = 0 ;
986   sleeper.tv_nsec = (long)(howLong * 1000) ;
987
988   nanosleep (&sleeper, &dummy) ;
989 }
990
991 void delayMicrosecondsHard (unsigned int howLong)
992 {
993 #ifdef  HARD_TIMER
994   volatile unsigned int dummy ;
995
996   *(timer + TIMER_LOAD)    = howLong ;
997   *(timer + TIMER_IRQ_CLR) = 0 ;
998
999   dummy = *timerIrqRaw ;
1000   while (dummy == 0)
1001     dummy = *timerIrqRaw ;
1002 #else
1003   struct timeval tNow, tLong, tEnd ;
1004
1005   gettimeofday (&tNow, NULL) ;
1006   tLong.tv_sec  = howLong / 1000000 ;
1007   tLong.tv_usec = howLong % 1000000 ;
1008   timeradd (&tNow, &tLong, &tEnd) ;
1009
1010   while (timercmp (&tNow, &tEnd, <))
1011     gettimeofday (&tNow, NULL) ;
1012 #endif
1013 }
1014
1015 void delayMicrosecondsWPi (unsigned int howLong)
1016 {
1017   struct timespec sleeper ;
1018
1019   /**/ if (howLong ==   0)
1020     return ;
1021   else if (howLong  < 100)
1022     delayMicrosecondsHard (howLong) ;
1023   else
1024   {
1025     sleeper.tv_sec  = 0 ;
1026     sleeper.tv_nsec = (long)(howLong * 1000) ;
1027     nanosleep (&sleeper, NULL) ;
1028   }
1029 }
1030
1031
1032 /*
1033  * millis:
1034  *      Return a number of milliseconds as an unsigned int.
1035  *********************************************************************************
1036  */
1037
1038 unsigned int millis (void)
1039 {
1040   struct timeval tv ;
1041   unsigned long long t1 ;
1042
1043   gettimeofday (&tv, NULL) ;
1044
1045   t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
1046
1047   return (uint32_t)(t1 - epoch) ;
1048 }
1049
1050
1051 /*
1052  * wiringPiSetup:
1053  *      Must be called once at the start of your program execution.
1054  *
1055  * Default setup: Initialises the system into wiringPi Pin mode and uses the
1056  *      memory mapped hardware directly.
1057  *********************************************************************************
1058  */
1059
1060 int wiringPiSetup (void)
1061 {
1062   int      fd ;
1063   int      boardRev ;
1064   uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
1065   struct timeval tv ;
1066
1067   if (getenv ("WIRINGPI_DEBUG") != NULL)
1068     wiringPiDebug = TRUE ;
1069
1070   if (wiringPiDebug)
1071     printf ("wiringPi: wiringPiSetup called\n") ;
1072
1073             pinMode =           pinModeWPi ;
1074     pullUpDnControl =   pullUpDnControlWPi ;
1075        digitalWrite =      digitalWriteWPi ;
1076    digitalWriteByte = digitalWriteByteGpio ;    // Same code
1077            pwmWrite =          pwmWriteWPi ;
1078         setPadDrive =       setPadDriveWPi ;
1079         digitalRead =       digitalReadWPi ;
1080    waitForInterrupt =  waitForInterruptWPi ;
1081   delayMicroseconds = delayMicrosecondsWPi ;
1082          pwmSetMode =        pwmSetModeWPi ;
1083         pwmSetRange =       pwmSetRangeWPi ;
1084         pwmSetClock =       pwmSetClockWPi ;
1085   
1086   if ((boardRev = piBoardRev ()) < 0)
1087     return -1 ;
1088
1089   if (boardRev == 1)
1090     pinToGpio = pinToGpioR1 ;
1091   else
1092     pinToGpio = pinToGpioR2 ;
1093
1094 // Open the master /dev/memory device
1095
1096   if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
1097   {
1098     fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
1099     return -1 ;
1100   }
1101
1102 // GPIO:
1103
1104 // Allocate 2 pages - 1 ...
1105
1106   if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1107   {
1108     fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
1109     return -1 ;
1110   }
1111
1112 // ... presumably to make sure we can round it up to a whole page size
1113
1114   if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
1115     gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
1116
1117   gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
1118
1119   if ((int32_t)gpio < 0)
1120   {
1121     fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
1122     return -1 ;
1123   }
1124
1125 // PWM
1126
1127   if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1128   {
1129     fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
1130     return -1 ;
1131   }
1132
1133   if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
1134     pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;
1135
1136   pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;
1137
1138   if ((int32_t)pwm < 0)
1139   {
1140     fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
1141     return -1 ;
1142   }
1143  
1144 // Clock control (needed for PWM)
1145
1146   if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1147   {
1148     fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
1149     return -1 ;
1150   }
1151
1152   if (((uint32_t)clkMem % PAGE_SIZE) != 0)
1153     clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;
1154
1155   clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;
1156
1157   if ((int32_t)clk < 0)
1158   {
1159     fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
1160     return -1 ;
1161   }
1162  
1163 // The drive pads
1164
1165   if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1166   {
1167     fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
1168     return -1 ;
1169   }
1170
1171   if (((uint32_t)padsMem % PAGE_SIZE) != 0)
1172     padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;
1173
1174   pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;
1175
1176   if ((int32_t)pads < 0)
1177   {
1178     fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
1179     return -1 ;
1180   }
1181
1182 #ifdef  DEBUG_PADS
1183   printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
1184   printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
1185 #endif
1186
1187 // The system timer
1188
1189   if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1190   {
1191     fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ;
1192     return -1 ;
1193   }
1194
1195   if (((uint32_t)timerMem % PAGE_SIZE) != 0)
1196     timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ;
1197
1198   timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ;
1199
1200   if ((int32_t)timer < 0)
1201   {
1202     fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
1203     return -1 ;
1204   }
1205
1206 // Set the timer to free-running, 1MHz.
1207 //      0xF9 is 249, the timer divide is base clock / (divide+1)
1208 //      so base clock is 250MHz / 250 = 1MHz.
1209
1210   *(timer + TIMER_CONTROL) = 0x0000280 ;
1211   *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
1212   timerIrqRaw = timer + TIMER_IRQ_RAW ;
1213
1214 // Initialise our epoch for millis()
1215
1216   gettimeofday (&tv, NULL) ;
1217   epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
1218
1219   return 0 ;
1220 }
1221
1222
1223 /*
1224  * wiringPiSetupGpio:
1225  *      Must be called once at the start of your program execution.
1226  *
1227  * GPIO setup: Initialises the system into GPIO Pin mode and uses the
1228  *      memory mapped hardware directly.
1229  *********************************************************************************
1230  */
1231
1232 int wiringPiSetupGpio (void)
1233 {
1234   int x  ;
1235
1236   if (wiringPiDebug)
1237     printf ("wiringPi: wiringPiSetupGpio called\n") ;
1238
1239   if ((x = wiringPiSetup ()) < 0)
1240     return x ;
1241
1242             pinMode =           pinModeGpio ;
1243     pullUpDnControl =   pullUpDnControlGpio ;
1244        digitalWrite =      digitalWriteGpio ;
1245    digitalWriteByte =  digitalWriteByteGpio ;
1246            pwmWrite =          pwmWriteGpio ;
1247         setPadDrive =       setPadDriveGpio ;
1248         digitalRead =       digitalReadGpio ;
1249    waitForInterrupt =  waitForInterruptGpio ;
1250   delayMicroseconds = delayMicrosecondsWPi ;    // Same
1251          pwmSetMode =        pwmSetModeWPi ;
1252         pwmSetRange =       pwmSetRangeWPi ;
1253         pwmSetClock =       pwmSetClockWPi ;
1254
1255   return 0 ;
1256 }
1257
1258
1259 /*
1260  * wiringPiSetupSys:
1261  *      Must be called once at the start of your program execution.
1262  *
1263  * Initialisation (again), however this time we are using the /sys/class/gpio
1264  *      interface to the GPIO systems - slightly slower, but always usable as
1265  *      a non-root user, assuming the devices are already exported and setup correctly.
1266  */
1267
1268 int wiringPiSetupSys (void)
1269 {
1270   int boardRev ;
1271   int pin ;
1272   struct timeval tv ;
1273   char fName [128] ;
1274
1275   if (wiringPiDebug)
1276     printf ("wiringPi: wiringPiSetupSys called\n") ;
1277
1278             pinMode =           pinModeSys ;
1279     pullUpDnControl =   pullUpDnControlSys ;
1280        digitalWrite =      digitalWriteSys ;
1281    digitalWriteByte =  digitalWriteByteSys ;
1282            pwmWrite =          pwmWriteSys ;
1283         setPadDrive =       setPadDriveSys ;
1284         digitalRead =       digitalReadSys ;
1285    waitForInterrupt =  waitForInterruptSys ;
1286   delayMicroseconds = delayMicrosecondsSys ;
1287          pwmSetMode =        pwmSetModeSys ;
1288         pwmSetRange =       pwmSetRangeSys ;
1289         pwmSetClock =       pwmSetClockSys ;
1290
1291   if ((boardRev = piBoardRev ()) < 0)
1292     return -1 ;
1293
1294   if (boardRev == 1)
1295     pinToGpio = pinToGpioR1 ;
1296   else
1297     pinToGpio = pinToGpioR2 ;
1298
1299
1300 // Open and scan the directory, looking for exported GPIOs, and pre-open
1301 //      the 'value' interface to speed things up for later
1302   
1303   for (pin = 0 ; pin < 64 ; ++pin)
1304   {
1305     sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
1306     sysFds [pin] = open (fName, O_RDWR) ;
1307   }
1308
1309 // Initialise the epoch for mills() ...
1310
1311   gettimeofday (&tv, NULL) ;
1312   epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
1313
1314   return 0 ;
1315 }