Skip to content

Commit 590d2b6

Browse files
chris-durandrleh
andcommitted
[sam] Add PCK configuration to PMC driver and fix enableUPll()
Co-authored-by: Raphael Lehmann <[email protected]>
1 parent ad6103f commit 590d2b6

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

src/modm/platform/clock/sam_pmc/clockgen.cpp.in

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// ----------------------------------------------------------------------------
1212

1313
#include "clockgen.hpp"
14+
#include <algorithm>
1415
#include <cmath>
1516

1617
// CMSIS Core compliance
@@ -135,4 +136,31 @@ ClockGen::pllBFrequency()
135136
}
136137
%% endif
137138

139+
%% if target.family == "e7x/s7x/v7x"
140+
void
141+
ClockGen::enablePck(Pck clock)
142+
{
143+
PMC->PMC_SCER = 1u << (PMC_SCER_PCK0_Pos + static_cast<uint8_t>(clock));
144+
145+
int_fast16_t deadlockPreventer = 10'000; // max ~10ms
146+
const uint8_t pckrdyPos = PMC_SR_PCKRDY0_Pos + static_cast<uint8_t>(clock);
147+
while (((PMC->PMC_SR & (1 << pckrdyPos)) == 0) and (deadlockPreventer-- > 0))
148+
modm::delay(std::chrono::microseconds{1});
149+
modm_assert(deadlockPreventer > 0, "clockgen.pck.enable", "timeout expired");
150+
}
151+
152+
void
153+
ClockGen::disablePck(Pck clock)
154+
{
155+
PMC->PMC_SCDR = 1u << (PMC_SCDR_PCK0_Pos + static_cast<uint8_t>(clock));
156+
}
157+
158+
void
159+
ClockGen::configurePck(Pck clock, PckSource source, uint16_t divider)
160+
{
161+
PMC->PMC_PCK[uint8_t(clock)] = PMC_PCK_CSS(uint8_t(source)) |
162+
PMC_PCK_PRES(std::clamp<uint16_t>(divider, 1, 256) - 1);
163+
}
164+
%% endif
165+
138166
} // namespace modm::platform

src/modm/platform/clock/sam_pmc/clockgen.hpp.in

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,32 @@ UtmiRefClk : uint32_t
228228
%% endif
229229

230230
static constexpr uint32_t SlowClkFreqHz = 32'768;
231+
232+
%% if target.family == "e7x/s7x/v7x"
233+
/// Programmable clocks
234+
enum class Pck
235+
{
236+
Pck0 = 0,
237+
Pck1 = 1,
238+
Pck2 = 2,
239+
Pck3 = 3,
240+
Pck4 = 4,
241+
Pck5 = 5,
242+
Pck6 = 6,
243+
Pck7 = 7
244+
};
245+
246+
/// Programmable clock sources
247+
enum class PckSource
248+
{
249+
SlowClock = PMC_PCK_CSS_SLOW_CLK,
250+
MainClock = PMC_PCK_CSS_MAIN_CLK,
251+
PllA = PMC_PCK_CSS_PLLA_CLK,
252+
UPll = PMC_PCK_CSS_UPLL_CLK,
253+
Mck = PMC_PCK_CSS_MCK
254+
};
255+
%% endif
256+
231257
/// @}
232258

233259
/**
@@ -295,6 +321,20 @@ public:
295321
template<UtmiRefClk refclk>
296322
static void
297323
enableUPll(uint32_t wait_cycles = 50);
324+
325+
static void
326+
enablePck(Pck clock);
327+
328+
static void
329+
disablePck(Pck clock);
330+
331+
/**
332+
* Configure programmable clock.
333+
* @warning The clock must be disabled when changing configuration.
334+
* @param divider clock divider (1-256)
335+
*/
336+
static void
337+
configurePck(Pck clock, PckSource source, uint16_t divider);
298338
%% endif
299339

300340
template <MasterClkSource src, MasterClkPrescaler pres,

src/modm/platform/clock/sam_pmc/clockgen_impl.hpp.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ template<UtmiRefClk refclk>
169169
void
170170
ClockGen::enableUPll(uint32_t wait_cycles)
171171
{
172-
REG_UTMI_CKTRIM = refclk;
172+
UTMI->UTMI_CKTRIM = static_cast<uint32_t>(refclk);
173173
PMC->CKGR_UCKR =
174174
CKGR_UCKR_UPLLCOUNT(wait_cycles) |
175175
CKGR_UCKR_UPLLEN;

0 commit comments

Comments
 (0)