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