X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=wiringPi%2FsoftPwm.c;h=0bde1804d84e7764fd5f48c42db037156bf01fe0;hb=05e2f67e7f43d83195fff108bcd952e7afe917ce;hp=a4f0fc43f6b0fc3e0dc434c1cef9087e0833a982;hpb=f18c8f7204d6354220fd6754578b3daa43734e1b;p=wiringPi.git diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c index a4f0fc4..0bde180 100644 --- a/wiringPi/softPwm.c +++ b/wiringPi/softPwm.c @@ -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/ @@ -28,17 +28,22 @@ #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) ; +} +}