chiark / gitweb /
changed to pin mode to support softPwm.
[wiringPi.git] / wiringPi / softPwm.c
index a4f0fc43f6b0fc3e0dc434c1cef9087e0833a982..0bde1804d84e7764fd5f48c42db037156bf01fe0 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) ;
+}
+}