chiark / gitweb /
changed to pin mode to support softPwm.
[wiringPi.git] / wiringPi / wiringPi.c
index e97a6d17f4f5694efc5f1c9a14416757de800e08..4660a67b47b2c21a9a60a2f8548d6f8b4d2548b4 100644 (file)
@@ -70,6 +70,8 @@
 #include <sys/wait.h>
 #include <sys/ioctl.h>
 
+#include "softPwm.h"
+
 #include "wiringPi.h"
 
 #ifndef        TRUE
@@ -118,7 +120,6 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ;
 #define        FSEL_INPT               0b000
 #define        FSEL_OUTP               0b001
 #define        FSEL_ALT0               0b100
-#define        FSEL_ALT0               0b100
 #define        FSEL_ALT1               0b101
 #define        FSEL_ALT2               0b110
 #define        FSEL_ALT3               0b111
@@ -925,6 +926,32 @@ void pinEnableED01Pi (int pin)
  *********************************************************************************
  */
 
+/*
+ * pinModeAlt:
+ *     This is an un-documented special to let you set any pin to any mode
+ *********************************************************************************
+ */
+
+void pinModeAlt (int pin, int mode)
+{
+  int fSel, shift ;
+
+  if ((pin & PI_GPIO_MASK) == 0)               // On-board pin
+  {
+    /**/ if (wiringPiMode == WPI_MODE_PINS)
+      pin = pinToGpio [pin] ;
+    else if (wiringPiMode == WPI_MODE_PHYS)
+      pin = physToGpio [pin] ;
+    else if (wiringPiMode != WPI_MODE_GPIO)
+      return ;
+
+    fSel  = gpioToGPFSEL [pin] ;
+    shift = gpioToShift  [pin] ;
+
+    *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ;
+  }
+}
+
 
 /*
  * pinMode:
@@ -936,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
   {
@@ -946,6 +974,8 @@ void pinMode (int pin, int mode)
     else if (wiringPiMode != WPI_MODE_GPIO)
       return ;
 
+    softPwmStop (origPin) ;
+
     fSel    = gpioToGPFSEL [pin] ;
     shift   = gpioToShift  [pin] ;
 
@@ -953,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
@@ -965,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)
     {
@@ -1448,6 +1480,8 @@ void delayMicrosecondsHard (unsigned int howLong)
 void delayMicroseconds (unsigned int howLong)
 {
   struct timespec sleeper ;
+  unsigned int uSecs = howLong % 1000000 ;
+  unsigned int wSecs = howLong / 1000000 ;
 
   /**/ if (howLong ==   0)
     return ;
@@ -1455,8 +1489,8 @@ void delayMicroseconds (unsigned int howLong)
     delayMicrosecondsHard (howLong) ;
   else
   {
-    sleeper.tv_sec  = 0 ;
-    sleeper.tv_nsec = (long)(howLong * 1000) ;
+    sleeper.tv_sec  = wSecs ;
+    sleeper.tv_nsec = (long)(uSecs * 1000L) ;
     nanosleep (&sleeper, NULL) ;
   }
 }
@@ -1539,7 +1573,7 @@ int wiringPiSetup (void)
 
 // Open the master /dev/memory device
 
-  if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
+  if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
     return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
 
 // GPIO: