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>
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/
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.
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.
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 ***********************************************************************
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
36 // Added waitForInterrupt code
40 // Added in support to use the /sys/class/gpio interface.
42 // Fixed a few more bugs to do with range-checking when in GPIO mode.
45 // Added c++ support for the .h file
46 // Added a new function to allow for using my "pin" numbers, or native
48 // Removed my busy-loop delay and replaced it with a call to delayMicroseconds
51 // Added in the 2 UART pins
52 // Change maxPins to numPins to more accurately reflect purpose
54 // Pad drive current fiddling
70 #include <sys/types.h>
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) ;
97 #define BCM_PASSWORD 0x5A000000
100 // Port function select bits
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
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 )-:
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)
123 #define PAGE_SIZE (4*1024)
124 #define BLOCK_SIZE (4*1024)
128 #define PWM_CONTROL 0
135 #define PWMCLK_CNTL 40
136 #define PWMCLK_DIV 41
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
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
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)
166 // Locals to hold pointers to the hardware
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 ;
177 static int wiringPiDebug = FALSE ;
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
183 // Each control register has 10 sets of 3 bits per GPIO pin:
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
194 // So the 3 bits for port X are:
195 // X / 10 + ((X % 10) * 3)
198 // Map a file descriptor from the /sys/class/gpio/gpioX/value
200 static int sysFds [64] ;
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!
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
210 static int *pinToGpio ;
212 static int pinToGpioR1 [64] =
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
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
227 static int pinToGpioR2 [64] =
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
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
245 // Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
247 static uint8_t gpioToGPFSEL [] =
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,
259 // Define the shift up for the 3 bits per pin in each GPFSEL port
261 static uint8_t gpioToShift [] =
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,
272 // (Word) offset to the GPIO Set registers for each GPIO pin
274 static uint8_t gpioToGPSET [] =
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,
282 // (Word) offset to the GPIO Clear registers for each GPIO pin
284 static uint8_t gpioToGPCLR [] =
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,
292 // (Word) offset to the GPIO Input level registers for each GPIO pin
294 static uint8_t gpioToGPLEV [] =
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,
303 // (Word) offset to the Event Detect Status
305 static uint8_t gpioToEDS [] =
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,
312 // (Word) offset to the Rising edgde ENable register
314 static uint8_t gpioToREN [] =
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,
321 // (Word) offset to the Falling edgde ENable register
323 static uint8_t gpioToFEN [] =
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,
332 // (Word) offset to the Pull Up Down Clock regsiter
336 static uint8_t gpioToPUDCLK [] =
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,
344 // the ALT value to put a GPIO pin into PWM mode
346 static uint8_t gpioToPwmALT [] =
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
358 static uint8_t gpioToPwmPort [] =
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
372 // Time for easy calculations
374 static unsigned long long epoch ;
378 *********************************************************************************
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 *********************************************************************************
390 int wpiPinToGpio (int wpiPin)
392 return pinToGpio [wpiPin & 63] ;
398 * Return a number representing the hardware revision of the board.
399 * Revision is currently 1 or 2. -1 is returned on error.
401 * Much confusion here )-:
402 * Seems there ar esome boards with 0000 in them (mistake in manufacture)
403 * and some board with 0005 in them (another mistake in manufacture).
404 * So the distinction between boards that I can see is:
412 * 000f - Rev 2 + 512MB
414 * A small thorn is the olde style overvolting - that will add in
417 *********************************************************************************
420 int piBoardRev (void)
425 static int boardRev = -1 ;
427 // No point checking twice...
432 if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
435 while (fgets (line, 120, cpuFd) != NULL)
436 if (strncmp (line, "Revision", 8) == 0)
443 fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
444 fprintf (stderr, " (No \"Revision\" line)\n") ;
449 for (c = line ; *c ; ++c)
455 fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
456 fprintf (stderr, " (No numeric revision string in: \"%s\"\n", line) ;
461 // If you have overvolted the Pi, then it appears that the revision
462 // has 100000 added to it!
466 printf ("piboardRev: This Pi has/is overvolted!\n") ;
468 lastChar = c [strlen (c) - 2] ;
470 /**/ if ((lastChar == '2') || (lastChar == '3'))
475 #ifdef DO_WE_CARE_ABOUT_THIS_NOW
478 fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ;
479 fprintf (stderr, " -> You may want to check:\n") ;
480 fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
481 fprintf (stderr, " -> Assuming a Rev 1 board\n") ;
487 printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ;
496 * Sets the mode of a pin to be input, output or PWM output
497 *********************************************************************************
500 void pinModeGpio (int pin, int mode)
502 int fSel, shift, alt ;
506 fSel = gpioToGPFSEL [pin] ;
507 shift = gpioToShift [pin] ;
509 /**/ if (mode == INPUT)
510 *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
511 else if (mode == OUTPUT)
512 *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
513 else if (mode == PWM_OUTPUT)
515 if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
518 // Set pin to PWM mode
520 *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
522 // Page 107 of the BCM Peripherals manual talks about the GPIO clocks,
523 // but I'm assuming (hoping!) that this applies to other clocks too.
525 *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
526 *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
527 delayMicroseconds (110) ; // See comments in pwmSetClockWPi
529 (void)*(pwm + PWM_CONTROL) ;
530 while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
531 delayMicroseconds (1) ;
533 *(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz)
534 *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk
536 // Default range regsiter of 1024
538 *(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ;
539 *(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ;
541 // Enable PWMs in balanced mode (default)
543 *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
546 // When we change mode of any pin, we remove the pull up/downs
547 // Or we used to... Hm. Commented out now because for some wieird reason,
548 // it seems to block subsequent attempts to set the pull up/downs and I've
549 // not quite gotten to the bottom of why this happens
550 // The down-side is that the pull up/downs are rememberd in the SoC between
551 // power cycles, so it's going to be a good idea to explicitly set them in
554 // pullUpDnControl (pin, PUD_OFF) ;
558 void pinModeWPi (int pin, int mode)
560 pinModeGpio (pinToGpio [pin & 63], mode) ;
563 void pinModeSys (int pin, int mode)
571 * Allow the user to control some of the PWM functions
572 *********************************************************************************
575 void pwmSetModeWPi (int mode)
577 if (mode == PWM_MODE_MS)
578 *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
580 *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
583 void pwmSetModeSys (int mode)
589 void pwmSetRangeWPi (unsigned int range)
591 *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
592 *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
595 void pwmSetRangeSys (unsigned int range)
602 * Set/Change the PWM clock. Originally my code, but changed
603 * (for the better!) by Chris Hall, <chris@kchall.plus.com>
604 * after further study of the manual and testing with a 'scope
605 *********************************************************************************
608 void pwmSetClockWPi (int divisor)
610 unsigned int pwm_control ;
614 printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
616 pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
618 // We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
621 *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
623 // Stop PWM clock before changing divisor. The delay after this does need to
624 // this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY
625 // flag is not working properly in balanced mode. Without the delay when DIV is
626 // adjusted the clock sometimes switches to very slow, once slow further DIV
627 // adjustments do nothing and it's difficult to get out of this mode.
629 *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
630 delayMicroseconds (110) ; // prevents clock going sloooow
632 while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
633 delayMicroseconds (1) ;
635 *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
637 *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
638 *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
641 printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
644 void pwmSetClockSys (int divisor)
654 * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
655 * Pin must already be in input mode with appropriate pull up/downs set.
656 *********************************************************************************
659 void pinEnableED01Pi (int pin)
661 pin = pinToGpio [pin & 63] ;
670 *********************************************************************************
673 void digitalWriteWPi (int pin, int value)
675 pin = pinToGpio [pin & 63] ;
678 *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
680 *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
683 void digitalWriteGpio (int pin, int value)
688 *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
690 *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
693 void digitalWriteSys (int pin, int value)
697 if (sysFds [pin] != -1)
700 write (sysFds [pin], "0\n", 2) ;
702 write (sysFds [pin], "1\n", 2) ;
709 * Set an output PWM value
710 *********************************************************************************
713 void pwmWriteGpio (int pin, int value)
718 port = gpioToPwmPort [pin] ;
720 *(pwm + port) = value ;
723 void pwmWriteWPi (int pin, int value)
725 pwmWriteGpio (pinToGpio [pin & 63], value) ;
728 void pwmWriteSys (int pin, int value)
736 * Set the PAD driver value
737 *********************************************************************************
740 void setPadDriveWPi (int group, int value)
744 if ((group < 0) || (group > 2))
747 wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
748 *(pads + group + 11) = wrVal ;
751 printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
752 printf ("Read : %08X\n", *(pads + group + 11)) ;
756 void setPadDriveGpio (int group, int value)
758 setPadDriveWPi (group, value) ;
761 void setPadDriveSys (int group, int value)
769 * Read the value of a given Pin, returning HIGH or LOW
770 *********************************************************************************
773 int digitalReadWPi (int pin)
775 pin = pinToGpio [pin & 63] ;
777 if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
783 int digitalReadGpio (int pin)
787 if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
793 int digitalReadSys (int pin)
799 if (sysFds [pin] == -1)
802 lseek (sysFds [pin], 0L, SEEK_SET) ;
803 read (sysFds [pin], &c, 1) ;
804 return (c == '0') ? 0 : 1 ;
810 * Control the internal pull-up/down resistors on a GPIO pin
811 * The Arduino only has pull-ups and these are enabled by writing 1
812 * to a port when in input mode - this paradigm doesn't quite apply
814 *********************************************************************************
817 void pullUpDnControlGpio (int pin, int pud)
822 *(gpio + GPPUD) = pud ; delayMicroseconds (5) ;
823 *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
825 *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
826 *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
829 void pullUpDnControlWPi (int pin, int pud)
831 pullUpDnControlGpio (pinToGpio [pin & 63], pud) ;
834 void pullUpDnControlSys (int pin, int pud)
842 * Wait for Interrupt on a GPIO pin.
843 * This is actually done via the /sys/class/gpio interface regardless of
844 * the wiringPi access mode in-use. Maybe sometime it might get a better
845 * way for a bit more efficiency.
846 *********************************************************************************
849 int waitForInterruptSys (int pin, int mS)
853 struct pollfd polls ;
855 if ((fd = sysFds [pin & 63]) == -1)
860 x = read (fd, buf, 6) ;
866 lseek (fd, 0, SEEK_SET) ;
868 // Setup poll structure
871 polls.events = POLLPRI ; // Urgent data!
875 return poll (&polls, 1, mS) ;
878 int waitForInterruptWPi (int pin, int mS)
880 return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
883 int waitForInterruptGpio (int pin, int mS)
885 return waitForInterruptSys (pin, mS) ;
891 * Wait for some number of milli seconds
892 *********************************************************************************
895 void delay (unsigned int howLong)
897 struct timespec sleeper, dummy ;
899 sleeper.tv_sec = (time_t)(howLong / 1000) ;
900 sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
902 nanosleep (&sleeper, &dummy) ;
908 * This is somewhat intersting. It seems that on the Pi, a single call
909 * to nanosleep takes some 80 to 130 microseconds anyway, so while
910 * obeying the standards (may take longer), it's not always what we
913 * So what I'll do now is if the delay is less than 100uS we'll do it
914 * in a hard loop, watching a built-in counter on the ARM chip. This is
915 * somewhat sub-optimal in that it uses 100% CPU, something not an issue
916 * in a microcontroller, but under a multi-tasking, multi-user OS, it's
917 * wastefull, however we've no real choice )-:
918 *********************************************************************************
921 void delayMicrosecondsSys (unsigned int howLong)
923 struct timespec sleeper, dummy ;
926 sleeper.tv_nsec = (long)(howLong * 1000) ;
928 nanosleep (&sleeper, &dummy) ;
931 void delayMicrosecondsHard (unsigned int howLong)
933 *(timer + TIMER_LOAD) = howLong ;
934 *(timer + TIMER_IRQ_CLR) = 0 ;
936 while (*timerIrqRaw == 0)
940 void delayMicrosecondsWPi (unsigned int howLong)
942 struct timespec sleeper, dummy ;
944 /**/ if (howLong == 0)
946 else if (howLong < 100)
947 delayMicrosecondsHard (howLong) ;
951 sleeper.tv_nsec = (long)(howLong * 1000) ;
952 nanosleep (&sleeper, &dummy) ;
959 * Return a number of milliseconds as an unsigned int.
960 *********************************************************************************
963 unsigned int millis (void)
966 unsigned long long t1 ;
968 gettimeofday (&tv, NULL) ;
970 t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
972 return (uint32_t)(t1 - epoch) ;
978 * Must be called once at the start of your program execution.
980 * Default setup: Initialises the system into wiringPi Pin mode and uses the
981 * memory mapped hardware directly.
982 *********************************************************************************
985 int wiringPiSetup (void)
989 uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
992 if (getenv ("WIRINGPI_DEBUG") != NULL)
993 wiringPiDebug = TRUE ;
996 printf ("wiringPi: wiringPiSetup called\n") ;
998 pinMode = pinModeWPi ;
999 pullUpDnControl = pullUpDnControlWPi ;
1000 digitalWrite = digitalWriteWPi ;
1001 pwmWrite = pwmWriteWPi ;
1002 setPadDrive = setPadDriveWPi ;
1003 digitalRead = digitalReadWPi ;
1004 waitForInterrupt = waitForInterruptWPi ;
1005 delayMicroseconds = delayMicrosecondsWPi ;
1006 pwmSetMode = pwmSetModeWPi ;
1007 pwmSetRange = pwmSetRangeWPi ;
1008 pwmSetClock = pwmSetClockWPi ;
1010 if ((boardRev = piBoardRev ()) < 0)
1014 pinToGpio = pinToGpioR1 ;
1016 pinToGpio = pinToGpioR2 ;
1018 // Open the master /dev/memory device
1020 if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
1022 fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
1028 // Allocate 2 pages - 1 ...
1030 if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1032 fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
1036 // ... presumably to make sure we can round it up to a whole page size
1038 if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
1039 gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
1041 gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
1043 if ((int32_t)gpio < 0)
1045 fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
1051 if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1053 fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
1057 if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
1058 pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;
1060 pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;
1062 if ((int32_t)pwm < 0)
1064 fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
1068 // Clock control (needed for PWM)
1070 if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1072 fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
1076 if (((uint32_t)clkMem % PAGE_SIZE) != 0)
1077 clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;
1079 clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;
1081 if ((int32_t)clk < 0)
1083 fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
1089 if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1091 fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
1095 if (((uint32_t)padsMem % PAGE_SIZE) != 0)
1096 padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;
1098 pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;
1100 if ((int32_t)pads < 0)
1102 fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
1107 printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
1108 printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
1113 if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1115 fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ;
1119 if (((uint32_t)timerMem % PAGE_SIZE) != 0)
1120 timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ;
1122 timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ;
1124 if ((int32_t)timer < 0)
1126 fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
1130 // Set the timer to free-running, 1MHz.
1131 // 0xF9 is 249, the timer divide is base clock / (divide+1)
1132 // so base clock is 250MHz / 250 = 1MHz.
1134 *(timer + TIMER_CONTROL) = 0x0000280 ;
1135 *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
1136 timerIrqRaw = timer + TIMER_IRQ_RAW ;
1138 // Initialise our epoch for millis()
1140 gettimeofday (&tv, NULL) ;
1141 epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
1148 * wiringPiSetupGpio:
1149 * Must be called once at the start of your program execution.
1151 * GPIO setup: Initialises the system into GPIO Pin mode and uses the
1152 * memory mapped hardware directly.
1153 *********************************************************************************
1156 int wiringPiSetupGpio (void)
1161 printf ("wiringPi: wiringPiSetupGpio called\n") ;
1163 if ((x = wiringPiSetup ()) < 0)
1166 pinMode = pinModeGpio ;
1167 pullUpDnControl = pullUpDnControlGpio ;
1168 digitalWrite = digitalWriteGpio ;
1169 pwmWrite = pwmWriteGpio ;
1170 setPadDrive = setPadDriveGpio ;
1171 digitalRead = digitalReadGpio ;
1172 waitForInterrupt = waitForInterruptGpio ;
1173 delayMicroseconds = delayMicrosecondsWPi ; // Same
1174 pwmSetMode = pwmSetModeWPi ;
1175 pwmSetRange = pwmSetRangeWPi ;
1176 pwmSetClock = pwmSetClockWPi ;
1184 * Must be called once at the start of your program execution.
1186 * Initialisation (again), however this time we are using the /sys/class/gpio
1187 * interface to the GPIO systems - slightly slower, but always usable as
1188 * a non-root user, assuming the devices are already exported and setup correctly.
1191 int wiringPiSetupSys (void)
1198 printf ("wiringPi: wiringPiSetupSys called\n") ;
1200 pinMode = pinModeSys ;
1201 pullUpDnControl = pullUpDnControlSys ;
1202 digitalWrite = digitalWriteSys ;
1203 pwmWrite = pwmWriteSys ;
1204 setPadDrive = setPadDriveSys ;
1205 digitalRead = digitalReadSys ;
1206 waitForInterrupt = waitForInterruptSys ;
1207 delayMicroseconds = delayMicrosecondsSys ;
1208 pwmSetMode = pwmSetModeSys ;
1209 pwmSetRange = pwmSetRangeSys ;
1210 pwmSetClock = pwmSetClockSys ;
1213 // Open and scan the directory, looking for exported GPIOs, and pre-open
1214 // the 'value' interface to speed things up for later
1216 for (pin = 0 ; pin < 64 ; ++pin)
1218 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
1219 sysFds [pin] = open (fName, O_RDWR) ;
1222 // Initialise the epoch for mills() ...
1224 gettimeofday (&tv, NULL) ;
1225 epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;