In this guide, we will explain how to activate the PWM interface and, based on examples, how to use it on one of our ST modules with the Dunfell BSP.
Configuration
1. Open a Terminal shell and set up the toolchain :: source /opt/st/stm32mp1/openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi unset LDFLAGS unset CFLAGS
- Enter the kernel source directory and set up the configuration for the machine you are using, and start the menuconfig tool
: make stm32mp1ugea_defconfig make menuconfig
Then activate the PWM framework in the kernel configuration tool
Device Drivers --->
[*] Pulse-Width Modulation (PWM) Support --->
- DT configuration example
The example below shows how to configure TIM1 channel 3 to act as:
PWM output on PE12, e.g. TIM1_CH3 (See pinctrl device tree configuration and GPIO internal peripheral) trigger source (synchronous with PWM) for other internal peripheral such as STM32 ADC
/* select TIM1_CH1 alternate function 1 on 'PE9' */
pwm1_pins_a: pwm1-0 {
pins {
pinmux = <STM32_PINMUX('E', 12, AF1)>;
bias-pull-down;
drive-push-pull;
slew-rate = <0>;
};
};
/* configure 'PE12' as analog input in low-power mode */
pwm1_sleep_pins_a: pwm1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('E', 12, ANALOG)>;
};
};
The PWM output doesn\'t require any DMA channel. Disable them if they are configured by default in the .dtsi/.dts file.
&timers1 {
status = "okay";
/* USER CODE BEGIN timers1 */
/* USER CODE END timers1 */
/delete-property/dmas;
/delete-property/dma-names;
pwm {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&tim1_pwm_pins_mx>;
pinctrl-1 = <&tim1_pwm_sleep_pins_mx>;
status = "okay";
/* USER CODE BEGIN timers1_pwm */
/* USER CODE END timers1_pwm */
};
timer@0 {
status = "okay";
};
};
How to use PWM with sysfs interface
The available PWM controllers are listed in sysfs:
Board $> ls /sys/class/pwm
pwmchip0
The number of channels per controller can be read in npwm (read-only)
Board $> cd /sys/class/pwm/pwmchip0
Board $> cat npwm
4
Each channel is exported (requested for sysfs activation) by writing the corresponding number in \'export\'.
- TIMx_CH1 is exported as \"pwm0\", TIMx_CH2 as \"pwm1\", and so on:
- PWM channels are numbered from 0 to (\'npwm\' - 1)
- TIM[1] channels are numbered from 1 to \'npwm\'.
As an example, proceed as follows to export the first channel (TIMx_CH3, e.g. channel 2):
Board $> echo 0 > export
Board $> ls
device export npwm power pwm2 subsystem uevent unexport
The period and duty cycle must be configured before enabling any channel.
As an example, proceed as follows to set a period of 100 ms with a duty cycle of 60% on channel 0:
Board $> echo 100000000 > pwm2/period
Board $> echo 60000000 > pwm2/duty_cycle
Board $> echo 1 > pwm2/enable
The polarity can be inverted or set to normal by using the polarity entry:
Board $> echo "inversed" > pwm2/polarity
Board $> cat pwm2/polarity
inversed
Board $> echo "normal" > pwm2/polarity
Board $> cat pwm2/polarity
normal