Pulse-width modulation (PWM) is a technique that modifies the duty cycle of a pulsing signal to encode information or to control the amount of energy provided to a charge.
On the ConnectCore MP13 system-on-module:
-
Eight Advanced-control timers signals (from TIM1 to TIM8) available from the STM32MP13 system-on-chip (multiplexed with other signals) that can be used to generate PWM output waveform.
On the ConnectCore MP13 Development Kit:
-
PWM8 channel 1 (Port A GPIO5) is available at PWM pin of MikroBus connector.
Kernel configuration
You can manage the STM32MP13 PWM driver support through the following kernel configuration options:
-
PWM support (
CONFIG_PWM
) -
STM32 PWM support (
CONFIG_PWM_STM32
) -
STM32 PWM low power support (
CONFIG_PWM_STM32_LP
)
These options are enabled as built-in on the default ConnectCore MP13 kernel configuration file.
Kernel driver
The driver for the STM32MP13 PWM is located at:
File | Description |
---|---|
STM32 PWM driver |
|
STM32 PWM LP driver |
Device tree bindings and customization
The STM32MP13 PWM interface is documented at Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
.
The STM32MP13 PWM LP interface is documented at Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
.
STM32MP13 PWM interfaces
The common STM32MP13 CPU device tree file contains entries for all the timers that can have PWM functionality (excerpt shows a few):
timers2: timer@40000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32-timers";
reg = <0x40000000 0x400>;
clocks = <&rcc TIM2_K>;
clock-names = "int";
dmas = <&dmamux1 18 0x400 0x80000001>,
<&dmamux1 19 0x400 0x80000001>,
<&dmamux1 20 0x400 0x80000001>,
<&dmamux1 21 0x400 0x80000001>,
<&dmamux1 22 0x400 0x80000001>;
dma-names = "ch1", "ch2", "ch3", "ch4", "up";
status = "disabled";
pwm {
compatible = "st,stm32-pwm";
#pwm-cells = <3>;
status = "disabled";
};
timer@1 {
compatible = "st,stm32h7-timer-trigger";
reg = <1>;
status = "disabled";
};
counter {
compatible = "st,stm32-timer-counter";
status = "disabled";
};
};
lptimer1: timer@40009000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32-lptimer";
reg = <0x40009000 0x400>;
interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc LPTIM1_K>;
clock-names = "mux";
power-domains = <&pd_core>;
wakeup-source;
status = "disabled";
pwm {
compatible = "st,stm32-pwm-lp";
#pwm-cells = <3>;
status = "disabled";
};
trigger@0 {
compatible = "st,stm32-lptimer-trigger";
reg = <0>;
status = "disabled";
};
counter {
compatible = "st,stm32-lptimer-counter";
status = "disabled";
};
timer {
compatible = "st,stm32-lptimer-timer";
status = "disabled";
};
};
PINCTRL configuration
You must configure the pads that are to be used as STM32MP13 PWMs. See Pin multiplexing (IOMUX).
STM32MP13 pads should only have one IOMUX configuration. Remove other configurations for those pads, like GPIO, when configuring them as PWMs. |
The following pad can be configured as PWM on the ConnectCore MP13 Development Kit:
-
On the mikroBUS™ connector J31:
Pad Signal PWM 1
MIKROBUS_PWM
PWM8 channel 1 (TIM8_CH1)
Example: enable PWM8 on ConnectCore MP13 Development Kit
For example, PWM8 is available on the ConnectCore MP13 Development Kit MikroBus connector which corresponds to pad Port A GPIO5 (TIM8_CH1) of the CPU. In order to enable it, you must:
-
Configure the pad Port A GPIO5 (TIM8_CH1)
-
Enable the PWM node.
On the default ConnectCore MP13 Development Kit device tree, this pad is configured to work as ADC input.
Use the overlay _ov_board_pwm8_ccmp13-dvk.dts
to enable the PWM functionality.
Refer to Device tree files and overlays for instructions on loading device tree overlays.
&timers8 {
/delete-property/dmas;
/delete-property/dma-names;
status = "disabled";
pwm {
pinctrl-0 = <&ccmp13_pwm8_pins_a>;
pinctrl-1 = <&ccmp13_pwm8_sleep_pins_a>;
pinctrl-names = "default", "sleep";
status = "okay";
};
timer@7 {
status = "okay";
};
};
pinctrl {
ccmp13_pwm8_pins_a: pwm8-0 {
pins {
pinmux = <STM32_PINMUX('A', 5, AF3)>; /* TIM8_CH1 */
bias-pull-down;
drive-push-pull;
slew-rate = <0>;
};
};
ccmp13_pwm8_sleep_pins_a: pwm8-sleep-0 {
pins {
pinmux = <STM32_PINMUX('A', 5, ANALOG)>;
};
};
};
Using the PWM channels
Control PWM signal from sysfs
Each of the eight TIM interfaces is registered in the system as a standalone PWM controller.
On the ConnectCore MP13 Development Kit:
-
PWM8 is enabled on pin 1 of MikroBus™ connector (J31) if using the overlay. See Example: enable PWM8 on ConnectCore MP13 Development Kit.
-
All other PWM channels are disabled by default
The PWM interfaces appear under /sys/class/pwm
:
# ls /sys/class/pwm/
pwmchip0
The PWM interfaces begin numbering with an index of 0.
Each PWM interface can manage several PWM channels.
Check the number of channels of an interface by printing the value of npwm
:
# cat /sys/class/pwm/pwmchip0/npwm
4
To access a channel of the PWM interface, write the channel index to the export
descriptor.
Notice the hardware manuals name the channels starting from 1 but Linux indexes start at 0.
To access channel 1, write 0 to the export
descriptor:
# echo 0 > /sys/class/pwm/pwmchip0/export
To get a PWM output on a given pad, the selected channel must match the pinctrl functionality for that pad.
For instance, in the example above, pad at Port A GPIO5 can function as PWM 8 channel 1, thus the 0 on the command.
Exporting a different channel would require to use a different pinctrl on a different pad.
|
You won’t be able to request PWM channels that are in use by other drivers, like the one used by the backlight. |
Now you can access the PWM channel and configure its settings:
# ls /sys/class/pwm/pwmchip0/pwm0/
duty_cycle enable period polarity power uevent
Period and duty cycle must be given in nanoseconds. For example, to configure a 100kHz signal with 20% duty cycle:
# echo 10000 > /sys/class/pwm/pwmchip0/pwm0/period
# echo 2000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
To enable the PWM signal:
# echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable
The default polarity is normal
(active high for the duty cycle).
To invert the polarity:
# echo inversed > /sys/class/pwm/pwmchip0/pwm0/polarity
Using Digi APIx library from a C application
An example application called apix-pwm-example
is included in the dey-examples-digiapix recipe (part of dey-examples package) of the meta-digi layer.
This application shows how to generate a PWM signal using Digi APIx library on the ConnectCore MP13 platform.
Go to GitHub to see the application instructions and source code.
See PWM API for more information about the PWM APIx.