Gordons Projects

--> Projects Top-Level GIT

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