PWM(Pulse Width Modulation) function is very common in embedded systems, it is the use of the microprocessor's digital outputs to control analog circuits is a very effective technique, widely used in many areas from measurement, communications to power control and conversion.
Rockchip PWM can support the standard PWM interface programming inside the Linux system.
The board leads a PWM for customized use, and the rest of the PWM for the screen backlight, has been exclusive to other drivers, can not be used for other functions.
The serial number of this PWM is 7, and the corresponding device node under 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 the device tree, we can know that febd0030 is the first address of the register of pwm7, so pwmchip1 is the node of pwm7.
The following is a simple logic analyzer to capture the waveform of this pwm, wired as follows
The nodes of sysfs all need root privileges to operate, and the operation of pwm using the command line or a program compiled in C language all need root privileges. If you are using ssh or LX terminal, first execute the following command to get root privileges.
sudo su
Setting pwm to userspace
echo 0 > /sys/class/pwm/pwmchip1/export
Set the period of PWM, here in ns
echo 10000 > /sys/class/pwm/pwmchip1/pwm0/period
Sets the duty cycle, in case of normal output polarity, this parameter specifies the duration of the PWM wave high for one cycle, in ns
echo 5000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle
The polarity parameter is used to specify the output polarity, i.e. whether the PWM output is inverted or not.
echo normal > /sys/class/pwm/pwmchip1/pwm0/polarity
Enable pwm channel output
echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable
The result of the execution is as follows, you can see the correct period and high level duration. Here the length of one frame is 1us
By connecting to the libperipheral_api.a static library, the following interfaces can be called in C to operate the PWM
/**
* @name: user_pwm_enable
* @description: Set the pwm attribute and enable pwm.
* @param pwmchip_num: pwmchip serial number
* @param pwmchannel_num: pwm channel number
* @param period: cycle time
* @param duty_cycle: duration of high level
* @param polarity: 0 - polarity not reversed other - polarity reversed
* @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: shutdown 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 demos are as follows, taking the operation of 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 the test demo source code test.c into the same path, compile the command as follows
aarch64-none-linux-gnu-gcc test.c peripheral_api.a -I. -o pwmtest
Execute on the board . /pwmtest
Use the logic analyzer to capture the waveform as follows
You can see that the high level duration is 6us and the period 8us