-
Notifications
You must be signed in to change notification settings - Fork 8.2k
[WIP] drivers: mfd: add support for stm32 timers #20293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] drivers: mfd: add support for stm32 timers #20293
Conversation
|
@maxvankessel, thanks for this contribution. Looks pretty nice with interesting bonuses like transition to LL API. |
fa9f030 to
679311c
Compare
|
@avisconti , FYI, IIRC, you need a timer driver for some application |
You remember correctly. It was the #17140 PR, which is frozen for the moment as there was some |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a timer driver user, so I can't comment much on functional side of the driver.
I'l try to get more reviewers on that side.
Though, I've made a first review in term of integration in zephyr driver model. And this is already in good shape on that side. Few comments though:
- To match other divers naming convention, please rename timer driver to timer_ll_stm32.c (or mfd_timer_...).
- Also rename functions with same name space timer_stm32_enable, ...
- Split your PR in few commits. I think that at least the mfd introduction might be reviewed in wider audience, even tought it is stm32 specific (keep one PR for now though)
drivers/mfd/stm32_timers.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there stm32 series on which this is not working ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment corresponds to TIM_CR1_DIR_Pos. Maybe you could give some comments on it.
My opinion: TIM_CR1_DIR_Pos is not very portable over several series. It might be different on other devices. (I've seen this on the ADC)
Same goes for: TIM_CR1_CMS_Pos, TIM_SMCR_SMS_Pos, TIM_SMCR_TS_Pos, TIM_CR2_MMS_Pos
679311c to
0b11a01
Compare
|
@maxvankessel, I'm starting having a deeper look. To see real interest of the mfd, it would be nice to have an (even light) implementation of another driver based on this mfd_timer. Current in-tree potential user would be counter(timer). Also, to ease the review, it would be nice to split the PR in commits (spliting based on subystem would be a good start for now). This would be anyway a pre-requisite if we want to get this merged. |
0b11a01 to
e042060
Compare
|
@erwango So I've split the commit, removed pwm contents from the mfd commit. What do you mean with "counter"?
Quadrature decoder? Or a capture interface? What is it you want to count? Something went wrong on a rebase, so thats why it closed and reopend |
e042060 to
e1827c0
Compare
42084a1 to
88aa574
Compare
|
Some checks failed. Please fix and resubmit. checkpatch issuesCodeowners issuesNits issuesTip: The bot edits this comment instead of posting a new one, so you can check the comment's history to see earlier messages. |
88aa574 to
944a1c0
Compare
Thanks for having taken the point into account, but I didn't meant to remove the PWM impact purely for the PR. Splitting the PR into several commits is generally a good way to ease the review process (then maybe we split the PR into several PRs to speed up the merge of large PRs, but we're not there yet).
Since interest of mfd is to serve multiple drivers, it would be valuable to demonstrate it within this change. This is why it would be valuable in your PR to have both pwm and counter demonstrated as timer-mfd users. |
|
@henrikbrixandersen I hear what you are saying, it's more like a base for all timer based drivers. I have made a quadrature decoder, and I realised it was a near copy of the PWM driver. Currently the PWM driver holds the complete timer instance, and a driver couldn't be written without kernel modification. I was not planning to modify the PWM api, as the way Linux implements several features for the timer driver (capture, encoder, hall). But I was stuck using the current implementation. Suggestions are welcome. |
@maxvankessel I am currently implementing quadrature decoder, frequency counter and pulse width measurement support atop of the NXP FlexTimer. What I have done so far is to use different device tree bindings per function, but this too feel wrong (the devicetree should describe the hardware, not the software configuration of the hardware). I too have a bit of duplicated code between the various drivers utilizing the FlexTimer, but it's not too much, I think. A common approach to this problem (one device instance, different drivers on top) within Zephyr would be nice. IMO, this should be taken into consideration in the current devicetree rework effort. /cc @galak. |
Added multi functional device driver. Added support for new timer base (mfd stm32 timers), which aims to be more versatile. Signed-off-by: Max van Kessel <[email protected]>
944a1c0 to
63737d4
Compare
instance 5 Seemed to have slip past Signed-off-by: Max van Kessel <[email protected]>
Deprecation of the parent-bus and child-bus Signed-off-by: Max van Kessel <[email protected]>
Corrected clock control include Signed-off-by: Max van Kessel <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maxvankessel Overall looks like a nice addition, as it would allow to implement more specific drivers on top of STM32 timer generic functionality. I have a custom driver that would benefit from a these changes (I'm using a master & slave configuration). Let me know if I can help on testing or code changes.
| u32_t tim_clk, apb_psc; | ||
|
|
||
| if (pclken->bus == STM32_CLOCK_BUS_APB1) { | ||
| apb_psc = CONFIG_CLOCK_STM32_APB1_PRESCALER; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to support H7 series PSC needs to use D2PRE1 / D2PRE2 (see #23590)
| /* enable clock */ | ||
| if (clock_control_on(data->clock, | ||
| (clock_control_subsys_t *)&cfg->pclken) == 0) { | ||
| err = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd return -EIO here (avoids if below)
| const struct mfd_timer_stm32_config *cfg = DEV_CFG(dev); | ||
|
|
||
| /* Timer is enabled by master timer if slave mode is set */ | ||
| if ((cfg->slave_mode << TIM_SMCR_SMS_Pos) != LL_TIM_SLAVEMODE_TRIGGER) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd just save LL_TIM_SLAVEMODE_TRIGGER to cfg->slave_mode, see next comment
| LL_TIM_SetTriggerInput(tim, mode); | ||
| } | ||
|
|
||
| mode = cfg->master_trig << TIM_CR2_MMS_Pos; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using cfg->var << SHIFT strategy I'd implement some helper functions to convert from dt binding values to actual definitions in the LL headers. I think it would be more portable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example of the mentioned idea: https://github.com/zephyrproject-rtos/zephyr/blob/master/drivers/serial/uart_stm32.c#L139
| mode = cfg->slave_mode << TIM_SMCR_SMS_Pos; | ||
| LL_TIM_SetSlaveMode(tim, mode); | ||
|
|
||
| if (cfg->slave_mode != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if shift (<<) approach is changed as suggested, cfg->slave_mode != LL_TIM_SLAVEMODE_DISABLED would be more readable.
| LL_TIM_SetTriggerOutput(tim, mode); | ||
|
|
||
| /* TODO: create binding for me ?*/ | ||
| LL_TIM_DisableARRPreload(tim); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be configurable as TODO suggests
So, I was a bit upset due to extensibility of the timer driver for the stm32 within Zephyr.
I opened up an enhancement issue #20262. And started digging around how Linux does this.
So I got inspired by by the MFD driver for stm32-timers, see stm32-timers.
I'm using the stm32f4 series as a motorcontroller (with hall sensors and field oriented control). And the timer can do a pretty good job here. But I want to use the timer as a base for other modules, like hall sensors and 3 phase generation. So I got it to work, and changed it only for the F4 series (all is based on the original drive, but I moved from the bulky HAL driver to to LL driver).
Also I moved from the DTS fixups to the instance based implementation. But it still needs more cleanup.
So I would like to hear from you, if it's useful I will cleanup things further so it can be merged.
TODO's