File tree Expand file tree Collapse file tree 3 files changed +69
-1
lines changed
src/modm/platform/clock/sam_pmc Expand file tree Collapse file tree 3 files changed +69
-1
lines changed Original file line number Diff line number Diff line change 11
11
// ----------------------------------------------------------------------------
12
12
13
13
#include "clockgen.hpp"
14
+ #include <algorithm>
14
15
#include <cmath>
15
16
16
17
// CMSIS Core compliance
@@ -135,4 +136,31 @@ ClockGen::pllBFrequency()
135
136
}
136
137
%% endif
137
138
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
+
138
166
} // namespace modm::platform
Original file line number Diff line number Diff line change @@ -228,6 +228,32 @@ UtmiRefClk : uint32_t
228
228
%% endif
229
229
230
230
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
+
231
257
/// @}
232
258
233
259
/**
@@ -295,6 +321,20 @@ public:
295
321
template<UtmiRefClk refclk>
296
322
static void
297
323
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);
298
338
%% endif
299
339
300
340
template <MasterClkSource src, MasterClkPrescaler pres,
Original file line number Diff line number Diff line change @@ -169,7 +169,7 @@ template<UtmiRefClk refclk>
169
169
void
170
170
ClockGen::enableUPll(uint32_t wait_cycles)
171
171
{
172
- REG_UTMI_CKTRIM = refclk;
172
+ UTMI->UTMI_CKTRIM = static_cast<uint32_t>( refclk) ;
173
173
PMC->CKGR_UCKR =
174
174
CKGR_UCKR_UPLLCOUNT(wait_cycles) |
175
175
CKGR_UCKR_UPLLEN;
You can’t perform that action at this time.
0 commit comments