Gordons Projects

--> Projects Top-Level GIT

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