chiark / gitweb /
Big update here.
authorGordon Henderson <projects@drogon.net>
Thu, 6 Dec 2012 21:49:41 +0000 (21:49 +0000)
committerGordon Henderson <projects@drogon.net>
Thu, 6 Dec 2012 21:49:41 +0000 (21:49 +0000)
delayMicrosecondsHard re-written - again.
Added a serialRead example program, and added in the okLed
to the examples too.
Updated/checked some of the GPIO/PWM code.
Added in some experimental servo and tone generating code and
and example or 2.
Tweaks to the gpio command to correctly load the I2C modules too.

19 files changed:
People
examples/Makefile
examples/delayTest.c
examples/okLed.c [new file with mode: 0644]
examples/pwm.c [moved from examples/softPwm.c with 100% similarity]
examples/serialRead.c [new file with mode: 0644]
examples/servo.c [new file with mode: 0644]
examples/tone.c [new file with mode: 0644]
gpio/gpio.1
gpio/gpio.c
wiringPi/Makefile
wiringPi/softServo.c [new file with mode: 0644]
wiringPi/softServo.h [new file with mode: 0644]
wiringPi/softTone.c [new file with mode: 0644]
wiringPi/softTone.h [new file with mode: 0644]
wiringPi/wiringPi.c
wiringPi/wiringPi.h
wiringPi/wiringPiFace.c
wiringPi/wiringPiSPI.c

diff --git a/People b/People
index 2c5fa9205d068a1da82534172afb63ca020fcd16..e0c262c09be7fee02594f31a7c20ea02d8778d7c 100644 (file)
--- a/People
+++ b/People
@@ -8,3 +8,8 @@ Nick Lott: (And others)
 Philipp Stefan Neininger:
   Minor bug in the Makefile to do with cross compiling
 
+Chris McSweeny
+  Hints and tips about the use of arithmetic in gettimeofday()
+    inside the dealyMicrosecondsHard() function.
+  And spotting a couple of schoolboy errors in the (experimental)
+  softServo code, prompting me to completely re-write it.
index 16bf7e2fa6e408000d7a6ebea20523fcd1e30186..738d36c7234f0c37ccdc6d94072dfb57459757c1 100644 (file)
@@ -30,16 +30,19 @@ INCLUDE     = -I/usr/local/include
 CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
 
 LDFLAGS        = -L/usr/local/lib
-LIBS    = -lwiringPi
+LDLIBS    = -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 softPwm.c
+SRC    =       test1.c test2.c speed.c lcd.c wfi.c             \
+               piface.c gertboard.c nes.c                      \
+               pwm.c tone.c servo.c                            \
+               delayTest.c serialRead.c okLed.c
 
-OBJ    =       test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o softPwm.o
+OBJ    =       $(SRC:.c=.o)
 
-BINS   =       test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm
+BINS   =       $(SRC:.c=)
 
 all:   
        @cat README.TXT
@@ -48,43 +51,59 @@ all:
 
 test1: test1.o
        @echo [link]
-       $(CC) -o $@ test1.o $(LDFLAGS) $(LIBS)
+       @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS)
        
 test2: test2.o
        @echo [link]
-       $(CC) -o $@ test2.o $(LDFLAGS) $(LIBS)
+       @$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS)
 
 speed: speed.o
        @echo [link]
-       $(CC) -o $@ speed.o $(LDFLAGS) $(LIBS)
+       @$(CC) -o $@ speed.o $(LDFLAGS) $(LDLIBS)
 
 lcd:   lcd.o
        @echo [link]
-       $(CC) -o $@ lcd.o $(LDFLAGS) $(LIBS)
+       @$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS)
 
 wfi:   wfi.o
        @echo [link]
-       $(CC) -o $@ wfi.o $(LDFLAGS) $(LIBS) -lpthread
+       @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS)
 
 piface:        piface.o
        @echo [link]
-       $(CC) -o $@ piface.o $(LDFLAGS) $(LIBS) -lpthread
+       @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) -lpthread
 
 gertboard:     gertboard.o
        @echo [link]
-       $(CC) -o $@ gertboard.o $(LDFLAGS) $(LIBS) -lm
+       @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) -lm
 
 nes:   nes.o
        @echo [link]
-       $(CC) -o $@ nes.o $(LDFLAGS) $(LIBS) -lm
+       @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) -lm
 
-softPwm:       softPwm.o
+pwm:   pwm.o
        @echo [link]
-       $(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread
+       @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) -lm -lpthread
 
 delayTest:     delayTest.o
        @echo [link]
-       $(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS)
+       @$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS)
+
+serialRead:    serialRead.o
+       @echo [link]
+       @$(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS)
+
+okLed: okLed.o
+       @echo [link]
+       @$(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS)
+
+tone:  tone.o
+       @echo [link]
+       @$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS)
+
+servo: servo.o
+       @echo [link]
+       @$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS)
 
 
 .c.o:
@@ -92,7 +111,7 @@ delayTest:   delayTest.o
        @$(CC) -c $(CFLAGS) $< -o $@
 
 clean:
-       rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm
+       rm -f $(OBJ) *~ core tags $(BINS)
 
 tags:  $(SRC)
        @echo [ctags]
index 8c955224ecb08ef78c61edb57182492ee892b93d..d05f3ffc28dcc65e7bbf558331454278c6165c72 100644 (file)
@@ -3,30 +3,24 @@
 #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 ;
+  int t ;
+  int max, min ;
+  int del ;
+  int underRuns, overRuns, exactRuns, total ;
+  int descheds ;
 
   if (wiringPiSetup () == -1)
     return 1 ;
 
-  piHiPri (10) ;
-  sleep (1) ;
+  piHiPri (10) ; sleep (1) ;
 
 // Baseline test
 
@@ -34,35 +28,56 @@ int main()
   gettimeofday (&t2, NULL) ;
 
   t = t2.tv_usec - t1.tv_usec ;
-  printf ("Baseline test: %lld\n", t);
+  printf ("Baseline test: %d\n", t);
 
-  for (x = 0 ; x < CYCLES ; ++x)
+  for (del = 1 ; del < 200 ; ++del)
   {
-    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 ;
-  }
+    underRuns = overRuns = exactRuns = total = 0 ;
+    descheds = 0 ;
+    max = del ;
+    min = del ;
 
-  printf ("Done: Max: %d, min: %d\n", max, min) ;
+    for (x = 0 ; x < CYCLES ; ++x)
+    {
+      for (;;)                         // Repeat this if we get a delay over 999uS
+      {                                        // -> High probability Linux has deschedulled us
+       gettimeofday (&t1, NULL) ;
+         delayMicroseconds (del) ;
+       gettimeofday (&t2, NULL) ;
 
-  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") ;
+       if (t2.tv_usec < t1.tv_usec)    // Counter wrapped
+         t = (1000000 + t2.tv_usec) - t1.tv_usec;
+       else
+         t = t2.tv_usec - t1.tv_usec ;
+       if (t > 999)
+       {
+         ++descheds ;
+         continue ;
+       }
+       else
+         break ;
+      }
+
+      if (t > max)
+      {
+        max = t ;
+       ++overRuns ;
+      }
+      else if (t < min)
+      {
+       min = t ;
+       ++underRuns ;
+      }
+      else
+       ++exactRuns ;
+
+      total += t ;
+    }
+    printf ("Delay: %3d. Min: %3d, Max: %3d, Unders: %3d, Overs: %3d, Exacts: %3d, Average: %3d,  Descheds: %2d\n",
+       del, min, max, underRuns, overRuns, exactRuns, total / CYCLES,  descheds) ;
+    fflush (stdout) ;
+    delay (1) ;
   }
-  printf ("\n") ;
 
   return 0 ;
 }
diff --git a/examples/okLed.c b/examples/okLed.c
new file mode 100644 (file)
index 0000000..3bf21e2
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * okLed:
+ *      Make the OK LED on the Pi Pulsate...
+ *    Copyright (c) 2012 gordon Henderson, but please Share and Enjoy!
+ *
+ * Originally posted to the Raspberry Pi forums:
+ *  http://www.raspberrypi.org/phpBB3/viewtopic.php?p=162581#p162581
+ *
+ * Compile this and store it somewhere, then kick it off at boot time
+ *    e.g. by putting it in /etc/rc.local and running it in the
+ *    background &
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <wiringPi.h>
+#include <softPwm.h>
+
+#define OK_LED  16
+
+int main ()
+{
+  int fd, i ;
+
+  if ((fd = open ("/sys/class/leds/led0/trigger", O_RDWR)) < 0)
+  {
+    fprintf (stderr, "Unable to change LED trigger: %s\n", strerror (errno)) ;
+    return 1 ;
+  }
+
+  write (fd, "none\n", 5) ;
+  close (fd) ;
+
+  if (wiringPiSetupGpio () < 0)
+  {
+    fprintf (stderr, "Unable to setup GPIO: %s\n", strerror (errno)) ;
+    return 1 ;
+  }
+
+  softPwmCreate (OK_LED, 0, 100) ;
+
+  for (;;)
+  {
+    for (i = 0 ; i <= 100 ; ++i)
+    {
+      softPwmWrite (OK_LED, i) ;
+      delay (10) ;
+    }
+    delay (50) ;
+
+    for (i = 100 ; i >= 0 ; --i)
+    {
+      softPwmWrite (OK_LED, i) ;
+      delay (10) ;
+    }
+    delay (10) ;
+  }
+
+  return 0 ;
+}
similarity index 100%
rename from examples/softPwm.c
rename to examples/pwm.c
diff --git a/examples/serialRead.c b/examples/serialRead.c
new file mode 100644 (file)
index 0000000..34b9bad
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * serialRead.c:
+ *     Example program to read bytes from the Serial line
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <wiringSerial.h>
+
+int main ()
+{
+  int fd ;
+
+  if ((fd = serialOpen ("/dev/ttyAMA0", 115200)) < 0)
+  {
+    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
+    return 1 ;
+  }
+
+// Loop, getting and printing characters
+
+  for (;;)
+  {
+    putchar (serialGetchar (fd)) ;
+    fflush (stdout) ;
+  }
+}
diff --git a/examples/servo.c b/examples/servo.c
new file mode 100644 (file)
index 0000000..0237832
--- /dev/null
@@ -0,0 +1,33 @@
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <wiringPi.h>
+#include <softServo.h>
+
+int main ()
+{
+  if (wiringPiSetup () == -1)
+  {
+    fprintf (stdout, "oops: %s\n", strerror (errno)) ;
+    return 1 ;
+  }
+
+  softServoSetup (0, 1, 2, 3, 4, 5, 6, 7) ;
+
+  softServoWrite (0,  0) ;
+/*
+  softServoWrite (1, 1000) ;
+  softServoWrite (2, 1100) ;
+  softServoWrite (3, 1200) ;
+  softServoWrite (4, 1300) ;
+  softServoWrite (5, 1400) ;
+  softServoWrite (6, 1500) ;
+  softServoWrite (7, 2200) ;
+*/
+
+  for (;;)
+    delay (10) ;
+
+}
diff --git a/examples/tone.c b/examples/tone.c
new file mode 100644 (file)
index 0000000..8b1fcd7
--- /dev/null
@@ -0,0 +1,37 @@
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <wiringPi.h>
+#include <softTone.h>
+
+#define RANGE          100
+#define        NUM_LEDS         12
+
+int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ;
+
+int main ()
+{
+  int i, j ;
+  char buf [80] ;
+
+  if (wiringPiSetup () == -1)
+  {
+    fprintf (stdout, "oops: %s\n", strerror (errno)) ;
+    return 1 ;
+  }
+
+  softToneCreate (3) ;
+
+  for (;;)
+  {
+    for (i = 0 ; i < 8 ; ++i)
+    {
+      printf ("%3d\n", i) ;
+      softToneWrite (3, scale [i]) ;
+      delay (500) ;
+    }
+  }
+
+}
index be38791cb344159587d15942ce28beb89bfa8bb2..c39e5dc9c3e093b72717cc6c0e783e78c726be43 100644 (file)
@@ -9,11 +9,11 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
 .PP
 .B gpio
 .B [ \-g ]
-.B read/write/pwm/mode ...
+.B read/write/wb/pwm/mode ...
 .PP
 .B gpio
 .B [ \-p ]
-.B read/write/mode
+.B read/write/wb
 .B ...
 .PP
 .B gpio
@@ -82,7 +82,14 @@ respective logic levels.
 
 .TP
 .B write <pin> <value>
-Write the given value (0 or 1) to the pin.
+Write the given value (0 or 1) to the pin. You need to set the pin
+to output mode first.
+
+.TP
+.B wb <value>
+Write the given byte to the 8 main GPIO pins. You can prefix it with 0x
+to specify a hexadecimal number. You need to set pins to output mode
+first.
 
 .TP
 .B readall
index f019c1ff9765166793c06ec6618a3d5fb63222e2..52fcb6fc554470032f6e21782098c15e792ef5c3 100644 (file)
 #  define      FALSE   (1==2)
 #endif
 
-#define        VERSION "1.4"
+#define        VERSION "1.5"
 
 static int wpMode ;
 
 char *usage = "Usage: gpio -v\n"
               "       gpio -h\n"
-              "       gpio [-g] <read/write/pwm/mode> ...\n"
-              "       gpio [-p] <read/write/mode> ...\n"
+              "       gpio [-g] <read/write/wb/pwm/mode> ...\n"
+              "       gpio [-p] <read/write/wb> ...\n"
              "       gpio readall\n"
              "       gpio unexportall/exports ...\n"
              "       gpio export/edge/unexport ...\n"
@@ -133,7 +133,7 @@ static void _doLoadUsage (char *argv [])
 
 static void doLoad (int argc, char *argv [])
 {
-  char *module ;
+  char *module1, *module2 ;
   char cmd [80] ;
   char *file1, *file2 ;
 
@@ -142,28 +142,36 @@ static void doLoad (int argc, char *argv [])
 
   /**/ if (strcasecmp (argv [2], "spi") == 0)
   {
-    module = "spi_bcm2708" ;
+    module1 = "spidev" ;
+    module2 = "spi_bcm2708" ;
     file1  = "/dev/spidev0.0" ;
     file2  = "/dev/spidev0.1" ;
   }
   else if (strcasecmp (argv [2], "i2c") == 0)
   {
-    module = "i2c_bcm2708" ;
+    module1 = "i2c_dev" ;
+    module2 = "i2c_bcm2708" ;
     file1  = "/dev/i2c-0" ;
     file2  = "/dev/i2c-1" ;
   }
   else
     _doLoadUsage (argv) ;
 
-  if (!moduleLoaded (module))
+  if (!moduleLoaded (module1))
   {
-    sprintf (cmd, "modprobe %s", module) ;
+    sprintf (cmd, "modprobe %s", module1) ;
     system (cmd) ;
   }
 
-  if (!moduleLoaded (module))
+  if (!moduleLoaded (module2))
   {
-    fprintf (stderr, "%s: Unable to load %s\n", argv [0], module) ;
+    sprintf (cmd, "modprobe %s", module2) ;
+    system (cmd) ;
+  }
+
+  if (!moduleLoaded (module2))
+  {
+    fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
     exit (1) ;
   }
 
@@ -588,6 +596,7 @@ static void doPadDrive (int argc, char *argv [])
 /*
  * doGbw:
  *     gpio gbw channel value
+ *     Gertboard Write - To the Analog output
  *********************************************************************************
  */
 
@@ -629,6 +638,7 @@ static void doGbw (int argc, char *argv [])
 /*
  * doGbr:
  *     gpio gbr channel
+ *     From the analog input
  *********************************************************************************
  */
 
@@ -682,7 +692,12 @@ static void doWrite (int argc, char *argv [])
   if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
     return ;
 
-  val = atoi (argv [3]) ;
+  /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
+    val = 1 ;
+  else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
+    val = 0 ;
+  else
+    val = atoi (argv [3]) ;
 
   /**/ if (val == 0)
     digitalWrite (pin, LOW) ;
@@ -690,6 +705,27 @@ static void doWrite (int argc, char *argv [])
     digitalWrite (pin, HIGH) ;
 }
 
+/*
+ * doWriteByte:
+ *     gpio write value
+ *********************************************************************************
+ */
+
+static void doWriteByte (int argc, char *argv [])
+{
+  int val ;
+
+  if (argc != 3)
+  {
+    fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  val = (int)strtol (argv [2], NULL, 0) ;
+
+  digitalWriteByte (val) ;
+}
+
 
 /*
  * doRead:
@@ -936,11 +972,12 @@ int main (int argc, char *argv [])
 
 // Check for wiring commands
 
-  /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall  () ;
-  else if (strcasecmp (argv [1], "read" )    == 0) doRead     (argc, argv) ;
-  else if (strcasecmp (argv [1], "write")    == 0) doWrite    (argc, argv) ;
-  else if (strcasecmp (argv [1], "pwm"  )    == 0) doPwm      (argc, argv) ;
-  else if (strcasecmp (argv [1], "mode" )    == 0) doMode     (argc, argv) ;
+  /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall   () ;
+  else if (strcasecmp (argv [1], "read" )    == 0) doRead      (argc, argv) ;
+  else if (strcasecmp (argv [1], "write")    == 0) doWrite     (argc, argv) ;
+  else if (strcasecmp (argv [1], "wb")       == 0) doWriteByte (argc, argv) ;
+  else if (strcasecmp (argv [1], "pwm"  )    == 0) doPwm       (argc, argv) ;
+  else if (strcasecmp (argv [1], "mode" )    == 0) doMode      (argc, argv) ;
   else
   {
     fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
index c0a39f993db9822ce0781bb09b46d916aee063eb..e18a654eddc5de9424c44fd4c01906efe69749de 100644 (file)
 DYN_VERS_MAJ=1
 DYN_VERS_MIN=0
 
+VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
+DESTDIR=/usr
+PREFIX=/local
+
 STATIC=libwiringPi.a
-DYNAMIC=libwiringPi.so.$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
+DYNAMIC=libwiringPi.so.$(VERSION)
 
 #DEBUG = -g -O0
 DEBUG  = -O2
@@ -41,21 +45,22 @@ LIBS    =
 SRC    =       wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c  \
                gertboard.c                                             \
                piNes.c                                                 \
-               lcd.c piHiPri.c piThread.c softPwm.c wiringPiSPI.c
+               lcd.c piHiPri.c piThread.c wiringPiSPI.c                \
+               softPwm.c softServo.c softTone.c
 
 OBJ    =       $(SRC:.c=.o)
 
-#all:          $(STATIC) $(DYNAMIC)
-all:           $(DYNAMIC)
+all:           $(STATIC) $(DYNAMIC)
+#all:          $(DYNAMIC)
 
 $(STATIC):     $(OBJ)
-       @echo [Link (Static)]
+       @echo "[Link (Static)]"
        @ar rcs $(STATIC) $(OBJ)
        @ranlib $(STATIC)
-       @size   $(STATIC)
+#      @size   $(STATIC)
 
 $(DYNAMIC):    $(OBJ)
-       @echo [Link]
+       @echo "[Link (Dynamic)]"
        @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ)
 
 .c.o:
@@ -74,34 +79,38 @@ tags:       $(SRC)
 .PHONEY:       install
 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 softPwm.h      /usr/local/include
-       @install -m 0644 lcd.h          /usr/local/include
-       @install -m 0644 wiringPiSPI.h  /usr/local/include
-#      @install -m 0644 libwiringPi.a  /usr/local/lib
-       @install        -m 0755 libwiringPi.so.1.0 /usr/local/lib
-       @ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so
-       @ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so.1
+       @install -m 0755 -d                     $(DESTDIR)$(PREFIX)/lib
+       @install -m 0755 -d                     $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 wiringPi.h             $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 wiringSerial.h         $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 wiringShift.h          $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 gertboard.h            $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 piNes.h                $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 softPwm.h              $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 softServo.h            $(DESTDIR)$(PREFIX)/include
+       @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 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:       uninstall
 uninstall:
        @echo "[UnInstall]"
-       @rm -f /usr/local/include/wiringPi.h
-       @rm -f /usr/local/include/wiringSerial.h
-       @rm -f /usr/local/include/wiringShift.h
-       @rm -f /usr/local/include/gertboard.h
-       @rm -f /usr/local/include/piNes.h
-       @rm -f /usr/local/include/softPwm.h
-       @rm -f /usr/local/include/lcd.h
-       @rm -f /usr/local/include/wiringPiSPI.h
-       @rm -f /usr/local/lib/libwiringPi.*
+       @rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/piNes.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/softPwm.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/softServo.h
+       @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)/lib/libwiringPi.*
        @ldconfig
 
 
diff --git a/wiringPi/softServo.c b/wiringPi/softServo.c
new file mode 100644 (file)
index 0000000..a6ff1fb
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * softServo.c:
+ *     Provide N channels of software driven PWM suitable for RC
+ *     servo motors.
+ *     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 <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include "wiringPi.h"
+#include "softServo.h"
+
+// RC Servo motors are a bit of an oddity - designed in the days when 
+//     radio control was experimental and people were tryin to make
+//     things as simple as possible as it was all very expensive...
+//
+// So... To drive an RC Servo motor, you need to send it a modified PWM
+//     signal - it needs anything from 1ms to 2ms - with 1ms meaning
+//     to move the server fully left, and 2ms meaning to move it fully
+//     right. Then you need a long gap before sending the next pulse.
+//     The reason for this is that you send a multiplexed stream of these
+//     pulses up the radio signal into the reciever which de-multiplexes
+//     them into the signals for each individual servo. Typically there
+//     might be 8 channels, so you need at least 8 "slots" of 2mS pulses
+//     meaning the entire frame must fit into a 16mS slot - which would
+//     then be repeated...
+//
+// In practice we have a total slot width of about 20mS - so we're sending 50
+//     updates per second to each servo.
+//
+// In this code, we don't need to be too fussy about the gap as we're not doing
+//     the multipexing, but it does need to be at least 10mS, and preferably 16
+//     from what I've been able to determine.
+
+
+#define        MAX_SERVOS      8
+
+static int pinMap     [MAX_SERVOS] ;   // Keep track of our pins
+static int pulseWidth [MAX_SERVOS] ;   // microseconds
+
+
+/*
+ * softServoThread:
+ *     Thread to do the actual Servo PWM output
+ *********************************************************************************
+ */
+
+static PI_THREAD (softServoThread)
+{
+  register int i, j, k, m, tmp ;
+  int lastDelay, pin, servo ;
+
+  int myDelays [MAX_SERVOS] ;
+  int myPins   [MAX_SERVOS] ;
+
+  struct timeval  tNow, tStart, tPeriod, tGap, tTotal ;
+  struct timespec tNs ;
+
+  tTotal.tv_sec  =    0 ;
+  tTotal.tv_usec = 8000 ;
+
+  piHiPri (50) ;
+
+  for (;;)
+  {
+    gettimeofday (&tStart, NULL) ;
+
+    memcpy (myDelays, pulseWidth, sizeof (myDelays)) ;
+    memcpy (myPins,   pinMap,     sizeof (myPins)) ;
+
+// Sort the delays (& pins), shortest first
+
+    for (m = MAX_SERVOS / 2 ; m > 0 ; m /= 2 )
+      for (j = m ; j < MAX_SERVOS ; ++j)
+       for (i = j - m ; i >= 0 ; i -= m)
+       {
+         k = i + m ;
+         if (myDelays [k] >= myDelays [i])
+           break ;
+         else // Swap
+         {
+           tmp = myDelays [i] ; myDelays [i] = myDelays [k] ; myDelays [k] = tmp ;
+           tmp = myPins   [i] ; myPins   [i] = myPins   [k] ; myPins   [k] = tmp ;
+         }
+       }
+
+// All on
+
+    lastDelay = 0 ;
+    for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
+    {
+      if ((pin = myPins [servo]) == -1)
+       continue ;
+
+      digitalWrite (pin, HIGH) ;
+      myDelays [servo] = myDelays [servo] - lastDelay ;
+      lastDelay += myDelays [servo] ;
+    }
+
+// Now loop, turning them all off as required
+
+    for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
+    {
+      if ((pin = myPins [servo]) == -1)
+       continue ;
+
+      delayMicroseconds (myDelays [servo]) ;
+      digitalWrite (pin, LOW) ;
+    }
+
+// Wait until the end of an 8mS time-slot
+
+    gettimeofday (&tNow, NULL) ;
+    timersub (&tNow, &tStart, &tPeriod) ;
+    timersub (&tTotal, &tPeriod, &tGap) ;
+    tNs.tv_sec  = tGap.tv_sec ;
+    tNs.tv_nsec = tGap.tv_usec * 1000 ;
+    nanosleep (&tNs, NULL) ;
+  }
+
+  return NULL ;
+}
+
+
+/*
+ * softServoWrite:
+ *     Write a Servo value to the given pin
+ *********************************************************************************
+ */
+
+void softServoWrite (int servoPin, int value)
+{
+  int servo ;
+
+  servoPin &= 63 ;
+
+  /**/ if (value < -250)
+    value = -250 ;
+  else if (value > 1250)
+    value = 1250 ;
+
+  for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
+    if (pinMap [servo] == servoPin)
+      pulseWidth [servo] = value + 1000 ; // uS
+}
+
+
+/*
+ * softServoSetup:
+ *     Setup the software servo system
+ *********************************************************************************
+ */
+
+int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7)
+{
+  int servo ;
+
+  if (p0 != -1) { pinMode (p0, OUTPUT) ; digitalWrite (p0, LOW) ; }
+  if (p1 != -1) { pinMode (p1, OUTPUT) ; digitalWrite (p1, LOW) ; }
+  if (p2 != -1) { pinMode (p2, OUTPUT) ; digitalWrite (p2, LOW) ; }
+  if (p3 != -1) { pinMode (p3, OUTPUT) ; digitalWrite (p3, LOW) ; }
+  if (p4 != -1) { pinMode (p4, OUTPUT) ; digitalWrite (p4, LOW) ; }
+  if (p5 != -1) { pinMode (p5, OUTPUT) ; digitalWrite (p5, LOW) ; }
+  if (p6 != -1) { pinMode (p6, OUTPUT) ; digitalWrite (p6, LOW) ; }
+  if (p7 != -1) { pinMode (p7, OUTPUT) ; digitalWrite (p7, LOW) ; }
+
+  pinMap [0] = p0 ;
+  pinMap [1] = p1 ;
+  pinMap [2] = p2 ;
+  pinMap [3] = p3 ;
+  pinMap [4] = p4 ;
+  pinMap [5] = p5 ;
+  pinMap [6] = p6 ;
+  pinMap [7] = p7 ;
+
+  for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
+    pulseWidth [servo] = 1500 ;                // Mid point
+  
+  return piThreadCreate (softServoThread) ;
+}
diff --git a/wiringPi/softServo.h b/wiringPi/softServo.h
new file mode 100644 (file)
index 0000000..794cf55
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * softServo.h:
+ *     Provide N channels of software driven PWM suitable for RC
+ *     servo motors.
+ *     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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void softServoWrite  (int pin, int value) ;
+extern int softServoSetup   (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c
new file mode 100644 (file)
index 0000000..d14c2a2
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * softTone.c:
+ *     For that authentic retro sound...
+ *     Er... A little experiment to produce tones out of a Pi using
+ *     one (or 2) GPIO pins and a piezeo "speaker" element.
+ *     (Or a high impedance speaker, but don'y blame me if you blow-up
+ *     the GPIO pins!)
+ *     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 <pthread.h>
+
+#include "wiringPi.h"
+#include "softTone.h"
+
+#define        MAX_PINS        64
+
+#define        PULSE_TIME      100
+
+static int frewqs [MAX_PINS] ;
+
+static int newPin = -1 ;
+
+
+/*
+ * softToneThread:
+ *     Thread to do the actual PWM output
+ *********************************************************************************
+ */
+
+static PI_THREAD (softToneThread)
+{
+  int pin, frewq, halfPeriod ;
+
+  pin    = newPin ;
+  newPin = -1 ;
+
+  piHiPri (50) ;
+
+  for (;;)
+  {
+    frewq = frewqs [pin] ;
+    if (frewq != 0)
+    {
+      halfPeriod = 500000 / frewq ;
+
+      digitalWrite (pin, HIGH) ;
+      delayMicroseconds (halfPeriod) ;
+
+      digitalWrite (pin, LOW) ;
+      delayMicroseconds (halfPeriod) ;
+    }
+  }
+
+  return NULL ;
+}
+
+
+/*
+ * softToneWrite:
+ *     Write a frequency value to the given pin
+ *********************************************************************************
+ */
+
+void softToneWrite (int pin, int frewq)
+{
+  pin &= 63 ;
+
+  /**/ if (frewq < 0)
+    frewq = 0 ;
+  else if (frewq > 5000)       // Max 5KHz
+    frewq = 5000 ;
+
+  frewqs [pin] = frewq ;
+}
+
+
+/*
+ * softToneCreate:
+ *     Create a new tone thread.
+ *********************************************************************************
+ */
+
+int softToneCreate (int pin)
+{
+  int res ;
+
+  pinMode      (pin, OUTPUT) ;
+  digitalWrite (pin, LOW) ;
+
+  frewqs [pin] = 0 ;
+
+  newPin = pin ;
+  res = piThreadCreate (softToneThread) ;
+
+  while (newPin != -1)
+    delay (1) ;
+
+  return res ;
+}
diff --git a/wiringPi/softTone.h b/wiringPi/softTone.h
new file mode 100644 (file)
index 0000000..80c64fe
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * softTone.c:
+ *     For that authentic retro sound...
+ *     Er... A little experiment to produce tones out of a Pi using
+ *     one (or 2) GPIO pins and a piezeo "speaker" element.
+ *     (Or a high impedance speaker, but don'y blame me if you blow-up
+ *     the GPIO pins!)
+ *     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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int  softToneCreate (int pin) ;
+extern void softToneWrite  (int pin, int frewq) ;
+
+#ifdef __cplusplus
+}
+#endif
index 9fe3ab1b33d409376cb1c6938cce8cd3fbe9a7cb..df4d9698300b3fdb0eefca50a8abb84df8b6ffcc 100644 (file)
@@ -77,6 +77,7 @@
 void (*pinMode)           (int pin, int mode) ;
 void (*pullUpDnControl)   (int pin, int pud) ;
 void (*digitalWrite)      (int pin, int value) ;
+void (*digitalWriteByte)  (int value) ;
 void (*pwmWrite)          (int pin, int value) ;
 void (*setPadDrive)       (int group, int value) ;
 int  (*digitalRead)       (int pin) ;
@@ -399,15 +400,15 @@ int wpiPinToGpio (int wpiPin)
  *     Revision is currently 1 or 2. -1 is returned on error.
  *
  *     Much confusion here )-:
- *     Seems there ar esome boards with 0000 in them (mistake in manufacture)
- *     and some board with 0005 in them (another mistake in manufacture).
+ *     Seems there arsome boards with 0000 in them (mistake in manufacture)
+ *     and some board with 0005 in them (another mistake in manufacture?)
  *     So the distinction between boards that I can see is:
  *     0000 - Error
  *     0001 - Not used
  *     0002 - Rev 1
  *     0003 - Rev 1
  *     0004 - Rev 2
- *     0005 - Rev 2
+ *     0005 - Rev 2 (but error)
  *     0006 - Rev 2
  *     000f - Rev 2 + 512MB
  *
@@ -499,6 +500,8 @@ int piBoardRev (void)
 
 void pinModeGpio (int pin, int mode)
 {
+//  register int barrier ;
+
   int fSel, shift, alt ;
 
   pin &= 63 ;
@@ -519,30 +522,40 @@ void pinModeGpio (int pin, int mode)
 
     *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
 
+    delayMicroseconds (110) ;                          // See comments in pwmSetClockWPi
+    *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
+
 //  Page 107 of the BCM Peripherals manual talks about the GPIO clocks,
 //     but I'm assuming (hoping!) that this applies to other clocks too.
 
     *(pwm + PWM_CONTROL) = 0 ;                         // Stop PWM
+
     *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ;       // Stop PWM Clock
-      delayMicroseconds (110) ; // See comments in pwmSetClockWPi
+    delayMicroseconds (110) ;                          // See comments in pwmSetClockWPi
 
-    (void)*(pwm + PWM_CONTROL) ;
-    while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
+    while ((*(clk + PWMCLK_CNTL) & 0x80) != 0)         // Wait for clock to be !BUSY
       delayMicroseconds (1) ;
 
     *(clk + PWMCLK_DIV)  = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz)
     *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ;       // enable clk
 
-// Default range regsiter of 1024
+    delayMicroseconds (110) ;                          // See comments in pwmSetClockWPi
+
+// Default range register of 1024
 
-    *(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ;
-    *(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ;
+    *(pwm + PWM0_RANGE) = 1024 ; delayMicroseconds (10) ;
+    *(pwm + PWM1_RANGE) = 1024 ; delayMicroseconds (10) ;
+    *(pwm + PWM0_DATA)  =    0 ; delayMicroseconds (10) ;
+    *(pwm + PWM1_DATA)  =    0 ; delayMicroseconds (10) ;
 
 // Enable PWMs in balanced mode (default)
 
     *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
+
+    delay (100) ;
   }
 
+
 // When we change mode of any pin, we remove the pull up/downs
 //     Or we used to... Hm. Commented out now because for some wieird reason,
 //     it seems to block subsequent attempts to set the pull up/downs and I've
@@ -629,7 +642,7 @@ void pwmSetClockWPi (int divisor)
   *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
     delayMicroseconds (110) ;                  // prevents clock going sloooow
 
-  while ((*(pwm + PWM_CONTROL) & 0x80) != 0)   // Wait for clock to be !BUSY
+  while ((*(clk + PWMCLK_CNTL) & 0x80) != 0)   // Wait for clock to be !BUSY
     delayMicroseconds (1) ;
 
   *(clk + PWMCLK_DIV)  = BCM_PASSWORD | (divisor << 12) ;
@@ -704,6 +717,50 @@ void digitalWriteSys (int pin, int value)
 }
 
 
+/*
+ * digitalWriteByte:
+ *     Write an 8-bit byte to the first 8 GPIO pins - try to do it as
+ *     fast as possible.
+ *     However it still needs 2 operations to set the bits, so any external
+ *     hardware must not rely on seeing a change as there will be a change 
+ *     to set the outputs bits to zero, then another change to set the 1's
+ *********************************************************************************
+ */
+
+void digitalWriteByteGpio (int value)
+{
+  uint32_t pinSet = 0 ;
+  uint32_t pinClr = 0 ;
+  int mask = 1 ;
+  int pin ;
+
+  for (pin = 0 ; pin < 8 ; ++pin)
+  {
+    if ((value & mask) == 0)
+      pinClr |= (1 << pinToGpio [pin]) ;
+    else
+      pinSet |= (1 << pinToGpio [pin]) ;
+
+    *(gpio + gpioToGPCLR [0]) = pinClr ;
+    *(gpio + gpioToGPSET [0]) = pinSet ;
+
+    mask <<= 1 ;
+  }
+}
+
+void digitalWriteByteSys (int value)
+{
+  int mask = 1 ;
+  int pin ;
+
+  for (pin = 0 ; pin < 8 ; ++pin)
+  {
+    digitalWriteSys (pinToGpio [pin], value & mask) ;
+    mask <<= 1 ;
+  }
+}
+
+
 /*
  * pwmWrite:
  *     Set an output PWM value
@@ -915,6 +972,9 @@ void delay (unsigned int howLong)
  *     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 )-:
+ *
+ *      Plan B: It seems all might not be well with that plan, so changing it
+ *      to use gettimeofday () and poll on that instead...
  *********************************************************************************
  */
 
@@ -930,16 +990,31 @@ void delayMicrosecondsSys (unsigned int howLong)
 
 void delayMicrosecondsHard (unsigned int howLong)
 {
+#ifdef  HARD_TIMER
+  volatile unsigned int dummy ;
+
   *(timer + TIMER_LOAD)    = howLong ;
   *(timer + TIMER_IRQ_CLR) = 0 ;
 
-  while (*timerIrqRaw == 0)
-    ;
+  dummy = *timerIrqRaw ;
+  while (dummy == 0)
+    dummy = *timerIrqRaw ;
+#else
+  struct timeval tNow, tLong, tEnd ;
+
+  gettimeofday (&tNow, NULL) ;
+  tLong.tv_sec  = howLong / 1000000 ;
+  tLong.tv_usec = howLong % 1000000 ;
+  timeradd (&tNow, &tLong, &tEnd) ;
+
+  while (timercmp (&tNow, &tEnd, <))
+    gettimeofday (&tNow, NULL) ;
+#endif
 }
 
 void delayMicrosecondsWPi (unsigned int howLong)
 {
-  struct timespec sleeper, dummy ;
+  struct timespec sleeper ;
 
   /**/ if (howLong ==   0)
     return ;
@@ -949,7 +1024,7 @@ void delayMicrosecondsWPi (unsigned int howLong)
   {
     sleeper.tv_sec  = 0 ;
     sleeper.tv_nsec = (long)(howLong * 1000) ;
-    nanosleep (&sleeper, &dummy) ;
+    nanosleep (&sleeper, NULL) ;
   }
 }
 
@@ -998,6 +1073,7 @@ int wiringPiSetup (void)
             pinMode =           pinModeWPi ;
     pullUpDnControl =   pullUpDnControlWPi ;
        digitalWrite =      digitalWriteWPi ;
+   digitalWriteByte = digitalWriteByteGpio ;   // Same code
            pwmWrite =          pwmWriteWPi ;
         setPadDrive =       setPadDriveWPi ;
         digitalRead =       digitalReadWPi ;
@@ -1166,6 +1242,7 @@ int wiringPiSetupGpio (void)
             pinMode =           pinModeGpio ;
     pullUpDnControl =   pullUpDnControlGpio ;
        digitalWrite =      digitalWriteGpio ;
+   digitalWriteByte =  digitalWriteByteGpio ;
            pwmWrite =          pwmWriteGpio ;
         setPadDrive =       setPadDriveGpio ;
         digitalRead =       digitalReadGpio ;
@@ -1190,6 +1267,7 @@ int wiringPiSetupGpio (void)
 
 int wiringPiSetupSys (void)
 {
+  int boardRev ;
   int pin ;
   struct timeval tv ;
   char fName [128] ;
@@ -1200,6 +1278,7 @@ int wiringPiSetupSys (void)
             pinMode =           pinModeSys ;
     pullUpDnControl =   pullUpDnControlSys ;
        digitalWrite =      digitalWriteSys ;
+   digitalWriteByte =  digitalWriteByteSys ;
            pwmWrite =          pwmWriteSys ;
         setPadDrive =       setPadDriveSys ;
         digitalRead =       digitalReadSys ;
@@ -1209,6 +1288,14 @@ int wiringPiSetupSys (void)
         pwmSetRange =       pwmSetRangeSys ;
         pwmSetClock =       pwmSetClockSys ;
 
+  if ((boardRev = piBoardRev ()) < 0)
+    return -1 ;
+
+  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
index cab3080d4812861e9df47beaa2cd33b91c04f0b5..6a7278ee2d568d651a9a0c1bdd1313104a65dc82 100644 (file)
@@ -70,6 +70,7 @@ extern int  wiringPiSetupPiFaceForGpioProg (void) ;   // Don't use this - for gpio
 extern void (*pinMode)           (int pin, int mode) ;
 extern void (*pullUpDnControl)   (int pin, int pud) ;
 extern void (*digitalWrite)      (int pin, int value) ;
+extern void (*digitalWriteByte)  (int value) ;
 extern void (*pwmWrite)          (int pin, int value) ;
 extern void (*setPadDrive)       (int group, int value) ;
 extern int  (*digitalRead)       (int pin) ;
index 2425413ac7ddacf586bd0b8b076e0e8074fcaa53..ac3c6fa3ac0c8863cf21dd8ebe50401a2da3fe61 100644 (file)
@@ -182,6 +182,11 @@ void digitalWritePiFace (int pin, int value)
   writeByte (GPIOA, dataOutRegister) ;
 }
 
+void digitalWriteBytePiFace (int value)
+{
+  writeByte (GPIOA, value) ;
+}
+
 
 void digitalWritePiFaceSpecial (int pin, int value)
 {
@@ -318,12 +323,13 @@ int wiringPiSetupPiFace (void)
   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 ;
+           pinMode =              pinModePiFace ;
+   pullUpDnControl =      pullUpDnControlPiFace ;
+      digitalWrite =         digitalWritePiFace ;
+  digitalWriteByte =     digitalWriteBytePiFace ;
+          pwmWrite =             pwmWritePiFace ;
+       digitalRead =          digitalReadPiFace ;
+  waitForInterrupt =     waitForInterruptPiFace ;
 
   return 0 ;
 }
@@ -344,12 +350,13 @@ int wiringPiSetupPiFaceForGpioProg (void)
   if (x != 0)
     return x ;
 
-           pinMode =          pinModePiFace ;
+           pinMode =                 pinModePiFace ;
    pullUpDnControl =  pullUpDnControlPiFaceSpecial ;
       digitalWrite =     digitalWritePiFaceSpecial ;
-          pwmWrite =         pwmWritePiFace ;
-       digitalRead =      digitalReadPiFace ;
-  waitForInterrupt = waitForInterruptPiFace ;
+  digitalWriteByte =        digitalWriteBytePiFace ;
+          pwmWrite =                pwmWritePiFace ;
+       digitalRead =             digitalReadPiFace ;
+  waitForInterrupt =        waitForInterruptPiFace ;
 
   return 0 ;
 }
index f2e30003ed1c28306b1c204f996f1d82c88a469d..44414985318a3bcee99ebfd38173ea5bea18242e 100644 (file)
@@ -52,7 +52,7 @@ static int         spiFds [2] ;
 
 int wiringPiSPIGetFd (int channel)
 {
-  return spiFds [channel &1] ;
+  return spiFds [channel & 1] ;
 }