Hardware Reference
In-Depth Information
pwm Program
The program software pwm is listed at the end of this chapter. To facilitate discussion,
I'll show excerpts of it here. The hardware example driven by pwm.c is the nastier of the
two programs presented. This is due to the difficulty of programming the PWM hardware
registers and the clock-rate registers.
The main program invokes pwm_init() , which gains access to the Pi's peripherals
in much the same way that the other examples did in gpio_init() . The same mmap()
techniques are used for access to the PWM and CLK control registers.
Whether operating pwm to just set the PWM peripheral or to use the CPU percent-busy
function, the PWM frequency must be set by the function pwm_frequency() :
static int
pwm_frequency(float freq) {
...
This function stops the clock that is running and computes a new integer divisor.
After disabling the clock, a little sleep time is used to allow the clock peripheral to stop.
The maximum clock rate appears to be 19.2 MHz. To compute the divisor, the following
calculation is used:
div = 19200000
I
f
where:
I div is the computed integer divisor.
f is the desired PWM frequency.
The range of the resulting I div is checked against the peripheral's limits. The value
of I div is then forced to remain in range, but the return value is -1 or +1 depending on
whether the frequency is under or over the limits.
idiv = (long)( clock_rate / (double) freq );
if ( idiv < 1 ) {
idiv = 1; /* Lowest divisor */
rc = -1;
} else if ( idiv >= 0x1000 ) {
idiv = 0xFFF; /* Highest divisor */
rc = +1;
}
Once that is calculated, the value of I div is loaded:
ugclk[PWMCLK_DIV] = 0x5A000000 | ( idiv << 12 );
 
Search WWH ::




Custom Search