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