Skip to content

Creating abstractions over Pwm trait is not ideal #244

@amiraeva

Description

@amiraeva

I'm working on a project in which I've defined an ActuatorMotor which wraps a Pwm channel on my device. As I'm refactoring to make ActuatorMotor generic over the specific Pwm hardware, I've found it annoying that all Pwm functions take Pwm::Channel by move.

Here's an example:

struct ActuatorMotor<P: Pwm> {
    pwm: P,
    channel: P::Channel,
}

impl<P: Pwm> ActuatorMotor<P>
{
    fn set_velocity(&mut self, v: Velocity) {
        // do stuff with velocity or whatever to get duty
        let duty = todo!();
        self.pwm.set_duty(self.channel, duty);
        // error: can't move out of self.channel
    }
}

A workaround that seems to work for now is to make channel store a closure which spits out instances of Pwm::Channel i.e. Fn() -> P::Channel. At a first glance, requiring a Clone and/or Copy bound on Pwm::Channel would solve my problem, or altering the method signatures in Pwm to instead take &mut Pwm::Channel instead of by move.

Activity

changed the title [-]Creating abstractions over Pwm trait not ideal[/-] [+]Creating abstractions over Pwm trait is not ideal[/+] on Aug 17, 2020
ryankurte

ryankurte commented on Aug 17, 2020

@ryankurte
Contributor

huh this can be frustrating! while we don't currently require Clone or Copy bounds from embedded-hal, if these are currently implemented for the types you require could you partially resolve this with a where: P::Channel = Clone (I can't remember the exact syntax for this, sorry if it's not quite right) bound on your ActuatorMotor impl?

eldruin

eldruin commented on Aug 17, 2020

@eldruin
Member

Have you tried PwmPin?

amiraeva

amiraeva commented on Aug 17, 2020

@amiraeva
Author

Thanks to both of you for getting back to me. The closure approach got too noisy, so I gave up and settled on using PwmPin. I just figured I'd chime in on my experience using Pwm in its current state before it gets stabilized. Why can't it take Channel as an &mut argument just like adc::Oneshot does for the pin argument in its methods?

eldruin

eldruin commented on Aug 17, 2020

@eldruin
Member

Thank you @amiraeva.
I would be fine with changing the methods to accept a mutable reference channel but we should see how that fits for HAL implementations for MCUs.

added this to the v1.0.0 milestone on Aug 22, 2020
David-OConnor

David-OConnor commented on Oct 12, 2020

@David-OConnor

Possibly related: It's not always ideal to represent PWM as a pin. For example, in STM32, PWM is controlled by timer peripherals. In F3, the PWM module used raw pointers so it could make it fit with the channel paradigm. I ended up adding PWM functionality to the timer struct, and was unable to make it work with the channel-based EH traits.

ryankurte

ryankurte commented on Oct 12, 2020

@ryankurte
Contributor

I ended up adding PWM functionality to the timer struct, and was unable to make it work with the channel-based EH traits.

interesting experience, are you able to share this code? it's an interesting use case, in my experience with PWM / timers it is not uncommon to run 2+ channels of PWM from a single timer but, the configuration changes between them tend to be somewhat restricted.

David-OConnor

David-OConnor commented on Oct 12, 2020

@David-OConnor

stm32-rs/stm32f3xx-hal#141

Discussion in there is also relevant; has comments from me and the original, EH/channel-based PWM module author. You'll see the crux of the issue is that the trait is channel-based, while most of the settings for STM32 MCUs are not.

Eg, compare the code in that PR to the pwm.rs module, which uses the EH trait: https://github.com/stm32-rs/stm32f3xx-hal/blob/master/src/pwm.rs

added a commit that references this issue on Mar 11, 2021
eldruin

eldruin commented on Jul 9, 2021

@eldruin
Member

Fixed in #246

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @eldruin@ryankurte@David-OConnor@amiraeva

        Issue actions

          Creating abstractions over Pwm trait is not ideal · Issue #244 · rust-embedded/embedded-hal