Gordons Projects

--> Projects Top-Level GIT

changed to pin mode to support softPwm.
authorGordon Henderson <projects@drogon.net>
Tue, 20 May 2014 10:43:07 +0000 (11:43 +0100)
committerGordon Henderson <projects@drogon.net>
Tue, 20 May 2014 10:43:07 +0000 (11:43 +0100)
bugfix in blink.sh - wring pin
improving the maxdetect routing - a little.
gpio pins

examples/blink.sh
examples/blink6drcs.c [new file with mode: 0644]
examples/rht03.c
gpio/Makefile
gpio/gpio.1
gpio/gpio.c
gpio/pins.c [new file with mode: 0644]
wiringPi/softPwm.c
wiringPi/softPwm.h
wiringPi/wiringPi.c
wiringPi/wiringPi.h

index 2aa378a..7755383 100644 (file)
@@ -25,7 +25,7 @@
 
 # LED Pin - wiringPi pin 0 is BCM_GPIO 17.
 
-LED=0
+PIN=0
 
 gpio mode $PIN out
 
diff --git a/examples/blink6drcs.c b/examples/blink6drcs.c
new file mode 100644 (file)
index 0000000..32f4921
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * blink6drcs.c:
+ *     Simple sequence over 6 pins on a remote DRC board.
+ *     Aimed at the Gertduino, but it's fairly generic.
+ *     This version uses DRC to talk to the ATmega on the Gertduino
+ *
+ * Copyright (c) 2012-2014 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * 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 <wiringPi.h>
+#include <drcSerial.h>
+
+#define        GERT_BASE       100
+
+static int pinMap [] =
+{
+  GERT_BASE + 6, GERT_BASE + 5, GERT_BASE + 3, GERT_BASE + 10, GERT_BASE + 9, GERT_BASE + 13,
+} ;
+
+// Simple sequencer data
+//     Triplets of LED, On/Off and delay
+
+
+int 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, 1,
+   5, 0, 1,
+
+   0, 0, 1,    // Extra delay
+
+// Back again
+
+               5, 1, 1,
+               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
+
+   0, 9, 0,    // End marker
+
+} ;
+
+
+int main (void)
+{
+  int pin ;
+  int dataPtr ;
+  int l, s, d ;
+
+  printf ("Raspberry Pi - 6-LED Sequence\n") ;
+  printf ("=============================\n") ;
+  printf ("\n") ;
+  printf ("  Use the 2 buttons to temporarily speed up the sequence\n") ;
+
+  wiringPiSetupSys  () ;       // Not using the Pi's GPIO here
+  drcSetupSerial (GERT_BASE, 20, "/dev/ttyAMA0", 115200) ;
+
+  for (pin = 0 ; pin < 6 ; ++pin)
+    pinMode (pinMap [pin], OUTPUT) ;
+
+  pinMode (GERT_BASE + 16, INPUT) ;    // Buttons
+  pinMode (GERT_BASE + 17, INPUT) ;
+
+  pullUpDnControl (GERT_BASE + 16, PUD_UP) ;
+  pullUpDnControl (GERT_BASE + 17, PUD_UP) ;
+
+  dataPtr = 0 ;
+
+  for (;;)
+  {
+    l = data [dataPtr++] ;     // LED
+    s = data [dataPtr++] ;     // State
+    d = data [dataPtr++] ;     // Duration (10ths)
+
+    if (s == 9)                        // 9 -> End Marker
+    {
+      dataPtr = 0 ;
+      continue ;
+    }
+
+    digitalWrite (pinMap [l], s) ;
+    delay        (d * digitalRead (GERT_BASE + 16) * 15 + digitalRead (GERT_BASE + 17) * 20) ;
+  }
+
+  return 0 ;
+}
index e0cc116..566e954 100644 (file)
@@ -56,6 +56,11 @@ int main (void)
     {
       temp = newTemp ;
       rh   = newRh ;
+      if ((temp & 0x8000) != 0)        // Negative
+      {
+       temp &= 0x7FFF ;
+       temp = -temp ;
+      }
       printf ("Temp: %5.1f, RH: %5.1f%%\n", temp / 10.0, rh / 10.0) ;
     }
   }
index 8fa12d5..37b4887 100644 (file)
@@ -38,7 +38,7 @@ LIBS    = -lwiringPi -lwiringPiDev -lpthread -lm
 # May not need to  alter anything below this line
 ###############################################################################
 
-SRC    =       gpio.c extensions.c readall.c
+SRC    =       gpio.c extensions.c readall.c pins.c
 
 OBJ    =       $(SRC:.c=.o)
 
@@ -52,17 +52,17 @@ gpio:       $(OBJ)
        @echo [Compile] $<
        @$(CC) -c $(CFLAGS) $< -o $@
 
-.PHONEY:       clean
+.PHONY:        clean
 clean:
        @echo "[Clean]"
        @rm -f $(OBJ) gpio *~ core tags *.bak
 
-.PHONEY:       tags
+.PHONY:        tags
 tags:  $(SRC)
        @echo [ctags]
        @ctags $(SRC)
 
-.PHONEY:       install
+.PHONY:        install
 install:
        @echo "[Install]"
        @cp gpio                $(DESTDIR)$(PREFIX)/bin
@@ -71,13 +71,13 @@ install:
        @mkdir -p               $(DESTDIR)$(PREFIX)/man/man1
        @cp gpio.1              $(DESTDIR)$(PREFIX)/man/man1
 
-.PHONEY:       uninstall
+.PHONY:        uninstall
 uninstall:
        @echo "[UnInstall]"
        @rm -f $(DESTDIR)$(PREFIX)/bin/gpio
        @rm -f $(DESTDIR)$(PREFIX)/man/man1/gpio.1
 
-.PHONEY:       depend
+.PHONY:        depend
 depend:
        makedepend -Y $(SRC)
 
index e1cba32..7300466 100644 (file)
@@ -115,6 +115,28 @@ Write the given value (0 or 1) to the pin. You need to set the pin
 to output mode first.
 
 .TP
+.B aread <pin>
+Read the analog value of the given pin. This needs to be uses in
+conjunction with a -x flag to add in an extension that handles analog
+inputs.  respective logic levels.
+
+e.g. gpio -x mcp3002:200:0 aread 200
+
+will read the first analog input on an mcp3002 SPI ADC chip.
+
+.TP
+.B awrite <pin> <value>
+Write the analog value to the given pin. This needs to be used in
+conjunction with a -x flag to add in an extension that handles analog
+inputs.  respective logic levels.
+
+e.g. gpio -x mcp4802:200:0 awrite 200 128
+
+will write the value 128 to the first DAC port on an mcp4802 chip on
+the Pi's SPI bus 0.
+
+
+.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
@@ -132,8 +154,9 @@ digital and analog read on each pin in-turn.
 
 .TP
 .B reset
-Resets the GPIO - As much as it's possible to do. All pins are set to input
-mode and all the internal pull-up/down resistors are disconnected (tristate mode).
+Resets the GPIO - As much as it's possible to do. All pins are set to
+input mode and all the internal pull-up/down resistors are disconnected
+(tristate mode).
 
 The reset command is usable with an extension module (via the -x parameter),
 but it's limited to turning the pin into input mode (if applicable) and
index b65af0e..d941db5 100644 (file)
 
 extern int wiringPiDebug ;
 
+// External functions I can't be bothered creating a separate .h file for:
+
 extern void doReadall    (void) ;
 extern void doReadallOld (void) ;
 
+extern void doPins       (void) ;
+
 #ifndef TRUE
 #  define      TRUE    (1==1)
 #  define      FALSE   (1==2)
 #endif
 
-#define        VERSION         "2.13"
+#define        VERSION         "2.14"
 #define        I2CDETECT       "/usr/sbin/i2cdetect"
 
 int wpMode ;
@@ -1078,7 +1082,7 @@ int main (int argc, char *argv [])
   if (strcmp (argv [1], "-v") == 0)
   {
     printf ("gpio version: %s\n", VERSION) ;
-    printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
+    printf ("Copyright (c) 2012-2014 Gordon Henderson\n") ;
     printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
     printf ("For details type: %s -warranty\n", argv [0]) ;
     printf ("\n") ;
@@ -1220,6 +1224,7 @@ int main (int argc, char *argv [])
   else if (strcasecmp (argv [1], "drive"    ) == 0) doPadDrive   (argc, argv) ;
   else if (strcasecmp (argv [1], "readall"  ) == 0) doReadallOld () ;
   else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall    () ;
+  else if (strcasecmp (argv [1], "pins"     ) == 0) doPins       () ;
   else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect  (argc, argv) ;
   else if (strcasecmp (argv [1], "i2cd"     ) == 0) doI2Cdetect  (argc, argv) ;
   else if (strcasecmp (argv [1], "reset"    ) == 0) doReset      (argv [0]) ;
diff --git a/gpio/pins.c b/gpio/pins.c
new file mode 100644 (file)
index 0000000..6df3cb2
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * pins.c:
+ *     Just display a handy Pi pinnout diagram.
+ *     Copyright (c) 2012-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 <stdint.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <wiringPi.h>
+
+extern int wpMode ;
+
+void doPins (void)
+{
+  printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
+
+  printf (
+" +-----+--------+------------+--------+-----+\n"
+" | Pin |   Name ||  P1 Pin  ||  Name  | Pin |\n"
+" +-----+--------+------------+--------+-----+\n"
+" |     |  3.3v  ||  1 oo 2  ||     5v |     |\n"
+" |   8 |   SDA  ||  3 oo 4  ||     5v |     |\n"
+" |   9 |    SCL ||  5 oo 6  ||    Gnd |     |\n"
+" |   7 | GPIO 7 ||  7 oo 8  ||    TxD |  15 |\n"
+" |     |    GND ||  9 oo 10 ||    RxD |  16 |\n"
+" |   0 | GPIO 0 || 11 oo 12 || GPIO 1 |   1 |\n"
+" |   2 | GPIO 2 || 13 oo 14 ||    Gnd |     |\n"
+" |   3 | GPIO 3 || 15 oo 16 || GPIO 4 |   4 |\n"
+" |     |   3.3v || 17 oo 18 || GPIO 5 |   5 |\n"
+" |  12 |   MOSI || 19 oo 20 ||    Gnd |     |\n"
+" |  13 |   MISO || 21 oo 22 || GPIO 6 |   6 |\n"
+" |  14 |   SCLK || 23 oo 24 ||   CE 0 |  10 |\n"
+" |     |    Gnd || 25 oo 26 ||   CE 1 |  11 |\n"
+" +-----+--------+------------+--------+-----+\n") ;
+
+/***
+ +---
+ |  5v|  5v| Gnd | TxD | RxD | G1  | Gnd |  G4  |  G5  | G
+ |  2 |  4 |  6 |  8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 |\n"
+ |  1 |  3 |  5 |  7 |  9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 |\n"
+***/
+
+}
index a4f0fc4..0bde180 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * softPwm.c:
  *     Provide 2 channels of software driven PWM.
- *     Copyright (c) 2012 Gordon Henderson
+ *     Copyright (c) 2012-2014 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
 #include "wiringPi.h"
 #include "softPwm.h"
 
+// MAX_PINS:
+//     This is more than the number of Pi pins because we can actually softPwm
+//     pins that are on GPIO expanders. It's not that efficient and more than 1 or
+//     2 pins on e.g. (SPI) mcp23s17 won't really be that effective, however...
+
 #define        MAX_PINS        1024
 
 // The PWM Frequency is derived from the "pulse time" below. Essentially,
 //     the frequency is a function of the range and this pulse time.
-//     The total period will be range * pulse time in uS, so a pulse time
-//     of 100 and a range of 100 gives a period of 100 * 100 = 10,000 uS
+//     The total period will be range * pulse time in µS, so a pulse time
+//     of 100 and a range of 100 gives a period of 100 * 100 = 10,000 µS
 //     which is a frequency of 100Hz.
 //
 //     It's possible to get a higher frequency by lowering the pulse time,
 //     however CPU uage will skyrocket as wiringPi uses a hard-loop to time
-//     periods under 100uS - this is because the Linux timer calls are just
+//     periods under 100µS - this is because the Linux timer calls are just
 //     accurate at all, and have an overhead.
 //
 //     Another way to increase the frequency is to reduce the range - however
@@ -46,8 +51,9 @@
 
 #define        PULSE_TIME      100
 
-static int marks [MAX_PINS] ;
-static int range [MAX_PINS] ;
+static int marks         [MAX_PINS] ;
+static int range         [MAX_PINS] ;
+static pthread_t threads [MAX_PINS] ;
 
 int newPin = -1 ;
 
@@ -106,13 +112,20 @@ void softPwmWrite (int pin, int value)
 
 /*
  * softPwmCreate:
- *     Create a new PWM thread.
+ *     Create a new softPWM thread.
  *********************************************************************************
  */
 
 int softPwmCreate (int pin, int initialValue, int pwmRange)
 {
   int res ;
+  pthread_t myThread ;
+
+  if (range [pin] != 0)        // Already running on this pin
+    return -1 ;
+
+  if (range <= 0)
+    return -1 ;
 
   pinMode      (pin, OUTPUT) ;
   digitalWrite (pin, LOW) ;
@@ -121,10 +134,30 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
   range [pin] = pwmRange ;
 
   newPin = pin ;
-  res = piThreadCreate (softPwmThread) ;
+  res    = pthread_create (&myThread, NULL, softPwmThread, NULL) ;
 
   while (newPin != -1)
     delay (1) ;
 
+  threads [pin] = myThread ;
+
   return res ;
 }
+
+
+/*
+ * softPwmStop:
+ *     Stop an existing softPWM thread
+ *********************************************************************************
+ */
+
+void softPwmStop (int pin)
+{
+  if (range [pin] != 0)
+  {
+    pthread_cancel (threads [pin]) ;
+    pthread_join   (threads [pin], NULL) ;
+    range [pin] = 0 ;
+    digitalWrite (pin, LOW) ;
+}
+}
index 28ad299..0351da5 100644 (file)
@@ -28,6 +28,7 @@ extern "C" {
 
 extern int  softPwmCreate (int pin, int value, int range) ;
 extern void softPwmWrite  (int pin, int value) ;
+extern void softPwmStop   (int pin) ;
 
 #ifdef __cplusplus
 }
index b54ad29..4660a67 100644 (file)
@@ -70,6 +70,8 @@
 #include <sys/wait.h>
 #include <sys/ioctl.h>
 
+#include "softPwm.h"
+
 #include "wiringPi.h"
 
 #ifndef        TRUE
@@ -961,6 +963,7 @@ void pinMode (int pin, int mode)
 {
   int    fSel, shift, alt ;
   struct wiringPiNodeStruct *node = wiringPiNodes ;
+  int origPin = pin ;
 
   if ((pin & PI_GPIO_MASK) == 0)               // On-board pin
   {
@@ -971,6 +974,8 @@ void pinMode (int pin, int mode)
     else if (wiringPiMode != WPI_MODE_GPIO)
       return ;
 
+    softPwmStop (origPin) ;
+
     fSel    = gpioToGPFSEL [pin] ;
     shift   = gpioToShift  [pin] ;
 
@@ -978,9 +983,11 @@ void pinMode (int pin, int mode)
       *(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 == SOFT_PWM_OUTPUT)
+      softPwmCreate (origPin, 0, 100) ;
     else if (mode == PWM_OUTPUT)
     {
-      if ((alt = gpioToPwmALT [pin]) == 0)     // Not a PWM pin
+      if ((alt = gpioToPwmALT [pin]) == 0)     // Not a hardware capable PWM pin
        return ;
 
 // Set pin to PWM mode
@@ -990,7 +997,7 @@ void pinMode (int pin, int mode)
 
       pwmSetMode  (PWM_MODE_BAL) ;     // Pi default mode
       pwmSetRange (1024) ;             // Default range of 1024
-      pwmSetClock (32) ;                       // 19.2 / 32 = 600KHz - Also starts the PWM
+      pwmSetClock (32) ;               // 19.2 / 32 = 600KHz - Also starts the PWM
     }
     else if (mode == GPIO_CLOCK)
     {
index ce4680a..4eea3e5 100644 (file)
@@ -42,6 +42,7 @@
 #define        OUTPUT                   1
 #define        PWM_OUTPUT               2
 #define        GPIO_CLOCK               3
+#define        SOFT_PWM_OUTPUT          4
 
 #define        LOW                      0
 #define        HIGH                     1