Gordons Projects

--> Projects Top-Level GIT

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