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:57:09 UTC

recommendations for IO pin declarations

While writing a PWM driver for the STM32s mcu family I came across the issue of assigning output pins for a pwm channel.

PWM output in STM32s is done by configuring a pin for "alternate functions" - where specific pins have specific (possible) alternate functions. In other words, only a very limited number of timer:channel:pin combinations are possible, each one requiring a very specific alternate function.

`struct pwm_chan_config` only specifies the pin number. I've been using the `data` member to put the burden on the application to specify the "correct" number for the alternate function - but I find this a little unsatisfactory.

So I was wondering if somebody has a recommendation, better approach to solving this issue?

Have fun,
Markus

Re: recommendations for IO pin declarations

Posted by markus <ma...@bibi.ca>.
+1

On Fri, 09 Mar 2018 10:35:46 -0800
"Sterling Hughes" <st...@gmail.com> wrote:

> Do folks think having a pin_t type makes sense where the function of
> the pin can be stored in a standard way?  I could see an argument for
> this — obviously we couldn’t change all the code at once, but we
> could start by adding that, and then slowly migrate to it.
> 
> On 8 Mar 2018, at 23:04, markus wrote:
> 
> > Hi Miguel,
> >
> > that is what I'm currently doing. I thought it might be possible to 
> > store the alternate function in the pin itself, if a pin variable 
> > would have at leas 12 bit. But mynewt does not declare a type for a 
> > pin, and there is no standard about the variable size of storing a 
> > pin. Some components (including pwm) use a uint8_t - which is
> > barely enough to store the pad id alone.
> >
> > For now it seems we'll have to put the burden of on the user.
> >
> > Thanks,
> > Markus
> >
> > On Fri, 9 Mar 2018 04:16:44 -0100
> > Miguel Azevedo <mi...@gmail.com> wrote:
> >  
> >> Hi Markus,
> >>
> >> One thing I forgot to mention, and that after giving this some 
> >> thought
> >> makes some sense, is to pass the pin restriction information (what
> >> channels a pin may accept, etc) using the data parameter on
> >> pwm_dev_init, passed through os_dev_create which is called on
> >> hal_bsp.c. For me it makes sense to have these values stored 
> >> somewhere
> >> on the BSP (or even MCU), since they look like they are directly
> >> dependent on the board model(or the mcu model?) you're using.
> >>
> >> Best regards,
> >>
> >> Miguel
> >>
> >> On Thu, Mar 1, 2018 at 5:57 PM, Wayne Keenan
> >> <wa...@gmail.com> wrote:  
> >>> It is a complicated issue indeed.
> >>> Forgetting the pins, the CubeMX tool also resolves conflicts of
> >>> clock sources as well. (STM chips are most
> >>> flexible/interesting :) )
> >>>
> >>> So I'd like to point out that there are other internal parts of
> >>> MicroPython that can help guide MyNewt MCU support on clocks too,
> >>> without the need for CubeMX.
> >>>
> >>>
> >>>
> >>> Thanks,
> >>> Wayne
> >>>
> >>> On 1 March 2018 at 18:48, Wayne Keenan <wa...@gmail.com>
> >>> wrote:  
> >>>> That's a good point, but also having used CubeMX myself I always
> >>>> thought it is very application specific design time choices.
> >>>> IMHO What MyNewt MCU support would need is 'a level above that'.
> >>>>
> >>>> I've perhaps missed something.
> >>>>
> >>>> But AFAIK the MicroPython CSV files are (easily) parsable
> >>>> representations of what's in the STM32 data sheets for each MCU,
> >>>> so it's minus the bespoke tooling, libraries and generated
> >>>> boilerplate code CubeMX generates.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> Thanks,
> >>>> Wayne
> >>>>
> >>>> On 1 March 2018 at 17:43, Raoul van Bergen
> >>>> <ra...@me.com> wrote:
> >>>>  
> >>>>> Hi,
> >>>>> Just my opinion from long time experience with STM32.
> >>>>>
> >>>>> IF (!) there is anything to be supported for this from external,
> >>>>> it should be the definition files generated by the free CubeMX
> >>>>> tool from STM itself. This tool allows you to first create the
> >>>>> perfect matching pin assignment for your application (it was
> >>>>> already mentioned this can become very complicated) and next it
> >>>>> can generate the complete BSP /HAL support source files based on
> >>>>> the library from STM.
> >>>>>
> >>>>> I know some other vendors have similar tools as well.
> >>>>>
> >>>>> I am not advocating to use ST's own library at all but at least
> >>>>> the include files generated by CubeMX do hold the proper defines
> >>>>> and macros needed to do the pin assignments correctly and this
> >>>>> tool is kept up-to-date for all STM32 processors at all times,
> >>>>> so "your" STM32 of choice will always be there......
> >>>>>
> >>>>> Regards,
> >>>>> Raoul
> >>>>>
> >>>>>
> >>>>>
> >>>>> -----Original Message-----
> >>>>> From: Wayne Keenan [mailto:wayne.keenan@gmail.com]
> >>>>> Sent: 01 March 2018 18:24
> >>>>> To: dev@mynewt.apache.org
> >>>>> Cc: Miguel Azevedo <mi...@gmail.com>
> >>>>> Subject: Re: recommendations for IO pin declarations
> >>>>>
> >>>>> If you take a look at MicroPython, it has CSV files describing
> >>>>> the Alternate Functions of pins for many STM32 devices.
> >>>>>
> >>>>> Files matching *_af.csv under: https://github.com/
> >>>>> micropython/micropython/tree/master/ports/stm32/boards
> >>>>>
> >>>>> Perhaps the Mynewt STM32 MCU support could/should import and use
> >>>>> them?
> >>>>>
> >>>>>
> >>>>> Thanks,
> >>>>> Wayne
> >>>>>
> >>>>> On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:
> >>>>>  
> >>>>>> I didn't explain this correctly, let me start again.
> >>>>>>
> >>>>>> First off, this is not PWM specific, it is the way how STM32's
> >>>>>> map internal peripherals to IO pads (also known as pins).
> >>>>>>
> >>>>>> Each IO pad can be operated in up to 16 different functions,
> >>>>>> called alternate functions. At reset each pad assumes AF0, it's
> >>>>>> default function, which can be changed at runtime. I've
> >>>>>> attached an excerpt of the AF table (not sure if attachments
> >>>>>> make it through).
> >>>>>>
> >>>>>> Taking the IO pin PA1 as an example which has the following AF
> >>>>>> assignments
> >>>>>> 0 ... -
> >>>>>> 1 ... TIM2_CH2
> >>>>>> 2 ... -
> >>>>>> 3 ... TSC_G1_IO2
> >>>>>> 4 ... -
> >>>>>> 5 ... -
> >>>>>> 6 ... -
> >>>>>> 7 ... USART2_RTS_DE
> >>>>>> 8 ... -
> >>>>>> 9 ... TIM15_CH1N
> >>>>>> 10... -
> >>>>>>  .....
> >>>>>>
> >>>>>> At reset the pin assumes AF0, which has no alternate function
> >>>>>> which means it is operating as a regular IO pin. If you
> >>>>>> reconfigure the pin for AF1, then it will output whatever
> >>>>>> channel 2 of timer 2 is configured to do. If you configure the
> >>>>>> pin for AF9 it will output whatever the complementary channel 1
> >>>>>> of timer 15 is configured for (regardless of you configured
> >>>>>> channel 2 of timer 2 to do).
> >>>>>>
> >>>>>> So for mcu peripherals, if their signals need to be connected
> >>>>>> to a pad, one doesn't just need the pin number, but one also
> >>>>>> needs the AF  
> >>>>> number.  
> >>>>>>
> >>>>>> If you look at the instantiation of the uart here:
> >>>>>> https://github.com/apache/mynewt-core/blob/master/hw/bsp/
> >>>>>> nucleo-f413zh/src/hal_bsp.c#L45
> >>>>>> you'll notice GPIO_AF7_USART3, which is required in order to
> >>>>>> connect the signals of UART3 to the io pins.
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On Thu, 1 Mar 2018 09:50:16 -0300
> >>>>>> Miguel Azevedo <mi...@gmail.com> wrote:
> >>>>>>  
> >>>>>>>> Unfortunately there is no universal AF value for pwm
> >>>>>>>> channels, on some pins it's 1, on some it's 6 ... , some
> >>>>>>>> pins cannot be used as pwm channel outputs at all and some
> >>>>>>>> pins could be used as the output of multiple channels.  
> >>>>>>>
> >>>>>>> Not sure I got it right.
> >>>>>>> So you can configure a given pin using 1 or 6 depending on
> >>>>>>> whether you want it to output a single pwm chan or multiple?
> >>>>>>> Having a single gpio output multiple channels feels a lot
> >>>>>>> like an uncommon feature btw.
> >>>>>>>  
> >>>>>>>> It's bad enough that only certain pins work for a given
> >>>>>>>> timer/channel but it's even worse because the driver also
> >>>>>>>> needs to know the AF number to use.  
> >>>>>>> It definitely does not look great but it feels that you will
> >>>>>>> need either a lot of #ifdefs or have the driver knowing these
> >>>>>>> restrictions. Aren't these restrictions described on some .h
> >>>>>>> from stm?  
> >>>>>>>> As an additional crux, the HW timer to be used (TIM1 above)
> >>>>>>>> typically gets defined by the BSP in hal_bsp_init, whereas
> >>>>>>>> pwm_chan_config is application runtime code. I would prefer
> >>>>>>>> to break the coupling, or at least make it less fragile.  
> >>>>>>>
> >>>>>>> I see, I'm not sure about that one. I mean it does not make
> >>>>>>> much sense to me, because one might want to reconfigure
> >>>>>>> channels on runtime, just take a look at what we're doing on
> >>>>>>> pwm_test on last PR.
> >>>>>>>
> >>>>>>> It sounds like stm PWM has a bunch of limitations you have to
> >>>>>>> deal with and there are some things you probably won't be
> >>>>>>> able to run from. I already implemented two PWM drivers using
> >>>>>>> the current interface, I think we should be flexible at this
> >>>>>>> stage regarding the API interface so it will be useful for
> >>>>>>> you. However I feel that having an AF field by default doesnt
> >>>>>>> make much sense.
> >>>>>>>
> >>>>>>> Thanks,
> >>>>>>>
> >>>>>>> On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca>
> >>>>>>> wrote:  
> >>>>>>>> This is the implementation of pwm_configure_channel:
> >>>>>>>>
> >>>>>>>> static int
> >>>>>>>> stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t
> >>>>>>>> cnum, struct pwm_chan_cfg *cfg) {
> >>>>>>>>     stm32f3_pwm_dev_t *pwm;
> >>>>>>>>
> >>>>>>>>     assert(dev->pwm_instance_id < PWM_COUNT);
> >>>>>>>>     assert(cnum < STM32F3_PWM_CH_COUNT);
> >>>>>>>>
> >>>>>>>>     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
> >>>>>>>>
> >>>>>>>>     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
> >>>>>>>>         return -1;
> >>>>>>>>     }
> >>>>>>>>
> >>>>>>>>     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
> >>>>>>>>         if (hal_gpio_init_af(cfg->pin,
> >>>>>>>>                             (uint8_t)(uintptr_t)cfg->data,
> >>>>>>>>                             HAL_GPIO_PULL_NONE,
> >>>>>>>>                             0)) {
> >>>>>>>>             return -1;
> >>>>>>>>         }
> >>>>>>>>     }
> >>>>>>>>
> >>>>>>>>     pwm->ch[cnum].duty      = 0;
> >>>>>>>>     pwm->ch[cnum].pin       = cfg->pin;
> >>>>>>>>     pwm->ch[cnum].invert    = cfg->inverted;
> >>>>>>>>     pwm->ch[cnum].update    = 0;
> >>>>>>>>     pwm->ch[cnum].enabled   = 0;
> >>>>>>>>     pwm->ch[cnum].configure = 1;
> >>>>>>>>
> >>>>>>>>     return 0;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> On an STM to connect the output pad with the PWM channel I
> >>>>>>>> have to configure it for the alternate function (which is
> >>>>>>>> done by hal_gpio_init_af). The AF value, the result of
> >>>>>>>> `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15
> >>>>>>>> which determines what the pin is used for.
> >>>>>>>>
> >>>>>>>> Unfortunately there is no universal AF value for pwm
> >>>>>>>> channels, on some pins it's 1, on some it's 6 ... , some
> >>>>>>>> pins cannot be used as pwm channel outputs at all and some
> >>>>>>>> pins could be used as the output of multiple channels.
> >>>>>>>>
> >>>>>>>> With the construct above the application has to make a call
> >>>>>>>> like:
> >>>>>>>>
> >>>>>>>>         struct pwm_chan_cfg cfg;
> >>>>>>>>         cfg.pin = 8;
> >>>>>>>>         cfg.inverted = false;
> >>>>>>>>         cfg.data = (void*)6;
> >>>>>>>>         pwm_chan_config(pwm, 0, &cfg);
> >>>>>>>>
> >>>>>>>> But this ONLY works if `pwm` is bound to the mcu's TIM1 and
> >>>>>>>> you use channel 0. For TIM1 and channel 1 the app would
> >>>>>>>> have to use `pin=9/data=6`.
> >>>>>>>>
> >>>>>>>> It's bad enough that only certain pins work for a given
> >>>>>>>> timer/channel but it's even worse because the driver also
> >>>>>>>> needs to know the AF number to use.
> >>>>>>>>
> >>>>>>>> As an additional crux, the HW timer to be used (TIM1 above)
> >>>>>>>> typically gets defined by the BSP in hal_bsp_init, whereas
> >>>>>>>> pwm_chan_config is application runtime code. I would prefer
> >>>>>>>> to break the coupling, or at least make it less fragile.
> >>>>>>>>
> >>>>>>>> Does this make sense?
> >>>>>>>> Markus
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On Thu, 1 Mar 2018 01:58:46 -0300
> >>>>>>>> Miguel Azevedo <mi...@gmail.com> wrote:
> >>>>>>>>  
> >>>>>>>>> Hi markus,
> >>>>>>>>>  
> >>>>>>>>>> `struct pwm_chan_config` only specifies the pin number.
> >>>>>>>>>> I've been using the `data` member to put the burden on
> >>>>>>>>>> the application to specify the "correct" number for the
> >>>>>>>>>> alternate function > - but I find this a little
> >>>>>>>>>> unsatisfactory.  
> >>>>>>>>> That sounds a lot driver/hw specific. Can you show us the
> >>>>>>>>> code for that?
> >>>>>>>>>
> >>>>>>>>> Thanks,
> >>>>>>>>> Miguel
> >>>>>>>>>
> >>>>>>>>> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca>
> >>>>>>>>> wrote:  
> >>>>>>>>>> While writing a PWM driver for the STM32s mcu family I
> >>>>>>>>>> came across the issue of assigning output pins for a pwm
> >>>>>>>>>> channel.
> >>>>>>>>>>
> >>>>>>>>>> PWM output in STM32s is done by configuring a pin for
> >>>>>>>>>> "alternate functions" - where specific pins have specific
> >>>>>>>>>> (possible) alternate functions. In other words, only a
> >>>>>>>>>> very limited number of timer:channel:pin combinations
> >>>>>>>>>> are possible, each one requiring a very specific
> >>>>>>>>>> alternate function.
> >>>>>>>>>>
> >>>>>>>>>> `struct pwm_chan_config` only specifies the pin number.
> >>>>>>>>>> I've been using the `data` member to put the burden on
> >>>>>>>>>> the application to specify the "correct" number for the
> >>>>>>>>>> alternate function - but I find this a little
> >>>>>>>>>> unsatisfactory.
> >>>>>>>>>>
> >>>>>>>>>> So I was wondering if somebody has a recommendation,
> >>>>>>>>>> better approach to solving this issue?
> >>>>>>>>>>
> >>>>>>>>>> Have fun,
> >>>>>>>>>> Markus  
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>  
> >>>>>>>>  
> >>>>>>>
> >>>>>>>
> >>>>>>>  
> >>>>>>
> >>>>>>  
> >>>>>
> >>>>>  
> >>>>  
> >>
> >>
> >>  


Re: recommendations for IO pin declarations

Posted by Sterling Hughes <st...@gmail.com>.
Do folks think having a pin_t type makes sense where the function of the 
pin can be stored in a standard way?  I could see an argument for this 
— obviously we couldn’t change all the code at once, but we could 
start by adding that, and then slowly migrate to it.

On 8 Mar 2018, at 23:04, markus wrote:

> Hi Miguel,
>
> that is what I'm currently doing. I thought it might be possible to 
> store the alternate function in the pin itself, if a pin variable 
> would have at leas 12 bit. But mynewt does not declare a type for a 
> pin, and there is no standard about the variable size of storing a 
> pin. Some components (including pwm) use a uint8_t - which is barely 
> enough to store the pad id alone.
>
> For now it seems we'll have to put the burden of on the user.
>
> Thanks,
> Markus
>
> On Fri, 9 Mar 2018 04:16:44 -0100
> Miguel Azevedo <mi...@gmail.com> wrote:
>
>> Hi Markus,
>>
>> One thing I forgot to mention, and that after giving this some 
>> thought
>> makes some sense, is to pass the pin restriction information (what
>> channels a pin may accept, etc) using the data parameter on
>> pwm_dev_init, passed through os_dev_create which is called on
>> hal_bsp.c. For me it makes sense to have these values stored 
>> somewhere
>> on the BSP (or even MCU), since they look like they are directly
>> dependent on the board model(or the mcu model?) you're using.
>>
>> Best regards,
>>
>> Miguel
>>
>> On Thu, Mar 1, 2018 at 5:57 PM, Wayne Keenan <wa...@gmail.com>
>> wrote:
>>> It is a complicated issue indeed.
>>> Forgetting the pins, the CubeMX tool also resolves conflicts of
>>> clock sources as well. (STM chips are most flexible/interesting :) )
>>>
>>> So I'd like to point out that there are other internal parts of
>>> MicroPython that can help guide MyNewt MCU support on clocks too,
>>> without the need for CubeMX.
>>>
>>>
>>>
>>> Thanks,
>>> Wayne
>>>
>>> On 1 March 2018 at 18:48, Wayne Keenan <wa...@gmail.com>
>>> wrote:
>>>> That's a good point, but also having used CubeMX myself I always
>>>> thought it is very application specific design time choices.  IMHO
>>>> What MyNewt MCU support would need is 'a level above that'.
>>>>
>>>> I've perhaps missed something.
>>>>
>>>> But AFAIK the MicroPython CSV files are (easily) parsable
>>>> representations of what's in the STM32 data sheets for each MCU,
>>>> so it's minus the bespoke tooling, libraries and generated
>>>> boilerplate code CubeMX generates.
>>>>
>>>>
>>>>
>>>>
>>>> Thanks,
>>>> Wayne
>>>>
>>>> On 1 March 2018 at 17:43, Raoul van Bergen
>>>> <ra...@me.com> wrote:
>>>>
>>>>> Hi,
>>>>> Just my opinion from long time experience with STM32.
>>>>>
>>>>> IF (!) there is anything to be supported for this from external,
>>>>> it should be the definition files generated by the free CubeMX
>>>>> tool from STM itself. This tool allows you to first create the
>>>>> perfect matching pin assignment for your application (it was
>>>>> already mentioned this can become very complicated) and next it
>>>>> can generate the complete BSP /HAL support source files based on
>>>>> the library from STM.
>>>>>
>>>>> I know some other vendors have similar tools as well.
>>>>>
>>>>> I am not advocating to use ST's own library at all but at least
>>>>> the include files generated by CubeMX do hold the proper defines
>>>>> and macros needed to do the pin assignments correctly and this
>>>>> tool is kept up-to-date for all STM32 processors at all times, so
>>>>> "your" STM32 of choice will always be there......
>>>>>
>>>>> Regards,
>>>>> Raoul
>>>>>
>>>>>
>>>>>
>>>>> -----Original Message-----
>>>>> From: Wayne Keenan [mailto:wayne.keenan@gmail.com]
>>>>> Sent: 01 March 2018 18:24
>>>>> To: dev@mynewt.apache.org
>>>>> Cc: Miguel Azevedo <mi...@gmail.com>
>>>>> Subject: Re: recommendations for IO pin declarations
>>>>>
>>>>> If you take a look at MicroPython, it has CSV files describing the
>>>>> Alternate Functions of pins for many STM32 devices.
>>>>>
>>>>> Files matching *_af.csv under: https://github.com/
>>>>> micropython/micropython/tree/master/ports/stm32/boards
>>>>>
>>>>> Perhaps the Mynewt STM32 MCU support could/should import and use
>>>>> them?
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Wayne
>>>>>
>>>>> On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:
>>>>>
>>>>>> I didn't explain this correctly, let me start again.
>>>>>>
>>>>>> First off, this is not PWM specific, it is the way how STM32's
>>>>>> map internal peripherals to IO pads (also known as pins).
>>>>>>
>>>>>> Each IO pad can be operated in up to 16 different functions,
>>>>>> called alternate functions. At reset each pad assumes AF0, it's
>>>>>> default function, which can be changed at runtime. I've
>>>>>> attached an excerpt of the AF table (not sure if attachments
>>>>>> make it through).
>>>>>>
>>>>>> Taking the IO pin PA1 as an example which has the following AF
>>>>>> assignments
>>>>>> 0 ... -
>>>>>> 1 ... TIM2_CH2
>>>>>> 2 ... -
>>>>>> 3 ... TSC_G1_IO2
>>>>>> 4 ... -
>>>>>> 5 ... -
>>>>>> 6 ... -
>>>>>> 7 ... USART2_RTS_DE
>>>>>> 8 ... -
>>>>>> 9 ... TIM15_CH1N
>>>>>> 10... -
>>>>>>  .....
>>>>>>
>>>>>> At reset the pin assumes AF0, which has no alternate function
>>>>>> which means it is operating as a regular IO pin. If you
>>>>>> reconfigure the pin for AF1, then it will output whatever
>>>>>> channel 2 of timer 2 is configured to do. If you configure the
>>>>>> pin for AF9 it will output whatever the complementary channel 1
>>>>>> of timer 15 is configured for (regardless of you configured
>>>>>> channel 2 of timer 2 to do).
>>>>>>
>>>>>> So for mcu peripherals, if their signals need to be connected
>>>>>> to a pad, one doesn't just need the pin number, but one also
>>>>>> needs the AF
>>>>> number.
>>>>>>
>>>>>> If you look at the instantiation of the uart here:
>>>>>> https://github.com/apache/mynewt-core/blob/master/hw/bsp/
>>>>>> nucleo-f413zh/src/hal_bsp.c#L45
>>>>>> you'll notice GPIO_AF7_USART3, which is required in order to
>>>>>> connect the signals of UART3 to the io pins.
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Thu, 1 Mar 2018 09:50:16 -0300
>>>>>> Miguel Azevedo <mi...@gmail.com> wrote:
>>>>>>
>>>>>>>> Unfortunately there is no universal AF value for pwm
>>>>>>>> channels, on some pins it's 1, on some it's 6 ... , some
>>>>>>>> pins cannot be used as pwm channel outputs at all and some
>>>>>>>> pins could be used as the output of multiple channels.
>>>>>>>
>>>>>>> Not sure I got it right.
>>>>>>> So you can configure a given pin using 1 or 6 depending on
>>>>>>> whether you want it to output a single pwm chan or multiple?
>>>>>>> Having a single gpio output multiple channels feels a lot
>>>>>>> like an uncommon feature btw.
>>>>>>>
>>>>>>>> It's bad enough that only certain pins work for a given
>>>>>>>> timer/channel but it's even worse because the driver also
>>>>>>>> needs to know the AF number to use.
>>>>>>> It definitely does not look great but it feels that you will
>>>>>>> need either a lot of #ifdefs or have the driver knowing these
>>>>>>> restrictions. Aren't these restrictions described on some .h
>>>>>>> from stm?
>>>>>>>> As an additional crux, the HW timer to be used (TIM1 above)
>>>>>>>> typically gets defined by the BSP in hal_bsp_init, whereas
>>>>>>>> pwm_chan_config is application runtime code. I would prefer
>>>>>>>> to break the coupling, or at least make it less fragile.
>>>>>>>
>>>>>>> I see, I'm not sure about that one. I mean it does not make
>>>>>>> much sense to me, because one might want to reconfigure
>>>>>>> channels on runtime, just take a look at what we're doing on
>>>>>>> pwm_test on last PR.
>>>>>>>
>>>>>>> It sounds like stm PWM has a bunch of limitations you have to
>>>>>>> deal with and there are some things you probably won't be
>>>>>>> able to run from. I already implemented two PWM drivers using
>>>>>>> the current interface, I think we should be flexible at this
>>>>>>> stage regarding the API interface so it will be useful for
>>>>>>> you. However I feel that having an AF field by default doesnt
>>>>>>> make much sense.
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca>
>>>>>>> wrote:
>>>>>>>> This is the implementation of pwm_configure_channel:
>>>>>>>>
>>>>>>>> static int
>>>>>>>> stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t
>>>>>>>> cnum, struct pwm_chan_cfg *cfg) {
>>>>>>>>     stm32f3_pwm_dev_t *pwm;
>>>>>>>>
>>>>>>>>     assert(dev->pwm_instance_id < PWM_COUNT);
>>>>>>>>     assert(cnum < STM32F3_PWM_CH_COUNT);
>>>>>>>>
>>>>>>>>     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
>>>>>>>>
>>>>>>>>     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
>>>>>>>>         return -1;
>>>>>>>>     }
>>>>>>>>
>>>>>>>>     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
>>>>>>>>         if (hal_gpio_init_af(cfg->pin,
>>>>>>>>                             (uint8_t)(uintptr_t)cfg->data,
>>>>>>>>                             HAL_GPIO_PULL_NONE,
>>>>>>>>                             0)) {
>>>>>>>>             return -1;
>>>>>>>>         }
>>>>>>>>     }
>>>>>>>>
>>>>>>>>     pwm->ch[cnum].duty      = 0;
>>>>>>>>     pwm->ch[cnum].pin       = cfg->pin;
>>>>>>>>     pwm->ch[cnum].invert    = cfg->inverted;
>>>>>>>>     pwm->ch[cnum].update    = 0;
>>>>>>>>     pwm->ch[cnum].enabled   = 0;
>>>>>>>>     pwm->ch[cnum].configure = 1;
>>>>>>>>
>>>>>>>>     return 0;
>>>>>>>> }
>>>>>>>>
>>>>>>>> On an STM to connect the output pad with the PWM channel I
>>>>>>>> have to configure it for the alternate function (which is
>>>>>>>> done by hal_gpio_init_af). The AF value, the result of
>>>>>>>> `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15
>>>>>>>> which determines what the pin is used for.
>>>>>>>>
>>>>>>>> Unfortunately there is no universal AF value for pwm
>>>>>>>> channels, on some pins it's 1, on some it's 6 ... , some
>>>>>>>> pins cannot be used as pwm channel outputs at all and some
>>>>>>>> pins could be used as the output of multiple channels.
>>>>>>>>
>>>>>>>> With the construct above the application has to make a call
>>>>>>>> like:
>>>>>>>>
>>>>>>>>         struct pwm_chan_cfg cfg;
>>>>>>>>         cfg.pin = 8;
>>>>>>>>         cfg.inverted = false;
>>>>>>>>         cfg.data = (void*)6;
>>>>>>>>         pwm_chan_config(pwm, 0, &cfg);
>>>>>>>>
>>>>>>>> But this ONLY works if `pwm` is bound to the mcu's TIM1 and
>>>>>>>> you use channel 0. For TIM1 and channel 1 the app would
>>>>>>>> have to use `pin=9/data=6`.
>>>>>>>>
>>>>>>>> It's bad enough that only certain pins work for a given
>>>>>>>> timer/channel but it's even worse because the driver also
>>>>>>>> needs to know the AF number to use.
>>>>>>>>
>>>>>>>> As an additional crux, the HW timer to be used (TIM1 above)
>>>>>>>> typically gets defined by the BSP in hal_bsp_init, whereas
>>>>>>>> pwm_chan_config is application runtime code. I would prefer
>>>>>>>> to break the coupling, or at least make it less fragile.
>>>>>>>>
>>>>>>>> Does this make sense?
>>>>>>>> Markus
>>>>>>>>
>>>>>>>>
>>>>>>>> On Thu, 1 Mar 2018 01:58:46 -0300
>>>>>>>> Miguel Azevedo <mi...@gmail.com> wrote:
>>>>>>>>
>>>>>>>>> Hi markus,
>>>>>>>>>
>>>>>>>>>> `struct pwm_chan_config` only specifies the pin number.
>>>>>>>>>> I've been using the `data` member to put the burden on
>>>>>>>>>> the application to specify the "correct" number for the
>>>>>>>>>> alternate function > - but I find this a little
>>>>>>>>>> unsatisfactory.
>>>>>>>>> That sounds a lot driver/hw specific. Can you show us the
>>>>>>>>> code for that?
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Miguel
>>>>>>>>>
>>>>>>>>> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca>
>>>>>>>>> wrote:
>>>>>>>>>> While writing a PWM driver for the STM32s mcu family I
>>>>>>>>>> came across the issue of assigning output pins for a pwm
>>>>>>>>>> channel.
>>>>>>>>>>
>>>>>>>>>> PWM output in STM32s is done by configuring a pin for
>>>>>>>>>> "alternate functions" - where specific pins have specific
>>>>>>>>>> (possible) alternate functions. In other words, only a
>>>>>>>>>> very limited number of timer:channel:pin combinations
>>>>>>>>>> are possible, each one requiring a very specific
>>>>>>>>>> alternate function.
>>>>>>>>>>
>>>>>>>>>> `struct pwm_chan_config` only specifies the pin number.
>>>>>>>>>> I've been using the `data` member to put the burden on
>>>>>>>>>> the application to specify the "correct" number for the
>>>>>>>>>> alternate function - but I find this a little
>>>>>>>>>> unsatisfactory.
>>>>>>>>>>
>>>>>>>>>> So I was wondering if somebody has a recommendation,
>>>>>>>>>> better approach to solving this issue?
>>>>>>>>>>
>>>>>>>>>> Have fun,
>>>>>>>>>> Markus
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>
>>
>>

Re: recommendations for IO pin declarations

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

that is what I'm currently doing. I thought it might be possible to store the alternate function in the pin itself, if a pin variable would have at leas 12 bit. But mynewt does not declare a type for a pin, and there is no standard about the variable size of storing a pin. Some components (including pwm) use a uint8_t - which is barely enough to store the pad id alone.

For now it seems we'll have to put the burden of on the user.

Thanks,
Markus

On Fri, 9 Mar 2018 04:16:44 -0100
Miguel Azevedo <mi...@gmail.com> wrote:

> Hi Markus,
> 
> One thing I forgot to mention, and that after giving this some thought
> makes some sense, is to pass the pin restriction information (what
> channels a pin may accept, etc) using the data parameter on
> pwm_dev_init, passed through os_dev_create which is called on
> hal_bsp.c. For me it makes sense to have these values stored somewhere
> on the BSP (or even MCU), since they look like they are directly
> dependent on the board model(or the mcu model?) you're using.
> 
> Best regards,
> 
> Miguel
> 
> On Thu, Mar 1, 2018 at 5:57 PM, Wayne Keenan <wa...@gmail.com>
> wrote:
> > It is a complicated issue indeed.
> > Forgetting the pins, the CubeMX tool also resolves conflicts of
> > clock sources as well. (STM chips are most flexible/interesting :) )
> >
> > So I'd like to point out that there are other internal parts of
> > MicroPython that can help guide MyNewt MCU support on clocks too,
> > without the need for CubeMX.
> >
> >
> >
> > Thanks,
> > Wayne
> >
> > On 1 March 2018 at 18:48, Wayne Keenan <wa...@gmail.com>
> > wrote: 
> >> That's a good point, but also having used CubeMX myself I always
> >> thought it is very application specific design time choices.  IMHO
> >> What MyNewt MCU support would need is 'a level above that'.
> >>
> >> I've perhaps missed something.
> >>
> >> But AFAIK the MicroPython CSV files are (easily) parsable
> >> representations of what's in the STM32 data sheets for each MCU,
> >> so it's minus the bespoke tooling, libraries and generated
> >> boilerplate code CubeMX generates.
> >>
> >>
> >>
> >>
> >> Thanks,
> >> Wayne
> >>
> >> On 1 March 2018 at 17:43, Raoul van Bergen
> >> <ra...@me.com> wrote:
> >>  
> >>> Hi,
> >>> Just my opinion from long time experience with STM32.
> >>>
> >>> IF (!) there is anything to be supported for this from external,
> >>> it should be the definition files generated by the free CubeMX
> >>> tool from STM itself. This tool allows you to first create the
> >>> perfect matching pin assignment for your application (it was
> >>> already mentioned this can become very complicated) and next it
> >>> can generate the complete BSP /HAL support source files based on
> >>> the library from STM.
> >>>
> >>> I know some other vendors have similar tools as well.
> >>>
> >>> I am not advocating to use ST's own library at all but at least
> >>> the include files generated by CubeMX do hold the proper defines
> >>> and macros needed to do the pin assignments correctly and this
> >>> tool is kept up-to-date for all STM32 processors at all times, so
> >>> "your" STM32 of choice will always be there......
> >>>
> >>> Regards,
> >>> Raoul
> >>>
> >>>
> >>>
> >>> -----Original Message-----
> >>> From: Wayne Keenan [mailto:wayne.keenan@gmail.com]
> >>> Sent: 01 March 2018 18:24
> >>> To: dev@mynewt.apache.org
> >>> Cc: Miguel Azevedo <mi...@gmail.com>
> >>> Subject: Re: recommendations for IO pin declarations
> >>>
> >>> If you take a look at MicroPython, it has CSV files describing the
> >>> Alternate Functions of pins for many STM32 devices.
> >>>
> >>> Files matching *_af.csv under: https://github.com/
> >>> micropython/micropython/tree/master/ports/stm32/boards
> >>>
> >>> Perhaps the Mynewt STM32 MCU support could/should import and use
> >>> them?
> >>>
> >>>
> >>> Thanks,
> >>> Wayne
> >>>
> >>> On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:
> >>>  
> >>> > I didn't explain this correctly, let me start again.
> >>> >
> >>> > First off, this is not PWM specific, it is the way how STM32's
> >>> > map internal peripherals to IO pads (also known as pins).
> >>> >
> >>> > Each IO pad can be operated in up to 16 different functions,
> >>> > called alternate functions. At reset each pad assumes AF0, it's
> >>> > default function, which can be changed at runtime. I've
> >>> > attached an excerpt of the AF table (not sure if attachments
> >>> > make it through).
> >>> >
> >>> > Taking the IO pin PA1 as an example which has the following AF
> >>> > assignments
> >>> > 0 ... -
> >>> > 1 ... TIM2_CH2
> >>> > 2 ... -
> >>> > 3 ... TSC_G1_IO2
> >>> > 4 ... -
> >>> > 5 ... -
> >>> > 6 ... -
> >>> > 7 ... USART2_RTS_DE
> >>> > 8 ... -
> >>> > 9 ... TIM15_CH1N
> >>> > 10... -
> >>> >  .....
> >>> >
> >>> > At reset the pin assumes AF0, which has no alternate function
> >>> > which means it is operating as a regular IO pin. If you
> >>> > reconfigure the pin for AF1, then it will output whatever
> >>> > channel 2 of timer 2 is configured to do. If you configure the
> >>> > pin for AF9 it will output whatever the complementary channel 1
> >>> > of timer 15 is configured for (regardless of you configured
> >>> > channel 2 of timer 2 to do).
> >>> >
> >>> > So for mcu peripherals, if their signals need to be connected
> >>> > to a pad, one doesn't just need the pin number, but one also
> >>> > needs the AF  
> >>> number.  
> >>> >
> >>> > If you look at the instantiation of the uart here:
> >>> > https://github.com/apache/mynewt-core/blob/master/hw/bsp/
> >>> > nucleo-f413zh/src/hal_bsp.c#L45
> >>> > you'll notice GPIO_AF7_USART3, which is required in order to
> >>> > connect the signals of UART3 to the io pins.
> >>> >
> >>> >
> >>> >
> >>> > On Thu, 1 Mar 2018 09:50:16 -0300
> >>> > Miguel Azevedo <mi...@gmail.com> wrote:
> >>> >  
> >>> > > > Unfortunately there is no universal AF value for pwm
> >>> > > > channels, on some pins it's 1, on some it's 6 ... , some
> >>> > > > pins cannot be used as pwm channel outputs at all and some
> >>> > > > pins could be used as the output of multiple channels.  
> >>> > >
> >>> > > Not sure I got it right.
> >>> > > So you can configure a given pin using 1 or 6 depending on
> >>> > > whether you want it to output a single pwm chan or multiple?
> >>> > > Having a single gpio output multiple channels feels a lot
> >>> > > like an uncommon feature btw.
> >>> > >  
> >>> > > > It's bad enough that only certain pins work for a given
> >>> > > > timer/channel but it's even worse because the driver also
> >>> > > > needs to know the AF number to use.  
> >>> > > It definitely does not look great but it feels that you will
> >>> > > need either a lot of #ifdefs or have the driver knowing these
> >>> > > restrictions. Aren't these restrictions described on some .h
> >>> > > from stm? 
> >>> > > > As an additional crux, the HW timer to be used (TIM1 above)
> >>> > > > typically gets defined by the BSP in hal_bsp_init, whereas
> >>> > > > pwm_chan_config is application runtime code. I would prefer
> >>> > > > to break the coupling, or at least make it less fragile.  
> >>> > >
> >>> > > I see, I'm not sure about that one. I mean it does not make
> >>> > > much sense to me, because one might want to reconfigure
> >>> > > channels on runtime, just take a look at what we're doing on
> >>> > > pwm_test on last PR.
> >>> > >
> >>> > > It sounds like stm PWM has a bunch of limitations you have to
> >>> > > deal with and there are some things you probably won't be
> >>> > > able to run from. I already implemented two PWM drivers using
> >>> > > the current interface, I think we should be flexible at this
> >>> > > stage regarding the API interface so it will be useful for
> >>> > > you. However I feel that having an AF field by default doesnt
> >>> > > make much sense.
> >>> > >
> >>> > > Thanks,
> >>> > >
> >>> > > On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca>
> >>> > > wrote:  
> >>> > > > This is the implementation of pwm_configure_channel:
> >>> > > >
> >>> > > > static int
> >>> > > > stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t
> >>> > > > cnum, struct pwm_chan_cfg *cfg) {
> >>> > > >     stm32f3_pwm_dev_t *pwm;
> >>> > > >
> >>> > > >     assert(dev->pwm_instance_id < PWM_COUNT);
> >>> > > >     assert(cnum < STM32F3_PWM_CH_COUNT);
> >>> > > >
> >>> > > >     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
> >>> > > >
> >>> > > >     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
> >>> > > >         return -1;
> >>> > > >     }
> >>> > > >
> >>> > > >     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
> >>> > > >         if (hal_gpio_init_af(cfg->pin,
> >>> > > >                             (uint8_t)(uintptr_t)cfg->data,
> >>> > > >                             HAL_GPIO_PULL_NONE,
> >>> > > >                             0)) {
> >>> > > >             return -1;
> >>> > > >         }
> >>> > > >     }
> >>> > > >
> >>> > > >     pwm->ch[cnum].duty      = 0;
> >>> > > >     pwm->ch[cnum].pin       = cfg->pin;
> >>> > > >     pwm->ch[cnum].invert    = cfg->inverted;
> >>> > > >     pwm->ch[cnum].update    = 0;
> >>> > > >     pwm->ch[cnum].enabled   = 0;
> >>> > > >     pwm->ch[cnum].configure = 1;
> >>> > > >
> >>> > > >     return 0;
> >>> > > > }
> >>> > > >
> >>> > > > On an STM to connect the output pad with the PWM channel I
> >>> > > > have to configure it for the alternate function (which is
> >>> > > > done by hal_gpio_init_af). The AF value, the result of
> >>> > > > `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15
> >>> > > > which determines what the pin is used for.
> >>> > > >
> >>> > > > Unfortunately there is no universal AF value for pwm
> >>> > > > channels, on some pins it's 1, on some it's 6 ... , some
> >>> > > > pins cannot be used as pwm channel outputs at all and some
> >>> > > > pins could be used as the output of multiple channels.
> >>> > > >
> >>> > > > With the construct above the application has to make a call
> >>> > > > like:
> >>> > > >
> >>> > > >         struct pwm_chan_cfg cfg;
> >>> > > >         cfg.pin = 8;
> >>> > > >         cfg.inverted = false;
> >>> > > >         cfg.data = (void*)6;
> >>> > > >         pwm_chan_config(pwm, 0, &cfg);
> >>> > > >
> >>> > > > But this ONLY works if `pwm` is bound to the mcu's TIM1 and
> >>> > > > you use channel 0. For TIM1 and channel 1 the app would
> >>> > > > have to use `pin=9/data=6`.
> >>> > > >
> >>> > > > It's bad enough that only certain pins work for a given
> >>> > > > timer/channel but it's even worse because the driver also
> >>> > > > needs to know the AF number to use.
> >>> > > >
> >>> > > > As an additional crux, the HW timer to be used (TIM1 above)
> >>> > > > typically gets defined by the BSP in hal_bsp_init, whereas
> >>> > > > pwm_chan_config is application runtime code. I would prefer
> >>> > > > to break the coupling, or at least make it less fragile.
> >>> > > >
> >>> > > > Does this make sense?
> >>> > > > Markus
> >>> > > >
> >>> > > >
> >>> > > > On Thu, 1 Mar 2018 01:58:46 -0300
> >>> > > > Miguel Azevedo <mi...@gmail.com> wrote:
> >>> > > >  
> >>> > > >> Hi markus,
> >>> > > >>  
> >>> > > >> > `struct pwm_chan_config` only specifies the pin number.
> >>> > > >> > I've been using the `data` member to put the burden on
> >>> > > >> > the application to specify the "correct" number for the
> >>> > > >> > alternate function > - but I find this a little
> >>> > > >> > unsatisfactory.  
> >>> > > >> That sounds a lot driver/hw specific. Can you show us the
> >>> > > >> code for that?
> >>> > > >>
> >>> > > >> Thanks,
> >>> > > >> Miguel
> >>> > > >>
> >>> > > >> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca>
> >>> > > >> wrote:  
> >>> > > >> > While writing a PWM driver for the STM32s mcu family I
> >>> > > >> > came across the issue of assigning output pins for a pwm
> >>> > > >> > channel.
> >>> > > >> >
> >>> > > >> > PWM output in STM32s is done by configuring a pin for
> >>> > > >> > "alternate functions" - where specific pins have specific
> >>> > > >> > (possible) alternate functions. In other words, only a
> >>> > > >> > very limited number of timer:channel:pin combinations
> >>> > > >> > are possible, each one requiring a very specific
> >>> > > >> > alternate function.
> >>> > > >> >
> >>> > > >> > `struct pwm_chan_config` only specifies the pin number.
> >>> > > >> > I've been using the `data` member to put the burden on
> >>> > > >> > the application to specify the "correct" number for the
> >>> > > >> > alternate function - but I find this a little
> >>> > > >> > unsatisfactory.
> >>> > > >> >
> >>> > > >> > So I was wondering if somebody has a recommendation,
> >>> > > >> > better approach to solving this issue?
> >>> > > >> >
> >>> > > >> > Have fun,
> >>> > > >> > Markus  
> >>> > > >>
> >>> > > >>
> >>> > > >>  
> >>> > > >  
> >>> > >
> >>> > >
> >>> > >  
> >>> >
> >>> >  
> >>>
> >>>  
> >>  
> 
> 
> 


Re: recommendations for IO pin declarations

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

One thing I forgot to mention, and that after giving this some thought
makes some sense, is to pass the pin restriction information (what
channels a pin may accept, etc) using the data parameter on
pwm_dev_init, passed through os_dev_create which is called on
hal_bsp.c. For me it makes sense to have these values stored somewhere
on the BSP (or even MCU), since they look like they are directly
dependent on the board model(or the mcu model?) you're using.

Best regards,

Miguel

On Thu, Mar 1, 2018 at 5:57 PM, Wayne Keenan <wa...@gmail.com> wrote:
> It is a complicated issue indeed.
> Forgetting the pins, the CubeMX tool also resolves conflicts of clock
> sources as well. (STM chips are most flexible/interesting :) )
>
> So I'd like to point out that there are other internal parts of MicroPython
> that can help guide MyNewt MCU support on clocks too, without the need for
> CubeMX.
>
>
>
> Thanks,
> Wayne
>
> On 1 March 2018 at 18:48, Wayne Keenan <wa...@gmail.com> wrote:
>
>> That's a good point, but also having used CubeMX myself I always thought
>> it is very application specific design time choices.  IMHO What MyNewt MCU
>> support would need is 'a level above that'.
>>
>> I've perhaps missed something.
>>
>> But AFAIK the MicroPython CSV files are (easily) parsable representations
>> of what's in the STM32 data sheets for each MCU, so it's minus the bespoke
>> tooling, libraries and generated boilerplate code CubeMX generates.
>>
>>
>>
>>
>> Thanks,
>> Wayne
>>
>> On 1 March 2018 at 17:43, Raoul van Bergen <ra...@me.com>
>> wrote:
>>
>>> Hi,
>>> Just my opinion from long time experience with STM32.
>>>
>>> IF (!) there is anything to be supported for this from external, it
>>> should be the definition files generated by the free CubeMX tool from STM
>>> itself. This tool allows you to first create the perfect matching pin
>>> assignment for your application (it was already mentioned this can become
>>> very complicated) and next it can generate the complete BSP /HAL support
>>> source files based on the library from STM.
>>>
>>> I know some other vendors have similar tools as well.
>>>
>>> I am not advocating to use ST's own library at all but at least the
>>> include files generated by CubeMX do hold the proper defines and macros
>>> needed to do the pin assignments correctly and this tool is kept up-to-date
>>> for all STM32 processors at all times, so "your" STM32 of choice will
>>> always be there......
>>>
>>> Regards,
>>> Raoul
>>>
>>>
>>>
>>> -----Original Message-----
>>> From: Wayne Keenan [mailto:wayne.keenan@gmail.com]
>>> Sent: 01 March 2018 18:24
>>> To: dev@mynewt.apache.org
>>> Cc: Miguel Azevedo <mi...@gmail.com>
>>> Subject: Re: recommendations for IO pin declarations
>>>
>>> If you take a look at MicroPython, it has CSV files describing the
>>> Alternate Functions of pins for many STM32 devices.
>>>
>>> Files matching *_af.csv under: https://github.com/
>>> micropython/micropython/tree/master/ports/stm32/boards
>>>
>>> Perhaps the Mynewt STM32 MCU support could/should import and use them?
>>>
>>>
>>> Thanks,
>>> Wayne
>>>
>>> On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:
>>>
>>> > I didn't explain this correctly, let me start again.
>>> >
>>> > First off, this is not PWM specific, it is the way how STM32's map
>>> > internal peripherals to IO pads (also known as pins).
>>> >
>>> > Each IO pad can be operated in up to 16 different functions, called
>>> > alternate functions. At reset each pad assumes AF0, it's default
>>> > function, which can be changed at runtime. I've attached an excerpt of
>>> > the AF table (not sure if attachments make it through).
>>> >
>>> > Taking the IO pin PA1 as an example which has the following AF
>>> > assignments
>>> > 0 ... -
>>> > 1 ... TIM2_CH2
>>> > 2 ... -
>>> > 3 ... TSC_G1_IO2
>>> > 4 ... -
>>> > 5 ... -
>>> > 6 ... -
>>> > 7 ... USART2_RTS_DE
>>> > 8 ... -
>>> > 9 ... TIM15_CH1N
>>> > 10... -
>>> >  .....
>>> >
>>> > At reset the pin assumes AF0, which has no alternate function which
>>> > means it is operating as a regular IO pin. If you reconfigure the pin
>>> > for AF1, then it will output whatever channel 2 of timer 2 is
>>> > configured to do. If you configure the pin for AF9 it will output
>>> > whatever the complementary channel 1 of timer 15 is configured for
>>> > (regardless of you configured channel 2 of timer 2 to do).
>>> >
>>> > So for mcu peripherals, if their signals need to be connected to a
>>> > pad, one doesn't just need the pin number, but one also needs the AF
>>> number.
>>> >
>>> > If you look at the instantiation of the uart here:
>>> > https://github.com/apache/mynewt-core/blob/master/hw/bsp/
>>> > nucleo-f413zh/src/hal_bsp.c#L45
>>> > you'll notice GPIO_AF7_USART3, which is required in order to connect
>>> > the signals of UART3 to the io pins.
>>> >
>>> >
>>> >
>>> > On Thu, 1 Mar 2018 09:50:16 -0300
>>> > Miguel Azevedo <mi...@gmail.com> wrote:
>>> >
>>> > > > Unfortunately there is no universal AF value for pwm channels, on
>>> > > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
>>> > > > pwm channel outputs at all and some pins could be used as the
>>> > > > output of multiple channels.
>>> > >
>>> > > Not sure I got it right.
>>> > > So you can configure a given pin using 1 or 6 depending on whether
>>> > > you want it to output a single pwm chan or multiple?
>>> > > Having a single gpio output multiple channels feels a lot like an
>>> > > uncommon feature btw.
>>> > >
>>> > > > It's bad enough that only certain pins work for a given
>>> > > > timer/channel but it's even worse because the driver also needs to
>>> > > > know the AF number to use.
>>> > > It definitely does not look great but it feels that you will need
>>> > > either a lot of #ifdefs or have the driver knowing these restrictions.
>>> > > Aren't these restrictions described on some .h from stm?
>>> > >
>>> > > > As an additional crux, the HW timer to be used (TIM1 above)
>>> > > > typically gets defined by the BSP in hal_bsp_init, whereas
>>> > > > pwm_chan_config is application runtime code. I would prefer to
>>> > > > break the coupling, or at least make it less fragile.
>>> > >
>>> > > I see, I'm not sure about that one. I mean it does not make much
>>> > > sense to me, because one might want to reconfigure channels on
>>> > > runtime, just take a look at what we're doing on pwm_test on last PR.
>>> > >
>>> > > It sounds like stm PWM has a bunch of limitations you have to deal
>>> > > with and there are some things you probably won't be able to run from.
>>> > > I already implemented two PWM drivers using the current interface, I
>>> > > think we should be flexible at this stage regarding the API
>>> > > interface so it will be useful for you.
>>> > > However I feel that having an AF field by default doesnt make much
>>> > > sense.
>>> > >
>>> > > Thanks,
>>> > >
>>> > > On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca> wrote:
>>> > > > This is the implementation of pwm_configure_channel:
>>> > > >
>>> > > > static int
>>> > > > stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum,
>>> > > > struct pwm_chan_cfg *cfg) {
>>> > > >     stm32f3_pwm_dev_t *pwm;
>>> > > >
>>> > > >     assert(dev->pwm_instance_id < PWM_COUNT);
>>> > > >     assert(cnum < STM32F3_PWM_CH_COUNT);
>>> > > >
>>> > > >     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
>>> > > >
>>> > > >     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
>>> > > >         return -1;
>>> > > >     }
>>> > > >
>>> > > >     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
>>> > > >         if (hal_gpio_init_af(cfg->pin,
>>> > > >                             (uint8_t)(uintptr_t)cfg->data,
>>> > > >                             HAL_GPIO_PULL_NONE,
>>> > > >                             0)) {
>>> > > >             return -1;
>>> > > >         }
>>> > > >     }
>>> > > >
>>> > > >     pwm->ch[cnum].duty      = 0;
>>> > > >     pwm->ch[cnum].pin       = cfg->pin;
>>> > > >     pwm->ch[cnum].invert    = cfg->inverted;
>>> > > >     pwm->ch[cnum].update    = 0;
>>> > > >     pwm->ch[cnum].enabled   = 0;
>>> > > >     pwm->ch[cnum].configure = 1;
>>> > > >
>>> > > >     return 0;
>>> > > > }
>>> > > >
>>> > > > On an STM to connect the output pad with the PWM channel I have to
>>> > > > configure it for the alternate function (which is done by
>>> > > > hal_gpio_init_af). The AF value, the result of
>>> > > > `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which
>>> > > > determines what the pin is used for.
>>> > > >
>>> > > > Unfortunately there is no universal AF value for pwm channels, on
>>> > > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
>>> > > > pwm channel outputs at all and some pins could be used as the
>>> > > > output of multiple channels.
>>> > > >
>>> > > > With the construct above the application has to make a call like:
>>> > > >
>>> > > >         struct pwm_chan_cfg cfg;
>>> > > >         cfg.pin = 8;
>>> > > >         cfg.inverted = false;
>>> > > >         cfg.data = (void*)6;
>>> > > >         pwm_chan_config(pwm, 0, &cfg);
>>> > > >
>>> > > > But this ONLY works if `pwm` is bound to the mcu's TIM1 and you
>>> > > > use channel 0. For TIM1 and channel 1 the app would have to use
>>> > > > `pin=9/data=6`.
>>> > > >
>>> > > > It's bad enough that only certain pins work for a given
>>> > > > timer/channel but it's even worse because the driver also needs to
>>> > > > know the AF number to use.
>>> > > >
>>> > > > As an additional crux, the HW timer to be used (TIM1 above)
>>> > > > typically gets defined by the BSP in hal_bsp_init, whereas
>>> > > > pwm_chan_config is application runtime code. I would prefer to
>>> > > > break the coupling, or at least make it less fragile.
>>> > > >
>>> > > > Does this make sense?
>>> > > > Markus
>>> > > >
>>> > > >
>>> > > > On Thu, 1 Mar 2018 01:58:46 -0300
>>> > > > Miguel Azevedo <mi...@gmail.com> wrote:
>>> > > >
>>> > > >> Hi markus,
>>> > > >>
>>> > > >> > `struct pwm_chan_config` only specifies the pin number. I've
>>> > > >> > been using the `data` member to put the burden on the
>>> > > >> > application to specify the "correct" number for the alternate
>>> > > >> > function > - but I find this a little unsatisfactory.
>>> > > >> That sounds a lot driver/hw specific. Can you show us the code
>>> > > >> for that?
>>> > > >>
>>> > > >> Thanks,
>>> > > >> Miguel
>>> > > >>
>>> > > >> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
>>> > > >> > While writing a PWM driver for the STM32s mcu family I came
>>> > > >> > across the issue of assigning output pins for a pwm channel.
>>> > > >> >
>>> > > >> > PWM output in STM32s is done by configuring a pin for
>>> > > >> > "alternate functions" - where specific pins have specific
>>> > > >> > (possible) alternate functions. In other words, only a very
>>> > > >> > limited number of timer:channel:pin combinations are possible,
>>> > > >> > each one requiring a very specific alternate function.
>>> > > >> >
>>> > > >> > `struct pwm_chan_config` only specifies the pin number. I've
>>> > > >> > been using the `data` member to put the burden on the
>>> > > >> > application to specify the "correct" number for the alternate
>>> > > >> > function - but I find this a little unsatisfactory.
>>> > > >> >
>>> > > >> > So I was wondering if somebody has a recommendation, better
>>> > > >> > approach to solving this issue?
>>> > > >> >
>>> > > >> > Have fun,
>>> > > >> > Markus
>>> > > >>
>>> > > >>
>>> > > >>
>>> > > >
>>> > >
>>> > >
>>> > >
>>> >
>>> >
>>>
>>>
>>



-- 
--
Miguel Azevedo

Re: recommendations for IO pin declarations

Posted by Wayne Keenan <wa...@gmail.com>.
It is a complicated issue indeed.
Forgetting the pins, the CubeMX tool also resolves conflicts of clock
sources as well. (STM chips are most flexible/interesting :) )

So I'd like to point out that there are other internal parts of MicroPython
that can help guide MyNewt MCU support on clocks too, without the need for
CubeMX.



Thanks,
Wayne

On 1 March 2018 at 18:48, Wayne Keenan <wa...@gmail.com> wrote:

> That's a good point, but also having used CubeMX myself I always thought
> it is very application specific design time choices.  IMHO What MyNewt MCU
> support would need is 'a level above that'.
>
> I've perhaps missed something.
>
> But AFAIK the MicroPython CSV files are (easily) parsable representations
> of what's in the STM32 data sheets for each MCU, so it's minus the bespoke
> tooling, libraries and generated boilerplate code CubeMX generates.
>
>
>
>
> Thanks,
> Wayne
>
> On 1 March 2018 at 17:43, Raoul van Bergen <ra...@me.com>
> wrote:
>
>> Hi,
>> Just my opinion from long time experience with STM32.
>>
>> IF (!) there is anything to be supported for this from external, it
>> should be the definition files generated by the free CubeMX tool from STM
>> itself. This tool allows you to first create the perfect matching pin
>> assignment for your application (it was already mentioned this can become
>> very complicated) and next it can generate the complete BSP /HAL support
>> source files based on the library from STM.
>>
>> I know some other vendors have similar tools as well.
>>
>> I am not advocating to use ST's own library at all but at least the
>> include files generated by CubeMX do hold the proper defines and macros
>> needed to do the pin assignments correctly and this tool is kept up-to-date
>> for all STM32 processors at all times, so "your" STM32 of choice will
>> always be there......
>>
>> Regards,
>> Raoul
>>
>>
>>
>> -----Original Message-----
>> From: Wayne Keenan [mailto:wayne.keenan@gmail.com]
>> Sent: 01 March 2018 18:24
>> To: dev@mynewt.apache.org
>> Cc: Miguel Azevedo <mi...@gmail.com>
>> Subject: Re: recommendations for IO pin declarations
>>
>> If you take a look at MicroPython, it has CSV files describing the
>> Alternate Functions of pins for many STM32 devices.
>>
>> Files matching *_af.csv under: https://github.com/
>> micropython/micropython/tree/master/ports/stm32/boards
>>
>> Perhaps the Mynewt STM32 MCU support could/should import and use them?
>>
>>
>> Thanks,
>> Wayne
>>
>> On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:
>>
>> > I didn't explain this correctly, let me start again.
>> >
>> > First off, this is not PWM specific, it is the way how STM32's map
>> > internal peripherals to IO pads (also known as pins).
>> >
>> > Each IO pad can be operated in up to 16 different functions, called
>> > alternate functions. At reset each pad assumes AF0, it's default
>> > function, which can be changed at runtime. I've attached an excerpt of
>> > the AF table (not sure if attachments make it through).
>> >
>> > Taking the IO pin PA1 as an example which has the following AF
>> > assignments
>> > 0 ... -
>> > 1 ... TIM2_CH2
>> > 2 ... -
>> > 3 ... TSC_G1_IO2
>> > 4 ... -
>> > 5 ... -
>> > 6 ... -
>> > 7 ... USART2_RTS_DE
>> > 8 ... -
>> > 9 ... TIM15_CH1N
>> > 10... -
>> >  .....
>> >
>> > At reset the pin assumes AF0, which has no alternate function which
>> > means it is operating as a regular IO pin. If you reconfigure the pin
>> > for AF1, then it will output whatever channel 2 of timer 2 is
>> > configured to do. If you configure the pin for AF9 it will output
>> > whatever the complementary channel 1 of timer 15 is configured for
>> > (regardless of you configured channel 2 of timer 2 to do).
>> >
>> > So for mcu peripherals, if their signals need to be connected to a
>> > pad, one doesn't just need the pin number, but one also needs the AF
>> number.
>> >
>> > If you look at the instantiation of the uart here:
>> > https://github.com/apache/mynewt-core/blob/master/hw/bsp/
>> > nucleo-f413zh/src/hal_bsp.c#L45
>> > you'll notice GPIO_AF7_USART3, which is required in order to connect
>> > the signals of UART3 to the io pins.
>> >
>> >
>> >
>> > On Thu, 1 Mar 2018 09:50:16 -0300
>> > Miguel Azevedo <mi...@gmail.com> wrote:
>> >
>> > > > Unfortunately there is no universal AF value for pwm channels, on
>> > > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
>> > > > pwm channel outputs at all and some pins could be used as the
>> > > > output of multiple channels.
>> > >
>> > > Not sure I got it right.
>> > > So you can configure a given pin using 1 or 6 depending on whether
>> > > you want it to output a single pwm chan or multiple?
>> > > Having a single gpio output multiple channels feels a lot like an
>> > > uncommon feature btw.
>> > >
>> > > > It's bad enough that only certain pins work for a given
>> > > > timer/channel but it's even worse because the driver also needs to
>> > > > know the AF number to use.
>> > > It definitely does not look great but it feels that you will need
>> > > either a lot of #ifdefs or have the driver knowing these restrictions.
>> > > Aren't these restrictions described on some .h from stm?
>> > >
>> > > > As an additional crux, the HW timer to be used (TIM1 above)
>> > > > typically gets defined by the BSP in hal_bsp_init, whereas
>> > > > pwm_chan_config is application runtime code. I would prefer to
>> > > > break the coupling, or at least make it less fragile.
>> > >
>> > > I see, I'm not sure about that one. I mean it does not make much
>> > > sense to me, because one might want to reconfigure channels on
>> > > runtime, just take a look at what we're doing on pwm_test on last PR.
>> > >
>> > > It sounds like stm PWM has a bunch of limitations you have to deal
>> > > with and there are some things you probably won't be able to run from.
>> > > I already implemented two PWM drivers using the current interface, I
>> > > think we should be flexible at this stage regarding the API
>> > > interface so it will be useful for you.
>> > > However I feel that having an AF field by default doesnt make much
>> > > sense.
>> > >
>> > > Thanks,
>> > >
>> > > On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca> wrote:
>> > > > This is the implementation of pwm_configure_channel:
>> > > >
>> > > > static int
>> > > > stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum,
>> > > > struct pwm_chan_cfg *cfg) {
>> > > >     stm32f3_pwm_dev_t *pwm;
>> > > >
>> > > >     assert(dev->pwm_instance_id < PWM_COUNT);
>> > > >     assert(cnum < STM32F3_PWM_CH_COUNT);
>> > > >
>> > > >     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
>> > > >
>> > > >     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
>> > > >         return -1;
>> > > >     }
>> > > >
>> > > >     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
>> > > >         if (hal_gpio_init_af(cfg->pin,
>> > > >                             (uint8_t)(uintptr_t)cfg->data,
>> > > >                             HAL_GPIO_PULL_NONE,
>> > > >                             0)) {
>> > > >             return -1;
>> > > >         }
>> > > >     }
>> > > >
>> > > >     pwm->ch[cnum].duty      = 0;
>> > > >     pwm->ch[cnum].pin       = cfg->pin;
>> > > >     pwm->ch[cnum].invert    = cfg->inverted;
>> > > >     pwm->ch[cnum].update    = 0;
>> > > >     pwm->ch[cnum].enabled   = 0;
>> > > >     pwm->ch[cnum].configure = 1;
>> > > >
>> > > >     return 0;
>> > > > }
>> > > >
>> > > > On an STM to connect the output pad with the PWM channel I have to
>> > > > configure it for the alternate function (which is done by
>> > > > hal_gpio_init_af). The AF value, the result of
>> > > > `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which
>> > > > determines what the pin is used for.
>> > > >
>> > > > Unfortunately there is no universal AF value for pwm channels, on
>> > > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
>> > > > pwm channel outputs at all and some pins could be used as the
>> > > > output of multiple channels.
>> > > >
>> > > > With the construct above the application has to make a call like:
>> > > >
>> > > >         struct pwm_chan_cfg cfg;
>> > > >         cfg.pin = 8;
>> > > >         cfg.inverted = false;
>> > > >         cfg.data = (void*)6;
>> > > >         pwm_chan_config(pwm, 0, &cfg);
>> > > >
>> > > > But this ONLY works if `pwm` is bound to the mcu's TIM1 and you
>> > > > use channel 0. For TIM1 and channel 1 the app would have to use
>> > > > `pin=9/data=6`.
>> > > >
>> > > > It's bad enough that only certain pins work for a given
>> > > > timer/channel but it's even worse because the driver also needs to
>> > > > know the AF number to use.
>> > > >
>> > > > As an additional crux, the HW timer to be used (TIM1 above)
>> > > > typically gets defined by the BSP in hal_bsp_init, whereas
>> > > > pwm_chan_config is application runtime code. I would prefer to
>> > > > break the coupling, or at least make it less fragile.
>> > > >
>> > > > Does this make sense?
>> > > > Markus
>> > > >
>> > > >
>> > > > On Thu, 1 Mar 2018 01:58:46 -0300
>> > > > Miguel Azevedo <mi...@gmail.com> wrote:
>> > > >
>> > > >> Hi markus,
>> > > >>
>> > > >> > `struct pwm_chan_config` only specifies the pin number. I've
>> > > >> > been using the `data` member to put the burden on the
>> > > >> > application to specify the "correct" number for the alternate
>> > > >> > function > - but I find this a little unsatisfactory.
>> > > >> That sounds a lot driver/hw specific. Can you show us the code
>> > > >> for that?
>> > > >>
>> > > >> Thanks,
>> > > >> Miguel
>> > > >>
>> > > >> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
>> > > >> > While writing a PWM driver for the STM32s mcu family I came
>> > > >> > across the issue of assigning output pins for a pwm channel.
>> > > >> >
>> > > >> > PWM output in STM32s is done by configuring a pin for
>> > > >> > "alternate functions" - where specific pins have specific
>> > > >> > (possible) alternate functions. In other words, only a very
>> > > >> > limited number of timer:channel:pin combinations are possible,
>> > > >> > each one requiring a very specific alternate function.
>> > > >> >
>> > > >> > `struct pwm_chan_config` only specifies the pin number. I've
>> > > >> > been using the `data` member to put the burden on the
>> > > >> > application to specify the "correct" number for the alternate
>> > > >> > function - but I find this a little unsatisfactory.
>> > > >> >
>> > > >> > So I was wondering if somebody has a recommendation, better
>> > > >> > approach to solving this issue?
>> > > >> >
>> > > >> > Have fun,
>> > > >> > Markus
>> > > >>
>> > > >>
>> > > >>
>> > > >
>> > >
>> > >
>> > >
>> >
>> >
>>
>>
>

Re: recommendations for IO pin declarations

Posted by Wayne Keenan <wa...@gmail.com>.
That's a good point, but also having used CubeMX myself I always thought it
is very application specific design time choices.  IMHO What MyNewt MCU
support would need is 'a level above that'.

I've perhaps missed something.

But AFAIK the MicroPython CSV files are (easily) parsable representations
of what's in the STM32 data sheets for each MCU, so it's minus the bespoke
tooling, libraries and generated boilerplate code CubeMX generates.




Thanks,
Wayne

On 1 March 2018 at 17:43, Raoul van Bergen <ra...@me.com> wrote:

> Hi,
> Just my opinion from long time experience with STM32.
>
> IF (!) there is anything to be supported for this from external, it should
> be the definition files generated by the free CubeMX tool from STM itself.
> This tool allows you to first create the perfect matching pin assignment
> for your application (it was already mentioned this can become very
> complicated) and next it can generate the complete BSP /HAL support source
> files based on the library from STM.
>
> I know some other vendors have similar tools as well.
>
> I am not advocating to use ST's own library at all but at least the
> include files generated by CubeMX do hold the proper defines and macros
> needed to do the pin assignments correctly and this tool is kept up-to-date
> for all STM32 processors at all times, so "your" STM32 of choice will
> always be there......
>
> Regards,
> Raoul
>
>
>
> -----Original Message-----
> From: Wayne Keenan [mailto:wayne.keenan@gmail.com]
> Sent: 01 March 2018 18:24
> To: dev@mynewt.apache.org
> Cc: Miguel Azevedo <mi...@gmail.com>
> Subject: Re: recommendations for IO pin declarations
>
> If you take a look at MicroPython, it has CSV files describing the
> Alternate Functions of pins for many STM32 devices.
>
> Files matching *_af.csv under: https://github.com/
> micropython/micropython/tree/master/ports/stm32/boards
>
> Perhaps the Mynewt STM32 MCU support could/should import and use them?
>
>
> Thanks,
> Wayne
>
> On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:
>
> > I didn't explain this correctly, let me start again.
> >
> > First off, this is not PWM specific, it is the way how STM32's map
> > internal peripherals to IO pads (also known as pins).
> >
> > Each IO pad can be operated in up to 16 different functions, called
> > alternate functions. At reset each pad assumes AF0, it's default
> > function, which can be changed at runtime. I've attached an excerpt of
> > the AF table (not sure if attachments make it through).
> >
> > Taking the IO pin PA1 as an example which has the following AF
> > assignments
> > 0 ... -
> > 1 ... TIM2_CH2
> > 2 ... -
> > 3 ... TSC_G1_IO2
> > 4 ... -
> > 5 ... -
> > 6 ... -
> > 7 ... USART2_RTS_DE
> > 8 ... -
> > 9 ... TIM15_CH1N
> > 10... -
> >  .....
> >
> > At reset the pin assumes AF0, which has no alternate function which
> > means it is operating as a regular IO pin. If you reconfigure the pin
> > for AF1, then it will output whatever channel 2 of timer 2 is
> > configured to do. If you configure the pin for AF9 it will output
> > whatever the complementary channel 1 of timer 15 is configured for
> > (regardless of you configured channel 2 of timer 2 to do).
> >
> > So for mcu peripherals, if their signals need to be connected to a
> > pad, one doesn't just need the pin number, but one also needs the AF
> number.
> >
> > If you look at the instantiation of the uart here:
> > https://github.com/apache/mynewt-core/blob/master/hw/bsp/
> > nucleo-f413zh/src/hal_bsp.c#L45
> > you'll notice GPIO_AF7_USART3, which is required in order to connect
> > the signals of UART3 to the io pins.
> >
> >
> >
> > On Thu, 1 Mar 2018 09:50:16 -0300
> > Miguel Azevedo <mi...@gmail.com> wrote:
> >
> > > > Unfortunately there is no universal AF value for pwm channels, on
> > > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
> > > > pwm channel outputs at all and some pins could be used as the
> > > > output of multiple channels.
> > >
> > > Not sure I got it right.
> > > So you can configure a given pin using 1 or 6 depending on whether
> > > you want it to output a single pwm chan or multiple?
> > > Having a single gpio output multiple channels feels a lot like an
> > > uncommon feature btw.
> > >
> > > > It's bad enough that only certain pins work for a given
> > > > timer/channel but it's even worse because the driver also needs to
> > > > know the AF number to use.
> > > It definitely does not look great but it feels that you will need
> > > either a lot of #ifdefs or have the driver knowing these restrictions.
> > > Aren't these restrictions described on some .h from stm?
> > >
> > > > As an additional crux, the HW timer to be used (TIM1 above)
> > > > typically gets defined by the BSP in hal_bsp_init, whereas
> > > > pwm_chan_config is application runtime code. I would prefer to
> > > > break the coupling, or at least make it less fragile.
> > >
> > > I see, I'm not sure about that one. I mean it does not make much
> > > sense to me, because one might want to reconfigure channels on
> > > runtime, just take a look at what we're doing on pwm_test on last PR.
> > >
> > > It sounds like stm PWM has a bunch of limitations you have to deal
> > > with and there are some things you probably won't be able to run from.
> > > I already implemented two PWM drivers using the current interface, I
> > > think we should be flexible at this stage regarding the API
> > > interface so it will be useful for you.
> > > However I feel that having an AF field by default doesnt make much
> > > sense.
> > >
> > > Thanks,
> > >
> > > On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca> wrote:
> > > > This is the implementation of pwm_configure_channel:
> > > >
> > > > static int
> > > > stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum,
> > > > struct pwm_chan_cfg *cfg) {
> > > >     stm32f3_pwm_dev_t *pwm;
> > > >
> > > >     assert(dev->pwm_instance_id < PWM_COUNT);
> > > >     assert(cnum < STM32F3_PWM_CH_COUNT);
> > > >
> > > >     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
> > > >
> > > >     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
> > > >         return -1;
> > > >     }
> > > >
> > > >     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
> > > >         if (hal_gpio_init_af(cfg->pin,
> > > >                             (uint8_t)(uintptr_t)cfg->data,
> > > >                             HAL_GPIO_PULL_NONE,
> > > >                             0)) {
> > > >             return -1;
> > > >         }
> > > >     }
> > > >
> > > >     pwm->ch[cnum].duty      = 0;
> > > >     pwm->ch[cnum].pin       = cfg->pin;
> > > >     pwm->ch[cnum].invert    = cfg->inverted;
> > > >     pwm->ch[cnum].update    = 0;
> > > >     pwm->ch[cnum].enabled   = 0;
> > > >     pwm->ch[cnum].configure = 1;
> > > >
> > > >     return 0;
> > > > }
> > > >
> > > > On an STM to connect the output pad with the PWM channel I have to
> > > > configure it for the alternate function (which is done by
> > > > hal_gpio_init_af). The AF value, the result of
> > > > `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which
> > > > determines what the pin is used for.
> > > >
> > > > Unfortunately there is no universal AF value for pwm channels, on
> > > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
> > > > pwm channel outputs at all and some pins could be used as the
> > > > output of multiple channels.
> > > >
> > > > With the construct above the application has to make a call like:
> > > >
> > > >         struct pwm_chan_cfg cfg;
> > > >         cfg.pin = 8;
> > > >         cfg.inverted = false;
> > > >         cfg.data = (void*)6;
> > > >         pwm_chan_config(pwm, 0, &cfg);
> > > >
> > > > But this ONLY works if `pwm` is bound to the mcu's TIM1 and you
> > > > use channel 0. For TIM1 and channel 1 the app would have to use
> > > > `pin=9/data=6`.
> > > >
> > > > It's bad enough that only certain pins work for a given
> > > > timer/channel but it's even worse because the driver also needs to
> > > > know the AF number to use.
> > > >
> > > > As an additional crux, the HW timer to be used (TIM1 above)
> > > > typically gets defined by the BSP in hal_bsp_init, whereas
> > > > pwm_chan_config is application runtime code. I would prefer to
> > > > break the coupling, or at least make it less fragile.
> > > >
> > > > Does this make sense?
> > > > Markus
> > > >
> > > >
> > > > On Thu, 1 Mar 2018 01:58:46 -0300
> > > > Miguel Azevedo <mi...@gmail.com> wrote:
> > > >
> > > >> Hi markus,
> > > >>
> > > >> > `struct pwm_chan_config` only specifies the pin number. I've
> > > >> > been using the `data` member to put the burden on the
> > > >> > application to specify the "correct" number for the alternate
> > > >> > function > - but I find this a little unsatisfactory.
> > > >> That sounds a lot driver/hw specific. Can you show us the code
> > > >> for that?
> > > >>
> > > >> Thanks,
> > > >> Miguel
> > > >>
> > > >> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
> > > >> > While writing a PWM driver for the STM32s mcu family I came
> > > >> > across the issue of assigning output pins for a pwm channel.
> > > >> >
> > > >> > PWM output in STM32s is done by configuring a pin for
> > > >> > "alternate functions" - where specific pins have specific
> > > >> > (possible) alternate functions. In other words, only a very
> > > >> > limited number of timer:channel:pin combinations are possible,
> > > >> > each one requiring a very specific alternate function.
> > > >> >
> > > >> > `struct pwm_chan_config` only specifies the pin number. I've
> > > >> > been using the `data` member to put the burden on the
> > > >> > application to specify the "correct" number for the alternate
> > > >> > function - but I find this a little unsatisfactory.
> > > >> >
> > > >> > So I was wondering if somebody has a recommendation, better
> > > >> > approach to solving this issue?
> > > >> >
> > > >> > Have fun,
> > > >> > Markus
> > > >>
> > > >>
> > > >>
> > > >
> > >
> > >
> > >
> >
> >
>
>

RE: recommendations for IO pin declarations

Posted by Raoul van Bergen <ra...@me.com>.
Hi,
Just my opinion from long time experience with STM32.

IF (!) there is anything to be supported for this from external, it should be the definition files generated by the free CubeMX tool from STM itself. This tool allows you to first create the perfect matching pin assignment for your application (it was already mentioned this can become very complicated) and next it can generate the complete BSP /HAL support source files based on the library from STM. 

I know some other vendors have similar tools as well.

I am not advocating to use ST's own library at all but at least the include files generated by CubeMX do hold the proper defines and macros needed to do the pin assignments correctly and this tool is kept up-to-date for all STM32 processors at all times, so "your" STM32 of choice will always be there......

Regards,
Raoul



-----Original Message-----
From: Wayne Keenan [mailto:wayne.keenan@gmail.com] 
Sent: 01 March 2018 18:24
To: dev@mynewt.apache.org
Cc: Miguel Azevedo <mi...@gmail.com>
Subject: Re: recommendations for IO pin declarations

If you take a look at MicroPython, it has CSV files describing the Alternate Functions of pins for many STM32 devices.

Files matching *_af.csv under: https://github.com/ micropython/micropython/tree/master/ports/stm32/boards

Perhaps the Mynewt STM32 MCU support could/should import and use them?


Thanks,
Wayne

On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:

> I didn't explain this correctly, let me start again.
>
> First off, this is not PWM specific, it is the way how STM32's map 
> internal peripherals to IO pads (also known as pins).
>
> Each IO pad can be operated in up to 16 different functions, called 
> alternate functions. At reset each pad assumes AF0, it's default 
> function, which can be changed at runtime. I've attached an excerpt of 
> the AF table (not sure if attachments make it through).
>
> Taking the IO pin PA1 as an example which has the following AF 
> assignments
> 0 ... -
> 1 ... TIM2_CH2
> 2 ... -
> 3 ... TSC_G1_IO2
> 4 ... -
> 5 ... -
> 6 ... -
> 7 ... USART2_RTS_DE
> 8 ... -
> 9 ... TIM15_CH1N
> 10... -
>  .....
>
> At reset the pin assumes AF0, which has no alternate function which 
> means it is operating as a regular IO pin. If you reconfigure the pin 
> for AF1, then it will output whatever channel 2 of timer 2 is 
> configured to do. If you configure the pin for AF9 it will output 
> whatever the complementary channel 1 of timer 15 is configured for 
> (regardless of you configured channel 2 of timer 2 to do).
>
> So for mcu peripherals, if their signals need to be connected to a 
> pad, one doesn't just need the pin number, but one also needs the AF number.
>
> If you look at the instantiation of the uart here:
> https://github.com/apache/mynewt-core/blob/master/hw/bsp/
> nucleo-f413zh/src/hal_bsp.c#L45
> you'll notice GPIO_AF7_USART3, which is required in order to connect 
> the signals of UART3 to the io pins.
>
>
>
> On Thu, 1 Mar 2018 09:50:16 -0300
> Miguel Azevedo <mi...@gmail.com> wrote:
>
> > > Unfortunately there is no universal AF value for pwm channels, on 
> > > some pins it's 1, on some it's 6 ... , some pins cannot be used as 
> > > pwm channel outputs at all and some pins could be used as the 
> > > output of multiple channels.
> >
> > Not sure I got it right.
> > So you can configure a given pin using 1 or 6 depending on whether 
> > you want it to output a single pwm chan or multiple?
> > Having a single gpio output multiple channels feels a lot like an 
> > uncommon feature btw.
> >
> > > It's bad enough that only certain pins work for a given 
> > > timer/channel but it's even worse because the driver also needs to 
> > > know the AF number to use.
> > It definitely does not look great but it feels that you will need 
> > either a lot of #ifdefs or have the driver knowing these restrictions.
> > Aren't these restrictions described on some .h from stm?
> >
> > > As an additional crux, the HW timer to be used (TIM1 above) 
> > > typically gets defined by the BSP in hal_bsp_init, whereas 
> > > pwm_chan_config is application runtime code. I would prefer to 
> > > break the coupling, or at least make it less fragile.
> >
> > I see, I'm not sure about that one. I mean it does not make much 
> > sense to me, because one might want to reconfigure channels on 
> > runtime, just take a look at what we're doing on pwm_test on last PR.
> >
> > It sounds like stm PWM has a bunch of limitations you have to deal 
> > with and there are some things you probably won't be able to run from.
> > I already implemented two PWM drivers using the current interface, I 
> > think we should be flexible at this stage regarding the API 
> > interface so it will be useful for you.
> > However I feel that having an AF field by default doesnt make much 
> > sense.
> >
> > Thanks,
> >
> > On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca> wrote:
> > > This is the implementation of pwm_configure_channel:
> > >
> > > static int
> > > stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum, 
> > > struct pwm_chan_cfg *cfg) {
> > >     stm32f3_pwm_dev_t *pwm;
> > >
> > >     assert(dev->pwm_instance_id < PWM_COUNT);
> > >     assert(cnum < STM32F3_PWM_CH_COUNT);
> > >
> > >     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
> > >
> > >     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
> > >         return -1;
> > >     }
> > >
> > >     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
> > >         if (hal_gpio_init_af(cfg->pin,
> > >                             (uint8_t)(uintptr_t)cfg->data,
> > >                             HAL_GPIO_PULL_NONE,
> > >                             0)) {
> > >             return -1;
> > >         }
> > >     }
> > >
> > >     pwm->ch[cnum].duty      = 0;
> > >     pwm->ch[cnum].pin       = cfg->pin;
> > >     pwm->ch[cnum].invert    = cfg->inverted;
> > >     pwm->ch[cnum].update    = 0;
> > >     pwm->ch[cnum].enabled   = 0;
> > >     pwm->ch[cnum].configure = 1;
> > >
> > >     return 0;
> > > }
> > >
> > > On an STM to connect the output pad with the PWM channel I have to 
> > > configure it for the alternate function (which is done by 
> > > hal_gpio_init_af). The AF value, the result of 
> > > `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which 
> > > determines what the pin is used for.
> > >
> > > Unfortunately there is no universal AF value for pwm channels, on 
> > > some pins it's 1, on some it's 6 ... , some pins cannot be used as 
> > > pwm channel outputs at all and some pins could be used as the 
> > > output of multiple channels.
> > >
> > > With the construct above the application has to make a call like:
> > >
> > >         struct pwm_chan_cfg cfg;
> > >         cfg.pin = 8;
> > >         cfg.inverted = false;
> > >         cfg.data = (void*)6;
> > >         pwm_chan_config(pwm, 0, &cfg);
> > >
> > > But this ONLY works if `pwm` is bound to the mcu's TIM1 and you 
> > > use channel 0. For TIM1 and channel 1 the app would have to use 
> > > `pin=9/data=6`.
> > >
> > > It's bad enough that only certain pins work for a given 
> > > timer/channel but it's even worse because the driver also needs to 
> > > know the AF number to use.
> > >
> > > As an additional crux, the HW timer to be used (TIM1 above) 
> > > typically gets defined by the BSP in hal_bsp_init, whereas 
> > > pwm_chan_config is application runtime code. I would prefer to 
> > > break the coupling, or at least make it less fragile.
> > >
> > > Does this make sense?
> > > Markus
> > >
> > >
> > > On Thu, 1 Mar 2018 01:58:46 -0300
> > > Miguel Azevedo <mi...@gmail.com> wrote:
> > >
> > >> Hi markus,
> > >>
> > >> > `struct pwm_chan_config` only specifies the pin number. I've 
> > >> > been using the `data` member to put the burden on the 
> > >> > application to specify the "correct" number for the alternate 
> > >> > function > - but I find this a little unsatisfactory.
> > >> That sounds a lot driver/hw specific. Can you show us the code 
> > >> for that?
> > >>
> > >> Thanks,
> > >> Miguel
> > >>
> > >> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
> > >> > While writing a PWM driver for the STM32s mcu family I came 
> > >> > across the issue of assigning output pins for a pwm channel.
> > >> >
> > >> > PWM output in STM32s is done by configuring a pin for 
> > >> > "alternate functions" - where specific pins have specific 
> > >> > (possible) alternate functions. In other words, only a very 
> > >> > limited number of timer:channel:pin combinations are possible, 
> > >> > each one requiring a very specific alternate function.
> > >> >
> > >> > `struct pwm_chan_config` only specifies the pin number. I've 
> > >> > been using the `data` member to put the burden on the 
> > >> > application to specify the "correct" number for the alternate 
> > >> > function - but I find this a little unsatisfactory.
> > >> >
> > >> > So I was wondering if somebody has a recommendation, better 
> > >> > approach to solving this issue?
> > >> >
> > >> > Have fun,
> > >> > Markus
> > >>
> > >>
> > >>
> > >
> >
> >
> >
>
>


Re: recommendations for IO pin declarations

Posted by Wayne Keenan <wa...@gmail.com>.
If you take a look at MicroPython, it has CSV files describing the
Alternate Functions of pins for many STM32 devices.

Files matching *_af.csv under: https://github.com/
micropython/micropython/tree/master/ports/stm32/boards

Perhaps the Mynewt STM32 MCU support could/should import and use them?


Thanks,
Wayne

On 1 March 2018 at 17:06, markus <ma...@bibi.ca> wrote:

> I didn't explain this correctly, let me start again.
>
> First off, this is not PWM specific, it is the way how STM32's map
> internal peripherals to IO pads (also known as pins).
>
> Each IO pad can be operated in up to 16 different functions, called
> alternate functions. At reset each pad assumes AF0, it's default function,
> which can be changed at runtime. I've attached an excerpt of the AF table
> (not sure if attachments make it through).
>
> Taking the IO pin PA1 as an example which has the following AF assignments
> 0 ... -
> 1 ... TIM2_CH2
> 2 ... -
> 3 ... TSC_G1_IO2
> 4 ... -
> 5 ... -
> 6 ... -
> 7 ... USART2_RTS_DE
> 8 ... -
> 9 ... TIM15_CH1N
> 10... -
>  .....
>
> At reset the pin assumes AF0, which has no alternate function which means
> it is operating as a regular IO pin. If you reconfigure the pin for AF1,
> then it will output whatever channel 2 of timer 2 is configured to do. If
> you configure the pin for AF9 it will output whatever the complementary
> channel 1 of timer 15 is configured for (regardless of you configured
> channel 2 of timer 2 to do).
>
> So for mcu peripherals, if their signals need to be connected to a pad,
> one doesn't just need the pin number, but one also needs the AF number.
>
> If you look at the instantiation of the uart here:
> https://github.com/apache/mynewt-core/blob/master/hw/bsp/
> nucleo-f413zh/src/hal_bsp.c#L45
> you'll notice GPIO_AF7_USART3, which is required in order to connect the
> signals of UART3 to the io pins.
>
>
>
> On Thu, 1 Mar 2018 09:50:16 -0300
> Miguel Azevedo <mi...@gmail.com> wrote:
>
> > > Unfortunately there is no universal AF value for pwm channels, on
> > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
> > > pwm channel outputs at all and some pins could be used as the
> > > output of multiple channels.
> >
> > Not sure I got it right.
> > So you can configure a given pin using 1 or 6 depending on whether you
> > want it to output a single pwm chan or multiple?
> > Having a single gpio output multiple channels feels a lot like an
> > uncommon feature btw.
> >
> > > It's bad enough that only certain pins work for a given
> > > timer/channel but it's even worse because the driver also needs to
> > > know the AF number to use.
> > It definitely does not look great but it feels that you will need
> > either a lot of #ifdefs or have the driver knowing these restrictions.
> > Aren't these restrictions described on some .h from stm?
> >
> > > As an additional crux, the HW timer to be used (TIM1 above)
> > > typically gets defined by the BSP in hal_bsp_init, whereas
> > > pwm_chan_config is application runtime code. I would prefer to
> > > break the coupling, or at least make it less fragile.
> >
> > I see, I'm not sure about that one. I mean it does not make much sense
> > to me, because one might want to reconfigure channels on runtime, just
> > take a look at what we're doing on pwm_test on last PR.
> >
> > It sounds like stm PWM has a bunch of limitations you have to deal
> > with and there are some things you probably won't be able to run from.
> > I already implemented two PWM drivers using the current interface, I
> > think we should be flexible at this stage regarding the API interface
> > so it will be useful for you.
> > However I feel that having an AF field by default doesnt make much
> > sense.
> >
> > Thanks,
> >
> > On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca> wrote:
> > > This is the implementation of pwm_configure_channel:
> > >
> > > static int
> > > stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum,
> > > struct pwm_chan_cfg *cfg) {
> > >     stm32f3_pwm_dev_t *pwm;
> > >
> > >     assert(dev->pwm_instance_id < PWM_COUNT);
> > >     assert(cnum < STM32F3_PWM_CH_COUNT);
> > >
> > >     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
> > >
> > >     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
> > >         return -1;
> > >     }
> > >
> > >     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
> > >         if (hal_gpio_init_af(cfg->pin,
> > >                             (uint8_t)(uintptr_t)cfg->data,
> > >                             HAL_GPIO_PULL_NONE,
> > >                             0)) {
> > >             return -1;
> > >         }
> > >     }
> > >
> > >     pwm->ch[cnum].duty      = 0;
> > >     pwm->ch[cnum].pin       = cfg->pin;
> > >     pwm->ch[cnum].invert    = cfg->inverted;
> > >     pwm->ch[cnum].update    = 0;
> > >     pwm->ch[cnum].enabled   = 0;
> > >     pwm->ch[cnum].configure = 1;
> > >
> > >     return 0;
> > > }
> > >
> > > On an STM to connect the output pad with the PWM channel I have to
> > > configure it for the alternate function (which is done by
> > > hal_gpio_init_af). The AF value, the result of
> > > `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which
> > > determines what the pin is used for.
> > >
> > > Unfortunately there is no universal AF value for pwm channels, on
> > > some pins it's 1, on some it's 6 ... , some pins cannot be used as
> > > pwm channel outputs at all and some pins could be used as the
> > > output of multiple channels.
> > >
> > > With the construct above the application has to make a call like:
> > >
> > >         struct pwm_chan_cfg cfg;
> > >         cfg.pin = 8;
> > >         cfg.inverted = false;
> > >         cfg.data = (void*)6;
> > >         pwm_chan_config(pwm, 0, &cfg);
> > >
> > > But this ONLY works if `pwm` is bound to the mcu's TIM1 and you use
> > > channel 0. For TIM1 and channel 1 the app would have to use
> > > `pin=9/data=6`.
> > >
> > > It's bad enough that only certain pins work for a given
> > > timer/channel but it's even worse because the driver also needs to
> > > know the AF number to use.
> > >
> > > As an additional crux, the HW timer to be used (TIM1 above)
> > > typically gets defined by the BSP in hal_bsp_init, whereas
> > > pwm_chan_config is application runtime code. I would prefer to
> > > break the coupling, or at least make it less fragile.
> > >
> > > Does this make sense?
> > > Markus
> > >
> > >
> > > On Thu, 1 Mar 2018 01:58:46 -0300
> > > Miguel Azevedo <mi...@gmail.com> wrote:
> > >
> > >> Hi markus,
> > >>
> > >> > `struct pwm_chan_config` only specifies the pin number. I've been
> > >> > using the `data` member to put the burden on the application to
> > >> > specify the "correct" number for the alternate function > - but I
> > >> > find this a little unsatisfactory.
> > >> That sounds a lot driver/hw specific. Can you show us the code for
> > >> that?
> > >>
> > >> Thanks,
> > >> Miguel
> > >>
> > >> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
> > >> > While writing a PWM driver for the STM32s mcu family I came
> > >> > across the issue of assigning output pins for a pwm channel.
> > >> >
> > >> > PWM output in STM32s is done by configuring a pin for "alternate
> > >> > functions" - where specific pins have specific (possible)
> > >> > alternate functions. In other words, only a very limited number
> > >> > of timer:channel:pin combinations are possible, each one
> > >> > requiring a very specific alternate function.
> > >> >
> > >> > `struct pwm_chan_config` only specifies the pin number. I've been
> > >> > using the `data` member to put the burden on the application to
> > >> > specify the "correct" number for the alternate function - but I
> > >> > find this a little unsatisfactory.
> > >> >
> > >> > So I was wondering if somebody has a recommendation, better
> > >> > approach to solving this issue?
> > >> >
> > >> > Have fun,
> > >> > Markus
> > >>
> > >>
> > >>
> > >
> >
> >
> >
>
>

Re: recommendations for IO pin declarations

Posted by markus <ma...@bibi.ca>.
I didn't explain this correctly, let me start again.

First off, this is not PWM specific, it is the way how STM32's map internal peripherals to IO pads (also known as pins).

Each IO pad can be operated in up to 16 different functions, called alternate functions. At reset each pad assumes AF0, it's default function, which can be changed at runtime. I've attached an excerpt of the AF table (not sure if attachments make it through).

Taking the IO pin PA1 as an example which has the following AF assignments
0 ... -
1 ... TIM2_CH2
2 ... -
3 ... TSC_G1_IO2
4 ... -
5 ... -
6 ... -
7 ... USART2_RTS_DE
8 ... -
9 ... TIM15_CH1N
10... -
 .....

At reset the pin assumes AF0, which has no alternate function which means it is operating as a regular IO pin. If you reconfigure the pin for AF1, then it will output whatever channel 2 of timer 2 is configured to do. If you configure the pin for AF9 it will output whatever the complementary channel 1 of timer 15 is configured for (regardless of you configured channel 2 of timer 2 to do).

So for mcu peripherals, if their signals need to be connected to a pad, one doesn't just need the pin number, but one also needs the AF number.

If you look at the instantiation of the uart here:
https://github.com/apache/mynewt-core/blob/master/hw/bsp/nucleo-f413zh/src/hal_bsp.c#L45
you'll notice GPIO_AF7_USART3, which is required in order to connect the signals of UART3 to the io pins.



On Thu, 1 Mar 2018 09:50:16 -0300
Miguel Azevedo <mi...@gmail.com> wrote:

> > Unfortunately there is no universal AF value for pwm channels, on
> > some pins it's 1, on some it's 6 ... , some pins cannot be used as
> > pwm channel outputs at all and some pins could be used as the
> > output of multiple channels.  
> 
> Not sure I got it right.
> So you can configure a given pin using 1 or 6 depending on whether you
> want it to output a single pwm chan or multiple?
> Having a single gpio output multiple channels feels a lot like an
> uncommon feature btw.
> 
> > It's bad enough that only certain pins work for a given
> > timer/channel but it's even worse because the driver also needs to
> > know the AF number to use.  
> It definitely does not look great but it feels that you will need
> either a lot of #ifdefs or have the driver knowing these restrictions.
> Aren't these restrictions described on some .h from stm?
> 
> > As an additional crux, the HW timer to be used (TIM1 above)
> > typically gets defined by the BSP in hal_bsp_init, whereas
> > pwm_chan_config is application runtime code. I would prefer to
> > break the coupling, or at least make it less fragile.  
> 
> I see, I'm not sure about that one. I mean it does not make much sense
> to me, because one might want to reconfigure channels on runtime, just
> take a look at what we're doing on pwm_test on last PR.
> 
> It sounds like stm PWM has a bunch of limitations you have to deal
> with and there are some things you probably won't be able to run from.
> I already implemented two PWM drivers using the current interface, I
> think we should be flexible at this stage regarding the API interface
> so it will be useful for you.
> However I feel that having an AF field by default doesnt make much
> sense.
> 
> Thanks,
> 
> On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca> wrote:
> > This is the implementation of pwm_configure_channel:
> >
> > static int
> > stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum,
> > struct pwm_chan_cfg *cfg) {
> >     stm32f3_pwm_dev_t *pwm;
> >
> >     assert(dev->pwm_instance_id < PWM_COUNT);
> >     assert(cnum < STM32F3_PWM_CH_COUNT);
> >
> >     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
> >
> >     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
> >         return -1;
> >     }
> >
> >     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
> >         if (hal_gpio_init_af(cfg->pin,
> >                             (uint8_t)(uintptr_t)cfg->data,
> >                             HAL_GPIO_PULL_NONE,
> >                             0)) {
> >             return -1;
> >         }
> >     }
> >
> >     pwm->ch[cnum].duty      = 0;
> >     pwm->ch[cnum].pin       = cfg->pin;
> >     pwm->ch[cnum].invert    = cfg->inverted;
> >     pwm->ch[cnum].update    = 0;
> >     pwm->ch[cnum].enabled   = 0;
> >     pwm->ch[cnum].configure = 1;
> >
> >     return 0;
> > }
> >
> > On an STM to connect the output pad with the PWM channel I have to
> > configure it for the alternate function (which is done by
> > hal_gpio_init_af). The AF value, the result of
> > `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which
> > determines what the pin is used for.
> >
> > Unfortunately there is no universal AF value for pwm channels, on
> > some pins it's 1, on some it's 6 ... , some pins cannot be used as
> > pwm channel outputs at all and some pins could be used as the
> > output of multiple channels.
> >
> > With the construct above the application has to make a call like:
> >
> >         struct pwm_chan_cfg cfg;
> >         cfg.pin = 8;
> >         cfg.inverted = false;
> >         cfg.data = (void*)6;
> >         pwm_chan_config(pwm, 0, &cfg);
> >
> > But this ONLY works if `pwm` is bound to the mcu's TIM1 and you use
> > channel 0. For TIM1 and channel 1 the app would have to use
> > `pin=9/data=6`.
> >
> > It's bad enough that only certain pins work for a given
> > timer/channel but it's even worse because the driver also needs to
> > know the AF number to use.
> >
> > As an additional crux, the HW timer to be used (TIM1 above)
> > typically gets defined by the BSP in hal_bsp_init, whereas
> > pwm_chan_config is application runtime code. I would prefer to
> > break the coupling, or at least make it less fragile.
> >
> > Does this make sense?
> > Markus
> >
> >
> > On Thu, 1 Mar 2018 01:58:46 -0300
> > Miguel Azevedo <mi...@gmail.com> wrote:
> >  
> >> Hi markus,
> >>  
> >> > `struct pwm_chan_config` only specifies the pin number. I've been
> >> > using the `data` member to put the burden on the application to
> >> > specify the "correct" number for the alternate function > - but I
> >> > find this a little unsatisfactory.  
> >> That sounds a lot driver/hw specific. Can you show us the code for
> >> that?
> >>
> >> Thanks,
> >> Miguel
> >>
> >> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:  
> >> > While writing a PWM driver for the STM32s mcu family I came
> >> > across the issue of assigning output pins for a pwm channel.
> >> >
> >> > PWM output in STM32s is done by configuring a pin for "alternate
> >> > functions" - where specific pins have specific (possible)
> >> > alternate functions. In other words, only a very limited number
> >> > of timer:channel:pin combinations are possible, each one
> >> > requiring a very specific alternate function.
> >> >
> >> > `struct pwm_chan_config` only specifies the pin number. I've been
> >> > using the `data` member to put the burden on the application to
> >> > specify the "correct" number for the alternate function - but I
> >> > find this a little unsatisfactory.
> >> >
> >> > So I was wondering if somebody has a recommendation, better
> >> > approach to solving this issue?
> >> >
> >> > Have fun,
> >> > Markus  
> >>
> >>
> >>  
> >  
> 
> 
> 


Re: recommendations for IO pin declarations

Posted by Miguel Azevedo <mi...@gmail.com>.
> Unfortunately there is no universal AF value for pwm channels, on some pins it's 1, on some it's 6 ... , some pins cannot be used as pwm channel outputs at all and some pins could be used as the output of multiple channels.

Not sure I got it right.
So you can configure a given pin using 1 or 6 depending on whether you
want it to output a single pwm chan or multiple?
Having a single gpio output multiple channels feels a lot like an
uncommon feature btw.

> It's bad enough that only certain pins work for a given timer/channel but it's even worse because the driver also needs to know the AF number to use.
It definitely does not look great but it feels that you will need
either a lot of #ifdefs or have the driver knowing these restrictions.
Aren't these restrictions described on some .h from stm?

> As an additional crux, the HW timer to be used (TIM1 above) typically gets defined by the BSP in hal_bsp_init, whereas pwm_chan_config is application runtime code. I would prefer to break the coupling, or at least make it less fragile.

I see, I'm not sure about that one. I mean it does not make much sense
to me, because one might want to reconfigure channels on runtime, just
take a look at what we're doing on pwm_test on last PR.

It sounds like stm PWM has a bunch of limitations you have to deal
with and there are some things you probably won't be able to run from.
I already implemented two PWM drivers using the current interface, I
think we should be flexible at this stage regarding the API interface
so it will be useful for you.
However I feel that having an AF field by default doesnt make much sense.

Thanks,

On Thu, Mar 1, 2018 at 2:51 AM, markus <ma...@bibi.ca> wrote:
> This is the implementation of pwm_configure_channel:
>
> static int
> stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum, struct pwm_chan_cfg *cfg)
> {
>     stm32f3_pwm_dev_t *pwm;
>
>     assert(dev->pwm_instance_id < PWM_COUNT);
>     assert(cnum < STM32F3_PWM_CH_COUNT);
>
>     pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];
>
>     if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
>         return -1;
>     }
>
>     if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
>         if (hal_gpio_init_af(cfg->pin,
>                             (uint8_t)(uintptr_t)cfg->data,
>                             HAL_GPIO_PULL_NONE,
>                             0)) {
>             return -1;
>         }
>     }
>
>     pwm->ch[cnum].duty      = 0;
>     pwm->ch[cnum].pin       = cfg->pin;
>     pwm->ch[cnum].invert    = cfg->inverted;
>     pwm->ch[cnum].update    = 0;
>     pwm->ch[cnum].enabled   = 0;
>     pwm->ch[cnum].configure = 1;
>
>     return 0;
> }
>
> On an STM to connect the output pad with the PWM channel I have to configure it for the alternate function (which is done by hal_gpio_init_af). The AF value, the result of `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which determines what the pin is used for.
>
> Unfortunately there is no universal AF value for pwm channels, on some pins it's 1, on some it's 6 ... , some pins cannot be used as pwm channel outputs at all and some pins could be used as the output of multiple channels.
>
> With the construct above the application has to make a call like:
>
>         struct pwm_chan_cfg cfg;
>         cfg.pin = 8;
>         cfg.inverted = false;
>         cfg.data = (void*)6;
>         pwm_chan_config(pwm, 0, &cfg);
>
> But this ONLY works if `pwm` is bound to the mcu's TIM1 and you use channel 0. For TIM1 and channel 1 the app would have to use `pin=9/data=6`.
>
> It's bad enough that only certain pins work for a given timer/channel but it's even worse because the driver also needs to know the AF number to use.
>
> As an additional crux, the HW timer to be used (TIM1 above) typically gets defined by the BSP in hal_bsp_init, whereas pwm_chan_config is application runtime code. I would prefer to break the coupling, or at least make it less fragile.
>
> Does this make sense?
> Markus
>
>
> On Thu, 1 Mar 2018 01:58:46 -0300
> Miguel Azevedo <mi...@gmail.com> wrote:
>
>> Hi markus,
>>
>> > `struct pwm_chan_config` only specifies the pin number. I've been
>> > using the `data` member to put the burden on the application to
>> > specify the "correct" number for the alternate function > - but I
>> > find this a little unsatisfactory.
>> That sounds a lot driver/hw specific. Can you show us the code for
>> that?
>>
>> Thanks,
>> Miguel
>>
>> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
>> > While writing a PWM driver for the STM32s mcu family I came across
>> > the issue of assigning output pins for a pwm channel.
>> >
>> > PWM output in STM32s is done by configuring a pin for "alternate
>> > functions" - where specific pins have specific (possible) alternate
>> > functions. In other words, only a very limited number of
>> > timer:channel:pin combinations are possible, each one requiring a
>> > very specific alternate function.
>> >
>> > `struct pwm_chan_config` only specifies the pin number. I've been
>> > using the `data` member to put the burden on the application to
>> > specify the "correct" number for the alternate function - but I
>> > find this a little unsatisfactory.
>> >
>> > So I was wondering if somebody has a recommendation, better
>> > approach to solving this issue?
>> >
>> > Have fun,
>> > Markus
>>
>>
>>
>



-- 
--
Miguel Azevedo

Re: recommendations for IO pin declarations

Posted by markus <ma...@bibi.ca>.
This is the implementation of pwm_configure_channel:

static int
stm32f3_pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum, struct pwm_chan_cfg *cfg)
{
    stm32f3_pwm_dev_t *pwm;

    assert(dev->pwm_instance_id < PWM_COUNT);
    assert(cnum < STM32F3_PWM_CH_COUNT);

    pwm = &stm32f3_pwm_dev[dev->pwm_instance_id];

    if (STM32F3_PWM_CH_DISABLED != pwm->ch[cnum].config) {
        return -1;
    }

    if (STM32F3_PWM_CH_NOPIN != cfg->pin) {
        if (hal_gpio_init_af(cfg->pin,
                            (uint8_t)(uintptr_t)cfg->data,
                            HAL_GPIO_PULL_NONE,
                            0)) {
            return -1;
        }
    }

    pwm->ch[cnum].duty      = 0;
    pwm->ch[cnum].pin       = cfg->pin;
    pwm->ch[cnum].invert    = cfg->inverted;
    pwm->ch[cnum].update    = 0;
    pwm->ch[cnum].enabled   = 0;
    pwm->ch[cnum].configure = 1;

    return 0;
}

On an STM to connect the output pad with the PWM channel I have to configure it for the alternate function (which is done by hal_gpio_init_af). The AF value, the result of `(uint8_t)(uintptr_t)cfg->data` is a value between 0 and 15 which determines what the pin is used for.

Unfortunately there is no universal AF value for pwm channels, on some pins it's 1, on some it's 6 ... , some pins cannot be used as pwm channel outputs at all and some pins could be used as the output of multiple channels.

With the construct above the application has to make a call like:

        struct pwm_chan_cfg cfg;
        cfg.pin = 8;
        cfg.inverted = false;
        cfg.data = (void*)6;
        pwm_chan_config(pwm, 0, &cfg);

But this ONLY works if `pwm` is bound to the mcu's TIM1 and you use channel 0. For TIM1 and channel 1 the app would have to use `pin=9/data=6`.

It's bad enough that only certain pins work for a given timer/channel but it's even worse because the driver also needs to know the AF number to use.

As an additional crux, the HW timer to be used (TIM1 above) typically gets defined by the BSP in hal_bsp_init, whereas pwm_chan_config is application runtime code. I would prefer to break the coupling, or at least make it less fragile.

Does this make sense?
Markus


On Thu, 1 Mar 2018 01:58:46 -0300
Miguel Azevedo <mi...@gmail.com> wrote:

> Hi markus,
> 
> > `struct pwm_chan_config` only specifies the pin number. I've been
> > using the `data` member to put the burden on the application to
> > specify the "correct" number for the alternate function > - but I
> > find this a little unsatisfactory.  
> That sounds a lot driver/hw specific. Can you show us the code for
> that?
> 
> Thanks,
> Miguel
> 
> On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
> > While writing a PWM driver for the STM32s mcu family I came across
> > the issue of assigning output pins for a pwm channel.
> >
> > PWM output in STM32s is done by configuring a pin for "alternate
> > functions" - where specific pins have specific (possible) alternate
> > functions. In other words, only a very limited number of
> > timer:channel:pin combinations are possible, each one requiring a
> > very specific alternate function.
> >
> > `struct pwm_chan_config` only specifies the pin number. I've been
> > using the `data` member to put the burden on the application to
> > specify the "correct" number for the alternate function - but I
> > find this a little unsatisfactory.
> >
> > So I was wondering if somebody has a recommendation, better
> > approach to solving this issue?
> >
> > Have fun,
> > Markus  
> 
> 
> 


Re: recommendations for IO pin declarations

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

> `struct pwm_chan_config` only specifies the pin number. I've been using the `data` member to put the burden on the application to specify the "correct" number for the alternate function > - but I find this a little unsatisfactory.
That sounds a lot driver/hw specific. Can you show us the code for that?

Thanks,
Miguel

On Wed, Feb 28, 2018 at 9:57 PM, markus <ma...@bibi.ca> wrote:
> While writing a PWM driver for the STM32s mcu family I came across the issue of assigning output pins for a pwm channel.
>
> PWM output in STM32s is done by configuring a pin for "alternate functions" - where specific pins have specific (possible) alternate functions. In other words, only a very limited number of timer:channel:pin combinations are possible, each one requiring a very specific alternate function.
>
> `struct pwm_chan_config` only specifies the pin number. I've been using the `data` member to put the burden on the application to specify the "correct" number for the alternate function - but I find this a little unsatisfactory.
>
> So I was wondering if somebody has a recommendation, better approach to solving this issue?
>
> Have fun,
> Markus



-- 
--
Miguel Azevedo