zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.9k stars 6.64k forks source link

Add RTC-based counter driver #56599

Open arbrauns opened 1 year ago

arbrauns commented 1 year ago

Is your enhancement proposal related to a problem? Please describe. With the new RTC API (#52618), a problem emerges: since devices can only implement one driver interface (#48934), RTC peripherals that were previously used only as counters can't reuse their devicetree compatible to become RTCs without dropping their counter driver.

Describe the solution you'd like Implement a generic counter driver that can piggyback off any RTC device, allowing RTC devices to still be used as counters. It would internally use the RTC API to implement the counter API.

Describe alternatives you've considered As done in #56334, there could simply be a check that CONFIG_RTC and CONFIG_COUNTER aren't active at the same time, so only either the RTC or counter driver can be implemented for a device. This would probably become quite annoying though because users may want to use an RTC device as an RTC, and a separate counter device as a counter.

cc @bjarki-trackunit

nordicjm commented 1 year ago

Are you perhaps becoming confused between real time counters and real time clocks? RTC is for clocks, not counters

arbrauns commented 1 year ago

I don't think so. For example, compatible: "st,stm32-rtc" (the real-time clock peripheral inside STM32 devices) is currently covered by drivers/counter/counter_ll_stm32_rtc.c, a counter driver. In order to use it as a proper RTC, it needs to be covered by an RTC driver, but that's not possible while also keeping the existing counter driver.

nordicjm commented 1 year ago

A single compatible can be covered by multiple drivers, for example, the mcp7940n is an RTC and has a driver (though it is a counter at present and need converting to RTC) but it also features as a BBRAM driver, one can:

The same should be possible with stm32 driver (not that I've looked into if it is a counter or clock)

nordicjm commented 1 year ago

https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/counter/counter_ll_stm32_rtc.c this should be converted and moved to RTC, not kept as a counter, but you can keep both and then deprecate the old one as to not break people already using it

arbrauns commented 1 year ago

[...] one can:

  • enable the counter driver and the BBRAM driver

Are you sure? I don't see how that would work without #48934; the API can only be either counter or bbram.

https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/counter/counter_ll_stm32_rtc.c this should be converted and moved to RTC, not kept as a counter, but you can keep both and then deprecate the old one as to not break people already using it

But why force people to stop using it as a counter? That's what my original suggestion (having a "proxy" counter driver that works with any RTC peripheral) is about.

bjarki-andreasen commented 1 year ago

The solution I prefer is keeping and deprecating the drivers using the counter API, while re-implementing the drivers using the RTC API, without creating new devicetree compatibles.

The main issue with this solution is selecting the appropriate driver, since drivers are currently automatically selected if the compatible exist. This can be handled safely by adding this if statement and deprecated warning to the existing Kconfigs for the counter drivers:

config SOME_COUNTER_DRIVER_FOR_RTC
    bool
    default y if !RTC
    select DEPRECATED
    depends on DT_HAS_SOME_RTC_ENABLED

while the new drivers Kconfig looks like this (it's only included if CONFIG_RTC=y)

config SOME_RTC_DRIVER_FOR_RTC
    bool
    default y
    depends on DT_HAS_SOME_RTC_ENABLED

This will keep the counter driver for the RTC, unless CONFIG_RTC=y. This is presuming that you want the RTC drivers for the RTC hardware, if CONFIG_RTC is enabled.

bjarki-andreasen commented 1 year ago

@arbrauns I expect once we start implementing a time subsystem, it will probably support getting time as a time_t from a real-time clock, I would describe that as using an RTC as a counter :)

bjarki-andreasen commented 9 months ago

We went with the solution I proposed here https://github.com/zephyrproject-rtos/zephyr/issues/56599#issuecomment-1498965901

tagunil commented 2 months ago

Actually there is a use case that requires using both the RTC API and the counter API for the same device at the same time. The STM32 RTC peripheral can be used both as the wall clock time source and as an idle timer for low-power modes (#63187). Are there any ideas around how to support such a case without implementing a proxy counter driver?