I could drive a servo by using PWM0 channel on GPIO 18 of Raspberry Pi with following c code:
#define BCM2708_PERI_BASE 0x3F000000
#define PWM_BASE (BCM2708_PERI_BASE + 0x20C000)
#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000)
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
#define PWM_CTL 0
#define PWM0_RNG 4
#define PWM0_DAT 5
#define PWM0_MS_MODE 0x0080 // Run in MS mode
#define PWM0_USEFIFO 0x0020 // Data from FIFO
#define PWM0_REVPOLAR 0x0010 // Reverse polarity
#define PWM0_OFFSTATE 0x0008 // Ouput Off state
#define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty
#define PWM0_SERIAL 0x0002 // Run in serial mode
#define PWM0_ENABLE 0x0001 // Channel Enable
#define PWMCLK_CNTL 40
#define PWMCLK_DIV 41
// stop clock and waiting for busy flag doesn't work, so kill clock
*(clk + PWMCLK_CNTL) = 0x5A000000 | (1 << 5); usleep(10);
// wait until busy flag is set
while ( (*(clk + PWMCLK_CNTL)) & 0x00000080){}
*(clk + PWMCLK_DIV) = 0x5A000000 | (Divisor << 12);
*(clk + PWMCLK_CNTL) = 0x5A000011;
*(pwm + PWM_CTL) = 0; usleep(10);
*(pwm + PWM0_RNG) = Counts; usleep(10);
*(pwm + PWM0_DAT) = (int) (DutyCycle * Counts / 100); usleep(10);
*(pwm + PWM_CTL) |= ( (1 << 7) | (1 << 0) );
However, when I tried to drive another servo on on another GPIO on PWM1 channel, it didn't work at all. The PWM1 channel has the following values:
#define PWM1_RNG 8
#define PWM1_DAT 9
#define PWM1_MS_MODE 0x8000 // Run in MS mode
#define PWM1_USEFIFO 0x2000 // Data from FIFO
#define PWM1_REVPOLAR 0x1000 // Reverse polarity
#define PWM1_OFFSTATE 0x0800 // Ouput Off state
#define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty
#define PWM1_SERIAL 0x0200 // Run in serial mode
#define PWM1_ENABLE 0x0100 // Channel Enable
Can anybody tell me where the registers are modified from PWM0 and PWM1?
Wading through available documentation, you have to set GPIO45 to its Alternate Function 0.
The PWM peripheral registers are described in the Broadcom peripheral documentation (this refers to the RPi1's BCM2835 but is mostly identical to the RPi's BCM2836 with respect to the peripheral set. Be aware that the PWM channels are referred to as PWM1/2 rather then PWM0/1 in the register tables.
User contributions licensed under CC BY-SA 3.0