+1

On Fri, 09 Mar 2018 10:35:46 -0800
"Sterling Hughes" <[email protected]> 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 <[email protected]> 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
> >> <[email protected]> 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 <[email protected]>
> >>> 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
> >>>> <[email protected]> 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:[email protected]]
> >>>>> Sent: 01 March 2018 18:24
> >>>>> To: [email protected]
> >>>>> Cc: Miguel Azevedo <[email protected]>
> >>>>> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]>
> >>>>>>> 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 <[email protected]> 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 <[email protected]>
> >>>>>>>>> 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  
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>  
> >>>>>>>>  
> >>>>>>>
> >>>>>>>
> >>>>>>>  
> >>>>>>
> >>>>>>  
> >>>>>
> >>>>>  
> >>>>  
> >>
> >>
> >>  

Reply via email to