Gordons Projects

--> Projects Top-Level GIT

Bumped the version to 2.40 - correctly this time, I hope.
[wiringPi] / wiringPi / softPwm.c
index 5999cc0..d99fa00 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * softPwm.c:
- *     Provide 2 channels of software driven PWM.
- *     Copyright (c) 2012-2014 Gordon Henderson
+ *     Provide many channels of software driven PWM.
+ *     Copyright (c) 2012-2017 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
 #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...
+//     This is more than the number of Pi pins because we can actually softPwm.
+//     Once upon a time I let pins on gpio expanders be softPwm'd, but it's really
+//     really not a good thing.
 
-#define        MAX_PINS        1024
+#define        MAX_PINS        64
 
 // The PWM Frequency is derived from the "pulse time" below. Essentially,
 //     the frequency is a function of the range and this pulse time.
@@ -45,7 +45,7 @@
 //     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 100┬ÁS - this is because the Linux timer calls are just
-//     accurate at all, and have an overhead.
+//     not accurate at all, and have an overhead.
 //
 //     Another way to increase the frequency is to reduce the range - however
 //     that reduces the overall output accuracy...
@@ -106,14 +106,15 @@ static void *softPwmThread (void *arg)
 
 void softPwmWrite (int pin, int value)
 {
-  pin &= (MAX_PINS - 1) ;
-
-  /**/ if (value < 0)
-    value = 0 ;
-  else if (value > range [pin])
-    value = range [pin] ;
+  if (pin < MAX_PINS)
+  {
+    /**/ if (value < 0)
+      value = 0 ;
+    else if (value > range [pin])
+      value = range [pin] ;
 
-  marks [pin] = value ;
+    marks [pin] = value ;
+  }
 }
 
 
@@ -129,6 +130,9 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
   pthread_t myThread ;
   int *passPin ;
 
+  if (pin >= MAX_PINS)
+    return -1 ;
+
   if (range [pin] != 0)        // Already running on this pin
     return -1 ;
 
@@ -139,15 +143,15 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
   if (passPin == NULL)
     return -1 ;
 
-  pinMode      (pin, OUTPUT) ;
   digitalWrite (pin, LOW) ;
+  pinMode      (pin, OUTPUT) ;
 
   marks [pin] = initialValue ;
   range [pin] = pwmRange ;
 
   *passPin = pin ;
-  newPin = pin ;
-  res    = pthread_create (&myThread, NULL, softPwmThread, (void *)passPin) ;
+  newPin   = pin ;
+  res      = pthread_create (&myThread, NULL, softPwmThread, (void *)passPin) ;
 
   while (newPin != -1)
     delay (1) ;
@@ -166,11 +170,14 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
 
 void softPwmStop (int pin)
 {
-  if (range [pin] != 0)
+  if (pin < MAX_PINS)
   {
-    pthread_cancel (threads [pin]) ;
-    pthread_join   (threads [pin], NULL) ;
-    range [pin] = 0 ;
-    digitalWrite (pin, LOW) ;
+    if (range [pin] != 0)
+    {
+      pthread_cancel (threads [pin]) ;
+      pthread_join   (threads [pin], NULL) ;
+      range [pin] = 0 ;
+      digitalWrite (pin, LOW) ;
+    }
   }
 }