1use crate::bscif;
15use kernel::utilities::registers::interfaces::{Readable, Writeable};
16use kernel::utilities::registers::{
17 register_bitfields, FieldValue, ReadOnly, ReadWrite, WriteOnly,
18};
19use kernel::utilities::StaticRef;
20
21pub enum Register {
22 IER = 0x00,
23 IDR = 0x04,
24 IMR = 0x08,
25 ISR = 0x0C,
26 ICR = 0x10,
27 PCLKSR = 0x14,
28 UNLOCK = 0x18,
29 CSCR = 0x1C,
30 OSCCTRL0 = 0x20,
31 PLL0 = 0x24,
32 DFLL0CONF = 0x28,
33 DFLL0MUL = 0x30,
34 DFLL0STEP = 0x34,
35 DFLL0SSG = 0x38,
36 RCFASTCFG = 0x48,
37 RC80MCR = 0x50,
38}
39
40#[allow(non_camel_case_types)]
41pub enum ClockSource {
42 RCSYS = 0,
43 OSC32K = 1,
44 DFLL0 = 2,
45 OSC0 = 3,
46 RC80M = 4,
47 RCFAST = 5,
48 RC1M = 6,
49 CLK_CPU = 7,
50 CLK_HSB = 8,
51 CLK_PBA = 9,
52 CLK_PBB = 10,
53 CLK_PBC = 11,
54 CLK_PBD = 12,
55 RC32K = 13,
56 RESERVED1 = 14,
57 CLK_1K = 15,
58 PLL0 = 16,
59 HRP = 17,
60 FP = 18,
61 GCLK_IN0 = 19,
62 GCLK_IN1 = 20,
63 GCLK11 = 21,
64}
65
66pub enum GenericClock {
67 GCLK0,
68 GCLK1,
69 GCLK2,
70 GCLK3,
71 GCLK4,
72 GCLK5,
73 GCLK6,
74 GCLK7,
75 GCLK8,
76 GCLK9,
77 GCLK10,
78 GCLK11,
79}
80
81#[repr(C)]
82struct ScifRegisters {
83 ier: WriteOnly<u32, Interrupt::Register>,
84 idr: WriteOnly<u32, Interrupt::Register>,
85 imr: ReadOnly<u32, Interrupt::Register>,
86 isr: ReadOnly<u32, Interrupt::Register>,
87 icr: WriteOnly<u32, Interrupt::Register>,
88 pclksr: ReadOnly<u32, Interrupt::Register>,
89 unlock: WriteOnly<u32, Unlock::Register>,
90 cscr: ReadWrite<u32>,
91 oscctrl0: ReadWrite<u32, Oscillator::Register>,
92 pll0: ReadWrite<u32, PllControl::Register>,
93 dfll0conf: ReadWrite<u32, Dfll::Register>,
94 dfll0val: ReadWrite<u32>,
95 dfll0mul: ReadWrite<u32>,
96 dfll0step: ReadWrite<u32, DfllStep::Register>,
97 dfll0ssg: ReadWrite<u32>,
98 dfll0ratio: ReadOnly<u32>,
99 dfll0sync: WriteOnly<u32>,
100 rccr: ReadWrite<u32>,
101 rcfastcfg: ReadWrite<u32, Rcfast::Register>,
102 rcfastsr: ReadOnly<u32>,
103 rc80mcr: ReadWrite<u32, Rc80m::Register>,
104 _reserved0: [u32; 4],
105 hrpcr: ReadWrite<u32>,
106 fpcr: ReadWrite<u32>,
107 fpmul: ReadWrite<u32>,
108 fpdiv: ReadWrite<u32>,
109 gcctrl0: ReadWrite<u32, GenericClockControl::Register>,
110 gcctrl1: ReadWrite<u32, GenericClockControl::Register>,
111 gcctrl2: ReadWrite<u32, GenericClockControl::Register>,
112 gcctrl3: ReadWrite<u32, GenericClockControl::Register>,
113 gcctrl4: ReadWrite<u32, GenericClockControl::Register>,
114 gcctrl5: ReadWrite<u32, GenericClockControl::Register>,
115 gcctrl6: ReadWrite<u32, GenericClockControl::Register>,
116 gcctrl7: ReadWrite<u32, GenericClockControl::Register>,
117 gcctrl8: ReadWrite<u32, GenericClockControl::Register>,
118 gcctrl9: ReadWrite<u32, GenericClockControl::Register>,
119 gcctrl10: ReadWrite<u32, GenericClockControl::Register>,
120 gcctrl11: ReadWrite<u32, GenericClockControl::Register>,
121 }
123
124register_bitfields![u32,
125 Interrupt [
126 RCFASTLOCKLOST 14,
127 RCFASTLOCK 13,
128 PLL0LOCKLOST 7,
129 PLL0LOCK 6,
130 DFLL0RCS 4,
131 DFLL0RDY 3,
132 DFLL0LOCKF 2,
133 DFLL0LOCKC 1,
134 OSC0RDY 0
135 ],
136 Unlock [
137 KEY OFFSET(24) NUMBITS(8) [],
138 ADDR OFFSET(0) NUMBITS(10) []
139 ],
140 Oscillator [
141 OSCEN OFFSET(16) NUMBITS(1) [],
142 STARTUP OFFSET(8) NUMBITS(4) [
143 Cycles64 = 1,
144 Cycles1024 = 14
145 ],
146 AGC OFFSET(3) NUMBITS(1) [],
147 GAIN OFFSET(1) NUMBITS(2) [
148 G0 = 0, G1 = 1, G2 = 2, G3 = 3, G4 = 4
149 ],
150 MODE OFFSET(0) NUMBITS(1) [
151 External = 0,
152 Crystal = 1
153 ]
154 ],
155 Dfll [
156 CALIB OFFSET(24) NUMBITS(4) [],
157 FCD OFFSET(23) NUMBITS(1) [],
158 RANGE OFFSET(16) NUMBITS(2) [],
159 QLDIS OFFSET(6) NUMBITS(1) [],
160 CCDIS OFFSET(5) NUMBITS(1) [],
161 LLAW OFFSET(3) NUMBITS(1) [],
162 STABLE OFFSET(2) NUMBITS(1) [],
163 MODE OFFSET(1) NUMBITS(1) [
164 OpenLoop = 0,
165 ClosedLoop = 1
166 ],
167 EN OFFSET(0) NUMBITS(1) []
168 ],
169 DfllStep [
170 CSTEP OFFSET(16) NUMBITS(5) [],
171 FSTEP OFFSET(0) NUMBITS(8) []
172 ],
173 GenericClockControl [
174 DIV OFFSET(16) NUMBITS(16) [],
175 OCSEL OFFSET(8) NUMBITS(5) [
176 ],
178 DIVEN OFFSET(1) NUMBITS(1) [],
179 CEN OFFSET(0) NUMBITS(1) []
180 ],
181 PllControl [
182 PLLCOUNT OFFSET(24) NUMBITS(6) [
183 Max = 0x3F
184 ],
185 PLLMUL OFFSET(16) NUMBITS(4) [],
186 PLLDIV OFFSET(8) NUMBITS(4) [],
187 PLLOSC OFFSET(1) NUMBITS(2) [
188 OSC0 = 0,
189 GCLK9 = 1
190 ],
191 PLLOPT OFFSET(3) NUMBITS(3) [
192 DivideBy2 = 2
193 ],
196 PLLEN OFFSET(0) NUMBITS(1) []
197 ],
198 Rcfast [
199 CALIB OFFSET(16) NUMBITS(7) [],
200 LOCKMARGIN OFFSET(12) NUMBITS(4) [],
201 FRANGE OFFSET(8) NUMBITS(2) [
202 Range4MHz = 0,
203 Range8MHz = 1,
204 Range12MHz = 2
205 ],
206 FCD OFFSET(7) NUMBITS(1) [],
207 NBPERIODS OFFSET(4) NUMBITS(3) [],
208 JITMODE OFFSET(2) NUMBITS(1) [],
209 TUNEEN OFFSET(1) NUMBITS(1) [],
210 EN OFFSET(0) NUMBITS(1) []
211 ],
212 Rc80m [
213 EN OFFSET(0) NUMBITS(1) []
214 ]
215];
216
217const SCIF: StaticRef<ScifRegisters> =
218 unsafe { StaticRef::new(0x400E0800 as *const ScifRegisters) };
219
220#[repr(usize)]
221pub enum Clock {
222 ClockRCSys = 0,
223 ClockOsc32 = 1,
224 ClockAPB = 2,
225 ClockGclk2 = 3,
226 Clock1K = 4,
227}
228
229pub fn unlock(register: Register) {
230 SCIF.unlock
231 .write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(register as u32));
232}
233
234pub fn oscillator_enable(internal: bool) {
235 let mode = if internal {
236 Oscillator::MODE::Crystal
237 } else {
238 Oscillator::MODE::External
239 };
240 unlock(Register::OSCCTRL0);
241 SCIF.oscctrl0.write(Oscillator::OSCEN::SET + mode);
242}
243
244pub fn oscillator_disable() {
245 unlock(Register::OSCCTRL0);
246 SCIF.oscctrl0.write(Oscillator::OSCEN::CLEAR);
247}
248
249pub fn setup_dfll_rc32k_48mhz() {
250 fn wait_dfll0_ready() {
251 while !SCIF.pclksr.is_set(Interrupt::DFLL0RDY) {}
252 }
253
254 if !SCIF.dfll0conf.is_set(Dfll::EN) || !SCIF.pclksr.is_set(Interrupt::DFLL0LOCKF) {
256 if !bscif::rc32k_enabled() {
258 bscif::enable_rc32k();
259 }
260
261 SCIF.dfll0sync.set(0x01);
268 wait_dfll0_ready();
269
270 let scif_dfll0conf = SCIF.dfll0conf.get();
273 let new_config_fields = Dfll::EN::SET + Dfll::MODE::ClosedLoop + Dfll::RANGE.val(2);
275 let scif_dfll0conf_new = new_config_fields.modify(scif_dfll0conf);
278
279 SCIF.gcctrl0.write(
281 GenericClockControl::CEN::SET
282 + GenericClockControl::OCSEL.val(ClockSource::RC32K as u32)
283 + GenericClockControl::DIVEN::CLEAR
284 + GenericClockControl::DIV.val(0),
285 );
286
287 unlock(Register::DFLL0CONF);
291 SCIF.dfll0conf.write(Dfll::EN::SET);
292 wait_dfll0_ready();
293
294 unlock(Register::DFLL0STEP);
296 SCIF.dfll0step
297 .write(DfllStep::FSTEP.val(4) + DfllStep::CSTEP.val(4));
298 wait_dfll0_ready();
299
300 unlock(Register::DFLL0MUL);
302 SCIF.dfll0mul.set(1464);
304 wait_dfll0_ready();
305
306 unlock(Register::DFLL0SSG);
308 SCIF.dfll0ssg.set(0);
310 wait_dfll0_ready();
311
312 unlock(Register::DFLL0CONF);
314 SCIF.dfll0conf.set(scif_dfll0conf_new);
316
317 while !SCIF.pclksr.is_set(Interrupt::DFLL0LOCKF) {}
319 }
320}
321
322pub unsafe fn disable_dfll_rc32k() {
323 SCIF.dfll0sync.set(0x01);
325 while !SCIF.pclksr.is_set(Interrupt::DFLL0RDY) {}
326
327 let dfll0conf = SCIF.dfll0conf.extract();
329 unlock(Register::DFLL0CONF);
330 SCIF.dfll0conf.modify_no_read(dfll0conf, Dfll::EN::CLEAR);
331
332 generic_clock_disable(GenericClock::GCLK0);
334
335 while SCIF.dfll0conf.is_set(Dfll::EN) {}
337}
338
339pub unsafe fn setup_osc_16mhz_fast_startup() {
340 unlock(Register::OSCCTRL0);
342 SCIF.oscctrl0.write(
343 Oscillator::OSCEN::SET
344 + Oscillator::STARTUP::Cycles64
345 + Oscillator::GAIN::G4
346 + Oscillator::MODE::Crystal,
347 );
348
349 while !SCIF.pclksr.is_set(Interrupt::OSC0RDY) {}
351}
352
353pub unsafe fn setup_osc_16mhz_slow_startup() {
354 unlock(Register::OSCCTRL0);
356 SCIF.oscctrl0.write(
357 Oscillator::OSCEN::SET
358 + Oscillator::STARTUP::Cycles1024
359 + Oscillator::GAIN::G4
360 + Oscillator::MODE::Crystal,
361 );
362
363 while !SCIF.pclksr.is_set(Interrupt::OSC0RDY) {}
365}
366
367pub unsafe fn disable_osc_16mhz() {
368 let oscctrl0 = SCIF.oscctrl0.extract();
370 unlock(Register::OSCCTRL0);
371 SCIF.oscctrl0
372 .modify_no_read(oscctrl0, Oscillator::OSCEN::CLEAR);
373
374 while SCIF.oscctrl0.is_set(Oscillator::OSCEN) {}
376}
377
378pub unsafe fn setup_pll_osc_48mhz() {
379 unlock(Register::PLL0);
382 SCIF.pll0.write(
383 PllControl::PLLCOUNT::Max
384 + PllControl::PLLMUL.val(5)
385 + PllControl::PLLDIV.val(1)
386 + PllControl::PLLOPT::DivideBy2
387 + PllControl::PLLOSC::OSC0
388 + PllControl::PLLEN::SET,
389 );
390
391 while !SCIF.pclksr.is_set(Interrupt::PLL0LOCK) {}
393}
394
395pub unsafe fn disable_pll() {
396 let pll0 = SCIF.pll0.extract();
398 unlock(Register::PLL0);
399 SCIF.pll0.modify_no_read(pll0, PllControl::PLLEN::CLEAR);
400
401 while SCIF.pll0.is_set(PllControl::PLLEN) {}
403}
404
405pub unsafe fn setup_rc_80mhz() {
406 let rc80mcr = SCIF.rc80mcr.extract();
408 unlock(Register::RC80MCR);
409 SCIF.rc80mcr.modify_no_read(rc80mcr, Rc80m::EN::SET);
410
411 while !SCIF.rc80mcr.is_set(Rc80m::EN) {}
413}
414
415pub unsafe fn disable_rc_80mhz() {
416 let rc80mcr = SCIF.rc80mcr.extract();
418 unlock(Register::RC80MCR);
419 SCIF.rc80mcr.modify_no_read(rc80mcr, Rc80m::EN::CLEAR);
420
421 while SCIF.rc80mcr.is_set(Rc80m::EN) {}
423}
424
425pub unsafe fn setup_rcfast_4mhz() {
426 let rcfastcfg = SCIF.rcfastcfg.extract();
428 unlock(Register::RCFASTCFG);
429 SCIF.rcfastcfg.modify_no_read(
430 rcfastcfg,
431 Rcfast::FRANGE::Range4MHz + Rcfast::TUNEEN::CLEAR + Rcfast::EN::SET,
432 );
433
434 while !SCIF.rcfastcfg.is_set(Rcfast::EN) {}
436}
437
438pub unsafe fn setup_rcfast_8mhz() {
439 let rcfastcfg = SCIF.rcfastcfg.extract();
441 unlock(Register::RCFASTCFG);
442 SCIF.rcfastcfg.modify_no_read(
443 rcfastcfg,
444 Rcfast::FRANGE::Range8MHz + Rcfast::TUNEEN::CLEAR + Rcfast::EN::SET,
445 );
446
447 while !SCIF.rcfastcfg.is_set(Rcfast::EN) {}
449}
450
451pub unsafe fn setup_rcfast_12mhz() {
452 let rcfastcfg = SCIF.rcfastcfg.extract();
454 unlock(Register::RCFASTCFG);
455 SCIF.rcfastcfg.modify_no_read(
456 rcfastcfg,
457 Rcfast::FRANGE::Range12MHz + Rcfast::TUNEEN::CLEAR + Rcfast::EN::SET,
458 );
459
460 while !SCIF.rcfastcfg.is_set(Rcfast::EN) {}
462}
463
464pub unsafe fn disable_rcfast() {
465 let rcfastcfg = SCIF.rcfastcfg.extract();
467 unlock(Register::RCFASTCFG);
468 SCIF.rcfastcfg.modify_no_read(rcfastcfg, Rcfast::EN::CLEAR);
469
470 while SCIF.rcfastcfg.is_set(Rcfast::EN) {}
472}
473
474pub fn generic_clock_disable(clock: GenericClock) {
475 generic_clock_control_write(clock, GenericClockControl::CEN::CLEAR);
476}
477
478pub fn generic_clock_enable(clock: GenericClock, source: ClockSource) {
479 generic_clock_control_write(
480 clock,
481 GenericClockControl::OCSEL.val(source as u32) + GenericClockControl::CEN::SET,
482 );
483}
484
485pub fn generic_clock_enable_divided(clock: GenericClock, source: ClockSource, divider: u16) {
488 generic_clock_control_write(
489 clock,
490 GenericClockControl::OCSEL.val(source as u32)
491 + GenericClockControl::DIVEN::SET
492 + GenericClockControl::DIV.val(divider as u32)
493 + GenericClockControl::CEN::SET,
494 );
495}
496
497fn generic_clock_control_write(
498 clock: GenericClock,
499 val: FieldValue<u32, GenericClockControl::Register>,
500) {
501 match clock {
502 GenericClock::GCLK0 => SCIF.gcctrl0.write(val),
503 GenericClock::GCLK1 => SCIF.gcctrl1.write(val),
504 GenericClock::GCLK2 => SCIF.gcctrl2.write(val),
505 GenericClock::GCLK3 => SCIF.gcctrl3.write(val),
506 GenericClock::GCLK4 => SCIF.gcctrl4.write(val),
507 GenericClock::GCLK5 => SCIF.gcctrl5.write(val),
508 GenericClock::GCLK6 => SCIF.gcctrl6.write(val),
509 GenericClock::GCLK7 => SCIF.gcctrl7.write(val),
510 GenericClock::GCLK8 => SCIF.gcctrl8.write(val),
511 GenericClock::GCLK9 => SCIF.gcctrl9.write(val),
512 GenericClock::GCLK10 => SCIF.gcctrl10.write(val),
513 GenericClock::GCLK11 => SCIF.gcctrl11.write(val),
514 }
515}