-
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
thumbv7targets. - Port the clock v2 API to
thumbv6mtargets. - Add clock v2 API support throughout the entire HAL for
thumbv6mtargets.
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
AhbClkorApbClkstructs, 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
Pclkstruct. According to the "1:1 clocks" section of theclock::v2module documentation, this "prevents users from modifying or disabling thePclkwhile it is in use by the peripheral". - All items that consume clocks (i.e. the above structs) should have a
freemethod that returns them. This should also of course return thepacperipheral struct as well if applicable. - To use the v2 API correctly, peripherals requiring a
Pclkneed to own it, and thePclkcan have different sources via itsI: PclkSourceIdgeneric. This means that the peripheral struct itself (e.g.Adc) needs to have the same generic parameter. The problem is that, onthumbv6targets, this generic on the peripheral struct and itsimplblocks cannot exist (since they currently have no v2 API), leading to requiring separateimplblocks for each chip family, hence potentially duplicated code. This is explained nicely in a comment for theAdc. TheAdctakes a partial approach by simply requiring a&Pclkat the time of creation, but this does not prevent thePclkfrom 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 tothumbv6targets (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
Pclkand it is problematic to take full ownership until the v2 is ported tothumbv6chips, see the explanation here. - The EIC can use a standard
Pclkor 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::Rtcabstraction and refactors to use the newrtc::modesabstractions. #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.