-
Notifications
You must be signed in to change notification settings - Fork 215
Description
Summary
This issue is meant to track and discuss issues related to migration to the clock v2 API.
The clock v2 API "...provides a simple, ergonomic, and most of all safe API to create and manage the clock tree in ATSAMD5x and E5x devices. It uses type-level programming techniques to prevent users from creating invalid or unsound clocking configurations."
The key feature compared to the clock v1 API is that the clock tree configuration is validated at compile time using type-level programming, which is better for most use cases in which the clock tree is set up once at the beginning of the program and then not changed.
Status
Currently, the v2 API is only implemented for thumbv7
targets, and is not widely supported throughout the HAL, making it currently largely unusable for most projects.
Tasks
The following are pending identified tasks at the highest level:
- Add clock v2 API support throughout the entire HAL for
thumbv7
targets. - Port the clock v2 API to
thumbv6m
targets. - Add clock v2 API support throughout the entire HAL for
thumbv6m
targets.
Task 1: HAL support for thumbv7
targets
Migration guidelines
- The focus should be on fully migrating peripherals to v2 and not worrying about still supporting v1.
- For safety, peripherals that depend on AHB or APB bus clocks, should require ownership of their
AhbClk
orApbClk
structs, even if their bus clock is enabled at startup, because these clocks can be disabled, rendering the peripheral non-functional. Requiring ownsership ensures that it cannot be disabled while the peripheral is in use. - Peripherals that require a PCLK should require ownership of the
Pclk
struct. According to the "1:1 clocks" section of theclock::v2
module documentation, this "prevents users from modifying or disabling thePclk
while it is in use by the peripheral". - All items that consume clocks (i.e. the above structs) should have a
free
method that returns them. This should also of course return thepac
peripheral struct as well if applicable. - To use the v2 API correctly, peripherals requiring a
Pclk
need to own it, and thePclk
can have different sources via itsI: PclkSourceId
generic. This means that the peripheral struct itself (e.g.Adc
) needs to have the same generic parameter. The problem is that, onthumbv6
targets, this generic on the peripheral struct and itsimpl
blocks cannot exist (since they currently have no v2 API), leading to requiring separateimpl
blocks for each chip family, hence potentially duplicated code. This is explained nicely in a comment for theAdc
. TheAdc
takes a partial approach by simply requiring a&Pclk
at the time of creation, but this does not prevent thePclk
from being disabled while still in use by theAdc
. After some discussion below, it was agreed that applicable peripherals should not be migrated until the v2 is ported tothumbv6
targets (i.e. Task 2). These peripherals are noted in the table below. - If examples use more than one peripheral that needs migrated and those perihperals are migrated in separate PRs, the example may be broken until both PRs are merged, and then the example can be fixed in a separate PR. An example of this is discussed below.
Peripheral migration tracking
This tracks the various peripherals/modules that require clocking for thumbv7
targets:
Peripheral | thumbv7 only |
Awaiting thumbv6 v2 port |
Clocks required | v1 Support | v2 Support | Clk ownership | free method |
Complete | Notes |
---|---|---|---|---|---|---|---|---|---|
ADC | ✅ | APB, PCLK | No | adc::AdcBuilder |
✅ | Partial migration with PR #814, see note 1 below | |||
AES | ✅ | APB | No | aes::Aes::new |
✅ | ✅ | ✅ | Migration merged in PR #920 | |
CAN | ✅ | AHB, PCLK | No | can::Dependencies::new |
✅ | ✅ | ✅ | Fixed in the merged PR #919 | |
DAC | APB, PCLK | No | dac::Dac::new |
✅ | ✅ | ✅ | New peripheral proposed in PR #904 | ||
Delay (SYSTICK) | GCLK0 | No | delay::Delay::new |
✅ | ✅ | ✅ | Fixed up in the proposed PR #929 | ||
DMAC | AHB | Yes | Yes | Does not require AHB clock proof | |||||
DSU | ✅ | AHB, APB | No | dsu::Dsu::new |
✅ | ✅ | ✅ | Migration proposed in PR #925 | |
EIC | ✅ | APB, PCLK / ULP32K | eic::Eic::new |
Partial | Provides methods to switch clock sources, may need changed, see note 2 below | ||||
ICM | ✅ | AHB, APB | No | icm::Icm::new |
✅ | ✅ | ✅ | Migration proposed in PR #927 | |
NVM | ✅ | AHB, APB | Yes | Yes | Does not require clock proof. There are several AHB mask bits for this: NVMCTRL_CACHE, NVMCTRL_SMEEPROM, and NVMCTRL | ||||
PUKCC | ✅ | AHB | pukcc::Pukcc::new |
No | |||||
PWM (TC/TCC) | ✅ | APB, PCLK | pwm::PwmX::new or pwm::TccXPwm::new |
No | |||||
QSPI | ✅ | AHB, APB | No | qspi::QspiBuilder::build |
Migration and overhaul proposed in PR #926 | ||||
RTC | ✅ | APB, RtcOsc | rtc::Rtc::count32_mode or rtc::Rtc::clock_mode |
No | No way to actually set the Rtc clock with v1 | ||||
RTC RTIC Monotonic | ✅ | APB, RtcOsc | rtc_monotonic!::start |
No | No clock proof required, but RTC clock rate must be known at compile time via rtc::rtic::rtc_clock::RtcClockRate |
||||
RTC Embassy time driver | ✅ | APB, RtcOsc | No | embassy_time!::init |
Proposed in PR #825, requires only RtcOsc but not AbpClk |
||||
Sercom I2C | ✅ | APB, PCLK | sercom::i2c::Config::new |
No | |||||
Sercom SPI | ✅ | APB, PCLK | sercom::spi::Config::new |
No | |||||
Sercom UART | ✅ | APB, PCLK | sercom::uart::Config::new |
No | |||||
TC | ✅ | APB, PCLK | timer::TimerCounter::tcx_ |
No | Open PR #690 updates this, but is out of date and incomplete | ||||
TRNG | ✅ | APB | trng::Trng::new |
No | |||||
USB | AHB, APB, PCLK | No | usb::UsbBus::new |
✅ | ✅ | ✅ | The PCLK must be 48 MHz. PR #916 proposes the migration | ||
WDT | APB | Yes | Yes | Uses the OSCULP32K, which is always enabled if the WDT is enabled, does not require APB clock proof. |
If anything was missed or there are any errors, please comment below.
Notes:
- The ADC currently only takes a reference to its
Pclk
and it is problematic to take full ownership until the v2 is ported tothumbv6
chips, see the explanation here. - The EIC can use a standard
Pclk
or the ULP32K clock, which is selected via the CKSEL bit in the EIC CTRLA register. Some discussion is needed on what the right way to handle this and switch clocks should be.
Here are other PRs and issues related to this:
- Issue RTC peripheral can be used without configuring the RTC clock #642 discusses that the RTC can be used without configuring the clock, which is a known issue that was discussed further in PR Fixes problems with the
rtc::Rtc
abstraction and refactors to use the newrtc::modes
abstractions. #845.
Task 2: Port the API to thumbv6m
targets.
Completion of this task is needed to reasonably complete some peripherals in Task 1, see the table and notes above.
Work on this is ongoing:
- PR Clock v2 thumbv6m #892 (Draft)
- A fork that does this. It has recent commits, but is way behind master.
Task 3: HAL support for thumbv6
targets
This of course depends on the completion of Task 2, and will also likely be able to leverage the work done in Task 1.