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 ;
174 static volatile uint32_t *timerIrqRaw ;
176 // Raspberry Pi board revision
178 static int boardRevision = -1 ;
182 static int wiringPiDebug = FALSE ;
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
188 // Each control register has 10 sets of 3 bits per GPIO pin:
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
199 // So the 3 bits for port X are:
200 // X / 10 + ((X % 10) * 3)
203 // Map a file descriptor from the /sys/class/gpio/gpioX/value
205 static int sysFds [64] ;
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!
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
215 static int *pinToGpio ;
217 static int pinToGpioR1 [64] =
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
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
232 static int pinToGpioR2 [64] =
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
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
249 // Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
251 static uint8_t gpioToGPFSEL [] =
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,
262 // Define the shift up for the 3 bits per pin in each GPFSEL port
264 static uint8_t gpioToShift [] =
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,
274 // (Word) offset to the GPIO Set registers for each GPIO pin
276 static uint8_t gpioToGPSET [] =
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,
283 // (Word) offset to the GPIO Clear registers for each GPIO pin
285 static uint8_t gpioToGPCLR [] =
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,
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,
302 // (Word) offset to the Event Detect Status
304 static uint8_t gpioToEDS [] =
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,
311 // (Word) offset to the Rising edgde ENable register
313 static uint8_t gpioToREN [] =
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,
320 // (Word) offset to the Falling edgde ENable register
322 static uint8_t gpioToFEN [] =
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,
330 // (Word) offset to the Pull Up Down Clock regsiter
334 static uint8_t gpioToPUDCLK [] =
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,
341 // the ALT value to put a GPIO pin into PWM mode
343 static uint8_t gpioToPwmALT [] =
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
355 static uint8_t gpioToPwmPort [] =
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
369 // Time for easy calculations
371 static unsigned long long epoch ;
373 //////////////////////////////////////////////////////////////////////////////////
378 * Sets the mode of a pin to be input, output or PWM output
379 *********************************************************************************
382 void pinModeGpio (int pin, int mode)
384 int fSel, shift, alt ;
388 fSel = gpioToGPFSEL [pin] ;
389 shift = gpioToShift [pin] ;
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)
397 if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
400 // Set pin to PWM mode
402 *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
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.
407 *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
408 *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
409 delayMicroseconds (110) ; // See comments in pwmSetClockWPi
411 (void)*(pwm + PWM_CONTROL) ;
412 while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
413 delayMicroseconds (1) ;
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
418 // Default range regsiter of 1024
420 *(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ;
421 *(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ;
423 // Enable PWMs in balanced mode (default)
425 *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
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
436 // pullUpDnControl (pin, PUD_OFF) ;
440 void pinModeWPi (int pin, int mode)
442 pinModeGpio (pinToGpio [pin & 63], mode) ;
445 void pinModeSys (int pin, int mode)
453 * Allow the user to control some of the PWM functions
454 *********************************************************************************
457 void pwmSetModeWPi (int mode)
459 if (mode == PWM_MODE_MS)
460 *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
462 *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
465 void pwmSetModeSys (int mode)
471 void pwmSetRangeWPi (unsigned int range)
473 *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
474 *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
477 void pwmSetRangeSys (unsigned int range)
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 *********************************************************************************
490 void pwmSetClockWPi (int divisor)
492 unsigned int pwm_control ;
496 printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
498 pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
500 // We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
503 *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
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.
511 *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
512 delayMicroseconds (110) ; // prevents clock going sloooow
514 while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
515 delayMicroseconds (1) ;
517 *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
519 *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
520 *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
523 printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
526 void pwmSetClockSys (int divisor)
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 *********************************************************************************
543 void pinEnableED01Pi (int pin)
545 pin = pinToGpio [pin & 63] ;
554 *********************************************************************************
557 void digitalWriteWPi (int pin, int value)
559 pin = pinToGpio [pin & 63] ;
562 *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
564 *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
567 void digitalWriteGpio (int pin, int value)
572 *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
574 *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
577 void digitalWriteSys (int pin, int value)
581 if (sysFds [pin] != -1)
584 write (sysFds [pin], "0\n", 2) ;
586 write (sysFds [pin], "1\n", 2) ;
593 * Set an output PWM value
594 *********************************************************************************
597 void pwmWriteGpio (int pin, int value)
602 port = gpioToPwmPort [pin] ;
604 *(pwm + port) = value ;
607 void pwmWriteWPi (int pin, int value)
609 pwmWriteGpio (pinToGpio [pin & 63], value) ;
612 void pwmWriteSys (int pin, int value)
620 * Set the PAD driver value
621 *********************************************************************************
624 void setPadDriveWPi (int group, int value)
628 if ((group < 0) || (group > 2))
631 wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
632 *(pads + group + 11) = wrVal ;
635 printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
636 printf ("Read : %08X\n", *(pads + group + 11)) ;
640 void setPadDriveGpio (int group, int value)
642 setPadDriveWPi (group, value) ;
645 void setPadDriveSys (int group, int value)
653 * Read the value of a given Pin, returning HIGH or LOW
654 *********************************************************************************
657 int digitalReadWPi (int pin)
659 pin = pinToGpio [pin & 63] ;
661 if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
667 int digitalReadGpio (int pin)
671 if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
677 int digitalReadSys (int pin)
683 if (sysFds [pin] == -1)
686 lseek (sysFds [pin], 0L, SEEK_SET) ;
687 read (sysFds [pin], &c, 1) ;
688 return (c == '0') ? 0 : 1 ;
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
698 *********************************************************************************
701 void pullUpDnControlGpio (int pin, int pud)
706 *(gpio + GPPUD) = pud ; delayMicroseconds (5) ;
707 *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
709 *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
710 *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
713 void pullUpDnControlWPi (int pin, int pud)
715 pullUpDnControlGpio (pinToGpio [pin & 63], pud) ;
718 void pullUpDnControlSys (int pin, int pud)
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 *********************************************************************************
733 int waitForInterruptSys (int pin, int mS)
737 struct pollfd polls ;
739 if ((fd = sysFds [pin & 63]) == -1)
744 x = read (fd, buf, 6) ;
750 lseek (fd, 0, SEEK_SET) ;
752 // Setup poll structure
755 polls.events = POLLPRI ; // Urgent data!
759 return poll (&polls, 1, mS) ;
762 int waitForInterruptWPi (int pin, int mS)
764 return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
767 int waitForInterruptGpio (int pin, int mS)
769 return waitForInterruptSys (pin, mS) ;
777 * Wait for some number of milli seconds
778 *********************************************************************************
781 void delay (unsigned int howLong)
783 struct timespec sleeper, dummy ;
785 sleeper.tv_sec = (time_t)(howLong / 1000) ;
786 sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
788 nanosleep (&sleeper, &dummy) ;
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
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 *********************************************************************************
807 void delayMicrosecondsSys (unsigned int howLong)
809 struct timespec sleeper, dummy ;
812 sleeper.tv_nsec = (long)(howLong * 1000) ;
814 nanosleep (&sleeper, &dummy) ;
817 void delayMicrosecondsHard (unsigned int howLong)
819 *(timer + TIMER_LOAD) = howLong ;
820 *(timer + TIMER_IRQ_CLR) = 0 ;
822 while (*timerIrqRaw == 0)
826 void delayMicrosecondsWPi (unsigned int howLong)
828 struct timespec sleeper, dummy ;
830 /**/ if (howLong == 0)
832 else if (howLong < 100)
833 delayMicrosecondsHard (howLong) ;
837 sleeper.tv_nsec = (long)(howLong * 1000) ;
838 nanosleep (&sleeper, &dummy) ;
845 * Return a number of milliseconds as an unsigned int.
846 *********************************************************************************
849 unsigned int millis (void)
852 unsigned long long t1 ;
854 gettimeofday (&tv, NULL) ;
856 t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
858 return (uint32_t)(t1 - epoch) ;
864 * Must be called once at the start of your program execution.
866 * Default setup: Initialises the system into wiringPi Pin mode and uses the
867 * memory mapped hardware directly.
868 *********************************************************************************
871 int wiringPiSetup (void)
878 uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
881 if (getenv ("WIRINGPI_DEBUG") != NULL)
882 wiringPiDebug = TRUE ;
885 printf ("wiringPi: wiringPiSetup called\n") ;
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 ;
899 // Find board revision
901 if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
903 fprintf (stderr, "wiringPiSetup: Unable to open /proc/cpuinfo: %s\n", strerror (errno)) ;
907 while (fgets (line, 80, cpuFd) != NULL)
908 if (strncmp (line, "Revision", 8) == 0)
909 for (c = line ; *c ; ++c)
913 revision = atoi (c) ;
920 fprintf (stderr, "wiringPiSetup: Unable to determine board revision\n") ;
925 // If you have overvolted the Pi, then it appears that the revision
926 // has 100000 added to it!
930 printf ("wiringPi: This Pi has/is overvolted!\n") ;
934 /**/ if ((revision == 2) || (revision == 3))
936 else if ((revision == 4) || (revision == 5) || (revision == 6))
940 fprintf (stderr, "wiringPiSetup: Unable to determine board revision: %d\n", revision) ;
946 if (boardRevision == 1)
947 pinToGpio = pinToGpioR1 ;
949 pinToGpio = pinToGpioR2 ;
952 printf ("wiringPi: Revision: %d, board revision: %d\n", revision, boardRevision) ;
954 // Open the master /dev/memory device
956 if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
958 fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
964 // Allocate 2 pages - 1 ...
966 if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
968 fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
972 // ... presumably to make sure we can round it up to a whole page size
974 if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
975 gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
977 gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
979 if ((int32_t)gpio < 0)
981 fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
987 if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
989 fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
993 if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
994 pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;
996 pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;
998 if ((int32_t)pwm < 0)
1000 fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
1004 // Clock control (needed for PWM)
1006 if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1008 fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
1012 if (((uint32_t)clkMem % PAGE_SIZE) != 0)
1013 clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;
1015 clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;
1017 if ((int32_t)clk < 0)
1019 fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
1025 if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1027 fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
1031 if (((uint32_t)padsMem % PAGE_SIZE) != 0)
1032 padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;
1034 pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;
1036 if ((int32_t)pads < 0)
1038 fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
1043 printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
1044 printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
1049 if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
1051 fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ;
1055 if (((uint32_t)timerMem % PAGE_SIZE) != 0)
1056 timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ;
1058 timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ;
1060 if ((int32_t)timer < 0)
1062 fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
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.
1070 *(timer + TIMER_CONTROL) = 0x0000280 ;
1071 *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
1072 timerIrqRaw = timer + TIMER_IRQ_RAW ;
1074 // Initialise our epoch for millis()
1076 gettimeofday (&tv, NULL) ;
1077 epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
1084 * wiringPiSetupGpio:
1085 * Must be called once at the start of your program execution.
1087 * GPIO setup: Initialises the system into GPIO Pin mode and uses the
1088 * memory mapped hardware directly.
1089 *********************************************************************************
1092 int wiringPiSetupGpio (void)
1097 printf ("wiringPi: wiringPiSetupGpio called\n") ;
1099 if ((x = wiringPiSetup ()) < 0)
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 ;
1120 * Must be called once at the start of your program execution.
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.
1127 int wiringPiSetupSys (void)
1134 printf ("wiringPi: wiringPiSetupSys called\n") ;
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 ;
1149 // Open and scan the directory, looking for exported GPIOs, and pre-open
1150 // the 'value' interface to speed things up for later
1152 for (pin = 0 ; pin < 64 ; ++pin)
1154 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
1155 sysFds [pin] = open (fName, O_RDWR) ;
1158 // Initialise the epoch for mills() ...
1160 gettimeofday (&tv, NULL) ;
1161 epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;