+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 > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>> > >>>>>> > >>>>> > >>>>> > >>>> > >> > >> > >>
