Difference between revisions of "PWM overview"

[quality revision] [quality revision]
m
 
m
 

Template:ArticleMainWriter Template:ArticleApprovedVersion This article gives information about the Linux® PWM framework.
It explains how to activate the PWM interface and, based on examples, how to use it.

1 Article Framework purpose[edit]

The purpose of this article is the following:

  • introduce PWM (pulse width modulation) Linux® Framework
  • provide general information of PWM
  • describe the main components and stakeholders
  • give examples of PWM usage

    PWM (Pulse Width Modulation) framework offers a unified interface for the users to:

    • control PWM output(s) such as period, duty cycle and polarity.
    • capture a PWM signal and report its period and duty cycle (e.g. input).

    The interface can be used from:

    • user space (sysfs) usage
    • kernel space (API) usage
    2 PWM

    PWMs can be used in various use cases, as mentioned in How to use the framework to control LEDs, beepers, vibrators or fans...

    2 System overview[edit]

    PWM sysfs interface PWM kernel interface STM32 TIM Linux driver STM32 LPTIM Linux driver STM32 TIM internal peripheral STM32 LPTIM internal peripheral
    PWM Implementation architecture Template:WarningImageMapOverlay

    2.1 Component description[edit]

    • PWM user (User space)

    The user can use PWM sysfs interface, from a user terminal or a custom application, to control PWM device(s) from user space.

    • PWM user (Kernel space)

    User drivers can use PWM API to control PWM external device(s) from kernel space (such as back-light, vibrator, LED or fan drivers).

    • PWM framework (Kernel space)

    The PWM core provides sysfs interface and PWM API. They can be used to implement PWM user and PWM controller drivers.

    • PWM drivers (Kernel space)

    Provider drivers such as STM32 TIM Linux driver and STM32 LPTIM Linux driver that expose PWM controller(s) to the core.

    • PWM hardware

    PWM controller(s) such as TIM internal peripheral[1] and LPTIM internal peripheral[2] used to drive external PWM controlled devices.

    2.2 API description[edit]

    Documentation on PWM interface can be found under kernel Documentation/pwm.txt

    2.2.1 Kernel PWM API[edit]

    The main useful user API are the following:

    • devm_pwm_get() or pwm_get() / pwm_put(): this API is used to look up, request, then free a PWM device.
    • pwm_init_state(), pwm_get_state(), pwm_apply_state(): this API is used to initialize, retrieve and apply the current PWM device state.
    • pwm_config(): this API updates the PWM device configuration (period and duty cycle).
    • ...

    2.2.2 Sysfs interface[edit]

    In addition to Documentation/pwm.txt[3] details on ABI are available in Documentation/ABI/testing/sysfs-class-pwm[4].

    3 PWM configuration Configuration[edit]

    3.1 Kernel configuration[edit]

    Activate PWM framework in the kernel configuration through the Linux menuconfig tool, Menuconfig or how to configure kernel (CONFIG_PWM=y):

    Device Drivers  --->
       [*] Pulse-Width Modulation (PWM) Support  --->
    

    Activate PWM drivers for STM32 PWM drivers: STM32 TIM Linux driver and/or STM32 LPTIM Linux driver

    3.2 Device tree configuration[edit]

    • PWM generic DT bindings:

    PWM DT bindings documentation[5] describes device tree properties related to standard PWM user nodes and PWM controller nodes.

    • Detailed DT configuration for STM32 internal peripherals:

    TIM device tree configuration and/or LPTIM device tree configuration

    4 How to use PWMthe framework[edit]

    PWM can be used either from the user or the kernel space.

    4.1 How to use PWM with sysfs interface[edit]

    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'.

    Info.png 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_CH1, e.g. channel 0):

    $Board $> echo 0 > export
    $Board $> ls
    device  export  npwm  power  pwm0  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 > pwm0/period
    $Board $> echo 60000000 > pwm0/duty_cycle
    $Board $> echo 1 > pwm0/enable
    

    The polarity can be inverted or set to normal by using the polarity entry:

    $Board $> echo "inversed" > pwm0/polarity
    $Board $> cat pwm0/polarity
    inversed
    
    $Board $> echo "normal" > pwm0/polarity
    $Board $> cat pwm0/polarity
    normal
    
    

    4.2 How to use PWM capture with sysfs interface[edit]

    PWM capture is available on some PWM controllers such as TIM internal peripheral[1] (see TIM configured in PWM input capture mode ).

    Info.png PWM output and capture mode are mutually exclusive on a TIM instance
    # First export a channel (e.g. 0), then capture PWM input on it:
    $Board $> cd /sys/class/pwm/pwmchip0
    $Board $> echo 0 > export
    
    $Board $> cd pwm0
    $Board $> ls
    capture  duty_cycle  enable  period  polarity  power  uevent
    
    $Board $> cat capture
    10000 1002               # capture result is in nano-seconds, e.g.: 100KHz, 10% duty cycle
    
    

    4.3 Example of PWM usage with kernel PWM API[edit]

    Several in-kernel drivers use kernel PWM API. Below a few examples:

    5 How to trace and debug the framework[edit]

    5.1 How to monitor with debugfs[edit]

    PWM usage can be monitored from debugfs 'pwm' entry. For example:

    $Board $> cd /sys/kernel/debug/
    $Board $> cat pwm
    platform/44000000.timer:pwm, 4 PWM devices                                                               <-- One timer instance exposes 4 PWM channels.
     pwm-0   (sysfs               ): requested enabled period: 1000000 ns duty: 500000 ns polarity: normal   <-- Channel 0 has been exported, enabled and configured via sysfs
     pwm-1   ((null)              ): period: 0 ns duty: 0 ns polarity: normal
     pwm-2   ((null)              ): period: 0 ns duty: 0 ns polarity: normal                                <-- Other channels aren't used currently
     pwm-3   ((null)              ): period: 0 ns duty: 0 ns polarity: normal
    

    5.2 Troubleshooting PWM capture[edit]

    Here are some clues on how to debug possible errors in PWM capture mode.
    See How to use PWM capture with sysfs interface as a pre-requisite.

    Board $> cat capture 
    cat: capture: Connection timed out
    
    

    This may be due to:

    • the input signal isn't recognized as a PWM input (or there's no input signal to capture).
    • a wrong alternate function number is used for the input pin configuration in the device-tree.
      See "TIM configured in PWM input capture mode" for further details.
    Board $> cat capture 
    cat: capture: Device or resource busy
    
    

    This may be due to:

    • a PWM channel on the same TIM instance is already running (in capture or output mode)
    Board $> cat capture 
    cat: capture: No such device
    
    

    This may be due to:

    Board $> cat capture
    cat: capture: Function not implemented
    
    

    This may be due to:

    • a wrong TIM instance is being used (e.g. "/sys/class/pwm/pwmchip/pwmchipN"), and it doesn't support capture (like LPTIM)
    • the DMA support isn't enabled (CONFIG_DMA_ENGINE)

    6 References[edit]

    1. 1.01.11.2 TIM internal peripheral
    2. LPTIM internal peripheral
    3. Documentation/pwm.txt, Linux PWM interface overview
    4. Documentation/ABI/testing/sysfs-class-pwm, Linux PWM Application binary interface
    5. Documentation/devicetree/bindings/pwm/pwm.txt, PWM DT bindings documentation
    6. drivers/input/misc/pwm-beeper.c , Example to use kernel PWM API
    7. drivers/input/misc/pwm-vibra.c , Example to use kernel PWM API



    <noinclude>
    
    {{ArticleBasedOnModel | [[Framework overview article model]]}}
    {{ArticleMainWriter | FabriceG}}
    {{ ArticleApprovedVersion | FabriceG | GeraldB, BenjaminG, LoicP, NathalieS | No previous approved version | AnneJ - 29June'18 - 7957 | 04July'18}}
    
    [[Category:Timers|0]]
    {{ReviewsComments|JCT 1840: alignment needed with the last version of the model [[Framework overview article model]]<br>
    
    [[Category:ToBeAlignedWithModel]]
    }}
    {{ReviewsComments|BPU W851: maybe good to see somewhere the fact you can output a channel on a TIM instance if one of its channel is in capture mode}}</noinclude>
    
    
    ==Article purpose==
    The purpose of this article is the following:
    * introduce PWM (pulse width modulation) Linux<sup>&reg;</sup> Framework
    * provide general information of PWM
    * describe the main components and stakeholders
    * give examples of PWM usage:
    ** user space (sysfs) usage
    ** kernel space (API) usage
    
    ==PWMThis article gives information about the Linux<sup>&reg;</sup> PWM framework.<br />
    
    It explains how to activate the PWM interface and, based on examples, how to use it.<br />
    <br />
    
    
    ==Framework purpose==
    '''PWM''' (Pulse Width Modulation) framework offers a unified interface for the users to:
    * control PWM output(s) such as period, duty cycle and polarity.
    * capture a PWM signal and report its period and duty cycle (e.g. input).
    
    The interface can be used from:
    * user space (sysfs)
    * kernel space (API)
    
    PWMs can be used in various use cases, as mentioned in [[#How to use the framework|How to use the framework]] to control LEDs, beepers, vibrators or fans...
    
    ==System overview==
    {{
    ImageMap|Image:PWM_overview.png {{!}} frame {{!}} center{{!}} PWM Implementation architecture<br/> {{WarningImageMapOverlay}}rect 400 232 500 272 [[PWM_overview#Sysfs_interface|PWM sysfs interface]]
    rect 612 335 736 368 [[PWM_overview#Kernel_PWM_API|PWM kernel interface]]
    rect 389 470 510 512 [[TIM Linux driver|STM32 TIM Linux driver]]
    rect 571 470 692 512 [[LPTIM Linux driver|STM32 LPTIM Linux driver]]
    rect 389 563 510 605 [[TIM internal peripheral|STM32 TIM internal peripheral]]
    rect 571 563 692 605 [[LPTIM internal peripheral|STM32 LPTIM internal peripheral]]
    }}
    ===Component description===
    * '''PWM user''' (User space)
    The user can use PWM sysfs interface, from a user terminal or a custom application, to control PWM device(s) from user space.
    * '''PWM user''' (Kernel space)
    User drivers can use PWM API to control PWM external device(s) from kernel space (such as back-light, vibrator, LED or fan drivers).
    * '''PWM framework''' (Kernel space)
    The PWM core provides sysfs interface and PWM API. They can be used to implement PWM user and PWM controller drivers.
    * '''PWM drivers''' (Kernel space)
    Provider drivers such as [[TIM Linux driver|STM32 TIM Linux driver]] and [[LPTIM Linux driver|STM32 LPTIM Linux driver]] that expose PWM controller(s) to the core.
    * '''PWM hardware'''
    PWM controller(s) such as ''TIM internal peripheral''<ref name="TIM internal peripheral">[[TIM internal peripheral]]</ref> and ''LPTIM internal peripheral''<ref name="LPTIM internal peripheral">[[LPTIM internal peripheral]]</ref> used to drive external PWM controlled devices.
    
    ===API description===
    Documentation on PWM interface can be found under kernel [https://www.kernel.org/doc/Documentation/pwm.txt Documentation/pwm.txt] 
    
    ====Kernel PWM API====
    The main useful user API are the following:
    *'''devm_pwm_get()''' or pwm_get() / pwm_put(): this API is used to look up, request, then free a PWM device.
    *'''pwm_init_state()''', '''pwm_get_state()''', '''pwm_apply_state()''': this API is used to initialize, retrieve and apply the current PWM device state.
    *'''pwm_config()''': this API updates the PWM device configuration (period and duty cycle).
    *...
    
    ====Sysfs interface====
    In addition to ''Documentation/pwm.txt''<ref>[https://www.kernel.org/doc/Documentation/pwm.txt Documentation/pwm.txt], Linux PWM interface overview</ref> details on ABI are available in ''Documentation/ABI/testing/sysfs-class-pwm''<ref>[https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-pwm Documentation/ABI/testing/sysfs-class-pwm], Linux PWM Application binary interface</ref>.
    
    ==PWM configurationConfiguration==
    
    ===Kernel configuration===
    Activate PWM framework in the kernel configuration through the Linux menuconfig tool, [[Menuconfig or how to configure kernel | Menuconfig or how to configure kernel ]] (CONFIG_PWM=y):
     Device Drivers  --->
        [*] Pulse-Width Modulation (PWM) Support  --->
    
    Activate PWM drivers for STM32 PWM drivers:
    [[TIM Linux driver#Kernel configuration |STM32 TIM Linux driver]] and/or [[LPTIM Linux driver#Kernel configuration |STM32 LPTIM Linux driver]]
    
    ===Device tree configuration===
    * PWM generic DT bindings:
    ''PWM DT bindings documentation''<ref>[https://www.kernel.org/doc/Documentation/devicetree/bindings/pwm/pwm.txt Documentation/devicetree/bindings/pwm/pwm.txt], PWM DT bindings documentation</ref> describes device tree properties related to standard '''PWM user nodes''' and '''PWM controller nodes'''.
    * Detailed DT configuration for STM32 internal peripherals:
    [[TIM device tree configuration]] and/or [[LPTIM device tree configuration]]
    
    ==How to use PWMthe framework==
    PWM can be used either from the user or the kernel space.
    
    ===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'.
    
    As an example, proceed as follows to export the first channel (e.g. channel 0):
    {{ReviewsComments|JPR 07Dec'18: Be careful, channel 0 for pwm, correspond to timer channel 1 on reference manual. To check if possible to precise this information.}}
     $ {{Info|'''TIMx_CH1''' is exported as '''"pwm0"''', TIMx_CH2 as "pwm1", and so on:
    *PWM channels are numbered from '''0 to 'npwm' - 1'''
    * TIM<ref name="TIM internal peripheral"/> channels are numbered from '''1 to 'npwm''''.}}
    
    As an example, proceed as follows to export the first channel (TIMx_CH1, e.g. channel 0):
     {{Board$}} echo '''0''' > export${{Board$}} ls
     device  export  '''npwm'''  power  '''pwm0'''  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 > pwm0/period${{Board$}} echo 60000000 > pwm0/duty_cycle${{Board$}} echo 1 > pwm0/enable
    
    The polarity can be inverted or set to normal by using the polarity entry:${{Board$}} echo "'''inversed'''" > pwm0/polarity${{Board$}} cat pwm0/polarity
     '''inversed'''
    ${{Board$}} echo "'''normal'''" > pwm0/polarity${{Board$}} cat pwm0/polarity
     '''normal'''
    
    ===How to use PWM capture with sysfs interface===
    PWM capture is available on some PWM controllers such as ''TIM internal peripheral''<ref name="TIM internal peripheral"/> (see [[TIM_device_tree_configuration#TIM configured in PWM input capture mode|TIM configured in PWM input capture mode]] ).
    {{Info|PWM output and capture mode are mutually exclusive on a TIM instance}}# First export a channel (e.g. 0), then capture PWM input on it:${{Board$}} cd /sys/class/pwm/pwmchip0${{Board$}} echo '''0''' > export
    ${{Board$}} cd pwm0${{Board$}} ls
     '''capture'''  duty_cycle  enable  period  polarity  power  uevent
    ${{Board$}} cat capture
     '''10000 1002'''               {{highlight|# capture result is in nano-seconds, e.g.: 100KHz, 10% duty cycle}}
    ===Example of PWM usage with kernel PWM API===
    Several in-kernel drivers use [[PWM_overview#Kernel_PWM_API|kernel PWM API]]. Below a few examples:
    * pwm-beeper: ''drivers/input/misc/pwm-beeper.c''<ref>{{CodeSource | Linux kernel | drivers/input/misc/pwm-beeper.c | drivers/input/misc/pwm-beeper.c}}, Example to use kernel PWM API</ref> driver, {{CodeSource | Linux kernel | Documentation/devicetree/bindings/input/pwm-beeper.txt | Documentation/devicetree/bindings/input/pwm-beeper.txt}} DT binding documentation.
    * pwm-vibrator: ''drivers/input/misc/pwm-vibra.c''<ref>{{CodeSource | Linux kernel | drivers/input/misc/pwm-vibra.c | drivers/input/misc/pwm-vibra.c}}, Example to use kernel PWM API</ref> driver, {{CodeSource | Linux kernel | Documentation/devicetree/bindings/input/pwm-vibrator.txt | Documentation/devicetree/bindings/input/pwm-vibrator.txt}} DT binding documentation.
    
    ==How to trace and debug the framework==
    === How to monitor with debugfs ===
    PWM usage can be monitored from [[Debugfs|debugfs]] 'pwm' entry. For example:${{Board$}} cd /sys/kernel/debug/${{Board$}} cat pwm
     platform/44000000.timer:pwm, 4 PWM devices                                                               {{highlight|<-- One timer instance exposes 4 PWM channels.}}
      pwm-0   (sysfs               ): requested enabled period: 1000000 ns duty: 500000 ns polarity: normal   {{highlight|<-- Channel 0 has been exported, enabled and configured via sysfs}}
      pwm-1   ((null)              ): period: 0 ns duty: 0 ns polarity: normal
      pwm-2   ((null)              ): period: 0 ns duty: 0 ns polarity: normal                                {{highlight|<-- Other channels aren't used currently}}
      pwm-3   ((null)              ): period: 0 ns duty: 0 ns polarity: normal
    
    ==References==
    <references />=== Troubleshooting PWM capture ===
    Here are some clues on how to debug possible errors in PWM capture mode.<br/>
    
    See [[#How to use PWM capture with sysfs interface|How to use PWM capture with sysfs interface]] as a pre-requisite.
     {{Board$}} cat capture 
     cat: capture: Connection timed out
    This may be due to:
    * the input signal isn't recognized as a PWM input (or there's no input signal to capture).
    * a wrong alternate function number is used for the input pin configuration in the device-tree.<br/>See "[[TIM_device_tree_configuration#TIM configured in PWM input capture mode|TIM configured in PWM input capture mode]]" for further details.
     {{Board$}} cat capture 
     cat: capture: Device or resource busy
    This may be due to:
    * a PWM channel on the same TIM instance is already running (in capture or output mode)
     {{Board$}} cat capture 
     cat: capture: No such device
    This may be due to:
    * the DMA isn't configured properly in the device-tree.<br/>See "[[TIM_device_tree_configuration#TIM configured in PWM input capture mode|TIM configured in PWM input capture mode]]" for further details.
     {{Board$}} cat capture
     cat: capture: Function not implemented
    This may be due to:
    * a wrong TIM instance is being used (e.g. "/sys/class/pwm/pwmchip/pwmchipN"), and it doesn't support capture (like LPTIM)
    * the DMA support isn't enabled (CONFIG_DMA_ENGINE)
    ==References==
    <references />
    
    <noinclude>
    
    {{ArticleBasedOnModel | Framework overview article model}}
    {{PublicationRequestId | 7957 | 2018-06-29 | AnneJ}}
    
    [[Category:Timers|0]]</noinclude>
    (9 intermediate revisions by 2 users not shown)
    Line 1: Line 1:
    <noinclude>
    +
    This article gives information about the Linux<sup>&reg;</sup> PWM framework.<br />
    {{ArticleBasedOnModel | [[Framework overview article model]]}}
    +
    It explains how to activate the PWM interface and, based on examples, how to use it.<br />
    {{ArticleMainWriter | FabriceG}}
    +
    <br />
    {{ ArticleApprovedVersion | FabriceG | GeraldB, BenjaminG, LoicP, NathalieS | No previous approved version | AnneJ - 29June'18 - 7957 | 04July'18}}
    +
     
      +
    ==Framework purpose==
      +
    '''PWM''' (Pulse Width Modulation) framework offers a unified interface for the users to:
      +
    * control PWM output(s) such as period, duty cycle and polarity.
      +
    * capture a PWM signal and report its period and duty cycle (e.g. input).
       
    [[Category:Timers|0]]
    +
    The interface can be used from:
    {{ReviewsComments|JCT 1840: alignment needed with the last version of the model [[Framework overview article model]]<br>
    +
    * user space (sysfs)
    [[Category:ToBeAlignedWithModel]]
    +
    * kernel space (API)
    }}
     
    {{ReviewsComments|BPU W851: maybe good to see somewhere the fact you can output a channel on a TIM instance if one of its channel is in capture mode}}
     
    </noinclude>
     
       
    ==Article purpose==
    +
    PWMs can be used in various use cases, as mentioned in [[#How to use the framework|How to use the framework]] to control LEDs, beepers, vibrators or fans...
    The purpose of this article is the following:
     
    * introduce PWM (pulse width modulation) Linux<sup>&reg;</sup> Framework
     
    * provide general information of PWM
     
    * describe the main components and stakeholders
     
    * give examples of PWM usage:
     
    ** user space (sysfs) usage
     
    ** kernel space (API) usage
     
       
    ==PWM overview==
    +
    ==System overview==
     
    {{
     
    {{
    ImageMap|Image:PWM_overview.png {{!}} frame {{!}} center{{!}} PWM Implementation architecture <br/> {{WarningImageMapOverlay}}
    +
    ImageMap|Image:PWM_overview.png {{!}} frame {{!}} center{{!}} PWM Implementation architecture
     
    rect 400 232 500 272 [[PWM_overview#Sysfs_interface|PWM sysfs interface]]
     
    rect 400 232 500 272 [[PWM_overview#Sysfs_interface|PWM sysfs interface]]
     
    rect 612 335 736 368 [[PWM_overview#Kernel_PWM_API|PWM kernel interface]]
     
    rect 612 335 736 368 [[PWM_overview#Kernel_PWM_API|PWM kernel interface]]
    Line 55: Line 49:
     
    In addition to ''Documentation/pwm.txt''<ref>[https://www.kernel.org/doc/Documentation/pwm.txt Documentation/pwm.txt], Linux PWM interface overview</ref> details on ABI are available in ''Documentation/ABI/testing/sysfs-class-pwm''<ref>[https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-pwm Documentation/ABI/testing/sysfs-class-pwm], Linux PWM Application binary interface</ref>.
     
    In addition to ''Documentation/pwm.txt''<ref>[https://www.kernel.org/doc/Documentation/pwm.txt Documentation/pwm.txt], Linux PWM interface overview</ref> details on ABI are available in ''Documentation/ABI/testing/sysfs-class-pwm''<ref>[https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-pwm Documentation/ABI/testing/sysfs-class-pwm], Linux PWM Application binary interface</ref>.
       
    ==PWM configuration==
    +
    ==Configuration==
       
     
    ===Kernel configuration===
     
    ===Kernel configuration===
    Line 71: Line 65:
     
    [[TIM device tree configuration]] and/or [[LPTIM device tree configuration]]
     
    [[TIM device tree configuration]] and/or [[LPTIM device tree configuration]]
       
    ==How to use PWM==
    +
    ==How to use the framework==
     
    PWM can be used either from the user or the kernel space.
     
    PWM can be used either from the user or the kernel space.
       
     
    ===How to use PWM with sysfs interface===
     
    ===How to use PWM with sysfs interface===
     
    The available PWM controllers are listed in sysfs:
     
    The available PWM controllers are listed in sysfs:
      $ ls /sys/class/pwm
    +
      {{Board$}} ls /sys/class/pwm
     
      '''pwmchip0'''
     
      '''pwmchip0'''
       
     
    The number of channels per controller can be read in npwm (read-only)
     
    The number of channels per controller can be read in npwm (read-only)
      $ cd /sys/class/pwm/pwmchip0
    +
      {{Board$}} cd /sys/class/pwm/pwmchip0
      $ cat npwm
    +
      {{Board$}} cat npwm
     
      '''4'''
     
      '''4'''
       
     
    Each channel is exported (requested for sysfs activation) by writing the corresponding number in 'export'.
     
    Each channel is exported (requested for sysfs activation) by writing the corresponding number in 'export'.
      +
    {{Info|'''TIMx_CH1''' is exported as '''"pwm0"''', TIMx_CH2 as "pwm1", and so on:
      +
    *PWM channels are numbered from '''0 to 'npwm' - 1'''
      +
    * TIM<ref name="TIM internal peripheral"/> channels are numbered from '''1 to 'npwm''''.}}
       
    As an example, proceed as follows to export the first channel (e.g. channel 0):
    +
    As an example, proceed as follows to export the first channel (TIMx_CH1, e.g. channel 0):
    {{ReviewsComments|JPR 07Dec'18: Be careful, channel 0 for pwm, correspond to timer channel 1 on reference manual. To check if possible to precise this information.}}
    +
    {{Board$}} echo '''0''' > export
    $ echo '''0''' > export
    +
      {{Board$}} ls
      $ ls
    +
      device  export  '''npwm''' power  '''pwm0'''  subsystem  uevent  unexport
      device  export  npwm  power  '''pwm0'''  subsystem  uevent  unexport
     
       
     
    The period and duty cycle must be configured before enabling any channel.
     
    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:
     
    As an example, proceed as follows to set a period of 100 ms with a duty cycle of 60% on channel 0:
      $ echo 100000000 > pwm0/period
    +
      {{Board$}} echo 100000000 > pwm0/period
      $ echo 60000000 > pwm0/duty_cycle
    +
      {{Board$}} echo 60000000 > pwm0/duty_cycle
      $ echo 1 > pwm0/enable
    +
      {{Board$}} echo 1 > pwm0/enable
       
     
    The polarity can be inverted or set to normal by using the polarity entry:
     
    The polarity can be inverted or set to normal by using the polarity entry:
      $ echo "'''inversed'''" > pwm0/polarity
    +
      {{Board$}} echo "'''inversed'''" > pwm0/polarity
      $ cat pwm0/polarity
    +
      {{Board$}} cat pwm0/polarity
     
      '''inversed'''
     
      '''inversed'''
     
       
     
       
      $ echo "'''normal'''" > pwm0/polarity
    +
      {{Board$}} echo "'''normal'''" > pwm0/polarity
      $ cat pwm0/polarity
    +
      {{Board$}} cat pwm0/polarity
     
      '''normal'''
     
      '''normal'''
       
     
    ===How to use PWM capture with sysfs interface===
     
    ===How to use PWM capture with sysfs interface===
     
    PWM capture is available on some PWM controllers such as ''TIM internal peripheral''<ref name="TIM internal peripheral"/> (see [[TIM_device_tree_configuration#TIM configured in PWM input capture mode|TIM configured in PWM input capture mode]] ).
     
    PWM capture is available on some PWM controllers such as ''TIM internal peripheral''<ref name="TIM internal peripheral"/> (see [[TIM_device_tree_configuration#TIM configured in PWM input capture mode|TIM configured in PWM input capture mode]] ).
     
    +
    {{Info|PWM output and capture mode are mutually exclusive on a TIM instance}}
     
      # First export a channel (e.g. 0), then capture PWM input on it:
     
      # First export a channel (e.g. 0), then capture PWM input on it:
      $ cd /sys/class/pwm/pwmchip0
    +
      {{Board$}} cd /sys/class/pwm/pwmchip0
      $ echo '''0''' > export
    +
      {{Board$}} echo '''0''' > export
     
       
     
       
      $ cd pwm0
    +
      {{Board$}} cd pwm0
      $ ls
    +
      {{Board$}} ls
     
      '''capture'''  duty_cycle  enable  period  polarity  power  uevent
     
      '''capture'''  duty_cycle  enable  period  polarity  power  uevent
     
       
     
       
      $ cat capture
    +
      {{Board$}} cat capture
     
      '''10000 1002'''              {{highlight|# capture result is in nano-seconds, e.g.: 100KHz, 10% duty cycle}}
     
      '''10000 1002'''              {{highlight|# capture result is in nano-seconds, e.g.: 100KHz, 10% duty cycle}}
     
     
    ===Example of PWM usage with kernel PWM API===
     
    ===Example of PWM usage with kernel PWM API===
     
    Several in-kernel drivers use [[PWM_overview#Kernel_PWM_API|kernel PWM API]]. Below a few examples:
     
    Several in-kernel drivers use [[PWM_overview#Kernel_PWM_API|kernel PWM API]]. Below a few examples:
    Line 130: Line 125:
     
    === How to monitor with debugfs ===
     
    === How to monitor with debugfs ===
     
    PWM usage can be monitored from [[Debugfs|debugfs]] 'pwm' entry. For example:
     
    PWM usage can be monitored from [[Debugfs|debugfs]] 'pwm' entry. For example:
      $ cd /sys/kernel/debug/
    +
      {{Board$}} cd /sys/kernel/debug/
      $ cat pwm
    +
      {{Board$}} cat pwm
     
      platform/44000000.timer:pwm, 4 PWM devices                                                              {{highlight|<-- One timer instance exposes 4 PWM channels.}}
     
      platform/44000000.timer:pwm, 4 PWM devices                                                              {{highlight|<-- One timer instance exposes 4 PWM channels.}}
     
       pwm-0  (sysfs              ): requested enabled period: 1000000 ns duty: 500000 ns polarity: normal  {{highlight|<-- Channel 0 has been exported, enabled and configured via sysfs}}
     
       pwm-0  (sysfs              ): requested enabled period: 1000000 ns duty: 500000 ns polarity: normal  {{highlight|<-- Channel 0 has been exported, enabled and configured via sysfs}}
    Line 137: Line 132:
     
       pwm-2  ((null)              ): period: 0 ns duty: 0 ns polarity: normal                                {{highlight|<-- Other channels aren't used currently}}
     
       pwm-2  ((null)              ): period: 0 ns duty: 0 ns polarity: normal                                {{highlight|<-- Other channels aren't used currently}}
     
       pwm-3  ((null)              ): period: 0 ns duty: 0 ns polarity: normal
     
       pwm-3  ((null)              ): period: 0 ns duty: 0 ns polarity: normal
     
    +
    === Troubleshooting PWM capture ===
      +
    Here are some clues on how to debug possible errors in PWM capture mode.<br/>
      +
    See [[#How to use PWM capture with sysfs interface|How to use PWM capture with sysfs interface]] as a pre-requisite.
      +
    {{Board$}} cat capture
      +
    cat: capture: Connection timed out
      +
    This may be due to:
      +
    * the input signal isn't recognized as a PWM input (or there's no input signal to capture).
      +
    * a wrong alternate function number is used for the input pin configuration in the device-tree.<br/>See "[[TIM_device_tree_configuration#TIM configured in PWM input capture mode|TIM configured in PWM input capture mode]]" for further details.
      +
    {{Board$}} cat capture
      +
    cat: capture: Device or resource busy
      +
    This may be due to:
      +
    * a PWM channel on the same TIM instance is already running (in capture or output mode)
      +
    {{Board$}} cat capture
      +
    cat: capture: No such device
      +
    This may be due to:
      +
    * the DMA isn't configured properly in the device-tree.<br/>See "[[TIM_device_tree_configuration#TIM configured in PWM input capture mode|TIM configured in PWM input capture mode]]" for further details.
      +
    {{Board$}} cat capture
      +
    cat: capture: Function not implemented
      +
    This may be due to:
      +
    * a wrong TIM instance is being used (e.g. "/sys/class/pwm/pwmchip/pwmchipN"), and it doesn't support capture (like LPTIM)
      +
    * the DMA support isn't enabled (CONFIG_DMA_ENGINE)
     
    ==References==
     
    ==References==
       
     
    <references />
     
    <references />
      +
      +
    <noinclude>
      +
    {{ArticleBasedOnModel | Framework overview article model}}
      +
    {{PublicationRequestId | 7957 | 2018-06-29 | AnneJ}}
      +
      +
    [[Category:Timers|0]]
      +
    </noinclude>