Przeglądaj źródła

Lots of changes here. Added new I2C test code, a new serialTest program,

and developed the new ISR - Interrupt Service Routine
handler - much easier than the old waitForInterrupt code!

Minor tweaks to the gpio program to recognise the environment variable
WIRINGPI_DEBUG too, and removed the printing of the errors from the
main wiringPi setup routines (and added some new ones!)
pull/22/head
Gordon Henderson 12 lat temu
rodzic
commit
13bbba7a22
15 zmienionych plików z 744 dodań i 91 usunięć
  1. +36
    -0
      INSTALL
  2. +10
    -2
      examples/Makefile
  3. +99
    -0
      examples/isr.c
  4. +1
    -0
      examples/okLed.c
  5. +57
    -0
      examples/serialTest.c
  6. +17
    -14
      examples/wfi.c
  7. +1
    -1
      gpio/Makefile
  8. +12
    -1
      gpio/gpio.1
  9. +20
    -4
      gpio/gpio.c
  10. +14
    -6
      wiringPi/Makefile
  11. +181
    -50
      wiringPi/wiringPi.c
  12. +24
    -13
      wiringPi/wiringPi.h
  13. +122
    -0
      wiringPi/wiringPiI2C.c
  14. +41
    -0
      wiringPi/wiringPiI2C.h
  15. +109
    -0
      wiringPi/wiringPiISR.c

+ 36
- 0
INSTALL Wyświetl plik

@@ -0,0 +1,36 @@

How to install wiringPi
=======================

The easiest way is to use the supplied 'build' script:

./build

that should do a complete install or upgrade of wiringPi for you.

That will install a dynamic library.

Some distributions do not have /usr/local/lib in the default LD_LIBRARY_PATH. To
fix this, you need to edit /etc/ld.so.conf and add in a single line:

/usr/local/lib

then run the ldconfig command.

sudo ldconfig

If you want to install a static library, you may need to do this manually:

cd wiringPi
make static
sudo make install-static


To un-install wiringPi:

./build uninstall

Gordon Henderson

projects@drogon.net
https://projects.drogon.net/

+ 10
- 2
examples/Makefile Wyświetl plik

@@ -35,10 +35,10 @@ LDLIBS = -lwiringPi
# Should not alter anything below this line
###############################################################################

SRC = test1.c test2.c speed.c lcd.c wfi.c \
SRC = test1.c test2.c speed.c lcd.c wfi.c isr.c \
piface.c gertboard.c nes.c \
pwm.c tone.c servo.c \
delayTest.c serialRead.c okLed.c
delayTest.c serialRead.c serialTest.c okLed.c

OBJ = $(SRC:.c=.o)

@@ -69,6 +69,10 @@ wfi: wfi.o
@echo [link]
@$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS)

isr: isr.o
@echo [link]
@$(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS)

piface: piface.o
@echo [link]
@$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) -lpthread
@@ -93,6 +97,10 @@ serialRead: serialRead.o
@echo [link]
@$(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS)

serialTest: serialTest.o
@echo [link]
@$(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS)

okLed: okLed.o
@echo [link]
@$(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS)


+ 99
- 0
examples/isr.c Wyświetl plik

@@ -0,0 +1,99 @@
/*
* isr.c:
* Wait for Interrupt test program - ISR method
*
* How to test:
* Use the SoC's pull-up and pull down resistors that are avalable
* on input pins. So compile & run this program (via sudo), then
* in another terminal:
* gpio mode 0 up
* gpio mode 0 down
* at which point it should trigger an interrupt. Toggle the pin
* up/down to generate more interrupts to test.
*
* Copyright (c) 2013 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 <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>


// What GPIO input are we using?
// This is a wiringPi pin number

#define BUTTON_PIN 0

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

static volatile int globalCounter = 0 ;


/*
* myInterrupt:
*********************************************************************************
*/

void myInterrupt (void)
{
++globalCounter ;
}


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

int main (void)
{
int myCounter = 0 ;

if (wiringPiSetup () < 0)
{
fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ;
return 1 ;
}

if (wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0)
{
fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ;
return 1 ;
}


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

while (myCounter == globalCounter)
delay (100) ;

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

return 0 ;
}

+ 1
- 0
examples/okLed.c Wyświetl plik

@@ -17,6 +17,7 @@
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>

#include <wiringPi.h>
#include <softPwm.h>


+ 57
- 0
examples/serialTest.c Wyświetl plik

@@ -0,0 +1,57 @@
/*
* serialTest.c:
* Very simple program to test the serial port. Expects
* the port to be looped back to itself
*
*/

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

#include <wiringPi.h>
#include <wiringSerial.h>

int main ()
{
int fd ;
int count ;
unsigned int nextTime ;

if ((fd = serialOpen ("/dev/ttyAMA0", 115200)) < 0)
{
fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
return 1 ;
}

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

nextTime = millis () + 300 ;

for (count = 0 ; count < 256 ; )
{
if (millis () > nextTime)
{
printf ("\nOut: %3d: ", count) ;
fflush (stdout) ;
serialPutchar (fd, count) ;
nextTime += 300 ;
++count ;
}

delay (3) ;

while (serialDataAvail (fd))
{
printf (" -> %3d", serialGetchar (fd)) ;
fflush (stdout) ;
}
}

printf ("\n") ;
return 0 ;
}

+ 17
- 14
examples/wfi.c Wyświetl plik

@@ -2,7 +2,17 @@
* wfi.c:
* Wait for Interrupt test program
*
* Copyright (c) 2012 Gordon Henderson.
* This program demonstrates the use of the waitForInterrupt()
* function in wiringPi. It listens to a button input on
* BCM_GPIO pin 17 (wiringPi pin 0)
*
* The biggest issue with this method is that it really only works
* well in Sys mode.
*
* Jan 2013: This way of doing things is sort of deprecated now, see
* the wiringPiISR() function instead and the isr.c test program here.
*
* Copyright (c) 2012-2013 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -33,9 +43,8 @@
#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
#define BUTTON_PIN 17

// Debounce time in mS

@@ -63,13 +72,11 @@ PI_THREAD (waitForIt)
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)
@@ -80,7 +87,6 @@ PI_THREAD (waitForIt)

// We have a valid one

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

piLock (COUNT_KEY) ;
@@ -89,7 +95,7 @@ PI_THREAD (waitForIt)

// Wait for key to be released

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

debounceTime = millis () + DEBOUNCE_TIME ;
@@ -108,11 +114,9 @@ void setup (void)
{

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

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

// Setup wiringPi

@@ -120,9 +124,8 @@ void setup (void)

// Fire off our interrupt handler

piThreadCreate (waitForIt) ;
piThreadCreate (waitForIt) ;

digitalWrite (17, 0) ;
}


@@ -147,7 +150,7 @@ int main (void)
piLock (COUNT_KEY) ;
myCounter = globalCounter ;
piUnlock (COUNT_KEY) ;
delay (5000) ;
delay (500) ;
}

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


+ 1
- 1
gpio/Makefile Wyświetl plik

@@ -30,7 +30,7 @@ INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe

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

# May not need to alter anything below this line
###############################################################################


+ 12
- 1
gpio/gpio.1 Wyświetl plik

@@ -57,6 +57,9 @@ converters on the Gertboard. 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.

It can also control the IO's on the PiFace IO board and load the SPI and I2C
kernel modules if required.

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.
@@ -70,6 +73,8 @@ Output the current version including the board revision of the Raspberry Pi.
.TP
.B \-g
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.
\fINOTE:\fR The BCM_GPIO pin numbers are always used with the
export and edge commands.

.TP
.B \-p
@@ -183,7 +188,7 @@ SPI digital to analogue converter.
The board jumpers need to be in-place to do this operation.


.SH "WiringPi vs. GPIO Pin numbering"
.SH "WiringPi vs. BCM_GPIO Pin numbering"

.PP
.TS
@@ -213,6 +218,12 @@ _
20 - 31
.TE

Note that "r1" and "r2" above refers to the board revision. Normally
wiringPi detects the correct board revision with use for it's own
numbering scheme, but if you are using a Revision 2 board with some
of the pins which change numbers between revisions you will need
to alter your software.

.SH FILES

.TP 2.2i


+ 20
- 4
gpio/gpio.c Wyświetl plik

@@ -35,12 +35,14 @@
#include <wiringPi.h>
#include <gertboard.h>

extern int wiringPiDebug ;

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

#define VERSION "1.5"
#define VERSION "1.6"

static int wpMode ;

@@ -127,7 +129,7 @@ static int moduleLoaded (char *modName)

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

@@ -136,16 +138,24 @@ static void doLoad (int argc, char *argv [])
char *module1, *module2 ;
char cmd [80] ;
char *file1, *file2 ;
char spiBuf [32] ;

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

spiBuf [0] = 0 ;

/**/ if (strcasecmp (argv [2], "spi") == 0)
{
module1 = "spidev" ;
module2 = "spi_bcm2708" ;
file1 = "/dev/spidev0.0" ;
file2 = "/dev/spidev0.1" ;
if (argc == 4)
sprintf (spiBuf, " bufsize=%d", atoi (argv [3]) * 1024) ;
else if (argc > 4)
_doLoadUsage (argv) ;
}
else if (strcasecmp (argv [2], "i2c") == 0)
{
@@ -159,7 +169,7 @@ static void doLoad (int argc, char *argv [])

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

@@ -848,6 +858,12 @@ int main (int argc, char *argv [])
{
int i ;

if (getenv ("WIRINGPI_DEBUG") != NULL)
{
printf ("gpio: wiringPi debug mode enabled\n") ;
wiringPiDebug = TRUE ;
}

if (argc == 1)
{
fprintf (stderr, "%s\n", usage) ;


+ 14
- 6
wiringPi/Makefile Wyświetl plik

@@ -1,4 +1,4 @@
#
# ;
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
#
@@ -45,13 +45,15 @@ LIBS =
SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \
gertboard.c \
piNes.c \
lcd.c piHiPri.c piThread.c wiringPiSPI.c \
lcd.c piHiPri.c piThread.c \
wiringPiSPI.c wiringPiI2C.c \
softPwm.c softServo.c softTone.c

OBJ = $(SRC:.c=.o)

all: $(STATIC) $(DYNAMIC)
#all: $(DYNAMIC)
all: $(DYNAMIC)

static: $(STATIC)

$(STATIC): $(OBJ)
@echo "[Link (Static)]"
@@ -77,7 +79,7 @@ tags: $(SRC)
@ctags $(SRC)

.PHONEY: install
install: $(TARGET)
install: $(DYNAMIC)
@echo "[Install]"
@install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
@install -m 0755 -d $(DESTDIR)$(PREFIX)/include
@@ -91,12 +93,17 @@ install: $(TARGET)
@install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include
@install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib
@install -m 0644 wiringPiI2C.h $(DESTDIR)$(PREFIX)/include
@install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib
@ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
@ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1
@ldconfig

.PHONEY: install-static
install-static: $(STATIC)
@echo "[Install Static]"
@install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib

.PHONEY: uninstall
uninstall:
@echo "[UnInstall]"
@@ -110,6 +117,7 @@ uninstall:
@rm -f $(DESTDIR)$(PREFIX)/include/softTone.h
@rm -f $(DESTDIR)$(PREFIX)/include/lcd.h
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h
@rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
@ldconfig



+ 181
- 50
wiringPi/wiringPi.c Wyświetl plik

@@ -65,10 +65,12 @@
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

#include "wiringPi.h"

@@ -173,9 +175,17 @@ static volatile uint32_t *pads ;
static volatile uint32_t *timer ;
static volatile uint32_t *timerIrqRaw ;

// Time for easy calculations

static unsigned long long epoch ;

// Misc

static int wiringPiMode = WPI_MODE_UNINITIALISED ;

// Debugging

static int wiringPiDebug = FALSE ;
int wiringPiDebug = FALSE ;

// The BCM2835 has 54 GPIO pins.
// BCM2835 data sheet, Page 90 onwards.
@@ -200,6 +210,11 @@ static int wiringPiDebug = FALSE ;

static int sysFds [64] ;

// ISR Data

static void (*isrFunctions [64])(void) ;


// 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!
@@ -370,10 +385,6 @@ static uint8_t gpioToPwmPort [] =
} ;


// Time for easy calculations

static unsigned long long epoch ;

/*
* Functions
*********************************************************************************
@@ -418,6 +429,15 @@ int wpiPinToGpio (int wpiPin)
*********************************************************************************
*/

static void piBoardRevOops (char *why)
{
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, " -> %s\n", why) ;
fprintf (stderr, " -> You may want to check:\n") ;
fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
exit (EXIT_FAILURE) ;
}

int piBoardRev (void)
{
FILE *cpuFd ;
@@ -440,24 +460,19 @@ int piBoardRev (void)
fclose (cpuFd) ;

if (line == NULL)
{
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, " (No \"Revision\" line)\n") ;
errno = 0 ;
return -1 ;
}
piBoardRevOops ("No \"Revision\" line") ;

line [strlen (line) - 1] = 0 ; // Chomp LF
if (wiringPiDebug)
printf ("piboardRev: Revision string: %s\n", line) ;

for (c = line ; *c ; ++c)
if (isdigit (*c))
break ;

if (!isdigit (*c))
{
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, " (No numeric revision string in: \"%s\"\n", line) ;
errno = 0 ;
return -1 ;
}
piBoardRevOops ("No numeric revision string") ;

// If you have overvolted the Pi, then it appears that the revision
// has 100000 added to it!
@@ -466,26 +481,18 @@ int piBoardRev (void)
if (strlen (c) != 4)
printf ("piboardRev: This Pi has/is overvolted!\n") ;

lastChar = c [strlen (c) - 2] ;
lastChar = line [strlen (line) - 1] ;

if (wiringPiDebug)
printf ("piboardRev: lastChar is: '%c' (%d, 0x%02X)\n", lastChar, lastChar, lastChar) ;

/**/ if ((lastChar == '2') || (lastChar == '3'))
boardRev = 1 ;
else
boardRev = 2 ;

#ifdef DO_WE_CARE_ABOUT_THIS_NOW
else
{
fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ;
fprintf (stderr, " -> You may want to check:\n") ;
fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
fprintf (stderr, " -> Assuming a Rev 1 board\n") ;
boardRev = 1 ;
}
#endif

if (wiringPiDebug)
printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ;
printf ("piBoardRev: Returning revision: %d\n", boardRev) ;

return boardRev ;
}
@@ -741,11 +748,11 @@ void digitalWriteByteGpio (int value)
else
pinSet |= (1 << pinToGpio [pin]) ;

*(gpio + gpioToGPCLR [0]) = pinClr ;
*(gpio + gpioToGPSET [0]) = pinSet ;

mask <<= 1 ;
}

*(gpio + gpioToGPCLR [0]) = pinClr ;
*(gpio + gpioToGPSET [0]) = pinSet ;
}

void digitalWriteByteSys (int value)
@@ -944,6 +951,99 @@ int waitForInterruptGpio (int pin, int mS)


/*
* interruptHandler:
* This is a thread and gets started to wait for the interrupt we're
* hoping to catch. It will call the user-function when the interrupt
* fires.
*********************************************************************************
*/

static void *interruptHandler (void *arg)
{
int myPin = *(int *)arg ;

(void)piHiPri (55) ; // Only effective if we run as root

for (;;)
if (waitForInterruptSys (myPin, -1) > 0)
isrFunctions [myPin] () ;

return NULL ;
}


/*
* wiringPiISR:
* Take the details and create an interrupt handler that will do a call-
* back to the user supplied function.
*********************************************************************************
*/

int wiringPiISR (int pin, int mode, void (*function)(void))
{
pthread_t threadId ;
char fName [64] ;
char *modeS ;
char pinS [8] ;
pid_t pid ;

pin &= 63 ;

if (wiringPiMode == WPI_MODE_UNINITIALISED)
{
fprintf (stderr, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
exit (EXIT_FAILURE) ;
}
else if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;

// Now export the pin and set the right edge
// We're going to use the gpio program to do this, so it assumes
// a full installation of wiringPi. It's a bit 'clunky', but it
// is a way that will work when we're running in "Sys" mode, as
// a non-root user. (without sudo)

if (mode != INT_EDGE_SETUP)
{
/**/ if (mode == INT_EDGE_FALLING)
modeS = "falling" ;
else if (mode == INT_EDGE_RISING)
modeS = "rising" ;
else
modeS = "both" ;

sprintf (pinS, "%d", pin) ;

if ((pid = fork ()) < 0) // Fail
return pid ;

if (pid == 0) // Child, exec
{
execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
return -1 ; // Failure ...
}
else // Parent, wait
wait (NULL) ;
}

// Now pre-open the /sys/class node - it may already be open if
// we had set it up earlier, but this will do no harm.

sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
if ((sysFds [pin] = open (fName, O_RDWR)) < 0)
return -1 ;

isrFunctions [pin] = function ;

pthread_create (&threadId, NULL, interruptHandler, &pin) ;

delay (1) ;

return 0 ;
}


/*
* delay:
* Wait for some number of milli seconds
*********************************************************************************
@@ -1064,8 +1164,17 @@ int wiringPiSetup (void)
uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
struct timeval tv ;

if (geteuid () != 0)
{
fprintf (stderr, "Must be root to call wiringPiSetup(). (Did you forget sudo?)\n") ;
exit (EXIT_FAILURE) ;
}

if (getenv ("WIRINGPI_DEBUG") != NULL)
{
printf ("wiringPi: Debug mode enabled\n") ;
wiringPiDebug = TRUE ;
}

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetup called\n") ;
@@ -1083,8 +1192,7 @@ int wiringPiSetup (void)
pwmSetRange = pwmSetRangeWPi ;
pwmSetClock = pwmSetClockWPi ;
if ((boardRev = piBoardRev ()) < 0)
return -1 ;
boardRev = piBoardRev () ;

if (boardRev == 1)
pinToGpio = pinToGpioR1 ;
@@ -1105,7 +1213,8 @@ int wiringPiSetup (void)

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

@@ -1118,7 +1227,8 @@ int wiringPiSetup (void)

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

@@ -1126,7 +1236,8 @@ int wiringPiSetup (void)

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

@@ -1137,7 +1248,8 @@ int wiringPiSetup (void)

if ((int32_t)pwm < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
if (wiringPiDebug)
fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
return -1 ;
}
@@ -1145,7 +1257,8 @@ int wiringPiSetup (void)

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

@@ -1156,7 +1269,8 @@ int wiringPiSetup (void)

if ((int32_t)clk < 0)
{
fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
if (wiringPiDebug)
fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
return -1 ;
}
@@ -1164,7 +1278,8 @@ int wiringPiSetup (void)

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

@@ -1175,7 +1290,8 @@ int wiringPiSetup (void)

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

@@ -1188,7 +1304,8 @@ int wiringPiSetup (void)

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

@@ -1199,7 +1316,8 @@ int wiringPiSetup (void)

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

@@ -1216,6 +1334,8 @@ int wiringPiSetup (void)
gettimeofday (&tv, NULL) ;
epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

wiringPiMode = WPI_MODE_PINS ;

return 0 ;
}

@@ -1233,12 +1353,18 @@ int wiringPiSetupGpio (void)
{
int x ;

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupGpio called\n") ;
if (geteuid () != 0)
{
fprintf (stderr, "Must be root to call wiringPiSetupGpio(). (Did you forget sudo?)\n") ;
exit (EXIT_FAILURE) ;
}

if ((x = wiringPiSetup ()) < 0)
return x ;

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupGpio called\n") ;

pinMode = pinModeGpio ;
pullUpDnControl = pullUpDnControlGpio ;
digitalWrite = digitalWriteGpio ;
@@ -1252,6 +1378,8 @@ int wiringPiSetupGpio (void)
pwmSetRange = pwmSetRangeWPi ;
pwmSetClock = pwmSetClockWPi ;

wiringPiMode = WPI_MODE_GPIO ;

return 0 ;
}

@@ -1272,6 +1400,9 @@ int wiringPiSetupSys (void)
struct timeval tv ;
char fName [128] ;

if (getenv ("WIRINGPI_DEBUG") != NULL)
wiringPiDebug = TRUE ;

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupSys called\n") ;

@@ -1288,15 +1419,13 @@ int wiringPiSetupSys (void)
pwmSetRange = pwmSetRangeSys ;
pwmSetClock = pwmSetClockSys ;

if ((boardRev = piBoardRev ()) < 0)
return -1 ;
boardRev = piBoardRev () ;

if (boardRev == 1)
pinToGpio = pinToGpioR1 ;
else
pinToGpio = pinToGpioR2 ;


// Open and scan the directory, looking for exported GPIOs, and pre-open
// the 'value' interface to speed things up for later
@@ -1311,5 +1440,7 @@ int wiringPiSetupSys (void)
gettimeofday (&tv, NULL) ;
epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;

wiringPiMode = WPI_MODE_GPIO_SYS ;

return 0 ;
}

+ 24
- 13
wiringPi/wiringPi.h Wyświetl plik

@@ -23,32 +23,44 @@

// Handy defines

// Deprecated
#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 WPI_MODE_UNINITIALISED -1

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

#define LOW 0
#define HIGH 1
#define LOW 0
#define HIGH 1

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

// PWM

#define PWM_MODE_MS 0
#define PWM_MODE_BAL 1
#define PWM_MODE_MS 0
#define PWM_MODE_BAL 1

// Interrupt levels

#define INT_EDGE_SETUP 0
#define INT_EDGE_FALLING 1
#define INT_EDGE_RISING 2

// Threads

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


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

#ifdef __cplusplus
@@ -82,11 +94,10 @@ extern void (*pwmSetClock) (int divisor) ;
// Interrupts

extern int (*waitForInterrupt) (int pin, int mS) ;
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;

// 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) ;


+ 122
- 0
wiringPi/wiringPiI2C.c Wyświetl plik

@@ -0,0 +1,122 @@
/*
* wiringPiI2C.c:
* Simplified I2C access routines
* Copyright (c) 2013 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 <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

#include "wiringPi.h"
#include "wiringPiI2C.h"


/*
* wiringPiI2CRead:
* Simple device read
*********************************************************************************
*/

int wiringPiI2CRead (int fd)
{
return i2c_smbus_read_byte (fd) ;
}


/*
* wiringPiI2CReadReg8: wiringPiI2CReadReg16:
* Read an 8 or 16-bit value from a regsiter on the device
*********************************************************************************
*/

int wiringPiI2CReadReg8 (int fd, int reg)
{
return i2c_smbus_read_byte_data (fd, reg) ;
}

int wiringPiI2CReadReg16 (int fd, int reg)
{
return i2c_smbus_read_word_data (fd, reg) ;
}


/*
* wiringPiI2CWrite:
* Simple device write
*********************************************************************************
*/

int wiringPiI2CWrite (int fd, int data)
{
return i2c_smbus_write_byte (fd, data) ;
}


/*
* wiringPiI2CWriteReg8: wiringPiI2CWriteReg16:
* Write an 8 or 16-bit value to the given register
*********************************************************************************
*/

int wiringPiI2CWriteReg8 (int fd, int reg, int data)
{
return i2c_smbus_write_byte_data (fd, reg, data) ;
}

int wiringPiI2CWriteReg16 (int fd, int reg, int data)
{
return i2c_smbus_write_word_data (fd, reg, data) ;
}


/*
* wiringPiI2CSetup:
* Open the I2C device, and regsiter the target device
*********************************************************************************
*/

int wiringPiI2CSetup (int devId)
{
int rev, fd ;
char *device ;

if ((rev = piBoardRev ()) < 0)
{
fprintf (stderr, "wiringPiI2CSetup: Unable to determine Pi board revision\n") ;
exit (1) ;
}

if (rev == 1)
device = "/dev/i2c-0" ;
else
device = "/dev/i2c-1" ;

if ((fd = open (device, O_RDWR)) < 0)
return -1 ;

if (ioctl (fd, I2C_SLAVE, devId) < 0)
return -1 ;

return fd ;
}

+ 41
- 0
wiringPi/wiringPiI2C.h Wyświetl plik

@@ -0,0 +1,41 @@
/*
* wiringPiI2C.h:
* Simplified I2C access routines
* Copyright (c) 2013 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/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern int wiringPiI2CRead (int fd) ;
extern int wiringPiI2CReadReg8 (int fd, int reg) ;
extern int wiringPiI2CReadReg16 (int fd, int reg) ;

extern int wiringPiI2CWrite (int fd, int data) ;
extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;

int wiringPiI2CSetup (int devId) ;

#ifdef __cplusplus
}
#endif

+ 109
- 0
wiringPi/wiringPiISR.c Wyświetl plik

@@ -0,0 +1,109 @@
/*
* wiringPiISR.c:
* Simplified Interrupt Service Routine handling
* Copyright (c) 2013 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 <fcntl.h>

#include "wiringPi.h"



static void (*isrFunctions [64])(void) ;
static int isrFds [64] ;

/*
* interruptHandler:
* This is a thread and gets started to wait for the interrupt we're
* hoping to catch. It will call the user-function when the interrupt
* fires.
*********************************************************************************
*/

static void *interruptHandler (void *arg)
{
int pin = *(int *)arg ;

(void)piHiPri (55) ;

for (;;)
{
if (waitForInterrupt (pin, -1) > 0)
isrFunctions [pin] () ;
}

return NULL ;
}

/*
* wiringPiISR:
* Take the details and create an interrupt handler that will do a call-
* back to the user supplied function.
*********************************************************************************
*/

int wiringPiISR (int pin, int mode, void (*function)(void))
{
pthread_t threadId ;
char command [64] ;

pin &= 63 ;

if (wiringPiMode == WPI_MODE_UNINITIALISED)
{
fprintf (stderr, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
exit (EXIT_FAILURE) ;
}
else if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;


isrFunctions [pin] = function ;

// Now export the pin and set the right edge

if (mode != INT_EDGE_SETUP)
{
/**/ if (mode == INT_EDGE_FALLING)
modes = "falling" ;
else if (mode == INT_EDGE_RISING)
modes = "rising" ;
else
modes = "both" ;

sprintf (command, "/usr/local/bin/gpio edge %d %s", pin, modes) ;
system (command) ;
}

sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
if ((isrFds [pin] = open (fName, O_RDWR)) < 0)
return -1 ;

{
fprintf ("std

pthread_create (&threadId, NULL, interruptHandler, &pin) ;
}



Ładowanie…
Anuluj
Zapisz