Skip to content

drivers: pwm: extend API to support events #93275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

javlands
Copy link
Contributor

@javlands javlands commented Jul 17, 2025

  • Extend the pwm API to also support pwm interrupts.
  • Implement pwm interrupts for the SAM controllers

@zephyrbot zephyrbot added platform: Microchip SAM Microchip SAM Platform (formerly Atmel SAM) area: PWM Pulse Width Modulation labels Jul 17, 2025
@pdgendt pdgendt assigned henrikbrixandersen and anangl and unassigned nandojve Jul 17, 2025
@javlands javlands force-pushed the pwm-interrupts branch 2 times, most recently from aa08572 to 49349f4 Compare July 17, 2025 14:46
Copy link
Contributor

@pdgendt pdgendt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update tests/drivers/build_all/pwm/testcase.yaml with:

diff --git a/tests/drivers/build_all/pwm/testcase.yaml b/tests/drivers/build_all/pwm/testcase.yaml
index 34156300b5d..270637d4625 100644
--- a/tests/drivers/build_all/pwm/testcase.yaml
+++ b/tests/drivers/build_all/pwm/testcase.yaml
@@ -43,6 +43,8 @@ tests:
     platform_allow:
       - sam_e70_xplained/same70q21
       - sam_v71_xult/samv71q21b
+    extra_configs:
+      - CONFIG_PWM_INTERRUPT=y
   drivers.pwm.stm32.build:
     platform_allow: disco_l475_iot1
   drivers.pwm.xec.build:

@pdgendt
Copy link
Contributor

pdgendt commented Jul 23, 2025

Ping to all reviewers

Should this be brought to the architecture working group meeting?

@henrikbrixandersen
Copy link
Member

Should this be brought to the architecture working group meeting?

I believe it should be. I am not convinced this is the right approach. We typically do not just expose IRQs to the application like this.

@henrikbrixandersen henrikbrixandersen added the Architecture Review Discussion in the Architecture WG required label Jul 23, 2025
@pdgendt
Copy link
Contributor

pdgendt commented Jul 23, 2025

I am not convinced this is the right approach. We typically do not just expose IRQs to the application like this.

What's the alternative? BTW, this is also very similar to the PWM capture API.

A usecase would be to use it for IR input/output, where I'd expect similar APIs. Envision a "remote control" subsystem using these drivers as carriers.

@henrikbrixandersen
Copy link
Member

What's the alternative? BTW, this is also very similar to the PWM capture API.

I don't think it is. The PWM capture callback provides the captured values upon a complete capture. The API proposed here merely forwards an IRQ from the device to the upper layer (subsystem or application).

A usecase would be to use it for IR input/output, where I'd expect similar APIs. Envision a "remote control" subsystem using these drivers as carriers.

For that, wouldn't it be more abstract to offload the "train" of PWM cycles to be handled in the driver/device itself? E.g. "perform N PWM cycles with period X, pulse width Y with callback on completion", or even the same but with multiple encoded PWM configurations to be "played" like a stream"

With the API proposed here, the subsystem would receive a callback upon each completed PWM cycle and have to respond to that, preventing hardware offload for capable devices.

@henrikbrixandersen
Copy link
Member

  • Extend the pwm API to also support pwm interrupts.

@javlands Please provide some context to this. What is your use-case?

@pdgendt
Copy link
Contributor

pdgendt commented Jul 24, 2025

@javlands Please provide some context to this. What is your use-case?

I can elaborate for my colleague

The use-case is a PWM peripheral connected to an IR LED, to emit an RC (remote control) code it is typically required to encode this by alternating pulses and spaces. Tracking the number of periods is desired to have an accurate carrier representation of an RC code.
In order to not rely on timers, we want to introduce a PWM interrupt callback mechanism.

@bjarki-andreasen
Copy link
Contributor

bjarki-andreasen commented Jul 29, 2025

The additions in this PR are too closely coupled to the interrupt part, rather than the "event" part. User's care when an event occurs, like PERIOD or FAULT, not how this event physically originated. Stuff like enabling an interrupt, reacting to it and clearing the pending irq flags, is not relevant to the user. All a user cares about is this part:

typedef void (*pwm_event_callback_t)(const struct device *dev, uint32_t events, void *user_data);
int pwm_event_callback_set(const struct device *dev, uint32_t event_mask, pwm_event_callback_t callback, void *user_data);
int pwm_event_callback_clear(const struct device *dev, pwm_event_callback_t callback);

whether this event occurs via interrupt, or via reading a status register of an external device, triggered by an interrupt pin for example, is not relevant to the user. So the API should abstract that part away :)

@carlescufi
Copy link
Member

carlescufi commented Jul 29, 2025

Architecture WG meeting:

  • The use case here is discussed in the call
  • The comment by @bjarki-andreasen here raises no objections, seems like a good idea to everyone
  • @carlescufi suggests a solution to the hardware acceleration issue raised by @henrikbrixandersen in this comment:
    • Start with the API in this PR (with the changes suggested by @bjarki-andreasen)
    • Later introduce a new function that allows the user to trigger a fixed set of N cycles (all with the same period and pulse):
      • int pwm_set_n_cycles(const struct device *dev, uint32_t channel, uint32_t period, uint32_t pulse, uint32_t n, pwm_flags_t flags);
    • At the same time introduce a new event in the event mask that triggers a callback at the end of the N cycles programmed

@ts4ling
Copy link
Contributor

ts4ling commented Jul 30, 2025

I get @henrikbrixandersen 's concerns ("preventing hardware offload") in a general view, but for my stepper use-case it doesn't matter. For my drv8849 stepper driver I'm using k_usleep() between every ramp up/down PWM-step and when I'm not ramping I just sleep longer. That's pretty ugly. I'd love to use a PWM interrupt to do some counting.

@javlands javlands force-pushed the pwm-interrupts branch 2 times, most recently from baa7e54 to e38f743 Compare July 31, 2025 09:32
javlands added 3 commits July 31, 2025 12:04
Extend the PWM API to support events, as some
controllers allow interrupts if e.g., a pwm period
has ended or a fault occured.

Signed-off-by: Jaro Van Landschoot <[email protected]>
The SAM4S pwm supports several events. This commit
implements the events when a channel period has ended
or a fault event has occured.

Signed-off-by: Jaro Van Landschoot <[email protected]>
Add the pwm event functions of the sam pwm driver to the
build all test.

Signed-off-by: Jaro Van Landschoot <[email protected]>
Copy link

@javlands
Copy link
Contributor Author

Hi all! Thanks for the feedback, I've processed it all:

A renaming was done from "interrupt" to "event", and the gpio API was used as a reference to (re)build the API:

  • The event API now consists of 1 function manage_event_callback, that is extended by 2 public functions pwm_add_event_callback() and pwm_remove_event_callback().
  • A callback struct was added to easily handle multiple callbacks for multiple channels
  • pwm_utils.h contains some generic implementations to cleanly handle all callbacks

@henrikbrixandersen
Copy link
Member

A renaming was done from "interrupt" to "event", and the gpio API was used as a reference to (re)build the API:

Please update the PR title and description to match. Thanks.

@henrikbrixandersen henrikbrixandersen moved this from Todo to In Progress in Architecture Review Aug 4, 2025
@javlands javlands changed the title drivers: pwm: extend API to support interrupts drivers: pwm: extend API to support events Aug 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Architecture Review Discussion in the Architecture WG required area: PWM Pulse Width Modulation platform: Microchip SAM Microchip SAM Platform (formerly Atmel SAM)
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

9 participants