Skip to content

Conversation

@kentjhall
Copy link

This driver implements the counter API for STM32F4 series general-purpose timers.

@github-actions github-actions bot added area: Counter area: Devicetree area: Devicetree Binding PR modifies or adds a Device Tree binding area: Tests Issues related to a particular existing or missing test platform: STM32 ST Micro STM32 labels Oct 13, 2021
@kentjhall kentjhall force-pushed the no-pio branch 2 times, most recently from 48f1b17 to 333801b Compare October 14, 2021 02:07
Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This driver is a long standing missing part in STM32 drivers and it is good having someone taking a stab at it. Thanks for this work.

I guess one of the reason it was missing is the fact cohabitation with pwm driver implementations, which share the same hardware component, has to be sorted out, and first at device tree level. This is missing in this proposal. More comments around this in the review.

Second point which is giving me concern is the integration in Zephyr code base. You chose to use HAL API to its whole extent (including msp_init, HAL_cortex api, ..). This isn't usual and, as I miss description of the implementation, I don't know if this is made on purpose or just a copy/paste of an existing, old fashioned, implementation.
For instance, STM32 PWM driver provides a well "zephyr integrated" driver, LL API based, functional with the same hardware block. So, I would be curious to know why LL API was not selected for this driver.
One reason might be the choice of using ZERO_LATENCY_IRQS, but once again, w/o context, hard for me to judge.

Minor last point would be to rename the driver to stm32 instead of stm32f4. Even if only limited to F4 for now (which is ok), it should be possible to extend, with minor modifications to other series in future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely, this property is the same as st,prescaler which is used for st,stm32-pwm.
This highlight an issue about device tree description of these timer nodes.
First, I'd suggest to create a new child node binding, similar to st,stm32-pwm, which would be used as reference for counter devices (st,stm32-counter for instance).
Then, some guards will be required in order to avoid resources conflicts between pwm and counter instances (that share the same hardware resources).
Last, it would be nice to be able to have some sort of code commonalisation between pwm and timer, as they will share common functionalities. For reference, this was the intent of #20293. Though I don't consider this last point as blocking for current PR.

Copy link
Author

@kentjhall kentjhall Oct 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the feedback! Almost everything makes sense to me; I guess I should have been following the PWM driver more, I was really just going off of the nrfx counter driver (and swapping out with the STM32’s HAL API) since my research group is using an nrfx board for our existing Zephyr use case. I’m working on swapping my HAL uses for LL. But I’m not sure I understand this point:

Then, some guards will be required in order to avoid resources conflicts between pwm and counter instances (that share the same hardware resources).

I’m not super familiar with DTS stuff, is there a way to implement such guards within the device tree? Or if not, what do you have in mind?

@ABOSTM
Copy link
Contributor

ABOSTM commented Oct 20, 2021

@kentjhall It seems part of my comment was missing in my previous review:
Here it is.

@kentjhall,
Thanks for this Pull Request. This is a huge work.
But, even if I guess it works for your case (your F4 boards, with your configuration),
I think it lack some genericity, clock computation is tight to your configuration,
also all STM32 series have General Purpose Timer, so we need to have a generic implementation compatible with other series, and as said @erwango, we need to take care of cohabitation with PWM which shares the same resources, and try to get synergies to avoid code duplication.
That said, I am currently already working on such driver implementation of counter, based on STM32 General Purpose timers (aka TIMx) taking into account the constraints mentioned above. But it is a long journey, tackling genericity is complex, so I still need some consequent work before publishing.

So yes Device Tree allow to dedicate some hardware ressources to some drivers ... but don't worry I will take care of this

Copy link
Contributor

@ABOSTM ABOSTM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems I completely miss my previous review,
Here is my initial comments

@kentjhall
Copy link
Author

Okay, I ported everything to the LL API, and also updated the naming and things. Note that despite the naming change, this driver is still only supporting STM32F4 (it should be easy to make it a bit more generic like how PWM driver does, but I don’t feel comfortable attempting it since I don’t have any other boards to test on). I understand that some things will likely still need to be fixed though, like figuring out the clock frequency correctly at compile-time and preventing resource conflicts with the PWM driver. If there are any similar examples I should look to across other drivers (particularly for the latter), let me know and I’ll be happy to implement these myself.

Copy link
Contributor

@ABOSTM ABOSTM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kentjhall,
Ok, I am fine if you continue on this PR, as you are on the right track and moving fast. Great Thanks.
So I will stop my own development.
Nevertheless I have an ongoing PR (#39628) to remove prescaler from PWM Device Tree binding and move it to timers binding. It has impact on counter timer as prescaler from counter would become useless, and prescaler from timer should be used instead..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nordic-krch , do you know why using arbitrary hardcoded half timer period instead of reusing the same guard period than for absolute (which is configurable) ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i recall correctly the assumption was that absolute guard may not be set and half period should be safe to use. We just need something that exceeds potential longest interruption. The only case when half period would fail if half period is less than potential longest preemption but handling counter in such scenario would not make much sense.

@kentjhall
Copy link
Author

Can ISR_DIRECT_DECLARE() return value 1 to inform scheduler? Or can this be configurable? Maybe could be good idea to propagate this information from callback from application.

https://github.com/zephyrproject-rtos/zephyr/blob/6a838bfaba59f75675b5641305277f6ec9bdff76/drivers/counter/counter_ll_stm32_timer.c#L587

@cz8pru Yes I was wondering about this—does anyone know if I am using IRQ_DIRECT_CONNECT/ISR_DIRECT_DECLARE correctly? At the time I wrote this, I was somewhat blindly following the nrfx counter driver, which has this:

ISR_DIRECT_DECLARE(counter_timer##idx##_isr_wrapper)	       \
		{							       \
			irq_handler(DEVICE_DT_GET(TIMER(idx)));		       \
			/* No rescheduling, it shall not access zephyr primitives. */ \
			return 0;					       \
		}				       \

But I don't really understand what that comment means or if it applies here. Should I be returning 1, and/or invoking ISR_DIRECT_PM?

@cz8pru
Copy link

cz8pru commented Nov 12, 2021

Can ISR_DIRECT_DECLARE() return value 1 to inform scheduler? Or can this be configurable? Maybe could be good idea to propagate this information from callback from application.
https://github.com/zephyrproject-rtos/zephyr/blob/6a838bfaba59f75675b5641305277f6ec9bdff76/drivers/counter/counter_ll_stm32_timer.c#L587

@cz8pru Yes I was wondering about this—does anyone know if I am using IRQ_DIRECT_CONNECT/ISR_DIRECT_DECLARE correctly? At the time I wrote this, I was somewhat blindly following the nrfx counter driver, which has this:

ISR_DIRECT_DECLARE(counter_timer##idx##_isr_wrapper)	       \
		{							       \
			irq_handler(DEVICE_DT_GET(TIMER(idx)));		       \
			/* No rescheduling, it shall not access zephyr primitives. */ \
			return 0;					       \
		}				       \

But I don't really understand what that comment means or if it applies here. Should I be returning 1, and/or invoking ISR_DIRECT_PM?

I am also not good guy to help you with this. I have here aplication which needs to periodically readout external device via SPI. So, I need periodically (precious, fast) start SPI transaction (for example every 500us). SPI transaction takes some time (OK, I can do it by using DMA but forget) and it cannot be placed into ISR. I can periodically run in in thread and run this thread which will depends on event. Event will be samaphore which is given in ISR and taken in such thread.
In this case, system has to inform sheduler that ISR is finished and scheduler has to reschedule task and run my thread. To do this, we have to return 1 from ISR_DIRECT_DECLARE.

I can imagine, that there are such situations to not inform scheduler... it will make it easier but with slower response. Is here some expert on drivers who can help us with interrupts? I prefer soltuin, where you can decided from app.
1/ propagate return value from application callback
2/ kconfig option
3/ ...

@erwango
Copy link
Member

erwango commented Nov 15, 2021

At the time I wrote this, I was somewhat blindly following the nrfx counter driver, which has this:

My initial response would be: unless you know what you are doing, please use IRQ_CONNECT/irq_enable. These are the ones used in most drivers.
Use of direct interrupts will provide gain in performance, but they come with constraints. You should read and understand the following before using them:

@kentjhall
Copy link
Author

At the time I wrote this, I was somewhat blindly following the nrfx counter driver, which has this:

My initial response would be: unless you know what you are doing, please use IRQ_CONNECT/irq_enable. These are the ones used in most drivers.

Ok, I've gone this route and switched to using IRQ_CONNECT.

@kentjhall kentjhall force-pushed the no-pio branch 2 times, most recently from c0040c2 to 89111b5 Compare November 16, 2021 00:40
@ABOSTM
Copy link
Contributor

ABOSTM commented Nov 17, 2021

@kentjhall #39628 has been merged, you can switch to timers node prescaler

@kentjhall
Copy link
Author

@kentjhall #39628 has been merged, you can switch to timers node prescaler

@ABOSTM Done. Definitely agree this is better, thanks!

@erwango erwango self-requested a review November 30, 2021 13:45
Copy link
Contributor

@ABOSTM ABOSTM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, except the remaining open point about "freq" which should be computed at runtime but is part of Zephyr API. (see previous comments)
@nordic-krch , as code maintainer, could you help to fix this point ?

Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last remarks, then, aside from the pending points reported by other reviewers, LGTM.

Kent Hall added 2 commits December 9, 2021 20:04
- Shim for counter API using LL_TIM driver.
- Supports all general-purpose (TIMx) timers.

Signed-off-by: Kent Hall <[email protected]>
Updates counter driver test suite to support STM32F4 timers.

Signed-off-by: Kent Hall <[email protected]>
Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on my side. Thanks for all the efforts and patience @kentjhall, great work!
You can add yourself in CODEOWNER file in front of this driver (could be done in a later PR).

@gmarull, @nordic-krch, @ABOSTM, @mbolivar-nordic, would you mind having a new look ?

Copy link
Contributor

@ABOSTM ABOSTM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@nordic-krch nordic-krch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

Copy link
Contributor

@mbolivar-nordic mbolivar-nordic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DT bits LGTM

@gmarull gmarull dismissed their stale review December 10, 2021 18:56

Dropping change request, I don't have time to review this one now.

@nashif nashif merged commit ce95e03 into zephyrproject-rtos:main Dec 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Build System area: Counter area: Devicetree Binding PR modifies or adds a Device Tree binding area: Devicetree area: Tests Issues related to a particular existing or missing test platform: STM32 ST Micro STM32

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants