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 <miguella...@gmail.com> wrote:Hi Markus,One thing I forgot to mention, and that after giving this some thoughtmakes 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 onhal_bsp.c. For me it makes sense to have these values stored somewhereon 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 <wayne.kee...@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 <wayne.kee...@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 <raoul.van.ber...@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.kee...@gmail.com] Sent: 01 March 2018 18:24 To: dev@mynewt.apache.org Cc: Miguel Azevedo <miguella...@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 <mar...@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 AFnumber.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 <miguella...@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 <mar...@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 <miguella...@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 <mar...@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