Hardware Reference
In-Depth Information
The reverse of
open
is the
pwm_close()
call. Here the thread is instructed to stop
(
stopf=1
), and if there is a thread running, a join with the thread is performed. The join
causes the caller to block until the thread itself has ended. Then the
PWM
structure is freed,
completing the close operation.
void
pwm_close(PWM *pwm) {
pwm->stopf = 1;
if ( pwm->thread )
pthread_join(pwm->thread,0);
pwm->thread = 0;
free(pwm);
}
The software PWM signal starts when the ratio is established by a call to
pwm_ratio()
:
void
pwm_ratio(PWM *pwm,unsigned n,unsigned m) {
pwm->n = n <= m ? n : m;
pwm->m = m;
if ( !pwm->thread )
pthread_create(&pwm->thread,0,soft_pwm,pwm);
else
pwm->chgf = 1;
}
This call establishes the values for N and M. Then if no thread is currently running,
one is created with the thread's ID saved in the
PWM
structure. If the thread is already
running, we simply point out to the thread that the
N
M
values have changed so that it can
adapt to it at the cycle's end.
The function
soft_pwm()
is the software PWM engine itself. The
pthread_create()
call passes the
PWM
structure into the call as a
void *arg
, which is used by the function to
access the
PWM
structure. The entire procedure is an outer and inner loop. The outer loop
runs as long as the
stopf
flag is zero. Then the floating-point period variables
fperiod
,
percent
, and
ontime
are calculated.
From there, the inner loop continues until either the
chgf
or
stopf
flag variables
become nonzero. If the
stopf
becomes nonzero, both loops are exited. Once the thread
function exits, the thread ends. The thread resources are reclaimed in the
pwm_close()
call when it joins.
static void *
soft_pw(void *arg) {
PWM *pwm = (PWM *)arg;
double fperiod, percent, ontime;