The pulse width modulation (PWM) function is very common in embedded systems. It is a very effective technology that uses the digital output of the microprocessor to control analog circuits. It is widely used in many fields from measurement, communication to power control and conversion.
Rockchip PWM can support standard PWM interface programming under Linux.
One PWM is led out on the board for custom purposes, and the rest is for screen backlight PWM, which has been exclusively used by other drivers and cannot be used for other functions.
The serial number of this PWM is 7. The corresponding device node in Linux can be queried by the following command
root@linaro-alip:~# find /sys -name "*pwmchip*"
/sys/class/pwm/pwmchip2
/sys/class/pwm/pwmchip0
/sys/class/pwm/pwmchip1
/sys/devices/platform/febd0030.pwm/pwm/pwmchip1
/sys/devices/platform/febd0020.pwm/pwm/pwmchip0
/sys/devices/platform/febf0010.pwm/pwm/pwmchip2
By querying the datasheet or device tree, we can know that febd0030 is pwm7 The register first address, so pwmchip1 is the node of pwm7.
The following uses a simple logic analyzer to capture the waveform of this pwm, and the wiring is as follows
All sysfs nodes require root privileges to operate, and using command lines or programs compiled in C language to operate pwm requires root privileges. If you are using ssh or LX terminal, execute the following command to obtain root privileges first.
sudo su
Set pwm to userspace use
echo 0 > /sys/class/pwm/pwmchip1/export
Set the PWM period, the unit here is ns
echo 10000 > /sys/class/pwm/pwmchip1/pwm0/period
Set the duty cycle. If it is a normal output polarity, this parameter specifies the high level duration in one cycle of the PWM wave, in ns
echo 5000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle
The polarity parameter is used to specify the output polarity, that is, whether the PWM output is inverted
echo normal > /sys/class/pwm/pwmchip1/pwm0/polarity
Enable pwm channel output
echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable
The execution result is as follows, and the correct cycle and high level duration can be seen. Here the length of one grid is 1us
By connecting the libperipheral_api.a static library, you can use C language to call the following interface to operate PWM
/**
* @name: user_pwm_enable
* @description: Set pwm properties and turn on pwm
* @param pwmchip_num: pwmchip serial number
* @param pwmchannel_num: pwm channel number
* @param period: period
* @param duty_cycle: high level duration
* @param polarity: 0 - polarity does not reverse Others - polarity reverse
* @return equal to 0 - success less than 0 - failure
*/
int user_pwm_enable(int pwmchip_num, int pwmchannel_num, int period, int duty_cycle, unsigned char polarity);
/**
* @name: user_pwm_disable
* @description: Disable pwm
* @param pwmchip_num: pwmchip serial number
* @param pwmchannel_num: pwm channel number
* @return equal to 0 - success less than 0 - failure
*/
int user_pwm_disable(int pwmchip_num, int pwmchannel_num);
The test demo is as follows, taking PWM7 as an example
#include "peripheral_api.h"
void pwm_api_test(void)
{
user_pwm_enable(1,0,8000,6000,0);
sleep(5);
user_pwm_disable(1,0);
return;
}
int main()
{
pwm_api_test();
return 0;
}
Put the peripheral_api.a static library, peripheral_api.h and test demo source code test.c in the same path, and compile the command as follows
aarch64-none-linux-gnu-gcc test.c peripheral_api.a -I. -o pwmtest
Execute ./pwmtest on the board
Use the logic analyzer to capture the waveform as follows
You can see that the high level duration is 6us and the period is 8us