wiringpi 0.0.1-armv6l-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile('wiringpi/wiringpi')
@@ -0,0 +1,587 @@
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 General Public License as published by
15
+ * the Free Software Foundation, either version 3 of the License, or
16
+ * (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 General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License
24
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
25
+ ***********************************************************************
26
+ */
27
+
28
+ // Revisions:
29
+ // 11 Jun 2012:
30
+ // Fixed some typos.
31
+ // Added c++ support for the .h file
32
+ // Added a new function to allow for using my "pin" numbers, or native
33
+ // GPIO pin numbers.
34
+ // Removed my busy-loop delay and replaced it with a call to delayMicroseconds
35
+ //
36
+ // 02 May 2012:
37
+ // Added in the 2 UART pins
38
+ // Change maxPins to numPins to more accurately reflect purpose
39
+
40
+ // Pad drive current fiddling
41
+
42
+ #undef DEBUG_PADS
43
+
44
+ #include <stdio.h>
45
+ #include <stdint.h>
46
+ #include <errno.h>
47
+ #include <string.h>
48
+ #include <time.h>
49
+ #include <fcntl.h>
50
+ #include <sys/mman.h>
51
+
52
+ #include "wiringpi.h"
53
+
54
+ #ifndef TRUE
55
+ #define TRUE (1==1)
56
+ #define FALSE (1==2)
57
+ #endif
58
+
59
+ // Port function select bits
60
+
61
+ #define FSEL_INPT 0b000
62
+ #define FSEL_OUTP 0b001
63
+ #define FSEL_ALT0 0b100
64
+ #define FSEL_ALT0 0b100
65
+ #define FSEL_ALT1 0b101
66
+ #define FSEL_ALT2 0b110
67
+ #define FSEL_ALT3 0b111
68
+ #define FSEL_ALT4 0b011
69
+ #define FSEL_ALT5 0b010
70
+
71
+ // Access from ARM Running Linux
72
+ // Take from Gerts code. Some of this is not in the manual
73
+ // that I can find )-:
74
+
75
+ #define BCM2708_PERI_BASE 0x20000000
76
+ #define GPIO_PADS (BCM2708_PERI_BASE + 0x100000)
77
+ #define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000)
78
+ #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
79
+ #define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000)
80
+
81
+ #define PAGE_SIZE (4*1024)
82
+ #define BLOCK_SIZE (4*1024)
83
+
84
+ // PWM
85
+
86
+ #define PWM_CONTROL 0
87
+ #define PWM_STATUS 1
88
+ #define PWM0_RANGE 4
89
+ #define PWM0_DATA 5
90
+ #define PWM1_RANGE 8
91
+ #define PWM1_DATA 9
92
+
93
+ #define PWMCLK_CNTL 40
94
+ #define PWMCLK_DIV 41
95
+
96
+ #define PWM1_MS_MODE 0x8000 // Run in MS mode
97
+ #define PWM1_USEFIFO 0x2000 // Data from FIFO
98
+ #define PWM1_REVPOLAR 0x1000 // Reverse polarity
99
+ #define PWM1_OFFSTATE 0x0800 // Ouput Off state
100
+ #define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty
101
+ #define PWM1_SERIAL 0x0200 // Run in serial mode
102
+ #define PWM1_ENABLE 0x0100 // Channel Enable
103
+
104
+ #define PWM0_MS_MODE 0x0080 // Run in MS mode
105
+ #define PWM0_USEFIFO 0x0020 // Data from FIFO
106
+ #define PWM0_REVPOLAR 0x0010 // Reverse polarity
107
+ #define PWM0_OFFSTATE 0x0008 // Ouput Off state
108
+ #define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty
109
+ #define PWM0_SERIAL 0x0002 // Run in serial mode
110
+ #define PWM0_ENABLE 0x0001 // Channel Enable
111
+
112
+
113
+ // Locals to hold pointers to the hardware
114
+
115
+ static volatile uint32_t *gpio ;
116
+ static volatile uint32_t *pwm ;
117
+ static volatile uint32_t *clk ;
118
+
119
+ // The BCM2835 has 54 GPIO pins.
120
+ // BCM2835 data sheet, Page 90 onwards.
121
+ // There are 6 control registers, each control the functions of a block
122
+ // of 10 pins.
123
+ // Each control register has 10 sets of 3 bits per GPIO pin:
124
+ //
125
+ // 000 = GPIO Pin X is an input
126
+ // 001 = GPIO Pin X is an output
127
+ // 100 = GPIO Pin X takes alternate function 0
128
+ // 101 = GPIO Pin X takes alternate function 1
129
+ // 110 = GPIO Pin X takes alternate function 2
130
+ // 111 = GPIO Pin X takes alternate function 3
131
+ // 011 = GPIO Pin X takes alternate function 4
132
+ // 010 = GPIO Pin X takes alternate function 5
133
+ //
134
+ // So the 3 bits for port X are:
135
+ // X / 10 + ((X % 10) * 3)
136
+
137
+ // mode
138
+
139
+ static int gpioPinMode ;
140
+
141
+ // Doing it the Arduino way with lookup tables...
142
+ // Yes, it's probably more innefficient than all the bit-twidling, but it
143
+ // does tend to make it all a bit clearer. At least to me!
144
+
145
+ // pinToGpio:
146
+ // Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
147
+
148
+ static int pinToGpio [] =
149
+ {
150
+ 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7
151
+ 0, 1, // I2C - SDA0, SCL0
152
+ 8, 7, // SPI - CE1, CE0
153
+ 10, 9, 11, // SPI - MISO, MOSI, SCLK
154
+ 14, 15, // UART - Tx, Rx
155
+ } ;
156
+
157
+ // gpioToGPFSEL:
158
+ // Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
159
+
160
+ static uint8_t gpioToGPFSEL [] =
161
+ {
162
+ 0,0,0,0,0,0,0,0,0,0,
163
+ 1,1,1,1,1,1,1,1,1,1,
164
+ 2,2,2,2,2,2,2,2,2,2,
165
+ 3,3,3,3,3,3,3,3,3,3,
166
+ 4,4,4,4,4,4,4,4,4,4,
167
+ 5,5,5,5,5,5,5,5,5,5,
168
+ } ;
169
+
170
+ // gpioToShift
171
+ // Define the shift up for the 3 bits per pin in each GPFSEL port
172
+
173
+ static uint8_t gpioToShift [] =
174
+ {
175
+ 0,3,6,9,12,15,18,21,24,27,
176
+ 0,3,6,9,12,15,18,21,24,27,
177
+ 0,3,6,9,12,15,18,21,24,27,
178
+ 0,3,6,9,12,15,18,21,24,27,
179
+ 0,3,6,9,12,15,18,21,24,27,
180
+ } ;
181
+
182
+ // gpioToGPSET:
183
+ // (Word) offset to the GPIO Set registers for each GPIO pin
184
+
185
+ static uint8_t gpioToGPSET [] =
186
+ {
187
+ 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,
188
+ 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,
189
+ } ;
190
+
191
+ // gpioToGPCLR:
192
+ // (Word) offset to the GPIO Clear registers for each GPIO pin
193
+
194
+ static uint8_t gpioToGPCLR [] =
195
+ {
196
+ 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,
197
+ 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,
198
+ } ;
199
+
200
+ // gpioToGPLEV:
201
+ // (Word) offset to the GPIO Input level registers for each GPIO pin
202
+
203
+ static uint8_t gpioToGPLEV [] =
204
+ {
205
+ 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,
206
+ 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,
207
+ } ;
208
+
209
+ // gpioToPUDCLK
210
+ // (Word) offset to the Pull Up Down Clock regsiter
211
+
212
+ static uint8_t gpioToPUDCLK [] =
213
+ {
214
+ 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,
215
+ 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,
216
+ } ;
217
+
218
+ // gpioToPwmALT
219
+ // the ALT value to put a GPIO pin into PWM mode
220
+
221
+ static uint8_t gpioToPwmALT [] =
222
+ {
223
+ 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
224
+ 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15
225
+ 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23
226
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
227
+ 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
228
+ FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47
229
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
230
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
231
+ } ;
232
+
233
+ static uint8_t gpioToPwmPort [] =
234
+ {
235
+ 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
236
+ 0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15
237
+ 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23
238
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
239
+ 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
240
+ PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47
241
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
242
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
243
+
244
+ } ;
245
+
246
+
247
+ //////////////////////////////////////////////////////////////////////////////////
248
+
249
+
250
+ /*
251
+ * wiringPiGpioMode:
252
+ * Set the mode - use Pin numbers (0-16) or GPIO number (seemingly random)
253
+ *********************************************************************************
254
+ */
255
+
256
+ void wiringPiGpioMode (int mode)
257
+ {
258
+ gpioPinMode = mode ;
259
+ }
260
+
261
+
262
+ /*
263
+ * wiringPiSetup:
264
+ * Must be called once at the start of your program execution.
265
+ *********************************************************************************
266
+ */
267
+
268
+ int wiringPiSetup (void)
269
+ {
270
+ int fd ;
271
+ uint8_t *gpioMem, *pwmMem, *clkMem ;
272
+
273
+ #ifdef DEBUG_PADS
274
+ uint8_t *gpioMem, *padsMem, *pwmMem, *clkMem ;
275
+ uint32_t *pads ;
276
+ #endif
277
+
278
+ // Set Pin mode by default
279
+
280
+ wiringPiGpioMode (WPI_MODE_PINS) ;
281
+
282
+ // Open the master /dev/memory device
283
+
284
+ if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
285
+ {
286
+ fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
287
+ return -1 ;
288
+ }
289
+
290
+ // GPIO:
291
+
292
+ // Allocate 2 pages - 1 ...
293
+
294
+ if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
295
+ {
296
+ fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
297
+ return -1 ;
298
+ }
299
+
300
+ // ... presumably to make sure we can round it up to a whole page size
301
+
302
+ if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
303
+ gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
304
+
305
+ gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
306
+
307
+ if ((int32_t)gpio < 0)
308
+ {
309
+ fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
310
+ return -1 ;
311
+ }
312
+
313
+ // PWM
314
+
315
+ if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
316
+ {
317
+ fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
318
+ return -1 ;
319
+ }
320
+
321
+ if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
322
+ pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;
323
+
324
+ pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;
325
+
326
+ if ((int32_t)pwm < 0)
327
+ {
328
+ fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
329
+ return -1 ;
330
+ }
331
+
332
+ // Clock control (needed for PWM)
333
+
334
+ if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
335
+ {
336
+ fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
337
+ return -1 ;
338
+ }
339
+
340
+ if (((uint32_t)clkMem % PAGE_SIZE) != 0)
341
+ clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;
342
+
343
+ clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;
344
+
345
+ if ((int32_t)clk < 0)
346
+ {
347
+ fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
348
+ return -1 ;
349
+ }
350
+
351
+ #ifdef DEBUG_PADS
352
+ if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
353
+ {
354
+ fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
355
+ return -1 ;
356
+ }
357
+
358
+ if (((uint32_t)padsMem % PAGE_SIZE) != 0)
359
+ padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;
360
+
361
+ pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;
362
+
363
+ if ((int32_t)pads < 0)
364
+ {
365
+ fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
366
+ return -1 ;
367
+ }
368
+
369
+ printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
370
+
371
+ printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
372
+ // *(pads + 11) = 0x1F ;
373
+ printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
374
+ #endif
375
+
376
+ return 0 ;
377
+ }
378
+
379
+
380
+ /*
381
+ * pinMode:
382
+ * Sets the mode of a pin to be input, output or PWM output
383
+ *********************************************************************************
384
+ */
385
+
386
+ void pinMode (int pin, int mode)
387
+ {
388
+ static int pwmRunning = FALSE ;
389
+
390
+ int gpioPin, fSel, shift ;
391
+ int alt ;
392
+
393
+
394
+ if (gpioPinMode == WPI_MODE_PINS)
395
+ {
396
+ if ((pin < 0) || (pin >= NUM_PINS))
397
+ return ;
398
+ gpioPin = pinToGpio [pin] ;
399
+ }
400
+ else
401
+ gpioPin = pin ;
402
+
403
+ fSel = gpioToGPFSEL [gpioPin] ;
404
+ shift = gpioToShift [gpioPin] ;
405
+
406
+
407
+ /**/ if (mode == INPUT)
408
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
409
+ else if (mode == OUTPUT)
410
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
411
+ else if (mode == PWM_OUTPUT)
412
+ {
413
+ if ((alt = gpioToPwmALT [gpioPin]) == 0) // Not a PWM pin
414
+ return ;
415
+
416
+ // Set pin to PWM mode
417
+
418
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
419
+
420
+ // We didn't initialise the PWM hardware at setup time - because it's possible that
421
+ // something else is using the PWM - e.g. the Audio systems! So if we use PWM
422
+ // here, then we're assuming that nothing else is, otherwise things are going
423
+ // to sound a bit funny...
424
+
425
+ if (!pwmRunning)
426
+ {
427
+
428
+ // Gert/Doms Values
429
+ *(clk + PWMCLK_DIV) = 0x5A000000 | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz)
430
+ *(clk + PWMCLK_CNTL) = 0x5A000011 ; // Source=osc and enable
431
+ digitalWrite (pin, LOW) ;
432
+ *(pwm + PWM_CONTROL) = 0 ; // Disable PWM
433
+ delayMicroseconds (10) ;
434
+ *(pwm + PWM0_RANGE) = 0x400 ;
435
+ delayMicroseconds (10) ;
436
+ *(pwm + PWM1_RANGE) = 0x400 ;
437
+ delayMicroseconds (10) ;
438
+
439
+ // Enable PWMs
440
+
441
+ *(pwm + PWM0_DATA) = 512 ;
442
+ *(pwm + PWM1_DATA) = 512 ;
443
+
444
+ *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
445
+ }
446
+
447
+ }
448
+
449
+ // When we change mode of any pin, we remove the pull up/downs
450
+
451
+ pullUpDnControl (pin, PUD_OFF) ;
452
+ }
453
+
454
+
455
+ /*
456
+ * digitalWrite:
457
+ * Set an output bit
458
+ *********************************************************************************
459
+ */
460
+
461
+ void digitalWrite (int pin, int value)
462
+ {
463
+ int gpioPin ;
464
+
465
+ if (gpioPinMode == WPI_MODE_PINS)
466
+ {
467
+ if ((pin < 0) || (pin >= NUM_PINS))
468
+ return ;
469
+ gpioPin = pinToGpio [pin] ;
470
+ }
471
+ else
472
+ gpioPin = pin ;
473
+
474
+ if (value == HIGH)
475
+ *(gpio + gpioToGPSET [gpioPin]) = 1 << gpioPin ;
476
+ else
477
+ *(gpio + gpioToGPCLR [gpioPin]) = 1 << gpioPin ;
478
+ }
479
+
480
+
481
+ /*
482
+ * pwnWrite:
483
+ * Set an output PWM value
484
+ *********************************************************************************
485
+ */
486
+
487
+ void pwmWrite (int pin, int value)
488
+ {
489
+ int port, gpioPin ;
490
+
491
+ if (gpioPinMode == WPI_MODE_PINS)
492
+ {
493
+ if ((pin < 0) || (pin >= NUM_PINS))
494
+ return ;
495
+ gpioPin = pinToGpio [pin] ;
496
+ }
497
+ else
498
+ gpioPin = pin ;
499
+
500
+ port = gpioToPwmPort [gpioPin] ;
501
+
502
+ *(pwm + port) = value & ~0x400 ;
503
+ }
504
+
505
+
506
+ /*
507
+ * digitalRead:
508
+ * Read the value of a given Pin, returning HIGH or LOW
509
+ *********************************************************************************
510
+ */
511
+
512
+ int digitalRead (int pin)
513
+ {
514
+ int gpioPin ;
515
+
516
+ if (gpioPinMode == WPI_MODE_PINS)
517
+ {
518
+ if ((pin < 0) || (pin >= NUM_PINS))
519
+ return 0 ;
520
+ gpioPin = pinToGpio [pin] ;
521
+ }
522
+ else
523
+ gpioPin = pin ;
524
+
525
+ if ((*(gpio + gpioToGPLEV [gpioPin]) & (1 << gpioPin)) != 0)
526
+ return HIGH ;
527
+ else
528
+ return LOW ;
529
+ }
530
+
531
+ /*
532
+ * pullUpDownCtrl:
533
+ * Control the internal pull-up/down resistors on a GPIO pin
534
+ * The Arduino only has pull-ups and these are enabled by writing 1
535
+ * to a port when in input mode - this paradigm doesn't quite apply
536
+ * here though.
537
+ *********************************************************************************
538
+ */
539
+
540
+ void pullUpDnControl (int pin, int pud)
541
+ {
542
+ int gpioPin ;
543
+
544
+ if (gpioPinMode == WPI_MODE_PINS)
545
+ {
546
+ if ((pin < 0) || (pin >= NUM_PINS))
547
+ return ;
548
+ gpioPin = pinToGpio [pin] ;
549
+ }
550
+ else
551
+ gpioPin = pin ;
552
+
553
+ *(gpio + 37) = pud ;
554
+ delayMicroseconds (10) ;
555
+ *(gpio + gpioToPUDCLK [gpioPin]) = 1 << gpioPin ;
556
+ delayMicroseconds (10) ;
557
+
558
+ *(gpio + 37) = 0 ;
559
+ *(gpio + gpioToPUDCLK [gpioPin]) = 0 ;
560
+ }
561
+
562
+
563
+ /*
564
+ * delay: delayMicroseconds
565
+ * Wait for some number of milli/micro seconds
566
+ *********************************************************************************
567
+ */
568
+
569
+ void delay (unsigned int howLong)
570
+ {
571
+ struct timespec sleeper, dummy ;
572
+
573
+ sleeper.tv_sec = (time_t)(howLong / 1000) ;
574
+ sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
575
+
576
+ nanosleep (&sleeper, &dummy) ;
577
+ }
578
+
579
+ void delayMicroseconds (unsigned int howLong)
580
+ {
581
+ struct timespec sleeper, dummy ;
582
+
583
+ sleeper.tv_sec = 0 ;
584
+ sleeper.tv_nsec = (long)(howLong * 1000) ;
585
+
586
+ nanosleep (&sleeper, &dummy) ;
587
+ }