Browse Source

Initial move to GIT

pull/22/head
Gordon Henderson 12 years ago
commit
bf0ad86017
37 changed files with 5334 additions and 0 deletions
  1. +165
    -0
      COPYING.LESSER
  2. +165
    -0
      examples/COPYING.LESSER
  3. +96
    -0
      examples/Makefile
  4. +68
    -0
      examples/delayTest.c
  5. +47
    -0
      examples/gertboard.c
  6. BIN
      examples/gertboard.png
  7. +129
    -0
      examples/lcd.c
  8. +44
    -0
      examples/nes.c
  9. +53
    -0
      examples/piface.c
  10. +105
    -0
      examples/speed.c
  11. +91
    -0
      examples/test1.c
  12. +41
    -0
      examples/test2.c
  13. +158
    -0
      examples/wfi.c
  14. +165
    -0
      gpio/COPYING.LESSER
  15. +73
    -0
      gpio/Makefile
  16. +179
    -0
      gpio/gpio.1
  17. +755
    -0
      gpio/gpio.c
  18. +23
    -0
      gpio/test.sh
  19. BIN
      wiringPi/.wiringPiFace.c.swp
  20. +165
    -0
      wiringPi/COPYING.LESSER
  21. +101
    -0
      wiringPi/Makefile
  22. +9
    -0
      wiringPi/README
  23. +184
    -0
      wiringPi/gertboard.c
  24. +39
    -0
      wiringPi/gertboard.h
  25. +365
    -0
      wiringPi/lcd.c
  26. +37
    -0
      wiringPi/lcd.h
  27. +50
    -0
      wiringPi/piHiPri.c
  28. +115
    -0
      wiringPi/piNes.c
  29. +37
    -0
      wiringPi/piNes.h
  30. +63
    -0
      wiringPi/piThread.c
  31. +981
    -0
      wiringPi/wiringPi.c
  32. +95
    -0
      wiringPi/wiringPi.h
  33. +355
    -0
      wiringPi/wiringPiFace.c
  34. +218
    -0
      wiringPi/wiringSerial.c
  35. +38
    -0
      wiringPi/wiringSerial.h
  36. +84
    -0
      wiringPi/wiringShift.c
  37. +41
    -0
      wiringPi/wiringShift.h

+ 165
- 0
COPYING.LESSER View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007

Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.


This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.

0. Additional Definitions.

As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.

"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.

An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.

A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".

The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.

The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.

1. Exception to Section 3 of the GNU GPL.

You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.

2. Conveying Modified Versions.

If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:

a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or

b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.

3. Object Code Incorporating Material from Library Header Files.

The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:

a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the object code with a copy of the GNU GPL and this license
document.

4. Combined Works.

You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:

a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.

c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.

d) Do one of the following:

0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.

1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.

e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)

5. Combined Libraries.

You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:

a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.

b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.

6. Revised Versions of the GNU Lesser General Public License.

The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.

If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

+ 165
- 0
examples/COPYING.LESSER View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007

Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.


This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.

0. Additional Definitions.

As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.

"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.

An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.

A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".

The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.

The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.

1. Exception to Section 3 of the GNU GPL.

You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.

2. Conveying Modified Versions.

If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:

a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or

b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.

3. Object Code Incorporating Material from Library Header Files.

The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:

a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the object code with a copy of the GNU GPL and this license
document.

4. Combined Works.

You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:

a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.

c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.

d) Do one of the following:

0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.

1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.

e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)

5. Combined Libraries.

You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:

a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.

b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.

6. Revised Versions of the GNU Lesser General Public License.

The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.

If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

+ 96
- 0
examples/Makefile View File

@@ -0,0 +1,96 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################


#DEBUG = -g -O0
DEBUG = -O3
CC = gcc
INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe

LDFLAGS = -L/usr/local/lib
LIBS = -lwiringPi

# Should not alter anything below this line
###############################################################################

SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c gertboard.c nes.c delayTest.c

OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o

all: test1 test2 speed lcd wfi piface gertboard nes

test1: test1.o
@echo [link]
$(CC) -o $@ test1.o $(LDFLAGS) $(LIBS)
test2: test2.o
@echo [link]
$(CC) -o $@ test2.o $(LDFLAGS) $(LIBS)

speed: speed.o
@echo [link]
$(CC) -o $@ speed.o $(LDFLAGS) $(LIBS)

lcd: lcd.o
@echo [link]
$(CC) -o $@ lcd.o $(LDFLAGS) $(LIBS)

wfi: wfi.o
@echo [link]
$(CC) -o $@ wfi.o $(LDFLAGS) $(LIBS) -lpthread

piface: piface.o
@echo [link]
$(CC) -o $@ piface.o $(LDFLAGS) $(LIBS) -lpthread

gertboard: gertboard.o
@echo [link]
$(CC) -o $@ gertboard.o $(LDFLAGS) $(LIBS) -lm

nes: nes.o
@echo [link]
$(CC) -o $@ nes.o $(LDFLAGS) $(LIBS) -lm


delayTest: delayTest.o
@echo [link]
$(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS)


.c.o:
@echo [CC] $<
@$(CC) -c $(CFLAGS) $< -o $@

clean:
rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface gertboard nes delayTest

tags: $(SRC)
@echo [ctags]
@ctags $(SRC)

depend:
makedepend -Y $(SRC)

# DO NOT DELETE

+ 68
- 0
examples/delayTest.c View File

@@ -0,0 +1,68 @@

#include <stdio.h>
#include <unistd.h>
#include <wiringPi.h>

#include <time.h>
#include <sys/types.h>
#include <sys/time.h>

#define CYCLES 1000
#define DELAY 99

int main()
{
int x ;
struct timeval t1, t2 ;
long long t ;
unsigned int max, min ;

unsigned int values [CYCLES] ;

max = 0 ;
min = 1000000 ;

if (wiringPiSetup () == -1)
return 1 ;

piHiPri (10) ;
sleep (1) ;

// Baseline test

gettimeofday (&t1, NULL) ;
gettimeofday (&t2, NULL) ;

t = t2.tv_usec - t1.tv_usec ;
printf ("Baseline test: %lld\n", t);

for (x = 0 ; x < CYCLES ; ++x)
{
gettimeofday (&t1, NULL) ;
delayMicroseconds (DELAY) ;
gettimeofday (&t2, NULL) ;
t = t2.tv_usec - t1.tv_usec ;
if (t > max) max = t ;
if (t < min) min = t ;
values [x] = t ;
}

printf ("Done: Max: %d, min: %d\n", max, min) ;

for (x = 0 ; x < CYCLES ; ++x)
{
printf ("%4d", values [x]) ;
if (values [x] > DELAY)
printf (".") ;
else if (values [x] < DELAY)
printf ("-") ;
else
printf (" ") ;
if (((x + 1) % 20) == 0)
printf ("\n") ;
}
printf ("\n") ;

return 0 ;
}

+ 47
- 0
examples/gertboard.c View File

@@ -0,0 +1,47 @@

/*
* gertboard.c:
* Simple test for the SPI bus on the Gertboard
*
* Hardware setup:
* D/A port 0 jumpered to A/D port 0.
*
* We output a sine wave on D/A port 0 and sample A/D port 0. We then
* copy this value to D/A port 1 and use a 'scope on both D/A ports
* to check all's well.
*
*/

#include <stdio.h>
#include <stdint.h>
//#include <stdlib.h>
#include <math.h>

#include <wiringPi.h>
#include <gertboard.h>

int main (void)
{
int angle ;
int h1 ;
uint32_t x1 ;

printf ("Raspberry Pi Gertboard SPI test program\n") ;

if (gertboardSPISetup () == -1)
return 1 ;

for (;;)
{
for (angle = 0 ; angle < 360 ; ++angle)
{
h1 = (int)rint (sin ((double)angle * M_PI / 180.0) * 127.0 + 128.0) ;
gertboardAnalogWrite (0, h1) ;

x1 = gertboardAnalogRead (0) ;
gertboardAnalogWrite (1, x1 >> 2) ; // 10-bit A/D, 8-bit D/A
}
}

return 0 ;
}

BIN
examples/gertboard.png View File

Before After
Width: 400  |  Height: 240  |  Size: 4.7 KiB

+ 129
- 0
examples/lcd.c View File

@@ -0,0 +1,129 @@
/*
* lcd.c:
* Text-based LCD driver.
* This is designed to drive the parallel interface LCD drivers
* based in the Hitachi HD44780U controller and compatables.
*
* Copyright (c) 2012 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include <unistd.h>
#include <string.h>
#include <time.h>

#include <wiringPi.h>
#include <lcd.h>

int main (void)
{
int i, j ;
int fd1, fd2 ;

char message1 [256] ;
char message2 [256] ;
char buf1 [30] ;
char buf2 [30] ;

struct tm *t ;
time_t tim ;

printf ("Raspberry Pi LCD test program\n") ;

if (wiringPiSetup () == -1)
exit (1) ;

fd1 = lcdInit (4, 20, 4, 8, 9, 4,5,6,7,0,0,0,0) ;
fd2 = lcdInit (2, 16, 4, 8, 10, 4,5,6,7,0,0,0,0) ;

//fd1 = lcdInit (4, 20, 8, 8, 9, 0,1,2,3,4,5,6,7) ;
//fd2 = lcdInit (2, 16, 8, 8, 10, 0,1,2,3,4,5,6,7) ;

if (fd1 == -1)
{
printf ("lcdInit 1 failed\n") ;
return 1 ;
}

if (fd2 == -1)
{
printf ("lcdInit 2 failed\n") ;
return 1 ;
}

sleep (1) ;

lcdPosition (fd1, 0, 0) ; lcdPuts (fd1, " Gordon Henderson") ;
lcdPosition (fd1, 0, 1) ; lcdPuts (fd1, " --------------") ;
/*
lcdPosition (fd1, 0, 2) ; lcdPuts (fd1, " 00:00:00") ;
lcdPosition (fd1, 0, 3) ; lcdPuts (fd1, " DD:MM:YY") ;
*/

lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ;
lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ;

sleep (2) ;

sprintf (message1, "%s", " http://projects.drogon.net/ ") ;
sprintf (message2, "%s", " This is a long message to go into the smaller display just for a demonstration of what we can do. ") ;

for (;;)
{
i = 0 ;
j = 0 ;
for (;;)
{
strncpy (buf1, &message1 [i], 20) ;
buf1 [20] = 0 ;
lcdPosition (fd1, 0, 1) ;
lcdPuts (fd1, buf1) ;
++i ;
if (i == strlen (message1) - 20)
i = 0 ;

strncpy (buf2, &message2 [j], 16) ;
buf2 [16] = 0 ;
lcdPosition (fd2, 0, 1) ;
lcdPuts (fd2, buf2) ;
++j ;
if (j == strlen (message2) - 16)
j = 0 ;

tim = time (NULL) ;
t = localtime (&tim) ;

sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
lcdPosition (fd1, 5, 2) ;
lcdPuts (fd1, buf1) ;

sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
lcdPosition (fd1, 4, 3) ;
lcdPuts (fd1, buf1) ;

delay (250) ;
}
}

return 0 ;
}

+ 44
- 0
examples/nes.c View File

@@ -0,0 +1,44 @@

#include <stdio.h>
#include <errno.h>
#include <string.h>

#include <wiringPi.h>
#include <piNes.h>

#define BLANK "| "

int main ()
{
int joystick ;
unsigned int buttons ;

if (wiringPiSetup () == -1)
{
fprintf (stdout, "oops: %s\n", strerror (errno)) ;
return 1 ;
}

if ((joystick = setupNesJoystick (2, 1, 0)) == -1)
{
fprintf (stdout, "Unable to setup joystick\n") ;
return 1 ;
}

for (;;)
{
buttons = readNesJoystick (joystick) ;

if ((buttons & NES_UP) != 0) printf ("| UP " ) ; else printf (BLANK) ;
if ((buttons & NES_DOWN) != 0) printf ("| DOWN " ) ; else printf (BLANK) ;
if ((buttons & NES_LEFT) != 0) printf ("| LEFT " ) ; else printf (BLANK) ;
if ((buttons & NES_RIGHT) != 0) printf ("|RIGHT " ) ; else printf (BLANK) ;
if ((buttons & NES_SELECT) != 0) printf ("|SELECT" ) ; else printf (BLANK) ;
if ((buttons & NES_START) != 0) printf ("|START " ) ; else printf (BLANK) ;
if ((buttons & NES_A) != 0) printf ("| A " ) ; else printf (BLANK) ;
if ((buttons & NES_B) != 0) printf ("| B " ) ; else printf (BLANK) ;
printf ("|\n") ;
}

return 0 ;
}

+ 53
- 0
examples/piface.c View File

@@ -0,0 +1,53 @@

/*
* piface.c:
* Simple test for the PiFace
*
* Read the buttons and output the same to the LEDs
*/

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int outputs [4] = { 0,0,0,0 } ;

void scanButton (int button)
{
if (digitalRead (button) == LOW)
{
outputs [button] ^= 1 ;
digitalWrite (button, outputs [button]) ;
}

while (digitalRead (button) == LOW)
delay (1) ;
}


int main (void)
{
int pin, button ;

printf ("Raspberry Pi wiringPiFace test program\n") ;

if (wiringPiSetupPiFace () == -1)
exit (1) ;

// Enable internal pull-ups

for (pin = 0 ; pin < 8 ; ++pin)
pullUpDnControl (pin, PUD_UP) ;


for (;;)
{
for (button = 0 ; button < 4 ; ++button)
scanButton (button) ;
delay (1) ;
}

return 0 ;
}

+ 105
- 0
examples/speed.c View File

@@ -0,0 +1,105 @@

/*
* speed.c:
* Simple program to measure the speed of the various GPIO
* access mechanisms.
*/

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define FAST_COUNT 10000000
#define SLOW_COUNT 1000000


int main (void)
{
int i ;
uint32_t start, end, count, sum, perSec ;

printf ("Raspberry Pi wiringPi speed test program\n") ;

// Start the standard way

if (wiringPiSetup () == -1)
exit (1) ;

printf ("Native wiringPi method: (%8d iterations)\n", FAST_COUNT) ;

pinMode (0, OUTPUT) ;

sum = 0 ;
for (i = 0 ; i < 3 ; ++i)
{
printf (" Pass: %d: ", i) ;
fflush (stdout) ;

start = millis () ;
for (count = 0 ; count < FAST_COUNT ; ++count)
digitalWrite (0, 1) ;
end = millis () ;
printf (" %8dmS\n", end - start) ;
sum += (end - start) ;
}
digitalWrite (0, 0) ;
printf (" Average: %8dmS", sum / 3) ;
perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
printf (": %6d/sec\n", perSec) ;


printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ;

if (wiringPiSetupGpio () == -1)
exit (1) ;

pinMode (17, OUTPUT) ;

sum = 0 ;
for (i = 0 ; i < 3 ; ++i)
{
printf (" Pass: %d: ", i) ;
fflush (stdout) ;

start = millis () ;
for (count = 0 ; count < 10000000 ; ++count)
digitalWrite (17, 1) ;
end = millis () ;
printf (" %8dmS\n", end - start) ;
sum += (end - start) ;
}
digitalWrite (17, 0) ;
printf (" Average: %8dmS", sum / 3) ;
perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
printf (": %6d/sec\n", perSec) ;


// Switch to SYS mode:

if (wiringPiSetupSys () == -1)
exit (1) ;

printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ;

sum = 0 ;
for (i = 0 ; i < 3 ; ++i)
{
printf (" Pass: %d: ", i) ;
fflush (stdout) ;

start = millis () ;
for (count = 0 ; count < SLOW_COUNT ; ++count)
digitalWrite (17, 1) ;
end = millis () ;
printf (" %8dmS\n", end - start) ;
sum += (end - start) ;
}
digitalWrite (17, 0) ;
printf (" Average: %8dmS", sum / 3) ;
perSec = (int)(double)SLOW_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
printf (": %6d/sec\n", perSec) ;

return 0 ;
}

+ 91
- 0
examples/test1.c View File

@@ -0,0 +1,91 @@

/*
* test1.c:
* Simple test program to test the wiringPi functions
*/

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


// Simple sequencer data
// Triplets of LED, On/Off and delay

uint8_t data [] =
{
0, 1, 1,
1, 1, 1,
0, 0, 0, 2, 1, 1,
1, 0, 0, 3, 1, 1,
2, 0, 0, 4, 1, 1,
3, 0, 0, 5, 1, 1,
4, 0, 0, 6, 1, 1,
5, 0, 0, 7, 1, 1,
6, 0, 1,
7, 0, 1,

0, 0, 1, // Extra delay

// Back again

7, 1, 1,
6, 1, 1,
7, 0, 0, 5, 1, 1,
6, 0, 0, 4, 1, 1,
5, 0, 0, 3, 1, 1,
4, 0, 0, 2, 1, 1,
3, 0, 0, 1, 1, 1,
2, 0, 0, 0, 1, 1,
1, 0, 1,
0, 0, 1,

0, 0, 1, // Extra delay

9, 9, 9, // End marker

} ;


int main (void)
{
int pin ;
int dataPtr ;
int l, s, d ;

printf ("Raspberry Pi wiringPi test program\n") ;

if (wiringPiSetup () == -1)
exit (1) ;

for (pin = 0 ; pin < 8 ; ++pin)
pinMode (pin, OUTPUT) ;

pinMode (8, INPUT) ; // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor

dataPtr = 0 ;

for (;;)
{
l = data [dataPtr++] ; // LED
s = data [dataPtr++] ; // State
d = data [dataPtr++] ; // Duration (10ths)

if ((l + s + d) == 27)
{
dataPtr = 0 ;
continue ;
}

digitalWrite (l, s) ;

if (digitalRead (8) == 0) // Pressed as our switch shorts to ground
delay (d * 10) ; // Faster!
else
delay (d * 100) ;
}

return 0 ;
}

+ 41
- 0
examples/test2.c View File

@@ -0,0 +1,41 @@

/*
* test2.c:
* Simple test program to test the wiringPi functions
* PWM test
*/

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main (void)
{
int bright ;

printf ("Raspberry Pi wiringPi PWM test program\n") ;

if (wiringPiSetup () == -1)
exit (1) ;

pinMode (1, PWM_OUTPUT) ;

for (;;)
{
for (bright = 0 ; bright < 1024 ; ++bright)
{
pwmWrite (1, bright) ;
delay (1) ;
}

for (bright = 1023 ; bright >= 0 ; --bright)
{
pwmWrite (1, bright) ;
delay (1) ;
}
}

return 0 ;
}

+ 158
- 0
examples/wfi.c View File

@@ -0,0 +1,158 @@
/*
* wfi.c:
* Wait for Interrupt test program
*
* Copyright (c) 2012 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>

// A 'key' which we can lock and unlock - values are 0 through 3
// This is interpreted internally as a pthread_mutex by wiringPi
// which is hiding some of that to make life simple.

#define COUNT_KEY 0

// What BCM_GPIO input are we using?
// GPIO 0 is one of the I2C pins with an on-board pull-up

#define BUTTON_PIN 0

// Debounce time in mS

#define DEBOUNCE_TIME 100


// globalCounter:
// Global variable to count interrupts
// Should be declared volatile to make sure the compiler doesn't cache it.

static volatile int globalCounter = 0 ;


/*
* waitForIt:
* This is a thread created using the wiringPi simplified threading
* mechanism. It will wait on an interrupt on the button and increment
* a counter.
*********************************************************************************
*/

PI_THREAD (waitForIt)
{
int state = 0 ;
int debounceTime = 0 ;

(void)piHiPri (10) ; // Set this thread to be high priority
digitalWrite (18, 1) ;

for (;;)
{
if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it
{

// Bouncing?

if (millis () < debounceTime)
{
debounceTime = millis () + DEBOUNCE_TIME ;
continue ;
}

// We have a valid one

digitalWrite (17, state) ;
state ^= 1 ;

piLock (COUNT_KEY) ;
++globalCounter ;
piUnlock (COUNT_KEY) ;

// Wait for key to be released

while (digitalRead (0) == LOW)
delay (1) ;

debounceTime = millis () + DEBOUNCE_TIME ;
}
}
}


/*
* setup:
* Demo a crude but effective way to initialise the hardware
*********************************************************************************
*/

void setup (void)
{

// Use the gpio program to initialise the hardware
// (This is the crude, but effective bit)

system ("gpio edge 0 falling") ;
system ("gpio export 17 out") ;
system ("gpio export 18 out") ;

// Setup wiringPi

wiringPiSetupSys () ;

// Fire off our interrupt handler

piThreadCreate (waitForIt) ;

digitalWrite (17, 0) ;
}


/*
* main
*********************************************************************************
*/

int main (void)
{
int lastCounter = 0 ;
int myCounter = 0 ;

setup () ;

for (;;)
{
printf ("Waiting ... ") ; fflush (stdout) ;

while (myCounter == lastCounter)
{
piLock (COUNT_KEY) ;
myCounter = globalCounter ;
piUnlock (COUNT_KEY) ;
delay (5000) ;
}

printf (" Done. myCounter: %5d\n", myCounter) ;
lastCounter = myCounter ;
}

return 0 ;
}

+ 165
- 0
gpio/COPYING.LESSER View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007

Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.


This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.

0. Additional Definitions.

As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.

"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.

An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.

A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".

The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.

The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.

1. Exception to Section 3 of the GNU GPL.

You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.

2. Conveying Modified Versions.

If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:

a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or

b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.

3. Object Code Incorporating Material from Library Header Files.

The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:

a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the object code with a copy of the GNU GPL and this license
document.

4. Combined Works.

You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:

a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.

c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.

d) Do one of the following:

0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.

1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.

e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)

5. Combined Libraries.

You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:

a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.

b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.

6. Revised Versions of the GNU Lesser General Public License.

The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.

If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

+ 73
- 0
gpio/Makefile View File

@@ -0,0 +1,73 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################


#DEBUG = -g -O0
DEBUG = -O3
CC = gcc
INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe

LDFLAGS = -L/usr/local/lib
LIBS = -lwiringPi

# Should not alter anything below this line
###############################################################################

SRC = gpio.c

OBJ = gpio.o

all: gpio

gpio: gpio.o
@echo [LD]
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)
.c.o:
@echo [CC] $<
@$(CC) -c $(CFLAGS) $< -o $@

clean:
rm -f $(OBJ) gpio *~ core tags

tags: $(SRC)
@echo [ctags]
@ctags $(SRC)

depend:
makedepend -Y $(SRC)

install:
cp gpio /usr/local/bin
chown root.root /usr/local/bin/gpio
chmod 4755 /usr/local/bin/gpio
mkdir -p /usr/local/man/man1
cp gpio.1 /usr/local/man/man1

uninstall:
rm -f /usr/local/bin/gpio
rm -f /usr/local/man/man1/gpio.1

# DO NOT DELETE

+ 179
- 0
gpio/gpio.1 View File

@@ -0,0 +1,179 @@
.TH "GPIO" "14 June 2012" "Command-Line access to Raspberry Pi and PiFace GPIO"

.SH NAME
gpio \- Command-line access to Raspberry Pi and PiFace GPIO

.SH SYNOPSIS
.TP
.B gpio
.RB [ \-v ]
.TP
.B gpio
.RB [ \-g ]
.RB < read/write/pwm/mode ...>
.TP
.B gpio
.RB [ \-p ]
.RB < read/write/mode ...>
.TP
.B gpio
.RB < export/edge/unexport/unexportall/exports ...>

.SH DESCRIPTION

.B GPIO
is a command line tool to allow the user easy access to the GPIO pins
on the Raspberry Pi. It's designed for simple testing and diagnostic
purposes, but can be used in shell scripts for general if somewhat slow
control of the GPIO pins.

Additionally, it can be used to set the exports in the \fI/sys/class/gpio\fR
system directory to allow subsequent programs to use the \fR/sys/class/gpio\fR
interface without needing to be run as root.

.SH OPTIONS

.TP
.B \-v
Output the current version

.TP
.B \-g
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.

.TP
.B \-p
Use the PiFace interface board and its corresponding pin numbers.

.TP
.B read
Read the digital value of the given pin and print 0 or 1 to represent the
respective logic levels.

.TP
.B write
Write the given value (0 or 1) to the pin.

.TP
.B pwm
Write a PWM value (0-1023) to the given pin.

.TP
.B mode
Set a pin into \fIinput\fR, \fIoutput\fR or \fIpwm\fR mode. Can also
use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal
pull-up, pull-down or tristate (off) controls.

.TP
.B export
Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the
mode command above however only \fIin\fR and \fIout\fR are supported at
this time. Note that the pin number is the \fBBCM_GPIO\fR number and
not the wiringPi number.

Once a GPIO pin has been exported, the \fBgpio\fR program changes the
ownership of the \fI/sys/class/gpio/gpioX/value\fR and if present in
later kernels, the \fI/sys/class/gpio/gpioX/edge\fR pseudo files to
that of the user running the \fBgpio\fR program. This means that you
can have a small script of gpio exports to setup the gpio pins as your
program requires without the need to run anything as root, or with the
sudo command.

.TP
.B edge
This exports a GPIO pin in the \fI/sys/class/gpio\fR directory, set
the direction to input and set the edge interrupt method to \fInone\fR,
\fIrising\fR, \fIfalling\fR or \fIboth\fR. Use like the export command
above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin
numbering.

Like the export commands abovem ownership is set to that of the
calling user, allowing subsequent access from user programs without
requiring root/sudo.

.TP
.B unexport
Un-Export a GPIO pin in the /sys/class/gpio directory.

.TP
.B unexportall
Un-Export all the GPIO pins in the /sys/class/gpio directory.

.TP
.B exports
Print a list (if any) of all the exported GPIO pins and their current values.

.SH "WiringPi vs. GPIO Pin numbering"

.PP
.TS
r r l.
WiringPi GPIO Function
_
0 17
1 18 (PWM)
2 21
3 22
4 23
5 24
6 25
7 4
8 0 SDA0
9 1 SCL0
10 8 SPI CE0
11 7 SPI CE1
12 10 SPI MOSI
13 9 SPI MISO
14 11 SPI SCLK
15 14 TxD
16 15 RxD
.TE

.SH FILES

.TP 2.2i
.I gpio
executable

.SH EXAMPLES
.TP 2.2i
gpio mode 4 output # Set pin 4 to output
.PP
gpio -g mode 23 output # Set GPIO pin 23 to output (same as WiringPi pin 4)
.PP
gpio mode 1 pwm # Set pin 1 to PWM mode
.PP
gpio pwm 1 512 # Set pin 1 to PWM value 512 - half brightness
.PP
gpio export 17 out # Set GPIO Pin 17 to output
.PP
gpio export 0 in # Set GPIO Pin 0 (SDA0) to input.
.PP
gpio -g read 0 # Read GPIO Pin 0 (SDA0)

.SH "NOTES"

When using the \fIexport\fR, \fIedge\fR or \fIunexport\fR commands, the
pin numbers are \fBalways\fR native BCM_GPIO numbers and never wiringPi
pin numbers.

.SH "SEE ALSO"

.LP
WiringPi's home page
.IP
https://projects.drogon.net/raspberry-pi/wiringpi/

.SH AUTHOR

Gordon Henderson

.SH "REPORTING BUGS"

Report bugs to <gordon@drogon.net>

.SH COPYRIGHT

Copyright (c) 2012 Gordon Henderson
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

+ 755
- 0
gpio/gpio.c View File

@@ -0,0 +1,755 @@
/*
* gpio.c:
* Set-UID command-line interface to the Raspberry Pi's GPIO
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>

#ifndef TRUE
# define TRUE (1==1)
# define FALSE (1==2)
#endif

#define VERSION "1.1"

static int wpMode ;

char *usage = "Usage: gpio -v\n"
" gpio [-g] <read/write/pwm/mode> ...\n"
" gpio [-p] <read/write/mode> ...\n"
" gpio export/edge/unexport/unexportall/exports ...\n"
" gpio drive <group> <value>\n"
" gpio load spi/i2c" ;



/*
* changeOwner:
* Change the ownership of the file to the real userId of the calling
* program so we can access it.
*********************************************************************************
*/

static void changeOwner (char *cmd, char *file)
{
uid_t uid = getuid () ;
uid_t gid = getgid () ;

if (chown (file, uid, gid) != 0)
{
if (errno == ENOENT) // Warn that it's not there
fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
else
{
fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
exit (1) ;
}
}
}


/*
* moduleLoaded:
* Return true/false if the supplied module is loaded
*********************************************************************************
*/

static int moduleLoaded (char *modName)
{
int len = strlen (modName) ;
int found = FALSE ;
FILE *fd = fopen ("/proc/modules", "r") ;
char line [80] ;

if (fd == NULL)
{
fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
exit (1) ;
}

while (fgets (line, 80, fd) != NULL)
{
if (strncmp (line, modName, len) != 0)
continue ;

found = TRUE ;
break ;
}

fclose (fd) ;

return found ;
}


/*
* doLoad:
* Load either the spi or i2c modules and change device ownerships, etc.
*********************************************************************************
*/

static void _doLoadUsage (char *argv [])
{
fprintf (stderr, "Usage: %s load <spi/i2c>\n", argv [0]) ;
exit (1) ;
}

static void doLoad (int argc, char *argv [])
{
char *module ;
char cmd [80] ;
char *file1, *file2 ;

if (argc != 3)
_doLoadUsage (argv) ;

/**/ if (strcasecmp (argv [2], "spi") == 0)
{
module = "spi_bcm2708" ;
file1 = "/dev/spidev0.0" ;
file2 = "/dev/spidev0.1" ;
}
else if (strcasecmp (argv [2], "i2c") == 0)
{
module = "i2c_bcm2708" ;
file1 = "/dev/i2c-0" ;
file2 = "/dev/i2c-1" ;
}
else
_doLoadUsage (argv) ;

if (!moduleLoaded (module))
{
sprintf (cmd, "modprobe %s", module) ;
system (cmd) ;
}

if (!moduleLoaded (module))
{
fprintf (stderr, "%s: Unable to load %s\n", argv [0], module) ;
exit (1) ;
}

sleep (1) ; // To let things get settled

changeOwner (argv [0], file1) ;
changeOwner (argv [0], file2) ;
}



/*
* doExports:
* List all GPIO exports
*********************************************************************************
*/

void doExports (void)
{
int fd ;
int i, l, first ;
char fName [128] ;
char buf [16] ;

// Rather crude, but who knows what others are up to...

for (first = 0, i = 0 ; i < 64 ; ++i)
{

// Try to read the direction

sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
if ((fd = open (fName, O_RDONLY)) == -1)
continue ;

if (first == 0)
{
++first ;
printf ("GPIO Pins exported:\n") ;
}

printf ("%4d: ", i) ;

if ((l = read (fd, buf, 16)) == 0)
sprintf (buf, "%s", "?") ;
buf [l] = 0 ;
if ((buf [strlen (buf) - 1]) == '\n')
buf [strlen (buf) - 1] = 0 ;

printf ("%-3s", buf) ;

close (fd) ;

// Try to Read the value

sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
if ((fd = open (fName, O_RDONLY)) == -1)
{
printf ("No Value file (huh?)\n") ;
continue ;
}

if ((l = read (fd, buf, 16)) == 0)
sprintf (buf, "%s", "?") ;

buf [l] = 0 ;
if ((buf [strlen (buf) - 1]) == '\n')
buf [strlen (buf) - 1] = 0 ;

printf (" %s", buf) ;

// Read any edge trigger file

sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
if ((fd = open (fName, O_RDONLY)) == -1)
{
printf ("\n") ;
continue ;
}

if ((l = read (fd, buf, 16)) == 0)
sprintf (buf, "%s", "?") ;

buf [l] = 0 ;
if ((buf [strlen (buf) - 1]) == '\n')
buf [strlen (buf) - 1] = 0 ;

printf (" %-8s\n", buf) ;

close (fd) ;
}
}


/*
* doExport:
* gpio export pin mode
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doExport (int argc, char *argv [])
{
FILE *fd ;
int pin ;
char *mode ;
char fName [128] ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;

mode = argv [3] ;

if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
exit (1) ;
}

fprintf (fd, "%d\n", pin) ;
fclose (fd) ;

sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
if ((fd = fopen (fName, "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
exit (1) ;
}

/**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
fprintf (fd, "in\n") ;
else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
fprintf (fd, "out\n") ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
exit (1) ;
}

fclose (fd) ;

// Change ownership so the current user can actually use it!

sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
changeOwner (argv [0], fName) ;

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
changeOwner (argv [0], fName) ;

}


/*
* doEdge:
* gpio edge pin mode
* Easy access to changing the edge trigger on a GPIO pin
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doEdge (int argc, char *argv [])
{
FILE *fd ;
int pin ;
char *mode ;
char fName [128] ;
uid_t uid ;
gid_t gid ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;

mode = argv [3] ;

// Export the pin and set direction to input

if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
exit (1) ;
}

fprintf (fd, "%d\n", pin) ;
fclose (fd) ;

sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
if ((fd = fopen (fName, "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
exit (1) ;
}

fprintf (fd, "in\n") ;
fclose (fd) ;

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
if ((fd = fopen (fName, "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
exit (1) ;
}

/**/ if (strcasecmp (mode, "none") == 0)
fprintf (fd, "none\n") ;
else if (strcasecmp (mode, "rising") == 0)
fprintf (fd, "rising\n") ;
else if (strcasecmp (mode, "falling") == 0)
fprintf (fd, "falling\n") ;
else if (strcasecmp (mode, "both") == 0)
fprintf (fd, "both\n") ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
exit (1) ;
}

// Change ownership so the current user can actually use it!

uid = getuid () ;
gid = getgid () ;

sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
if (chown (fName, uid, gid) != 0)
{
fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ;
exit (1) ;
}

// Also change ownership of the edge file

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
if (chown (fName, uid, gid) != 0)
{
fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ;
exit (1) ;
}

fclose (fd) ;
}


/*
* doUnexport:
* gpio unexport pin
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doUnexport (int argc, char *argv [])
{
FILE *fd ;
int pin ;

if (argc != 3)
{
fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;

if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
exit (1) ;
}

fprintf (fd, "%d\n", pin) ;
fclose (fd) ;
}


/*
* doUnexportAll:
* gpio unexportall
* Un-Export all the GPIO pins.
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doUnexportall (int argc, char *argv [])
{
FILE *fd ;
int pin ;

for (pin = 0 ; pin < 63 ; ++pin)
{
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
exit (1) ;
}
fprintf (fd, "%d\n", pin) ;
fclose (fd) ;
}
}


/*
* doMode:
* gpio mode pin mode ...
*********************************************************************************
*/

void doMode (int argc, char *argv [])
{
int pin ;
char *mode ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;

if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
return ;

mode = argv [3] ;

/**/ if (strcasecmp (mode, "in") == 0)
pinMode (pin, INPUT) ;
else if (strcasecmp (mode, "out") == 0)
pinMode (pin, OUTPUT) ;
else if (strcasecmp (mode, "pwm") == 0)
pinMode (pin, PWM_OUTPUT) ;
else if (strcasecmp (mode, "up") == 0)
pullUpDnControl (pin, PUD_UP) ;
else if (strcasecmp (mode, "down") == 0)
pullUpDnControl (pin, PUD_DOWN) ;
else if (strcasecmp (mode, "tri") == 0)
pullUpDnControl (pin, PUD_OFF) ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ;
exit (1) ;
}
}


/*
* doPadDrive:
* gpio drive group value
*********************************************************************************
*/

void doPadDrive (int argc, char *argv [])
{
int group, val ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
exit (1) ;
}

group = atoi (argv [2]) ;
val = atoi (argv [3]) ;

if ((group < 0) || (group > 2))
{
fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
exit (1) ;
}

if ((val < 0) || (val > 7))
{
fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
exit (1) ;
}

setPadDrive (group, val) ;
}


/*
* doWrite:
* gpio write pin value
*********************************************************************************
*/

void doWrite (int argc, char *argv [])
{
int pin, val ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;

if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
return ;

val = atoi (argv [3]) ;

/**/ if (val == 0)
digitalWrite (pin, LOW) ;
else
digitalWrite (pin, HIGH) ;
}


/*
* doRead:
* Read a pin and return the value
*********************************************************************************
*/

void doRead (int argc, char *argv [])
{
int pin, val ;

if (argc != 3)
{
fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;

if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
{
printf ("0\n") ;
return ;
}

val = digitalRead (pin) ;

printf ("%s\n", val == 0 ? "0" : "1") ;
}


/*
* doPwm:
* Output a PWM value on a pin
*********************************************************************************
*/

void doPwm (int argc, char *argv [])
{
int pin, val ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;

if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
return ;

val = atoi (argv [3]) ;

pwmWrite (pin, val) ;
}


/*
* main:
* Start here
*********************************************************************************
*/

int main (int argc, char *argv [])
{
int i ;

if (argc == 1)
{
fprintf (stderr, "%s: %s\n", argv [0], usage) ;
return 1 ;
}

if (strcasecmp (argv [1], "-v") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
return 0 ;
}

if (strcasecmp (argv [1], "-warranty") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("\n") ;
printf (" This program is free software; you can redistribute it and/or modify\n") ;
printf (" it under the terms of the GNU Leser General Public License as published\n") ;
printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
printf (" (at your option) any later version.\n") ;
printf ("\n") ;
printf (" This program is distributed in the hope that it will be useful,\n") ;
printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
printf (" GNU Lesser General Public License for more details.\n") ;
printf ("\n") ;
printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
printf ("\n") ;
return 0 ;
}

if (geteuid () != 0)
{
fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
return 1 ;
}

// Initial test for /sys/class/gpio operations:

/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports () ; return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }

// Check for -g argument

if (strcasecmp (argv [1], "-g") == 0)
{
if (wiringPiSetupGpio () == -1)
{
fprintf (stderr, "%s: Unable to initialise GPIO in GPIO mode.\n", argv [0]) ;
exit (1) ;
}

for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
wpMode = WPI_MODE_GPIO ;
}

// Check for -p argument for PiFace

else if (strcasecmp (argv [1], "-p") == 0)
{
if (wiringPiSetupPiFaceForGpioProg () == -1)
{
fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
exit (1) ;
}

for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
wpMode = WPI_MODE_PIFACE ;
}

// Default to wiringPi mode

else
{
if (wiringPiSetup () == -1)
{
fprintf (stderr, "%s: Unable to initialise GPIO in wiringPi mode\n", argv [0]) ;
exit (1) ;
}
wpMode = WPI_MODE_PINS ;
}

// Check for wiring commands

/**/ if (strcasecmp (argv [1], "write" ) == 0)
doWrite (argc, argv) ;
else if (strcasecmp (argv [1], "read" ) == 0)
doRead (argc, argv) ;
else if (strcasecmp (argv [1], "mode" ) == 0)
doMode (argc, argv) ;
else if (strcasecmp (argv [1], "pwm" ) == 0)
doPwm (argc, argv) ;
else if (strcasecmp (argv [1], "drive" ) == 0)
doPadDrive (argc, argv) ;
else
{
fprintf (stderr, "%s: Unknown command: %s. (read/write/pwm/mode/drive expected)\n", argv [0], argv [1]) ;
exit (1) ;
}
return 0 ;
}

+ 23
- 0
gpio/test.sh View File

@@ -0,0 +1,23 @@
#!/bin/bash

# Simple test - assumes LEDs on Pins 0-7.

for i in `seq 0 7`;
do
gpio mode $i out
done

while true;
do
for i in `seq 0 7`;
do
gpio write $i 1
sleep 0.1
done

for i in `seq 0 7`;
do
gpio write $i 0
sleep 0.1
done
done

BIN
wiringPi/.wiringPiFace.c.swp View File


+ 165
- 0
wiringPi/COPYING.LESSER View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007

Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.


This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.

0. Additional Definitions.

As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.

"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.

An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.

A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".

The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.

The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.

1. Exception to Section 3 of the GNU GPL.

You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.

2. Conveying Modified Versions.

If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:

a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or

b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.

3. Object Code Incorporating Material from Library Header Files.

The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:

a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the object code with a copy of the GNU GPL and this license
document.

4. Combined Works.

You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:

a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.

b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.

c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.

d) Do one of the following:

0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.

1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.

e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)

5. Combined Libraries.

You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:

a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.

b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.

6. Revised Versions of the GNU Lesser General Public License.

The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.

If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

+ 101
- 0
wiringPi/Makefile View File

@@ -0,0 +1,101 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
#
# Copyright (c) 2012 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# https://projects.drogon.net/raspberry-pi/wiringpi/
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################


TARGET=libwiringPi.a

#DEBUG = -g -O0
DEBUG = -O3
CC = gcc
INCLUDE = -I.
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe

LIBS =

# Should not alter anything below this line
###############################################################################

SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \
gertboard.c \
piNes.c \
lcd.c piHiPri.c piThread.c

OBJ = wiringPi.o wiringPiFace.o wiringSerial.o wiringShift.o \
gertboard.o \
piNes.o \
lcd.o piHiPri.o piThread.o

all: $(TARGET)

$(TARGET): $(OBJ)
@echo [AR] $(OBJ)
@ar rcs $(TARGET) $(OBJ)
@ranlib $(TARGET)
@size $(TARGET)

.c.o:
@echo [CC] $<
@$(CC) -c $(CFLAGS) $< -o $@

clean:
rm -f $(OBJ) $(TARGET) *~ core tags Makefile.bak

tags: $(SRC)
@echo [ctags]
@ctags $(SRC)

depend:
makedepend -Y $(SRC)

install: $(TARGET)
@echo [install]
install -m 0755 -d /usr/local/lib
install -m 0755 -d /usr/local/include
install -m 0644 wiringPi.h /usr/local/include
install -m 0644 wiringSerial.h /usr/local/include
install -m 0644 wiringShift.h /usr/local/include
install -m 0644 gertboard.h /usr/local/include
install -m 0644 piNes.h /usr/local/include
install -m 0644 lcd.h /usr/local/include
install -m 0644 libwiringPi.a /usr/local/lib

uninstall:
@echo [uninstall]
rm -f /usr/local/include/lcd.h
rm -f /usr/local/include/wiringShift.h
rm -f /usr/local/include/wiringPi.h
rm -f /usr/local/lib/libwiringPi.a



# DO NOT DELETE

wiringPi.o: wiringPi.h
wiringPiFace.o: wiringPi.h
wiringSerial.o: wiringSerial.h
wiringShift.o: wiringPi.h wiringShift.h
gertboard.o: gertboard.h
piNes.o: wiringPi.h piNes.h
lcd.o: wiringPi.h lcd.h
piHiPri.o: wiringPi.h
piThread.o: wiringPi.h

+ 9
- 0
wiringPi/README View File

@@ -0,0 +1,9 @@

WiringPi: An implementation of most of the Arduino Wiring
functions for the Raspberry Pi

-- And a lot lot more!

Full details at:
https://projects.drogon.net/raspberry-pi/wiringpi/


+ 184
- 0
wiringPi/gertboard.c View File

@@ -0,0 +1,184 @@
/*
* gertboard.c:
* Access routines for the SPI devices on the Gertboard
* Copyright (c) 2012 Gordon Henderson
*
* The Gertboard has:
*
* An MCP3002 dual-channel A to D convertor connected
* to the SPI bus, selected by chip-select A, and:
*
* An MCP4802 dual-channel D to A convertor connected
* to the SPI bus, selected via chip-select B.
*
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/


#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

#include "gertboard.h"


// The SPI bus parameters
// Variables as they need to be passed as pointers later on

static char *spiA2D = "/dev/spidev0.0" ;
static char *spiD2A = "/dev/spidev0.1" ;
static uint8_t spiMode = 0 ;
static uint8_t spiBPW = 8 ;
static uint32_t spiSpeed = 100000 ; // 1MHz
static uint16_t spiDelay = 0;

// Locals here to keep track of everything

static int spiFdA2D ;
static int spiFdD2A ;


/*
* gertboardAnalogWrite:
* Write an 8-bit data value to the MCP4802 Analog to digital
* convertor on the Gertboard.
*********************************************************************************
*/

void gertboardAnalogWrite (int chan, int value)
{
uint8_t spiBufTx [2] ;
uint8_t spiBufRx [2] ;
struct spi_ioc_transfer spi ;

uint8_t chanBits, dataBits ;

if (chan == 0)
chanBits = 0x30 ;
else
chanBits = 0xB0 ;

chanBits |= ((value >> 4) & 0x0F) ;
dataBits = ((value << 4) & 0xF0) ;

spiBufTx [0] = chanBits ;
spiBufTx [1] = dataBits ;

spi.tx_buf = (unsigned long)spiBufTx ;
spi.rx_buf = (unsigned long)spiBufRx ;
spi.len = 2 ;
spi.delay_usecs = spiDelay ;
spi.speed_hz = spiSpeed ;
spi.bits_per_word = spiBPW ;

ioctl (spiFdD2A, SPI_IOC_MESSAGE(1), &spi) ;
}


/*
* gertboardAnalogRead:
* Return the analog value of the given channel (0/1).
* The A/D is a 10-bit device
*********************************************************************************
*/

int gertboardAnalogRead (int chan)
{
uint8_t spiBufTx [4] ;
uint8_t spiBufRx [4] ;
struct spi_ioc_transfer spi ;

uint8_t chanBits ;

if (chan == 0)
chanBits = 0b0110100 ;
else
chanBits = 0b0111100 ;

spiBufTx [0] = chanBits ;
spiBufTx [1] = 0 ;

spi.tx_buf = (unsigned long)spiBufTx ;
spi.rx_buf = (unsigned long)spiBufRx ;
spi.len = 4 ;
spi.delay_usecs = spiDelay ;
spi.speed_hz = spiSpeed ;
spi.bits_per_word = spiBPW ;

ioctl (spiFdA2D, SPI_IOC_MESSAGE(1), &spi) ;

return spiBufRx [0] << 8 | spiBufRx [1] ;
}


/*
* setParams:
* Output the SPI bus parameters to the given device
*********************************************************************************
*/

static int setParams (int fd)
{
if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0)
return -1 ;

if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0)
return -1 ;

if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
return -1 ;

if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0)
return -1 ;

if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0)
return -1 ;

if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0)
return -1 ;

return 0 ;
}


/*
* gertboardSPISetup:
* Initialise the SPI bus, etc.
*********************************************************************************
*/

int gertboardSPISetup (void)
{
if ((spiFdA2D = open (spiA2D, O_RDWR)) < 0)
return -1 ;

if (setParams (spiFdA2D) != 0)
return -1 ;

if ((spiFdD2A = open (spiD2A, O_RDWR)) < 0)
return -1 ;

if (setParams (spiFdD2A) != 0)
return -1 ;

return 0 ;
}

+ 39
- 0
wiringPi/gertboard.h View File

@@ -0,0 +1,39 @@
/*
* gertboard.h:
* Access routines for the SPI devices on the Gertboard
* Copyright (c) 2012 Gordon Henderson
*
* The Gertboard has an MCP4802 dual-channel D to A convertor
* connected to the SPI bus, selected via chip-select B.
*
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern void gertboardAnalogWrite (int chan, int value) ;
extern int gertboardAnalogRead (int chan) ;
extern int gertboardSPISetup (void) ;

#ifdef __cplusplus
}
#endif

+ 365
- 0
wiringPi/lcd.c View File

@@ -0,0 +1,365 @@
/*
* lcd.c:
* Text-based LCD driver.
* This is designed to drive the parallel interface LCD drivers
* based in the Hitachi HD44780U controller and compatables.
*
* Copyright (c) 2012 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>

#include "wiringPi.h"
#include "lcd.h"

// Commands

#define LCD_CLEAR 0x01
#define LCD_HOME 0x02
#define LCD_ENTRY 0x04
#define LCD_ON_OFF 0x08
#define LCD_CDSHIFT 0x10
#define LCD_FUNC 0x20
#define LCD_CGRAM 0x40
#define LCD_DGRAM 0x80

#define LCD_ENTRY_SH 0x01
#define LCD_ENTRY_ID 0x02

#define LCD_ON_OFF_B 0x01
#define LCD_ON_OFF_C 0x02
#define LCD_ON_OFF_D 0x04

#define LCD_FUNC_F 0x04
#define LCD_FUNC_N 0x08
#define LCD_FUNC_DL 0x10

#define LCD_CDSHIFT_RL 0x04

struct lcdDataStruct
{
uint8_t bits, rows, cols ;
uint8_t rsPin, strbPin ;
uint8_t dataPins [8] ;
} ;

struct lcdDataStruct *lcds [MAX_LCDS] ;


/*
* strobe:
* Toggle the strobe (Really the "E") pin to the device.
* According to the docs, data is latched on the falling edge.
*********************************************************************************
*/

static void strobe (struct lcdDataStruct *lcd)
{
digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (1) ;
digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ;
}


/*
* sentDataCmd:
* Send an data or command byte to the display.
*********************************************************************************
*/

static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
{
uint8_t i, d4 ;

if (lcd->bits == 4)
{
d4 = (data >> 4) & 0x0F;
for (i = 0 ; i < 4 ; ++i)
{
digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
d4 >>= 1 ;
}
strobe (lcd) ;

d4 = data & 0x0F ;
for (i = 0 ; i < 4 ; ++i)
{
digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
d4 >>= 1 ;
}
}
else
{
for (i = 0 ; i < 8 ; ++i)
{
digitalWrite (lcd->dataPins [i], (data & 1)) ;
data >>= 1 ;
}
}
strobe (lcd) ;
}


/*
* putCommand:
* Send a command byte to the display
*********************************************************************************
*/

static void putCommand (struct lcdDataStruct *lcd, uint8_t command)
{
digitalWrite (lcd->rsPin, 0) ;
sendDataCmd (lcd, command) ;
}

static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
{
uint8_t i ;

digitalWrite (lcd->rsPin, 0) ;

for (i = 0 ; i < 4 ; ++i)
{
digitalWrite (lcd->dataPins [i], (command & 1)) ;
command >>= 1 ;
}
strobe (lcd) ;
}


/*
*********************************************************************************
* User Code below here
*********************************************************************************
*/

/*
* lcdHome: lcdClear:
* Home the cursor or clear the screen.
*********************************************************************************
*/

void lcdHome (int fd)
{
struct lcdDataStruct *lcd = lcds [fd] ;
putCommand (lcd, LCD_HOME) ;
}

void lcdClear (int fd)
{
struct lcdDataStruct *lcd = lcds [fd] ;
putCommand (lcd, LCD_CLEAR) ;
}


/*
* lcdPosition:
* Update the position of the cursor on the display
*********************************************************************************
*/


void lcdPosition (int fd, int x, int y)
{
static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ;
struct lcdDataStruct *lcd = lcds [fd] ;

putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ;
}


/*
* lcdPutchar:
* Send a data byte to be displayed on the display
*********************************************************************************
*/

void lcdPutchar (int fd, uint8_t data)
{
struct lcdDataStruct *lcd = lcds [fd] ;

digitalWrite (lcd->rsPin, 1) ;
sendDataCmd (lcd, data) ;
}


/*
* lcdPuts:
* Send a string to be displayed on the display
*********************************************************************************
*/

void lcdPuts (int fd, char *string)
{
while (*string)
lcdPutchar (fd, *string++) ;
}


/*
* lcdPrintf:
* Printf to an LCD display
*********************************************************************************
*/

void lcdPrintf (int fd, char *message, ...)
{
va_list argp ;
char buffer [1024] ;

va_start (argp, message) ;
vsnprintf (buffer, 1023, message, argp) ;
va_end (argp) ;

lcdPuts (fd, buffer) ;
}


/*
* lcdInit:
* Take a lot of parameters and initialise the LCD, and return a handle to
* that LCD, or -1 if any error.
*********************************************************************************
*/

int lcdInit (int rows, int cols, int bits, int rs, int strb,
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7)
{
static int initialised = 0 ;

uint8_t func ;
int i ;
int lcdFd = -1 ;
struct lcdDataStruct *lcd ;

if (initialised == 0)
{
initialised = 1 ;
for (i = 0 ; i < MAX_LCDS ; ++i)
lcds [i] = NULL ;
}

// Simple sanity checks

if (! ((bits == 4) || (bits == 8)))
return -1 ;

if ((rows < 0) || (rows > 20))
return -1 ;

if ((cols < 0) || (cols > 20))
return -1 ;

// Create a new LCD:

for (i = 0 ; i < MAX_LCDS ; ++i)
{
if (lcds [i] == NULL)
{
lcdFd = i ;
break ;
}
}

if (lcdFd == -1)
return -1 ;

lcd = malloc (sizeof (struct lcdDataStruct)) ;
if (lcd == NULL)
return -1 ;

lcd->rsPin = rs ;
lcd->strbPin = strb ;
lcd->bits = 8 ; // For now - we'll set it properly later.
lcd->rows = rows ;
lcd->cols = cols ;

lcd->dataPins [0] = d0 ;
lcd->dataPins [1] = d1 ;
lcd->dataPins [2] = d2 ;
lcd->dataPins [3] = d3 ;
lcd->dataPins [4] = d4 ;
lcd->dataPins [5] = d5 ;
lcd->dataPins [6] = d6 ;
lcd->dataPins [7] = d7 ;

lcds [lcdFd] = lcd ;

digitalWrite (lcd->rsPin, 0) ; pinMode (lcd->rsPin, OUTPUT) ;
digitalWrite (lcd->strbPin, 0) ; pinMode (lcd->strbPin, OUTPUT) ;

for (i = 0 ; i < bits ; ++i)
{
digitalWrite (lcd->dataPins [i], 0) ;
pinMode (lcd->dataPins [i], OUTPUT) ;
}
delay (35) ; // mS


// 4-bit mode?
// OK. This is a PIG and it's not at all obvious from the documentation I had,
// so I guess some others have worked through either with better documentation
// or more trial and error... Anyway here goes:
//
// It seems that the controller needs to see the FUNC command at least 3 times
// consecutively - in 8-bit mode. If you're only using 8-bit mode, then it appears
// that you can get away with one func-set, however I'd not rely on it...
//
// So to set 4-bit mode, you need to send the commands one nibble at a time,
// the same three times, but send the command to set it into 8-bit mode those
// three times, then send a final 4th command to set it into 4-bit mode, and only
// then can you flip the switch for the rest of the library to work in 4-bit
// mode which sends the commands as 2 x 4-bit values.

if (bits == 4)
{
func = LCD_FUNC | LCD_FUNC_DL ; // Set 8-bit mode 3 times
put4Command (lcd, func >> 4) ; delay (35) ;
put4Command (lcd, func >> 4) ; delay (35) ;
put4Command (lcd, func >> 4) ; delay (35) ;
func = LCD_FUNC ; // 4th set: 4-bit mode
put4Command (lcd, func >> 4) ; delay (35) ;
lcd->bits = 4 ;
}
else
{
func = LCD_FUNC | LCD_FUNC_DL ;
putCommand (lcd, func ) ; delay (35) ;
putCommand (lcd, func ) ; delay (35) ;
putCommand (lcd, func ) ; delay (35) ;
}

if (lcd->rows > 1)
{
func |= LCD_FUNC_N ;
putCommand (lcd, func) ; delay (35) ;
}

// Rest of the initialisation sequence

putCommand (lcd, LCD_ON_OFF | LCD_ON_OFF_D) ; delay (2) ;
putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; delay (2) ;
putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; delay (2) ;
putCommand (lcd, LCD_CLEAR) ; delay (5) ;

return lcdFd ;
}

+ 37
- 0
wiringPi/lcd.h View File

@@ -0,0 +1,37 @@
/*
* lcd.h:
* Text-based LCD driver.
* This is designed to drive the parallel interface LCD drivers
* based in the Hitachi HD44780U controller and compatables.
*
* Copyright (c) 2012 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#define MAX_LCDS 8

extern void lcdHome (int fd) ;
extern void lcdClear (int fd) ;
extern void lcdPosition (int fd, int x, int y) ;
extern void lcdPutchar (int fd, uint8_t data) ;
extern void lcdPuts (int fd, char *string) ;
extern void lcdPrintf (int fd, char *message, ...) ;

extern int lcdInit (int rows, int cols, int bits, int rs, int strb,
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;

+ 50
- 0
wiringPi/piHiPri.c View File

@@ -0,0 +1,50 @@
/*
* piHiPri:
* Simple way to get your program running at high priority
* with realtime schedulling.
*
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <sched.h>
#include <string.h>

#include "wiringPi.h"


/*
* piHiPri:
* Attempt to set a high priority schedulling for the running program
*********************************************************************************
*/

int piHiPri (int pri)
{
struct sched_param sched ;

memset (&sched, 0, sizeof(sched)) ;

if (pri > sched_get_priority_max (SCHED_RR))
pri = sched_get_priority_max (SCHED_RR) ;

sched.sched_priority = pri ;
return sched_setscheduler (0, SCHED_RR, &sched) ;
}

+ 115
- 0
wiringPi/piNes.c View File

@@ -0,0 +1,115 @@
/*
* piNes.c:
* Driver for the NES Joystick controller on the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <wiringPi.h>

#include "piNes.h"

#define MAX_NES_JOYSTICKS 8

#define NES_RIGHT 0x01
#define NES_LEFT 0x02
#define NES_DOWN 0x04
#define NES_UP 0x08
#define NES_START 0x10
#define NES_SELECT 0x20
#define NES_B 0x40
#define NES_A 0x80


// Data to store the pins for each controller

struct nesPinsStruct
{
unsigned int cPin, dPin, lPin ;
} ;

static struct nesPinsStruct nesPins [MAX_NES_JOYSTICKS] ;

static int joysticks = 0 ;


/*
* setupNesJoystick:
* Create a new NES joystick interface, program the pins, etc.
*********************************************************************************
*/

int setupNesJoystick (int dPin, int cPin, int lPin)
{
if (joysticks == MAX_NES_JOYSTICKS)
return -1 ;

nesPins [joysticks].dPin = dPin ;
nesPins [joysticks].cPin = cPin ;
nesPins [joysticks].lPin = lPin ;

digitalWrite (lPin, LOW) ;
digitalWrite (cPin, LOW) ;

pinMode (lPin, OUTPUT) ;
pinMode (cPin, OUTPUT) ;
pinMode (dPin, INPUT) ;

return joysticks++ ;
}


/*
* readNesJoystick:
* Do a single scan of the NES Joystick.
*********************************************************************************
*/

unsigned int readNesJoystick (int joystick)
{
unsigned int value = 0 ;
int i ;

struct nesPinsStruct *pins = &nesPins [joystick] ;
// Toggle Latch - which presents the first bit

digitalWrite (pins->lPin, HIGH) ;
delayMicroseconds (1) ;
digitalWrite (pins->lPin, LOW) ;
delayMicroseconds (1) ;

// Read first bit

value = digitalRead (pins->dPin) ;

// Now get the next 7 bits with the clock

for (i = 0 ; i < 7 ; ++i)
{
digitalWrite (pins->cPin, HIGH) ;
delayMicroseconds (1) ;
digitalWrite (pins->cPin, LOW) ;
delayMicroseconds (1) ;
value = (value << 1) | digitalRead (pins->dPin) ;
}

return ~value ;
}

+ 37
- 0
wiringPi/piNes.h View File

@@ -0,0 +1,37 @@
/*
* piNes.h:
* Driver for the NES Joystick controller on the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#define MAX_NES_JOYSTICKS 8

#define NES_RIGHT 0x01
#define NES_LEFT 0x02
#define NES_DOWN 0x04
#define NES_UP 0x08
#define NES_START 0x10
#define NES_SELECT 0x20
#define NES_B 0x40
#define NES_A 0x80

extern int setupNesJoystick (int dPin, int cPin, int lPin) ;
extern unsigned int readNesJoystick (int joystick) ;

+ 63
- 0
wiringPi/piThread.c View File

@@ -0,0 +1,63 @@
/*
* piThread.c:
* Provide a simplified interface to pthreads
*
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <pthread.h>
#include "wiringPi.h"

static pthread_mutex_t piMutexes [4] ;



/*
* piThreadCreate:
* Create and start a thread
*********************************************************************************
*/

int piThreadCreate (void *(*fn)(void *))
{
pthread_t myThread ;

return pthread_create (&myThread, NULL, fn, NULL) ;
}

/*
* piLock: piUnlock:
* Activate/Deactivate a mutex.
* We're keeping things simple here and only tracking 4 mutexes which
* is more than enough for out entry-level pthread programming
*********************************************************************************
*/

void piLock (int key)
{
pthread_mutex_lock (&piMutexes [key]) ;
}

void piUnlock (int key)
{
pthread_mutex_unlock (&piMutexes [key]) ;
}


+ 981
- 0
wiringPi/wiringPi.c View File

@@ -0,0 +1,981 @@
/*
* wiringPi:
* Arduino compatable (ish) Wiring library for the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
*
* Thanks to code samples from Gert Jan van Loo and the
* BCM2835 ARM Peripherals manual, however it's missing
* the clock section /grr/mutter/
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

// Revisions:
// 19 Jul 2012:
// Moved to the LGPL
// Added an abstraction layer to the main routines to save a tiny
// bit of run-time and make the clode a little cleaner (if a little
// larger)
// Added waitForInterrupt code
// Added piHiPri code
//
// 9 Jul 2012:
// Added in support to use the /sys/class/gpio interface.
// 2 Jul 2012:
// Fixed a few more bugs to do with range-checking when in GPIO mode.
// 11 Jun 2012:
// Fixed some typos.
// Added c++ support for the .h file
// Added a new function to allow for using my "pin" numbers, or native
// GPIO pin numbers.
// Removed my busy-loop delay and replaced it with a call to delayMicroseconds
//
// 02 May 2012:
// Added in the 2 UART pins
// Change maxPins to numPins to more accurately reflect purpose

// Pad drive current fiddling

#undef DEBUG_PADS

#include <stdio.h>
#include <stdint.h>
#include <poll.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "wiringPi.h"

// Function stubs

void (*pinMode) (int pin, int mode) ;
void (*pullUpDnControl) (int pin, int pud) ;
void (*digitalWrite) (int pin, int value) ;
void (*pwmWrite) (int pin, int value) ;
void (*setPadDrive) (int group, int value) ;
int (*digitalRead) (int pin) ;
int (*waitForInterrupt) (int pin, int mS) ;
void (*delayMicroseconds) (unsigned int howLong) ;


#ifndef TRUE
#define TRUE (1==1)
#define FALSE (1==2)
#endif

// BCM Magic

#define BCM_PASSWORD 0x5A000000


// Port function select bits

#define FSEL_INPT 0b000
#define FSEL_OUTP 0b001
#define FSEL_ALT0 0b100
#define FSEL_ALT0 0b100
#define FSEL_ALT1 0b101
#define FSEL_ALT2 0b110
#define FSEL_ALT3 0b111
#define FSEL_ALT4 0b011
#define FSEL_ALT5 0b010

// Access from ARM Running Linux
// Take from Gert/Doms code. Some of this is not in the manual
// that I can find )-:

#define BCM2708_PERI_BASE 0x20000000
#define GPIO_PADS (BCM2708_PERI_BASE + 0x100000)
#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000)
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
#define GPIO_TIMER (BCM2708_PERI_BASE + 0x00B000)
#define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000)

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

// PWM

#define PWM_CONTROL 0
#define PWM_STATUS 1
#define PWM0_RANGE 4
#define PWM0_DATA 5
#define PWM1_RANGE 8
#define PWM1_DATA 9

#define PWMCLK_CNTL 40
#define PWMCLK_DIV 41

#define PWM1_MS_MODE 0x8000 // Run in MS mode
#define PWM1_USEFIFO 0x2000 // Data from FIFO
#define PWM1_REVPOLAR 0x1000 // Reverse polarity
#define PWM1_OFFSTATE 0x0800 // Ouput Off state
#define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty
#define PWM1_SERIAL 0x0200 // Run in serial mode
#define PWM1_ENABLE 0x0100 // Channel Enable

#define PWM0_MS_MODE 0x0080 // Run in MS mode
#define PWM0_USEFIFO 0x0020 // Data from FIFO
#define PWM0_REVPOLAR 0x0010 // Reverse polarity
#define PWM0_OFFSTATE 0x0008 // Ouput Off state
#define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty
#define PWM0_SERIAL 0x0002 // Run in serial mode
#define PWM0_ENABLE 0x0001 // Channel Enable

// Timer

#define TIMER_LOAD (0x400 >> 2)
#define TIMER_VALUE (0x404 >> 2)
#define TIMER_CONTROL (0x408 >> 2)
#define TIMER_IRQ_CLR (0x40C >> 2)
#define TIMER_IRQ_RAW (0x410 >> 2)
#define TIMER_IRQ_MASK (0x414 >> 2)
#define TIMER_RELOAD (0x418 >> 2)
#define TIMER_PRE_DIV (0x41C >> 2)
#define TIMER_COUNTER (0x420 >> 2)

// Locals to hold pointers to the hardware

static volatile uint32_t *gpio ;
static volatile uint32_t *pwm ;
static volatile uint32_t *clk ;
static volatile uint32_t *pads ;
static volatile uint32_t *timer ;

static volatile uint32_t *timerIrqRaw ;

// The BCM2835 has 54 GPIO pins.
// BCM2835 data sheet, Page 90 onwards.
// There are 6 control registers, each control the functions of a block
// of 10 pins.
// Each control register has 10 sets of 3 bits per GPIO pin:
//
// 000 = GPIO Pin X is an input
// 001 = GPIO Pin X is an output
// 100 = GPIO Pin X takes alternate function 0
// 101 = GPIO Pin X takes alternate function 1
// 110 = GPIO Pin X takes alternate function 2
// 111 = GPIO Pin X takes alternate function 3
// 011 = GPIO Pin X takes alternate function 4
// 010 = GPIO Pin X takes alternate function 5
//
// So the 3 bits for port X are:
// X / 10 + ((X % 10) * 3)

// sysFds:
// Map a file descriptor from the /sys/class/gpio/gpioX/value

static int sysFds [64] ;

// Doing it the Arduino way with lookup tables...
// Yes, it's probably more innefficient than all the bit-twidling, but it
// does tend to make it all a bit clearer. At least to me!

// pinToGpio:
// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin

static int pinToGpio [64] =
{
17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7
0, 1, // I2C - SDA0, SCL0
8, 7, // SPI - CE1, CE0
10, 9, 11, // SPI - MOSI, MISO, SCLK
14, 15, // UART - Tx, Rx

// Padding:

-1, -1, -1,-1,-1,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
} ;

// gpioToGPFSEL:
// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)

static uint8_t gpioToGPFSEL [] =
{
0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,
} ;

// gpioToShift
// Define the shift up for the 3 bits per pin in each GPFSEL port

static uint8_t gpioToShift [] =
{
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
} ;

// gpioToGPSET:
// (Word) offset to the GPIO Set registers for each GPIO pin

static uint8_t gpioToGPSET [] =
{
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,
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,
} ;

// gpioToGPCLR:
// (Word) offset to the GPIO Clear registers for each GPIO pin

static uint8_t gpioToGPCLR [] =
{
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,
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,
} ;

// gpioToGPLEV:
// (Word) offset to the GPIO Input level registers for each GPIO pin

static uint8_t gpioToGPLEV [] =
{
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,
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,
} ;

#ifdef notYetReady
// gpioToEDS
// (Word) offset to the Event Detect Status

static uint8_t gpioToEDS [] =
{
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,
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,
} ;

// gpioToREN
// (Word) offset to the Rising edgde ENable register

static uint8_t gpioToREN [] =
{
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,
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,
} ;

// gpioToFEN
// (Word) offset to the Falling edgde ENable register

static uint8_t gpioToFEN [] =
{
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,
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,
} ;
#endif

// gpioToPUDCLK
// (Word) offset to the Pull Up Down Clock regsiter

#define GPPUD 37

static uint8_t gpioToPUDCLK [] =
{
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,
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,
} ;

// gpioToPwmALT
// the ALT value to put a GPIO pin into PWM mode

static uint8_t gpioToPwmALT [] =
{
0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15
0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23
0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47
0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
} ;

static uint8_t gpioToPwmPort [] =
{
0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15
0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23
0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47
0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63

} ;


// Time for easy calculations

static unsigned long long epoch ;

//////////////////////////////////////////////////////////////////////////////////


/*
* pinMode:
* Sets the mode of a pin to be input, output or PWM output
*********************************************************************************
*/

void pinModeGpio (int pin, int mode)
{
static int pwmRunning = FALSE ;
int fSel, shift, alt ;

pin &= 63 ;

fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;

/**/ if (mode == INPUT)
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
else if (mode == OUTPUT)
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
else if (mode == PWM_OUTPUT)
{
if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
return ;

// Set pin to PWM mode

*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;

// We didn't initialise the PWM hardware at setup time - because it's possible that
// something else is using the PWM - e.g. the Audio systems! So if we use PWM
// here, then we're assuming that nothing else is, otherwise things are going
// to sound a bit funny...

if (!pwmRunning)
{

// Gert/Doms Values
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz)
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Source=osc and enable
digitalWrite (pin, LOW) ;
*(pwm + PWM_CONTROL) = 0 ; // Disable PWM
delayMicroseconds (10) ;
*(pwm + PWM0_RANGE) = 0x400 ;
delayMicroseconds (10) ;
*(pwm + PWM1_RANGE) = 0x400 ;
delayMicroseconds (10) ;

// Enable PWMs

*(pwm + PWM0_DATA) = 512 ;
*(pwm + PWM1_DATA) = 512 ;

*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;

pwmRunning = TRUE ;
}

}

// When we change mode of any pin, we remove the pull up/downs

pullUpDnControl (pin, PUD_OFF) ;
}

void pinModeWPi (int pin, int mode)
{
pinModeGpio (pinToGpio [pin & 63], mode) ;
}

void pinModeSys (int pin, int mode)
{
return ;
}


#ifdef notYetReady
/*
* pinED01:
* pinED10:
* Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
* Pin must already be in input mode with appropriate pull up/downs set.
*********************************************************************************
*/

void pinEnableED01Pi (int pin)
{
pin = pinToGpio [pin & 63] ;
}
#endif



/*
* digitalWrite:
* Set an output bit
*********************************************************************************
*/

void digitalWriteWPi (int pin, int value)
{
pin = pinToGpio [pin & 63] ;

if (value == LOW)
*(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
else
*(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
}

void digitalWriteGpio (int pin, int value)
{
pin &= 63 ;

if (value == LOW)
*(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
else
*(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
}

void digitalWriteSys (int pin, int value)
{
pin &= 63 ;

if (sysFds [pin] != -1)
{
if (value == LOW)
write (sysFds [pin], "0\n", 2) ;
else
write (sysFds [pin], "1\n", 2) ;
}
}


/*
* pwnWrite:
* Set an output PWM value
*********************************************************************************
*/

void pwmWriteWPi (int pin, int value)
{
int port ;

pin = pinToGpio [pin & 63] ;
port = gpioToPwmPort [pin] ;

*(pwm + port) = value & 0x3FF ;
}

void pwmWriteGpio (int pin, int value)
{
int port ;

pin = pin & 63 ;
port = gpioToPwmPort [pin] ;

*(pwm + port) = value & 0x3FF ;
}

void pwmWriteSys (int pin, int value)
{
return ;
}


/*
* setPadDrive:
* Set the PAD driver value
*********************************************************************************
*/

void setPadDriveWPi (int group, int value)
{
uint32_t wrVal ;

if ((group < 0) || (group > 2))
return ;

wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
*(pads + group + 11) = wrVal ;

#ifdef DEBUG_PADS
printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
printf ("Read : %08X\n", *(pads + group + 11)) ;
#endif
}

void setPadDriveGpio (int group, int value)
{
setPadDriveWPi (group, value) ;
}

void setPadDriveSys (int group, int value)
{
return ;
}


/*
* digitalRead:
* Read the value of a given Pin, returning HIGH or LOW
*********************************************************************************
*/

int digitalReadWPi (int pin)
{
pin = pinToGpio [pin & 63] ;

if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
return HIGH ;
else
return LOW ;
}

int digitalReadGpio (int pin)
{
pin &= 63 ;

if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
return HIGH ;
else
return LOW ;
}

int digitalReadSys (int pin)
{
char c ;

pin &= 63 ;

if (sysFds [pin] == -1)
return 0 ;

lseek (sysFds [pin], 0L, SEEK_SET) ;
read (sysFds [pin], &c, 1) ;
return (c == '0') ? 0 : 1 ;
}


/*
* pullUpDownCtrl:
* Control the internal pull-up/down resistors on a GPIO pin
* The Arduino only has pull-ups and these are enabled by writing 1
* to a port when in input mode - this paradigm doesn't quite apply
* here though.
*********************************************************************************
*/

void pullUpDnControlWPi (int pin, int pud)
{
pin = pinToGpio [pin & 63] ;
pud &= 3 ;

*(gpio + GPPUD) = pud ; delayMicroseconds (10) ;
*(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (10) ;
*(gpio + GPPUD) = 0 ;
*(gpio + gpioToPUDCLK [pin]) = 0 ;
}

void pullUpDnControlGpio (int pin, int pud)
{
pin &= 63 ;
pud &= 3 ;

*(gpio + GPPUD) = pud ; delayMicroseconds (10) ;
*(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (10) ;
*(gpio + GPPUD) = 0 ;
*(gpio + gpioToPUDCLK [pin]) = 0 ;
}

void pullUpDnControlSys (int pin, int pud)
{
return ;
}


/*
* waitForInterrupt:
* Wait for Interrupt on a GPIO pin.
* This is actually done via the /sys/class/gpio interface regardless of
* the wiringPi access mode in-use. Maybe sometime it might get a better
* way for a bit more efficiency.
*********************************************************************************
*/

int waitForInterruptSys (int pin, int mS)
{
int fd, x ;
char buf [8] ;
struct pollfd polls ;

if ((fd = sysFds [pin & 63]) == -1)
return -2 ;

// Do a dummy read

x = read (fd, buf, 6) ;
if (x < 0)
return x ;

// And seek

lseek (fd, 0, SEEK_SET) ;

// Setup poll structure

polls.fd = fd ;
polls.events = POLLPRI ; // Urgent data!

// Wait for it ...

return poll (&polls, 1, mS) ;
}

int waitForInterruptWPi (int pin, int mS)
{
return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
}

int waitForInterruptGpio (int pin, int mS)
{
return waitForInterruptSys (pin, mS) ;
}




/*
* delay:
* Wait for some number of milli seconds
*********************************************************************************
*/

void delay (unsigned int howLong)
{
struct timespec sleeper, dummy ;

sleeper.tv_sec = (time_t)(howLong / 1000) ;
sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;

nanosleep (&sleeper, &dummy) ;
}

/*
* delayMicroseconds:
* This is somewhat intersting. It seems that on the Pi, a single call
* to nanosleep takes some 80 to 130 microseconds anyway, so while
* obeying the standards (may take longer), it's not always what we
* want!
*
* So what I'll do now is if the delay is less than 100uS we'll do it
* in a hard loop, watching a built-in counter on the ARM chip. This is
* somewhat sub-optimal in that it uses 100% CPU, something not an issue
* in a microcontroller, but under a multi-tasking, multi-user OS, it's
* wastefull, however we've no real choice )-:
*********************************************************************************
*/

void delayMicrosecondsSys (unsigned int howLong)
{
struct timespec sleeper, dummy ;

sleeper.tv_sec = 0 ;
sleeper.tv_nsec = (long)(howLong * 1000) ;

nanosleep (&sleeper, &dummy) ;
}

void delayMicrosecondsHard (unsigned int howLong)
{
*(timer + TIMER_LOAD) = howLong ;
*(timer + TIMER_IRQ_CLR) = 0 ;

while (*timerIrqRaw == 0)
;
}

void delayMicrosecondsWPi (unsigned int howLong)
{
struct timespec sleeper, dummy ;

/**/ if (howLong == 0)
return ;
else if (howLong < 100)
delayMicrosecondsHard (howLong) ;
else
{
sleeper.tv_sec = 0 ;
sleeper.tv_nsec = (long)(howLong * 1000) ;
nanosleep (&sleeper, &dummy) ;
}
}


/*
* millis:
* Return a number of milliseconds as an unsigned int.
*********************************************************************************
*/

unsigned int millis (void)
{
struct timeval tv ;
unsigned long long t1 ;

gettimeofday (&tv, NULL) ;

t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

return (uint32_t)(t1 - epoch) ;
}


/*
* wiringPiSetup:
* Must be called once at the start of your program execution.
*
* Default setup: Initialises the system into wiringPi Pin mode and uses the
* memory mapped hardware directly.
*********************************************************************************
*/

int wiringPiSetup (void)
{
int fd ;
uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
struct timeval tv ;

pinMode = pinModeWPi ;
pullUpDnControl = pullUpDnControlWPi ;
digitalWrite = digitalWriteWPi ;
pwmWrite = pwmWriteWPi ;
setPadDrive = setPadDriveWPi ;
digitalRead = digitalReadWPi ;
waitForInterrupt = waitForInterruptWPi ;
delayMicroseconds = delayMicrosecondsWPi ;
// Open the master /dev/memory device

if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
{
fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
return -1 ;
}

// GPIO:

// Allocate 2 pages - 1 ...

if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ;
return -1 ;
}

// ... presumably to make sure we can round it up to a whole page size

if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;

gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;

if ((int32_t)gpio < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
return -1 ;
}

// PWM

if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ;
return -1 ;
}

if (((uint32_t)pwmMem % PAGE_SIZE) != 0)
pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ;

pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ;

if ((int32_t)pwm < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
return -1 ;
}
// Clock control (needed for PWM)

if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ;
return -1 ;
}

if (((uint32_t)clkMem % PAGE_SIZE) != 0)
clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ;

clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ;

if ((int32_t)clk < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
return -1 ;
}
// The drive pads

if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ;
return -1 ;
}

if (((uint32_t)padsMem % PAGE_SIZE) != 0)
padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ;

pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ;

if ((int32_t)pads < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
return -1 ;
}

#ifdef DEBUG_PADS
printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ;
printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
#endif

// The system timer

if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ;
return -1 ;
}

if (((uint32_t)timerMem % PAGE_SIZE) != 0)
timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ;

timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ;

if ((int32_t)timer < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
return -1 ;
}

// Set the timer to free-running, 1MHz.
// 0xF9 is 249, the timer divide is base clock / (divide+1)
// so base clock is 250MHz / 250 = 1MHz.

*(timer + TIMER_CONTROL) = 0x0000280 ;
*(timer + TIMER_PRE_DIV) = 0x00000F9 ;
timerIrqRaw = timer + TIMER_IRQ_RAW ;

// Initialise our epoch for millis()

gettimeofday (&tv, NULL) ;
epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

return 0 ;
}


/*
* wiringPiSetupGpio:
* Must be called once at the start of your program execution.
*
* GPIO setup: Initialises the system into GPIO Pin mode and uses the
* memory mapped hardware directly.
*********************************************************************************
*/

int wiringPiSetupGpio (void)
{
int x = wiringPiSetup () ;

if (x != 0)
return x ;

pinMode = pinModeGpio ;
pullUpDnControl = pullUpDnControlGpio ;
digitalWrite = digitalWriteGpio ;
pwmWrite = pwmWriteGpio ;
setPadDrive = setPadDriveGpio ;
digitalRead = digitalReadGpio ;
waitForInterrupt = waitForInterruptGpio ;
delayMicroseconds = delayMicrosecondsWPi ; // Same

return 0 ;
}


/*
* wiringPiSetupSys:
* Must be called once at the start of your program execution.
*
* Initialisation (again), however this time we are using the /sys/class/gpio
* interface to the GPIO systems - slightly slower, but always usable as
* a non-root user, assuming the devices are already exported and setup correctly.
*/

int wiringPiSetupSys (void)
{
int pin ;
struct timeval tv ;
char fName [128] ;

pinMode = pinModeSys ;
pullUpDnControl = pullUpDnControlSys ;
digitalWrite = digitalWriteSys ;
pwmWrite = pwmWriteSys ;
setPadDrive = setPadDriveSys ;
digitalRead = digitalReadSys ;
waitForInterrupt = waitForInterruptSys ;
delayMicroseconds = delayMicrosecondsSys ;

// Open and scan the directory, looking for exported GPIOs, and pre-open
// the 'value' interface to speed things up for later
for (pin = 0 ; pin < 64 ; ++pin)
{
sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
sysFds [pin] = open (fName, O_RDWR) ;
}

// Initialise the epoch for mills() ...

gettimeofday (&tv, NULL) ;
epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

return 0 ;
}



+ 95
- 0
wiringPi/wiringPi.h View File

@@ -0,0 +1,95 @@
/*
* wiringPi:
* Arduino compatable (ish) Wiring library for the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

// Handy defines

#define NUM_PINS 17

#define WPI_MODE_PINS 0
#define WPI_MODE_GPIO 1
#define WPI_MODE_GPIO_SYS 2
#define WPI_MODE_PIFACE 3

#define INPUT 0
#define OUTPUT 1
#define PWM_OUTPUT 2

#define LOW 0
#define HIGH 1

#define PUD_OFF 0
#define PUD_DOWN 1
#define PUD_UP 2

// Function prototypes
// c++ wrappers thanks to a commend by Nick Lott
// (and others on the Raspberry Pi forums)

#ifdef __cplusplus
extern "C" {
#endif

// Basic wiringPi functions

extern int wiringPiSetup (void) ;
extern int wiringPiSetupSys (void) ;
extern int wiringPiSetupGpio (void) ;
extern int wiringPiSetupPiFace (void) ;

extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only

extern void (*pinMode) (int pin, int mode) ;
extern void (*pullUpDnControl) (int pin, int pud) ;
extern void (*digitalWrite) (int pin, int value) ;
extern void (*pwmWrite) (int pin, int value) ;
extern void (*setPadDrive) (int group, int value) ;
extern int (*digitalRead) (int pin) ;
extern void (*delayMicroseconds) (unsigned int howLong) ;

// Interrupts

extern int (*waitForInterrupt) (int pin, int mS) ;

// Threads

#define PI_THREAD(X) void *X (void *dummy)

extern int piThreadCreate (void *(*fn)(void *)) ;
extern void piLock (int key) ;
extern void piUnlock (int key) ;

// Schedulling priority

extern int piHiPri (int pri) ;


// Extras from arduino land

extern void delay (unsigned int howLong) ;
//extern void delayMicroseconds (unsigned int howLong) ;
//extern void delayMicrosecondsHard (unsigned int howLong) ;
extern unsigned int millis (void) ;

#ifdef __cplusplus
}
#endif

+ 355
- 0
wiringPi/wiringPiFace.c View File

@@ -0,0 +1,355 @@
/*
* wiringPiFace:
* Arduino compatable (ish) Wiring library for the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
*
* This file to interface with the PiFace peripheral device which
* has an MCP23S17 GPIO device connected via the SPI bus.
*
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/


#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/spi/spidev.h>

#include "wiringPi.h"


// The SPI bus parameters
// Variables as they need to be passed as pointers later on

static char *spiDevice = "/dev/spidev0.0" ;
static uint8_t spiMode = 0 ;
static uint8_t spiBPW = 8 ;
static uint32_t spiSpeed = 5000000 ;
static uint16_t spiDelay = 0;

// Locals here to keep track of everything

static int spiFd ;

// The MCP23S17 doesn't have bit-set operations, so it's
// cheaper to keep a copy here than to read/modify/write it

uint8_t dataOutRegister = 0 ;
uint8_t pudRegister = 0 ;

// MCP23S17 Registers

#define IOCON 0x0A

#define IODIRA 0x00
#define IPOLA 0x02
#define GPINTENA 0x04
#define DEFVALA 0x06
#define INTCONA 0x08
#define GPPUA 0x0C
#define INTFA 0x0E
#define INTCAPA 0x10
#define GPIOA 0x12
#define OLATA 0x14

#define IODIRB 0x01
#define IPOLB 0x03
#define GPINTENB 0x05
#define DEFVALB 0x07
#define INTCONB 0x09
#define GPPUB 0x0D
#define INTFB 0x0F
#define INTCAPB 0x11
#define GPIOB 0x13
#define OLATB 0x15

// Bits in the IOCON register

#define IOCON_BANK_MODE 0x80
#define IOCON_MIRROR 0x40
#define IOCON_SEQOP 0x20
#define IOCON_DISSLW 0x10
#define IOCON_HAEN 0x08
#define IOCON_ODR 0x04
#define IOCON_INTPOL 0x02
#define IOCON_UNUSED 0x01

// Default initialisation mode

#define IOCON_INIT (IOCON_SEQOP)

// Command codes

#define CMD_WRITE 0x40
#define CMD_READ 0x41


/*
* writeByte:
* Write a byte to a register on the MCP23S17 on the SPI bus.
* This is using the synchronous access mechanism.
*********************************************************************************
*/

static void writeByte (uint8_t reg, uint8_t data)
{
uint8_t spiBufTx [3] ;
uint8_t spiBufRx [3] ;
struct spi_ioc_transfer spi ;

spiBufTx [0] = CMD_WRITE ;
spiBufTx [1] = reg ;
spiBufTx [2] = data ;

spi.tx_buf = (unsigned long)spiBufTx ;
spi.rx_buf = (unsigned long)spiBufRx ;
spi.len = 3 ;
spi.delay_usecs = spiDelay ;
spi.speed_hz = spiSpeed ;
spi.bits_per_word = spiBPW ;

ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ;
}

/*
* readByte:
* Read a byte from a register on the MCP23S17 on the SPI bus.
* This is the synchronous access mechanism.
* What appears to happen is that the data returned is at
* the same offset as the number of bytes written to the device. So if we
* write 2 bytes (e.g. command then register number), then the data returned
* will by at the 3rd byte...
*********************************************************************************
*/

static uint8_t readByte (uint8_t reg)
{
uint8_t tx [4] ;
uint8_t rx [4] ;
struct spi_ioc_transfer spi ;

tx [0] = CMD_READ ;
tx [1] = reg ;
tx [2] = 0 ;

spi.tx_buf = (unsigned long)tx ;
spi.rx_buf = (unsigned long)rx ;
spi.len = 3 ;
spi.delay_usecs = spiDelay ;
spi.speed_hz = spiSpeed ;
spi.bits_per_word = spiBPW ;

ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ;

return rx [2] ;
}


/*
* digitalWritePiFace:
* Perform the digitalWrite function on the PiFace board
*********************************************************************************
*/

void digitalWritePiFace (int pin, int value)
{
uint8_t mask = 1 << pin ;

if (value == 0)
dataOutRegister &= (~mask) ;
else
dataOutRegister |= mask ;

writeByte (GPIOA, dataOutRegister) ;
}


void digitalWritePiFaceSpecial (int pin, int value)
{
uint8_t mask = 1 << pin ;
uint8_t old ;

old = readByte (GPIOA) ;

if (value == 0)
old &= (~mask) ;
else
old |= mask ;

writeByte (GPIOA, old) ;
}


/*
* digitalReadPiFace:
* Perform the digitalRead function on the PiFace board
*********************************************************************************
*/

int digitalReadPiFace (int pin)
{
uint8_t mask = 1 << pin ;

if ((readByte (GPIOB) & mask) != 0)
return HIGH ;
else
return LOW ;
}


/*
* pullUpDnControlPiFace:
* Perform the pullUpDnControl function on the PiFace board
*********************************************************************************
*/

void pullUpDnControlPiFace (int pin, int pud)
{
uint8_t mask = 1 << pin ;

if (pud == PUD_UP)
pudRegister |= mask ;
else
pudRegister &= (~mask) ;

writeByte (GPPUB, pudRegister) ;

}


void pullUpDnControlPiFaceSpecial (int pin, int pud)
{
uint8_t mask = 1 << pin ;
uint8_t old ;

old = readByte (GPPUB) ;

if (pud == PUD_UP)
old |= mask ;
else
old &= (~mask) ;

writeByte (GPPUB, old) ;

}



/*
* Dummy functions that are not used in this mode
*********************************************************************************
*/

void pinModePiFace (int pin, int mode) {}
void pwmWritePiFace (int pin, int value) {}
int waitForInterruptPiFace (int pin, int mS) { return 0 ; }


/*
* wiringPiSetupPiFace
* Setup the SPI interface and initialise the MCP23S17 chip
*********************************************************************************
*/

static int _wiringPiSetupPiFace (void)
{
if ((spiFd = open (spiDevice, O_RDWR)) < 0)
return -1 ;

// Set SPI parameters
// Why are we doing a read after write?
// I don't know - just blindliy copying an example elsewhere... -GH-

if (ioctl (spiFd, SPI_IOC_WR_MODE, &spiMode) < 0)
return -1 ;

if (ioctl (spiFd, SPI_IOC_RD_MODE, &spiMode) < 0)
return -1 ;

if (ioctl (spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
return -1 ;

if (ioctl (spiFd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0)
return -1 ;

if (ioctl (spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0)
return -1 ;

if (ioctl (spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0)
return -1 ;

// Setup the MCP23S17

writeByte (IOCON, IOCON_INIT) ;

writeByte (IODIRA, 0x00) ; // Port A -> Outputs
writeByte (IODIRB, 0xFF) ; // Port B -> Inputs

return 0 ;
}


int wiringPiSetupPiFace (void)
{
int x = _wiringPiSetupPiFace () ;

if (x != 0)
return x ;

writeByte (GPIOA, 0x00) ; // Set all outptus off
writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B

pinMode = pinModePiFace ;
pullUpDnControl = pullUpDnControlPiFace ;
digitalWrite = digitalWritePiFace ;
pwmWrite = pwmWritePiFace ;
digitalRead = digitalReadPiFace ;
waitForInterrupt = waitForInterruptPiFace ;

return 0 ;
}


/*
* wiringPiSetupPiFaceForGpioProg:
* Setup the SPI interface and initialise the MCP23S17 chip
* Special version for the gpio program
*********************************************************************************
*/


int wiringPiSetupPiFaceForGpioProg (void)
{
int x = _wiringPiSetupPiFace () ;

if (x != 0)
return x ;

pinMode = pinModePiFace ;
pullUpDnControl = pullUpDnControlPiFaceSpecial ;
digitalWrite = digitalWritePiFaceSpecial ;
pwmWrite = pwmWritePiFace ;
digitalRead = digitalReadPiFace ;
waitForInterrupt = waitForInterruptPiFace ;

return 0 ;
}

+ 218
- 0
wiringPi/wiringSerial.c View File

@@ -0,0 +1,218 @@
/*
* wiringSerial.c:
* Handle a serial port
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#undef DEBUG

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "wiringSerial.h"

/*
* serialOpen:
* Open and initialise the serial port, setting all the right
* port parameters - or as many as are required - hopefully!
*********************************************************************************
*/

int serialOpen (char *device, int baud)
{
struct termios options ;
speed_t myBaud ;
int status, fd ;

#ifdef DEBUG
printf ("openSerialPort: <%s> baud: $d\n", device, baud) ;
#endif

switch (baud)
{
case 50: myBaud = B50 ; break ;
case 75: myBaud = B75 ; break ;
case 110: myBaud = B110 ; break ;
case 134: myBaud = B134 ; break ;
case 150: myBaud = B150 ; break ;
case 200: myBaud = B200 ; break ;
case 300: myBaud = B300 ; break ;
case 600: myBaud = B600 ; break ;
case 1200: myBaud = B1200 ; break ;
case 1800: myBaud = B1800 ; break ;
case 2400: myBaud = B2400 ; break ;
case 9600: myBaud = B9600 ; break ;
case 19200: myBaud = B19200 ; break ;
case 38400: myBaud = B38400 ; break ;
case 57600: myBaud = B57600 ; break ;
case 115200: myBaud = B115200 ; break ;
case 230400: myBaud = B230400 ; break ;

default:
return -2 ;
}

if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
return -1 ;

fcntl (fd, F_SETFL, O_RDWR) ;

// Get and modify current options:

tcgetattr (fd, &options) ;

cfmakeraw (&options) ;
cfsetispeed (&options, myBaud) ;
cfsetospeed (&options, myBaud) ;

options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;

options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)

tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;

ioctl (fd, TIOCMGET, &status);

status |= TIOCM_DTR ;
status |= TIOCM_RTS ;

ioctl (fd, TIOCMSET, &status);

usleep (10000) ; // 10mS

return fd ;
}


/*
* serialFlush:
* Flush the serial buffers (both tx & rx)
*********************************************************************************
*/

void serialFlush (int fd)
{
tcflush (fd, TCIOFLUSH) ;
}


/*
* serialClose:
* Release the serial port
*********************************************************************************
*/

void serialClose (int fd)
{
close (fd) ;
}


/*
* serialPutchar:
* Send a single character to the serial port
*********************************************************************************
*/

void serialPutchar (int fd, unsigned char c)
{
write (fd, &c, 1) ;
}


/*
* serialPuts:
* Send a string to the serial port
*********************************************************************************
*/

void serialPuts (int fd, char *s)
{
write (fd, s, strlen (s)) ;
}

/*
* serialPrintf:
* Printf over Serial
*********************************************************************************
*/

void serialPrintf (int fd, char *message, ...)
{
va_list argp ;
char buffer [1024] ;

va_start (argp, message) ;
vsnprintf (buffer, 1023, message, argp) ;
va_end (argp) ;

serialPuts (fd, buffer) ;
}


/*
* serialDataAvail:
* Return the number of bytes of data avalable to be read in the serial port
*********************************************************************************
*/

int serialDataAvail (int fd)
{
int result ;

if (ioctl (fd, FIONREAD, &result) == -1)
return -1 ;

return result ;
}


/*
* serialGetchar:
* Get a single character from the serial device.
* Note: Zero is a valid character and this function will time-out after
* 10 seconds.
*********************************************************************************
*/

int serialGetchar (int fd)
{
uint8_t x ;

if (read (fd, &x, 1) != 1)
return -1 ;

return ((int)x) & 0xFF ;
}

+ 38
- 0
wiringPi/wiringSerial.h View File

@@ -0,0 +1,38 @@
/*
* wiringSerial.h:
* Handle a serial port
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern int serialOpen (char *device, int baud) ;
extern void serialClose (int fd) ;
extern void serialFlush (int fd) ;
extern void serialPutchar (int fd, unsigned char c) ;
extern void serialPuts (int fd, char *s) ;
extern void serialPrintf (int fd, char *message, ...) ;
extern int serialDataAvail (int fd) ;
extern int serialGetchar (int fd) ;

#ifdef __cplusplus
}
#endif

+ 84
- 0
wiringPi/wiringShift.c View File

@@ -0,0 +1,84 @@
/*
* wiringShift.c:
* Emulate some of the Arduino wiring functionality.
*
* Copyright (c) 2009-2012 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <stdint.h>

#include "wiringPi.h"
#include "wiringShift.h"

/*
* shiftIn:
* Shift data in from a clocked source
*********************************************************************************
*/

uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order)
{
uint8_t value = 0 ;
int8_t i ;
if (order == MSBFIRST)
for (i = 7 ; i >= 0 ; --i)
{
digitalWrite (cPin, HIGH) ;
value |= digitalRead (dPin) << i ;
digitalWrite (cPin, LOW) ;
}
else
for (i = 0 ; i < 8 ; ++i)
{
digitalWrite (cPin, HIGH) ;
value |= digitalRead (dPin) << i ;
digitalWrite (cPin, LOW) ;
}

return value;
}


/*
* shiftOut:
* Shift data out to a clocked source
*********************************************************************************
*/

void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val)
{
int8_t i;

if (order == MSBFIRST)
for (i = 7 ; i >= 0 ; --i)
{
digitalWrite (dPin, val & (1 << i)) ;
digitalWrite (cPin, HIGH) ;
digitalWrite (cPin, LOW) ;
}
else
for (i = 0 ; i < 8 ; ++i)
{
digitalWrite (dPin, val & (1 << i)) ;
digitalWrite (cPin, HIGH) ;
digitalWrite (cPin, LOW) ;
}
}

+ 41
- 0
wiringPi/wiringShift.h View File

@@ -0,0 +1,41 @@
/*
* wiringShift.h:
* Emulate some of the Arduino wiring functionality.
*
* Copyright (c) 2009-2012 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#define LSBFIRST 0
#define MSBFIRST 1

#ifndef _STDINT_H
# include <stdint.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ;
extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;

#ifdef __cplusplus
}
#endif

Loading…
Cancel
Save