PWM Usage

The AIO-1688JD4 development board only exposes one PWM (FAN) externally, but the Core-1688JD4’s gold fingers expose multiple PWMs. By running PMW read/write commands in the console or writing PWM read/write programs in kernel or user mode, you can perform input and output operations on the PWM.

  • PWM operates at a fixed frequency clock of 100MHz, with a total of 20 channels, each of which can be controlled individually.

  • The BM1688 has 5 PWM IPs (pwmchip0/ pwmchip4/ pwmchip8/ pwmchip12/ pwmchip16), each controlling 4 channels, allowing for a total of 20 channels.

In the Linux sysfs, the device nodes for pwm0~pwm3 are as follows:

/sys/class/pwm/pwmchip0/pwm0~3

In the Linux sysfs, the device nodes for pwm4~pwm7 are as follows:

/sys/class/pwm/pwmchip4/pwm0~3

Taking the fan’s device tree configuration as an example:

&fan0 {
		compatible = "pwm-fan";
		#cooling-cells = <2>;
		pwms = <&pwm2 3 1000000 0>; 
		cooling-levels = <255 170 100 1>; // max 1
};

Here, pwms = <&pwm2 3 1000000 0>; indicates the use of the PWM11 pin, as pwm2 is the third group, and 3 indicates the fourth channel, leading to the conclusion: 3 x 4 = 12(0~11)

And so on.

Operation Example

Example of PWM Operation Commands:

  • Use the echo command on the control panel to configure the PWM number to be operated on, in this case PWM1:

echo 1 > /sys/class/pwm/pwmchip0/export
  • Set the duration of one PWM cycle, in nanoseconds:

echo 1000000 >/sys/class/pwm/pwmchip0/pwm1/period
  • Set the “ON” time within one cycle, in nanoseconds, i.e., duty cycle =duty_cycle/period=50%:

echo 500000 >/sys/class/pwm/pwmchip0/pwm1/duty_cycle
  • Enable the PWM:

echo 1 >/sys/class/pwm/pwmchip0/pwm1/enable

Example of File IO Operation Program:

  • Configure the PWM number to be operated on, taking PWM1 as an example:

fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
if(fd < 0)
{
dbmsg("open export error\n");
return -1;
}
ret = write(fd, "1", strlen("0"));
if(ret < 0)
{
dbmsg("Export pwm1 error\n");
return -1;
}
  • Set the duration of one PWM cycle, in ns:

fd_period = open("/sys/class/pwm/pwmchip0/pwm1/period", O_RDWR);
ret = write(fd_period, "1000000", strlen("1000000"));
if(ret < 0)
{
dbmsg("Set period error\n");
return -1;
}
  • Set the “ON” time within one cycle, in ns: (In this example, the duty cycle is 50%)

fd_duty = open("/sys/class/pwm/pwmchip0/pwm1/duty_cycle", O_RDWR);
ret = write(fd_duty, "500000", strlen("500000"));
if(ret < 0)
{
dbmsg("Set period error\n");
return -1;
}
  • Enable PWM

fd_enable = open("/sys/class/pwm/pwmchip0/pwm1/enable", O_RDWR);
ret = write(fd_enable, "1", strlen("1"));
if(ret < 0)
{
dbmsg("enable pwm0 error\n");
return -1;
}