Skip to content

Conversation

@rnd-ash
Copy link
Contributor

@rnd-ash rnd-ash commented Apr 10, 2025

Summary

As part of my work for implementing the Event system for pulse counting, I noticed that there was some issues with the EIC implementation. This PR fixes them.

  1. Document the fact that when using the V2 clocking API, the user must enable the OSC32K clock and wire it up to the EIC Clock, since the HAL assumes that the OSC32K clock will drive the EIC peripheral. Later, I will possibly create a new constructor for the EIC peripheral that can take in a much faster clock source if the user wishes for it.

  2. Create a constructor for the EIC peripheral that does not assume that OSC32K clock source is used. This allows the EIC peripheral to be driven by a much faster clock source, thus, have a faster event detection frequency

  3. The enable_event method on an EIC channel does not actually function, as the EIC peripheral is enabled when the function is called, but the evctrl register is locked due to the peripheral being enabled. So the method now disables the EIC before enabling the bit, and then re-enables the peripheral. This is noted in the function documentation

@rnd-ash rnd-ash changed the title Fix EIC event enable, and document using OSC32K clock for EIC EIC Fixes for D5X Apr 14, 2025
Copy link
Contributor

@jbeaurivage jbeaurivage left a comment

Choose a reason for hiding this comment

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

Thanks @rnd-ash. I completely understand why one would want the EIC to run on a faster clock. What surprised me is learning that the OSCULP32K was NOT always enabled? For some reason I thought it couldn't be turned off. But maybe that's only the case on D21 targets.

/// Do not use this function if you are using the osc32k clock
/// for the EIC peripheral, instead use [`Eic::new`]
#[hal_cfg("eic-d5x")]
pub fn new_gclk(mclk: &mut pac::Mclk, _clock: EicClock, eic: pac::Eic) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

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

Only real suggestion would be to call this function new_with_gclk.

@rnd-ash
Copy link
Contributor Author

rnd-ash commented Apr 15, 2025

@jbeaurivage @ianrrees I had some conversations today about how this API works, and I believe my initial interpretation is wrong.

In summary, the EIC actually works like this.

  1. You can give it a GCLK or OSC32K clock source. GCLK is preferred for when the processor is active (as you can get way faster event frequency), however you would want to use the OSC32K clock source when you put the processor to sleep so that it can wake up.

  2. Connecting to OSC32K is not done via GCLK, EIC directly hooks into the OSC32K clock source when ctrla.cksel bit is set to 1.

So, forward question to ask. How to implement this in the API? I was thinking of the EIC clock source being an enum

pub enum EicClkSrc<'a>{
   Gclk(&'a EicClock),
   Ulp(&'a UlpClock)
}

Then provide this enum to the new() function of EIC so the user can initially set the clocking source. But then also provide switch_to_gclk and ``switch_to_ulp` methods to switch the clock provider for EIC.

Trying to implement this now, but I find that the V1 clock API does not have a struct to represent the OSC32K clock, any suggestions on how to go from here?

@jbeaurivage
Copy link
Contributor

@rnd-ash, your suggestion does make sense. IMO the premise behind the v1 clock API is that peripherals are pretty much responsible for setting up the clocking according to their needs. Therefore my suggestion would be this:

  • If you provide a constructor for clock v2, obviously you would use the type system to prove that the OSCULP32K output (or a GCLK) is enabled. Potentially two different constructors according the clock source.
  • For v1, enable the OSCULP32K inside the constructor if the user selects this clock source. In the switch_to_osculp32k, turn it on if it isn't already.

@jbeaurivage
Copy link
Contributor

Actually I would expose 3 different constructors:

  • One for v1, where the clock input can be selected using an enum
  • One for v2 with OSCULP32K
  • One for v2 with GCLK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants