Gordons Projects

--> Projects Top-Level GIT

Initial move to GIT
[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
405   pullUpDnControl (pin, PUD_OFF) ;
406 }
407
408 void pinModeWPi (int pin, int mode)
409 {
410   pinModeGpio (pinToGpio [pin & 63], mode) ;
411 }
412
413 void pinModeSys (int pin, int mode)
414 {
415   return ;
416 }
417
418
419 #ifdef notYetReady
420 /*
421  * pinED01:
422  * pinED10:
423  *      Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
424  *      Pin must already be in input mode with appropriate pull up/downs set.
425  *********************************************************************************
426  */
427
428 void pinEnableED01Pi (int pin)
429 {
430   pin = pinToGpio [pin & 63] ;
431 }
432 #endif
433
434
435
436 /*
437  * digitalWrite:
438  *      Set an output bit
439  *********************************************************************************
440  */
441
442 void digitalWriteWPi (int pin, int value)
443 {
444   pin = pinToGpio [pin & 63] ;
445
446   if (value == LOW)
447     *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
448   else
449     *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
450 }
451
452 void digitalWriteGpio (int pin, int value)
453 {
454   pin &= 63 ;
455
456   if (value == LOW)
457     *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
458   else
459     *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
460 }
461
462 void digitalWriteSys (int pin, int value)
463 {
464   pin &= 63 ;
465
466   if (sysFds [pin] != -1)
467   {
468     if (value == LOW)
469       write (sysFds [pin], "0\n", 2) ;
470     else
471       write (sysFds [pin], "1\n", 2) ;
472   }
473 }
474
475
476 /*
477  * pwnWrite:
478  *      Set an output PWM value
479  *********************************************************************************
480  */
481
482 void pwmWriteWPi (int pin, int value)
483 {
484   int port ;
485
486   pin  = pinToGpio [pin & 63] ;
487   port = gpioToPwmPort [pin] ;
488
489   *(pwm + port) = value & 0x3FF ;
490 }
491
492 void pwmWriteGpio (int pin, int value)
493 {
494   int port ;
495
496   pin  = pin & 63 ;
497   port = gpioToPwmPort [pin] ;
498
499   *(pwm + port) = value & 0x3FF ;
500 }
501
502 void pwmWriteSys (int pin, int value)
503 {
504   return ;
505 }
506
507
508 /*
509  * setPadDrive:
510  *      Set the PAD driver value
511  *********************************************************************************
512  */
513
514 void setPadDriveWPi (int group, int value)
515 {
516   uint32_t wrVal ;
517
518   if ((group < 0) || (group > 2))
519     return ;
520
521   wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
522   *(pads + group + 11) = wrVal ;
523
524 #ifdef  DEBUG_PADS
525   printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
526   printf ("Read : %08X\n", *(pads + group + 11)) ;
527 #endif
528 }
529
530 void setPadDriveGpio (int group, int value)
531 {
532   setPadDriveWPi (group, value) ;
533 }
534
535 void setPadDriveSys (int group, int value)
536 {
537   return ;
538 }
539
540
541 /*
542  * digitalRead:
543  *      Read the value of a given Pin, returning HIGH or LOW
544  *********************************************************************************
545  */
546
547 int digitalReadWPi (int pin)
548 {
549   pin = pinToGpio [pin & 63] ;
550
551   if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
552     return HIGH ;
553   else
554     return LOW ;
555 }
556
557 int digitalReadGpio (int pin)
558 {
559   pin &= 63 ;
560
561   if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
562     return HIGH ;
563   else
564     return LOW ;
565 }
566
567 int digitalReadSys (int pin)
568 {
569   char c ;
570
571   pin &= 63 ;
572
573   if (sysFds [pin] == -1)
574     return 0 ;
575
576   lseek (sysFds [pin], 0L, SEEK_SET) ;
577   read  (sysFds [pin], &c, 1) ;
578   return (c == '0') ? 0 : 1 ;
579 }
580
581
582 /*
583  * pullUpDownCtrl:
584  *      Control the internal pull-up/down resistors on a GPIO pin
585  *      The Arduino only has pull-ups and these are enabled by writing 1
586  *      to a port when in input mode - this paradigm doesn't quite apply
587  *      here though.
588  *********************************************************************************
589  */
590
591 void pullUpDnControlWPi (int pin, int pud)
592 {
593   pin  = pinToGpio [pin & 63] ;
594   pud &=  3 ;
595
596   *(gpio + GPPUD)              = pud ;                  delayMicroseconds (10) ;
597   *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;      delayMicroseconds (10) ;
598   
599   *(gpio + GPPUD)              = 0 ;
600   *(gpio + gpioToPUDCLK [pin]) = 0 ;
601 }
602
603 void pullUpDnControlGpio (int pin, int pud)
604 {
605   pin &= 63 ;
606   pud &=  3 ;
607
608   *(gpio + GPPUD)              = pud ;                  delayMicroseconds (10) ;
609   *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;      delayMicroseconds (10) ;
610   
611   *(gpio + GPPUD)              = 0 ;
612   *(gpio + gpioToPUDCLK [pin]) = 0 ;
613 }
614
615 void pullUpDnControlSys (int pin, int pud)
616 {
617   return ;
618 }
619
620
621 /*
622  * waitForInterrupt:
623  *      Wait for Interrupt on a GPIO pin.
624  *      This is actually done via the /sys/class/gpio interface regardless of
625  *      the wiringPi access mode in-use. Maybe sometime it might get a better
626  *      way for a bit more efficiency.
627  *********************************************************************************
628  */
629
630 int waitForInterruptSys (int pin, int mS)
631 {
632   int fd, x ;
633   char buf [8] ;
634   struct pollfd polls ;
635
636   if ((fd = sysFds [pin & 63]) == -1)
637     return -2 ;
638
639 // Do a dummy read
640
641   x = read (fd, buf, 6) ;
642   if (x < 0)
643     return x ;
644
645 // And seek
646
647   lseek (fd, 0, SEEK_SET) ;
648
649 // Setup poll structure
650
651   polls.fd     = fd ;
652   polls.events = POLLPRI ;      // Urgent data!
653
654 // Wait for it ...
655
656   return poll (&polls, 1, mS) ;
657 }
658
659 int waitForInterruptWPi (int pin, int mS)
660 {
661   return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
662 }
663
664 int waitForInterruptGpio (int pin, int mS)
665 {
666   return waitForInterruptSys (pin, mS) ;
667 }
668
669
670
671
672 /*
673  * delay:
674  *      Wait for some number of milli seconds
675  *********************************************************************************
676  */
677
678 void delay (unsigned int howLong)
679 {
680   struct timespec sleeper, dummy ;
681
682   sleeper.tv_sec  = (time_t)(howLong / 1000) ;
683   sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
684
685   nanosleep (&sleeper, &dummy) ;
686 }
687
688 /*
689  * delayMicroseconds:
690  *      This is somewhat intersting. It seems that on the Pi, a single call
691  *      to nanosleep takes some 80 to 130 microseconds anyway, so while
692  *      obeying the standards (may take longer), it's not always what we
693  *      want!
694  *
695  *      So what I'll do now is if the delay is less than 100uS we'll do it
696  *      in a hard loop, watching a built-in counter on the ARM chip. This is
697  *      somewhat sub-optimal in that it uses 100% CPU, something not an issue
698  *      in a microcontroller, but under a multi-tasking, multi-user OS, it's
699  *      wastefull, however we've no real choice )-:
700  *********************************************************************************
701  */
702
703 void delayMicrosecondsSys (unsigned int howLong)
704 {
705   struct timespec sleeper, dummy ;
706
707   sleeper.tv_sec  = 0 ;
708   sleeper.tv_nsec = (long)(howLong * 1000) ;
709
710   nanosleep (&sleeper, &dummy) ;
711 }
712
713 void delayMicrosecondsHard (unsigned int howLong)
714 {
715   *(timer + TIMER_LOAD)    = howLong ;
716   *(timer + TIMER_IRQ_CLR) = 0 ;
717
718   while (*timerIrqRaw == 0)
719     ;
720 }
721
722 void delayMicrosecondsWPi (unsigned int howLong)
723 {
724   struct timespec sleeper, dummy ;
725
726   /**/ if (howLong ==   0)
727     return ;
728   else if (howLong  < 100)
729     delayMicrosecondsHard (howLong) ;
730   else
731   {
732     sleeper.tv_sec  = 0 ;
733     sleeper.tv_nsec = (long)(howLong * 1000) ;
734     nanosleep (&sleeper, &dummy) ;
735   }
736 }
737
738
739 /*
740  * millis:
741  *      Return a number of milliseconds as an unsigned int.
742  *********************************************************************************
743  */
744
745 unsigned int millis (void)
746 {
747   struct timeval tv ;
748   unsigned long long t1 ;
749
750   gettimeofday (&tv, NULL) ;
751
752   t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
753
754   return (uint32_t)(t1 - epoch) ;
755 }
756
757
758 /*
759  * wiringPiSetup:
760  *      Must be called once at the start of your program execution.
761  *
762  * Default setup: Initialises the system into wiringPi Pin mode and uses the
763  *      memory mapped hardware directly.
764  *********************************************************************************
765  */
766
767 int wiringPiSetup (void)
768 {
769   int      fd ;
770   uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
771   struct timeval tv ;
772
773             pinMode =           pinModeWPi ;
774     pullUpDnControl =   pullUpDnControlWPi ;
775        digitalWrite =      digitalWriteWPi ;
776            pwmWrite =          pwmWriteWPi ;
777         setPadDrive =       setPadDriveWPi ;
778         digitalRead =       digitalReadWPi ;
779    waitForInterrupt =  waitForInterruptWPi ;
780   delayMicroseconds = delayMicrosecondsWPi ;
781   
782 // Open the master /dev/memory device
783
784   if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
785   {
786     fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
787     return -1 ;
788   }
789
790 // GPIO:
791
792 // Allocate 2 pages - 1 ...
793
794   if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
795   {
796     fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
797     return -1 ;
798   }
799
800 // ... presumably to make sure we can round it up to a whole page size
801
802   if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
803     gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
804
805   gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
806
807   if ((int32_t)gpio < 0)
808   {
809     fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
810     return -1 ;
811   }
812
813 // PWM
814
815   if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
816   {
817     fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
818     return -1 ;
819   }
820
821   if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
822     pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;
823
824   pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;
825
826   if ((int32_t)pwm < 0)
827   {
828     fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
829     return -1 ;
830   }
831  
832 // Clock control (needed for PWM)
833
834   if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
835   {
836     fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
837     return -1 ;
838   }
839
840   if (((uint32_t)clkMem % PAGE_SIZE) != 0)
841     clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;
842
843   clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;
844
845   if ((int32_t)clk < 0)
846   {
847     fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
848     return -1 ;
849   }
850  
851 // The drive pads
852
853   if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
854   {
855     fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
856     return -1 ;
857   }
858
859   if (((uint32_t)padsMem % PAGE_SIZE) != 0)
860     padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;
861
862   pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;
863
864   if ((int32_t)pads < 0)
865   {
866     fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
867     return -1 ;
868   }
869
870 #ifdef  DEBUG_PADS
871   printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
872   printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
873 #endif
874
875 // The system timer
876
877   if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
878   {
879     fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ;
880     return -1 ;
881   }
882
883   if (((uint32_t)timerMem % PAGE_SIZE) != 0)
884     timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ;
885
886   timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ;
887
888   if ((int32_t)timer < 0)
889   {
890     fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
891     return -1 ;
892   }
893
894 // Set the timer to free-running, 1MHz.
895 //      0xF9 is 249, the timer divide is base clock / (divide+1)
896 //      so base clock is 250MHz / 250 = 1MHz.
897
898   *(timer + TIMER_CONTROL) = 0x0000280 ;
899   *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
900   timerIrqRaw = timer + TIMER_IRQ_RAW ;
901
902 // Initialise our epoch for millis()
903
904   gettimeofday (&tv, NULL) ;
905   epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
906
907   return 0 ;
908 }
909
910
911 /*
912  * wiringPiSetupGpio:
913  *      Must be called once at the start of your program execution.
914  *
915  * GPIO setup: Initialises the system into GPIO Pin mode and uses the
916  *      memory mapped hardware directly.
917  *********************************************************************************
918  */
919
920 int wiringPiSetupGpio (void)
921 {
922   int x = wiringPiSetup () ;
923
924   if (x != 0)
925     return x ;
926
927             pinMode =           pinModeGpio ;
928     pullUpDnControl =   pullUpDnControlGpio ;
929        digitalWrite =      digitalWriteGpio ;
930            pwmWrite =          pwmWriteGpio ;
931         setPadDrive =       setPadDriveGpio ;
932         digitalRead =       digitalReadGpio ;
933    waitForInterrupt =  waitForInterruptGpio ;
934   delayMicroseconds = delayMicrosecondsWPi ;    // Same
935
936   return 0 ;
937 }
938
939
940 /*
941  * wiringPiSetupSys:
942  *      Must be called once at the start of your program execution.
943  *
944  * Initialisation (again), however this time we are using the /sys/class/gpio
945  *      interface to the GPIO systems - slightly slower, but always usable as
946  *      a non-root user, assuming the devices are already exported and setup correctly.
947  */
948
949 int wiringPiSetupSys (void)
950 {
951   int pin ;
952   struct timeval tv ;
953   char fName [128] ;
954
955             pinMode =           pinModeSys ;
956     pullUpDnControl =   pullUpDnControlSys ;
957        digitalWrite =      digitalWriteSys ;
958            pwmWrite =          pwmWriteSys ;
959         setPadDrive =       setPadDriveSys ;
960         digitalRead =       digitalReadSys ;
961    waitForInterrupt =  waitForInterruptSys ;
962   delayMicroseconds = delayMicrosecondsSys ;
963
964 // Open and scan the directory, looking for exported GPIOs, and pre-open
965 //      the 'value' interface to speed things up for later
966   
967   for (pin = 0 ; pin < 64 ; ++pin)
968   {
969     sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
970     sysFds [pin] = open (fName, O_RDWR) ;
971   }
972
973 // Initialise the epoch for mills() ...
974
975   gettimeofday (&tv, NULL) ;
976   epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
977
978   return 0 ;
979 }
980
981