Skip to content

Commit

Permalink
[clock] Connect peripheral clocks via API
Browse files Browse the repository at this point in the history
  • Loading branch information
henrikssn authored and salkinium committed Jul 20, 2020
1 parent fecc5e0 commit bad229a
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 16 deletions.
6 changes: 4 additions & 2 deletions src/modm/platform/clock/sam/gclk.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ modm::platform::GenericClockController::initExternalCrystal(
// Enable external crystal.
SYSCTRL->XOSC32K.reg =
SYSCTRL_XOSC32K_STARTUP( 0x6u ) |
SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K;
SYSCTRL_XOSC32K_XTALEN |
SYSCTRL_XOSC32K_RUNSTDBY |
SYSCTRL_XOSC32K_EN32K;
// separate call, as described in chapter 15.6.3
SYSCTRL->XOSC32K.bit.ENABLE = 1;
while (!SYSCTRL->PCLKSR.bit.XOSC32KRDY and --waitCycles);
Expand Down Expand Up @@ -94,7 +96,7 @@ modm::platform::GenericClockController::initDFLL48MHz(
!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) ||
!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF));
// Wait for synchronization.
while (!SYSCTRL->PCLKSR.bit.DFLLRDY and --waitCycles)
while (!SYSCTRL->PCLKSR.bit.DFLLRDY and --waitCycles);
return waitCycles;
}

Expand Down
65 changes: 57 additions & 8 deletions src/modm/platform/clock/sam/gclk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,59 @@ ClockSource : uint32_t
DFLL48M = GCLK_GENCTRL_SRC_DFLL48M_Val
};

enum class
ClockGenerator : uint32_t
{
System = 0,
ExternalCrystal32K = 1,
ULP32K = 2,
Internal8M = 3,
};

enum class ClockPeripheral : uint32_t {
Dfll48 = GCLK_CLKCTRL_ID_DFLL48_Val,
Fdpll = GCLK_CLKCTRL_ID_FDPLL_Val,
Fdpll32K = GCLK_CLKCTRL_ID_FDPLL32K_Val,
Wdt = GCLK_CLKCTRL_ID_WDT_Val,
Rtc = GCLK_CLKCTRL_ID_RTC_Val,
Eic = GCLK_CLKCTRL_ID_EIC_Val,
Usb = GCLK_CLKCTRL_ID_USB_Val,
Evsys0 = GCLK_CLKCTRL_ID_EVSYS_0_Val,
Evsys1 = GCLK_CLKCTRL_ID_EVSYS_1_Val,
Evsys2 = GCLK_CLKCTRL_ID_EVSYS_2_Val,
Evsys3 = GCLK_CLKCTRL_ID_EVSYS_3_Val,
Evsys4 = GCLK_CLKCTRL_ID_EVSYS_4_Val,
Evsys5 = GCLK_CLKCTRL_ID_EVSYS_5_Val,
Evsys6 = GCLK_CLKCTRL_ID_EVSYS_6_Val,
Evsys7 = GCLK_CLKCTRL_ID_EVSYS_7_Val,
Evsys8 = GCLK_CLKCTRL_ID_EVSYS_8_Val,
Evsys9 = GCLK_CLKCTRL_ID_EVSYS_9_Val,
Evsys10 = GCLK_CLKCTRL_ID_EVSYS_10_Val,
Evsys11 = GCLK_CLKCTRL_ID_EVSYS_11_Val,
SercomXSlow = GCLK_CLKCTRL_ID_SERCOMX_SLOW_Val,
Sercom0 = GCLK_CLKCTRL_ID_SERCOM0_CORE_Val,
Sercom1 = GCLK_CLKCTRL_ID_SERCOM1_CORE_Val,
Sercom2 = GCLK_CLKCTRL_ID_SERCOM2_CORE_Val,
Sercom3 = GCLK_CLKCTRL_ID_SERCOM3_CORE_Val,
Sercom4 = GCLK_CLKCTRL_ID_SERCOM4_CORE_Val,
Sercom5 = GCLK_CLKCTRL_ID_SERCOM5_CORE_Val,
Tcc0 = GCLK_CLKCTRL_ID_TCC0_TCC1_Val,
Tcc1 = GCLK_CLKCTRL_ID_TCC0_TCC1_Val,
Tcc2 = GCLK_CLKCTRL_ID_TCC2_TC3_Val,
Tc3 = GCLK_CLKCTRL_ID_TCC2_TC3_Val,
Tc4 = GCLK_CLKCTRL_ID_TC4_TC5_Val,
Tc5 = GCLK_CLKCTRL_ID_TC4_TC5_Val,
Tc6 = GCLK_CLKCTRL_ID_TC6_TC7_Val,
Tc7 = GCLK_CLKCTRL_ID_TC6_TC7_Val,
Adc = GCLK_CLKCTRL_ID_ADC_Val,
AcDig = GCLK_CLKCTRL_ID_AC_DIG_Val,
AcAna = GCLK_CLKCTRL_ID_AC_ANA_Val,
Dac = GCLK_CLKCTRL_ID_DAC_Val,
Ptc = GCLK_CLKCTRL_ID_PTC_Val,
I2s0 = GCLK_CLKCTRL_ID_I2S_0_Val,
I2s1 = GCLK_CLKCTRL_ID_I2S_1_Val
};

/**
* Clock management
*
Expand Down Expand Up @@ -55,15 +108,11 @@ class GenericClockController
ClockSource source = ClockSource::OSC8M,
uint32_t waitCycles = 2048);

template< ClockPeripheral peripheral >
static void
connect(ClockGenerator clockGen);

private:
enum class
ClockGenerator : uint32_t
{
System = 0,
ExternalCrystal32K = 1,
ULP32K = 2,
Internal8M = 3,
};

enum class
ClockMux : uint32_t
Expand Down
10 changes: 10 additions & 0 deletions src/modm/platform/clock/sam/gclk_impl.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,15 @@ GenericClockController::setFlashLatency()
return Core_Hz;
}

template< ClockPeripheral peripheral >
void
GenericClockController::connect(ClockGenerator clockGen)
{
GCLK->CLKCTRL.reg =
GCLK_CLKCTRL_CLKEN |
GCLK_CLKCTRL_GEN(uint32_t(clockGen)) |
GCLK_CLKCTRL_ID(uint32_t(peripheral));
}

}

4 changes: 2 additions & 2 deletions src/modm/platform/uart/sam/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class Instance(Module):
module.description = "Instance {}".format(self.instance)

def prepare(self, module, options):
module.depends(":platform:uart")
return True

def build(self, env):
Expand Down Expand Up @@ -63,7 +62,8 @@ def prepare(module, options):
":architecture:uart",
":math:algorithm",
":cmsis:device",
":platform:gpio")
":platform:gpio",
":platform:gclk")

global props
drivers = options[":target"].get_all_drivers("sercom")
Expand Down
1 change: 1 addition & 0 deletions src/modm/platform/uart/sam/uart_hal.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <stdint.h>
#include "../device.hpp"
#include "uart_base.hpp"
#include "modm/platform/clock/gclk.hpp"
#include "modm/platform/core/peripherals.hpp"

namespace modm
Expand Down
5 changes: 1 addition & 4 deletions src/modm/platform/uart/sam/uart_hal_impl.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,7 @@ modm::platform::{{ name }}::initialize(Parity parity)
{
// Enable peripheral clock in power manager.
PM->APBCMASK.bit.{{ peripheral }}_ = true;
// Init clock using GCLK0 as source.
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_{{ peripheral }}_CORE |
GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN ;
GenericClockController::connect<ClockPeripheral::{{ sercom }}>(ClockGenerator::System);
while (GCLK->STATUS.bit.SYNCBUSY);
// Reset USART
reset();
Expand Down

0 comments on commit bad229a

Please sign in to comment.