You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mynewt.apache.org by markus <ma...@bibi.ca> on 2018/03/01 00:53:19 UTC

clarification about pwm_test

I started implementing a PWM driver for the STM32 processors a few days ago and ran into an issue I need clarification. According to the doc the duty cycle should be absolutely defined between 0 (no output) and 65535 (full output).

However, pwm_test and pwm_nrf52 require the application code to get the base frequency, calculate the top value from that and then scale the duty cycle accordingly.

Just to be clear, the way I understand the interface a call like

  pwm_enable_duty_cycle(pwm, 0, 0x7FFF);

should always lead to a 50% duty cycle, regardless of what the pwm frequency was set to and regardless of what counter frequency is internally used by the pwm driver.

I would appreciate any clarifying comments as to what's going on here - or where I'm going wrong.

The second question has to do with the sequence of api calls and at what point the PWM is actually started (which is an explicit step for STM32s).
- Is it a safe assumption that an application must call pwm_chan_config for a channel before it can call pwm_enable_duty_cycle?
- Is there support for kicking off a PWM channel without configuring an output pin?

Lastly, in some email archive about the original PWM driver thread I found a reference to 'hal_pwm' - which I can't even find a header for. Did this get removed from the repo?

Thanks a lot,
Markus




Re: clarification about pwm_test

Posted by markus <ma...@bibi.ca>.
Hi Miguel

I went ahead and added an API call to get the max duty value from the driver, this is what I came up with:

https://github.com/mlampert/mynewt-core/commit/1505c2f15aa175c456273eb2bb1c918093071c17#diff-6e1ac1dce00788efcedf1e166f74cdb5

if you (and everyone else interested in the pwm driver) could have a look and let me know if this is the direction we want to go. The code isn't ready for review, it's really just about the API change.

Thanks,
Markus


On Wed, 28 Feb 2018 21:10:21 -0800
markus <ma...@bibi.ca> wrote:

> Hey Miguel,
> 
> thanks for the background that helps a lot.
> 
> I agree that (if this is the way the pwm api should work) the top
> value should be explicit. As the return value from pwm_set_frequency
> would be an option - given its prominence though it would probably
> make sense to add an API call for it or add it as a member to `struct
> pwm_dev`.
> 
> At least that way the dependency between the application and driver
> implementation gets broken.
> 
> It would be great if we could nail that down here so I can implement
> the stm driver correctly the first time ;).
> 
> The pin-less PWM is more a result of calling the APIs in the wrong
> order. I couldn't come up with a use case but also wasn't sure if it
> should be supported. I do have robot though where the h-bridge is a
> bit hard to control. What I ended up doing was to generate the same
> PWM in 2 hw-units and depending on state enabled one of the output
> pins.
> 
> Good stuff,
> Markus
> 
> 
> On Thu, 1 Mar 2018 00:48:36 -0300
> Miguel Azevedo <mi...@gmail.com> wrote:
> 
> > Hi Markus,
> >   
> > > According to the doc the duty cycle should be absolutely defined
> > > between 0 (no output) and 65535 (full output).    
> > Yes, the doc on the PWM API wasn't updated after the first drivers
> > got implemented, if you take a look at pwm_nrf52 on my latest pull
> > request on PWM the driver's doc is different.
> >   
> > > Just to be clear, the way I understand the interface a call like
> > >
> > >   pwm_enable_duty_cycle(pwm, 0, 0x7FFF);
> > >
> > > should always lead to a 50% duty cycle, regardless of what the pwm
> > > frequency was set to and regardless of what counter frequency is
> > > internally used by the pwm driver.    
> > 
> > Well, in a general way PWM uses clock division, so in practice you
> > have a top value, which is clock_freq/pwm_freq and this should be
> > the 100% duty cycle.
> > Some versions ago there was a PWM HAL API, I based the current PWM
> > API on that one, with a few differences which BTW where discussed
> > on this mailing list.
> > Why not convert it and always have a 0 - 65535 and not have external
> > code doing it?
> > At the time I implemented the pwm_nrf52 and soft_pwm drivers it made
> > more sense to have the duty cycle fraction value based on the top
> > value. This is because it would totally respect the resolution and
> > remove the need to convert from one value range to another each time
> > we change duty cycle.
> > If you convert it internally every time you change the duty cycle,
> > which probably will happen frequently, it won't be as efficient as
> > calculating a top value once you set the frequency(something which
> > is likely to happen less frequently).
> >   
> > > I would appreciate any clarifying comments as to what's going on
> > > here - or where I'm going wrong.    
> > What happens here is that I forgot to change the documentation,
> > although the drivers work consistently the way I just described.
> > Just to be clear here: I understand your concern about the fraction
> > range and that it is on the older API.
> > It still makes sense to me to use the real range and calculate the
> > top value when we set the frequency rather than converting from one
> > value range to another every time we change the duty cycle, its
> > just the way PWM works. Probably it would be better to return a top
> > value on the set_frequency function, this is one of the changes
> > would like to propose.
> >   
> > > The second question has to do with the sequence of api calls and
> > > at what point the PWM is actually started (which is an explicit
> > > step for STM32s).
> > > - Is it a safe assumption that an application must call
> > > pwm_chan_config for a channel before it can call
> > > pwm_enable_duty_cycle?    
> > Absolutely. As far as we go we need to set a GPIO output before we
> > fire up a PWM channel.
> >   
> > > - Is there support for kicking off a PWM channel without
> > > configuring an output pin?    
> > No, can you give us a use case where that would need happen?
> >   
> > > Lastly, in some email archive about the original PWM driver thread
> > > I found a reference to 'hal_pwm' - which I can't even find a
> > > header for. Did this get removed from the repo?    
> > Yes, it did, here you have it:
> > https://github.com/apache/mynewt-core/blob/mynewt_0_9_0_tag/hw/hal/include/hal/hal_pwm.h
> > 
> > Best,
> > 
> > Miguel
> > 
> > On Wed, Feb 28, 2018 at 9:53 PM, markus <ma...@bibi.ca> wrote:  
> > > I started implementing a PWM driver for the STM32 processors a few
> > > days ago and ran into an issue I need clarification. According to
> > > the doc the duty cycle should be absolutely defined between 0 (no
> > > output) and 65535 (full output).
> > >
> > > However, pwm_test and pwm_nrf52 require the application code to
> > > get the base frequency, calculate the top value from that and then
> > > scale the duty cycle accordingly.
> > >
> > > Just to be clear, the way I understand the interface a call like
> > >
> > >   pwm_enable_duty_cycle(pwm, 0, 0x7FFF);
> > >
> > > should always lead to a 50% duty cycle, regardless of what the pwm
> > > frequency was set to and regardless of what counter frequency is
> > > internally used by the pwm driver.
> > >
> > > I would appreciate any clarifying comments as to what's going on
> > > here - or where I'm going wrong.
> > >
> > > The second question has to do with the sequence of api calls and
> > > at what point the PWM is actually started (which is an explicit
> > > step for STM32s).
> > > - Is it a safe assumption that an application must call
> > > pwm_chan_config for a channel before it can call
> > > pwm_enable_duty_cycle?
> > > - Is there support for kicking off a PWM channel without
> > > configuring an output pin?
> > >
> > > Lastly, in some email archive about the original PWM driver thread
> > > I found a reference to 'hal_pwm' - which I can't even find a
> > > header for. Did this get removed from the repo?
> > >
> > > Thanks a lot,
> > > Markus
> > >
> > >
> > >    
> > 
> > 
> >   
> 


Re: clarification about pwm_test

Posted by markus <ma...@bibi.ca>.
Hey Miguel,

thanks for the background that helps a lot.

I agree that (if this is the way the pwm api should work) the top value should be explicit. As the return value from pwm_set_frequency would be an option - given its prominence though it would probably make sense to add an API call for it or add it as a member to `struct pwm_dev`.

At least that way the dependency between the application and driver implementation gets broken.

It would be great if we could nail that down here so I can implement the stm driver correctly the first time ;).

The pin-less PWM is more a result of calling the APIs in the wrong order. I couldn't come up with a use case but also wasn't sure if it should be supported. I do have robot though where the h-bridge is a bit hard to control. What I ended up doing was to generate the same PWM in 2 hw-units and depending on state enabled one of the output pins.

Good stuff,
Markus


On Thu, 1 Mar 2018 00:48:36 -0300
Miguel Azevedo <mi...@gmail.com> wrote:

> Hi Markus,
> 
> > According to the doc the duty cycle should be absolutely defined
> > between 0 (no output) and 65535 (full output).  
> Yes, the doc on the PWM API wasn't updated after the first drivers got
> implemented, if you take a look at pwm_nrf52 on my latest pull request
> on PWM the driver's doc is different.
> 
> > Just to be clear, the way I understand the interface a call like
> >
> >   pwm_enable_duty_cycle(pwm, 0, 0x7FFF);
> >
> > should always lead to a 50% duty cycle, regardless of what the pwm
> > frequency was set to and regardless of what counter frequency is
> > internally used by the pwm driver.  
> 
> Well, in a general way PWM uses clock division, so in practice you
> have a top value, which is clock_freq/pwm_freq and this should be the
> 100% duty cycle.
> Some versions ago there was a PWM HAL API, I based the current PWM API
> on that one, with a few differences which BTW where discussed on this
> mailing list.
> Why not convert it and always have a 0 - 65535 and not have external
> code doing it?
> At the time I implemented the pwm_nrf52 and soft_pwm drivers it made
> more sense to have the duty cycle fraction value based on the top
> value. This is because it would totally respect the resolution and
> remove the need to convert from one value range to another each time
> we change duty cycle.
> If you convert it internally every time you change the duty cycle,
> which probably will happen frequently, it won't be as efficient as
> calculating a top value once you set the frequency(something which is
> likely to happen less frequently).
> 
> > I would appreciate any clarifying comments as to what's going on
> > here - or where I'm going wrong.  
> What happens here is that I forgot to change the documentation,
> although the drivers work consistently the way I just described.
> Just to be clear here: I understand your concern about the fraction
> range and that it is on the older API.
> It still makes sense to me to use the real range and calculate the top
> value when we set the frequency rather than converting from one value
> range to another every time we change the duty cycle, its just the way
> PWM works. Probably it would be better to return a top value on the
> set_frequency function, this is one of the changes would like to
> propose.
> 
> > The second question has to do with the sequence of api calls and at
> > what point the PWM is actually started (which is an explicit step
> > for STM32s).
> > - Is it a safe assumption that an application must call
> > pwm_chan_config for a channel before it can call
> > pwm_enable_duty_cycle?  
> Absolutely. As far as we go we need to set a GPIO output before we
> fire up a PWM channel.
> 
> > - Is there support for kicking off a PWM channel without
> > configuring an output pin?  
> No, can you give us a use case where that would need happen?
> 
> > Lastly, in some email archive about the original PWM driver thread
> > I found a reference to 'hal_pwm' - which I can't even find a header
> > for. Did this get removed from the repo?  
> Yes, it did, here you have it:
> https://github.com/apache/mynewt-core/blob/mynewt_0_9_0_tag/hw/hal/include/hal/hal_pwm.h
> 
> Best,
> 
> Miguel
> 
> On Wed, Feb 28, 2018 at 9:53 PM, markus <ma...@bibi.ca> wrote:
> > I started implementing a PWM driver for the STM32 processors a few
> > days ago and ran into an issue I need clarification. According to
> > the doc the duty cycle should be absolutely defined between 0 (no
> > output) and 65535 (full output).
> >
> > However, pwm_test and pwm_nrf52 require the application code to get
> > the base frequency, calculate the top value from that and then
> > scale the duty cycle accordingly.
> >
> > Just to be clear, the way I understand the interface a call like
> >
> >   pwm_enable_duty_cycle(pwm, 0, 0x7FFF);
> >
> > should always lead to a 50% duty cycle, regardless of what the pwm
> > frequency was set to and regardless of what counter frequency is
> > internally used by the pwm driver.
> >
> > I would appreciate any clarifying comments as to what's going on
> > here - or where I'm going wrong.
> >
> > The second question has to do with the sequence of api calls and at
> > what point the PWM is actually started (which is an explicit step
> > for STM32s).
> > - Is it a safe assumption that an application must call
> > pwm_chan_config for a channel before it can call
> > pwm_enable_duty_cycle?
> > - Is there support for kicking off a PWM channel without
> > configuring an output pin?
> >
> > Lastly, in some email archive about the original PWM driver thread
> > I found a reference to 'hal_pwm' - which I can't even find a header
> > for. Did this get removed from the repo?
> >
> > Thanks a lot,
> > Markus
> >
> >
> >  
> 
> 
> 


Re: clarification about pwm_test

Posted by Miguel Azevedo <mi...@gmail.com>.
Hi Markus,

> According to the doc the duty cycle should be absolutely defined between 0 (no output) and 65535 (full output).
Yes, the doc on the PWM API wasn't updated after the first drivers got
implemented, if you take a look at pwm_nrf52 on my latest pull request
on PWM the driver's doc is different.

> Just to be clear, the way I understand the interface a call like
>
>   pwm_enable_duty_cycle(pwm, 0, 0x7FFF);
>
> should always lead to a 50% duty cycle, regardless of what the pwm frequency was set to and regardless of what counter frequency is internally used by the pwm driver.

Well, in a general way PWM uses clock division, so in practice you
have a top value, which is clock_freq/pwm_freq and this should be the
100% duty cycle.
Some versions ago there was a PWM HAL API, I based the current PWM API
on that one, with a few differences which BTW where discussed on this
mailing list.
Why not convert it and always have a 0 - 65535 and not have external
code doing it?
At the time I implemented the pwm_nrf52 and soft_pwm drivers it made
more sense to have the duty cycle fraction value based on the top
value. This is because it would totally respect the resolution and
remove the need to convert from one value range to another each time
we change duty cycle.
If you convert it internally every time you change the duty cycle,
which probably will happen frequently, it won't be as efficient as
calculating a top value once you set the frequency(something which is
likely to happen less frequently).

> I would appreciate any clarifying comments as to what's going on here - or where I'm going wrong.
What happens here is that I forgot to change the documentation,
although the drivers work consistently the way I just described.
Just to be clear here: I understand your concern about the fraction
range and that it is on the older API.
It still makes sense to me to use the real range and calculate the top
value when we set the frequency rather than converting from one value
range to another every time we change the duty cycle, its just the way
PWM works. Probably it would be better to return a top value on the
set_frequency function, this is one of the changes would like to
propose.

> The second question has to do with the sequence of api calls and at what point the PWM is actually started (which is an explicit step for STM32s).
> - Is it a safe assumption that an application must call pwm_chan_config for a channel before it can call pwm_enable_duty_cycle?
Absolutely. As far as we go we need to set a GPIO output before we
fire up a PWM channel.

> - Is there support for kicking off a PWM channel without configuring an output pin?
No, can you give us a use case where that would need happen?

> Lastly, in some email archive about the original PWM driver thread I found a reference to 'hal_pwm' - which I can't even find a header for. Did this get removed from the repo?
Yes, it did, here you have it:
https://github.com/apache/mynewt-core/blob/mynewt_0_9_0_tag/hw/hal/include/hal/hal_pwm.h

Best,

Miguel

On Wed, Feb 28, 2018 at 9:53 PM, markus <ma...@bibi.ca> wrote:
> I started implementing a PWM driver for the STM32 processors a few days ago and ran into an issue I need clarification. According to the doc the duty cycle should be absolutely defined between 0 (no output) and 65535 (full output).
>
> However, pwm_test and pwm_nrf52 require the application code to get the base frequency, calculate the top value from that and then scale the duty cycle accordingly.
>
> Just to be clear, the way I understand the interface a call like
>
>   pwm_enable_duty_cycle(pwm, 0, 0x7FFF);
>
> should always lead to a 50% duty cycle, regardless of what the pwm frequency was set to and regardless of what counter frequency is internally used by the pwm driver.
>
> I would appreciate any clarifying comments as to what's going on here - or where I'm going wrong.
>
> The second question has to do with the sequence of api calls and at what point the PWM is actually started (which is an explicit step for STM32s).
> - Is it a safe assumption that an application must call pwm_chan_config for a channel before it can call pwm_enable_duty_cycle?
> - Is there support for kicking off a PWM channel without configuring an output pin?
>
> Lastly, in some email archive about the original PWM driver thread I found a reference to 'hal_pwm' - which I can't even find a header for. Did this get removed from the repo?
>
> Thanks a lot,
> Markus
>
>
>



-- 
--
Miguel Azevedo