1use kernel::utilities::registers::interfaces::{Readable, Writeable};
8use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
9use kernel::utilities::StaticRef;
10
11#[repr(C)]
12struct BscifRegisters {
13    ier: WriteOnly<u32, Interrupt::Register>,
14    idr: WriteOnly<u32, Interrupt::Register>,
15    imr: ReadOnly<u32, Interrupt::Register>,
16    isr: ReadOnly<u32, Interrupt::Register>,
17    icr: WriteOnly<u32, Interrupt::Register>,
18    pclksr: ReadOnly<u32, PowerClocksStatus::Register>,
19    unlock: WriteOnly<u32, Unlock::Register>,
20    _reserved0: u32,
21    oscctrl32: ReadWrite<u32, Oscillator32Control::Register>,
22    rc32kcr: ReadWrite<u32, RC32Control::Register>,
23    rc32ktune: ReadWrite<u32, RC32kTuning::Register>,
24    bod33ctrl: ReadWrite<u32, BodControl::Register>,
25    bod33level: ReadWrite<u32, BodLevel::Register>,
26    bod33sampling: ReadWrite<u32, BodSamplingControl::Register>,
27    bod18ctrl: ReadWrite<u32, BodControl::Register>,
28    bot18level: ReadWrite<u32, BodLevel::Register>,
29    bod18sampling: ReadWrite<u32, BodSamplingControl::Register>,
30    vregcr: ReadWrite<u32, VoltageRegulatorConfig::Register>,
31    _reserved1: [u32; 4],
32    rc1mcr: ReadWrite<u32, RC1MClockConfig::Register>,
33    _reserved2: u32,
34    bgctrl: ReadWrite<u32, BandgapControl::Register>,
35    bgsr: ReadOnly<u32, BandgapStatus::Register>,
36    _reserved3: [u32; 4],
37    br0: ReadOnly<u32, Backup::Register>,
38    br1: ReadOnly<u32, Backup::Register>,
39    br2: ReadOnly<u32, Backup::Register>,
40    br3: ReadOnly<u32, Backup::Register>,
41}
42
43register_bitfields![u32,
44    Interrupt [
45        LPBGRDY 12,
46        VREGOK 10,
47        SSWRDY 9,
48        BOD18SYNRDY 8,
49        BOD33SYNRDY 7,
50        BOD18DET 6,
51        BOD33DET 5,
52        RC32SAT 4,
53        RC32KREFE 3,
54        RC32KLOCK 2,
55        RC32KRDY 1,
56        OSC32RDY 0
57    ],
58
59    PowerClocksStatus [
60        LPBGRDY 12,
61        RC1MRDY 11,
62        VREGOK 10,
63        SSWRDY 9,
64        BOD18SYNRDY 8,
65        BOD33SYNRDY 7,
66        BOD18DET 6,
67        BOD33DET 5,
68        RC32SAT 4,
69        RC32KREFE 3,
70        RC32KLOCK 2,
71        RC32KRDY 1,
72        OSC32RDY 0
73    ],
74
75    Unlock [
76        KEY OFFSET(24) NUMBITS(8) [],
78        ADDR OFFSET(0) NUMBITS(10) []
80    ],
81
82    Oscillator32Control [
83        STARTUP OFFSET(16) NUMBITS(3) [
85            Time0ms = 0,
86            Time1ms = 1,
87            Time72ms = 2,
88            Time143ms = 3,
89            Time570ms = 4,
90            Time1100ms = 5,
91            Time2300ms = 6,
92            Time4600ms = 7
93        ],
94        SELCURR OFFSET(12) NUMBITS(4) [
96            CrystalCurrent50nA = 0,
97            CrystalCurrent75nA = 1,
98            CrystalCurrent100nA = 2,
99            CrystalCurrent125nA = 3,
100            CrystalCurrent150nA = 4,
101            CrystalCurrent175nA = 5,
102            CrystalCurrent200nA = 6,
103            CrystalCurrent225nA = 7,
104            CrystalCurrent250nA = 8,
105            CrystalCurrent275nA = 9,
106            CrystalCurrent300nA = 10,
107            CrystalCurrent325nA = 11,
108            CrystalCurrent350nA = 12,
109            CrystalCurrent375nA = 13,
110            CrystalCurrent400nA = 14,
111            CrystalCurrent425nA = 15
112        ],
113        MODE OFFSET(8) NUMBITS(3) [
115            ExternalClock = 0,
116            CrystalMode = 1,
117            AmplitudeCrystalMode = 3,
118            CrystalHighCurrentMode = 4,
119            AmplitudeCrystalHighCurrentMode = 5
120        ],
121        EN1K OFFSET(3) NUMBITS(1) [
123            OutputDisable = 0,
124            OutputEnable = 1
125        ],
126        EN32K OFFSET(2) NUMBITS(1) [
128            OutputDisable = 0,
129            OutputEnable = 1
130        ],
131        OSC32EN OFFSET(0) NUMBITS(1) [
133            OscillatorDisable = 0,
134            OscillatorEnable = 1
135        ]
136    ],
137
138    RC32Control [
139        FCD OFFSET(7) NUMBITS(1) [
141            ReloadCalib = 0,
142            KeepCalib = 1
143        ],
144        REF OFFSET(5) NUMBITS(1) [
146            Osc32kReference = 0,
147            GclkReference = 1
148        ],
149        MODE OFFSET(4) NUMBITS(1) [
151            OpenLoop = 0,
152            ClosedLoop = 1
153        ],
154        EN1K OFFSET(3) NUMBITS(1) [
156            OutputDisable = 0,
157            OutputEnable = 1
158        ],
159        EN32K OFFSET(2) NUMBITS(1) [
161            OutputDisable = 0,
162            OutputEnable = 1
163        ],
164        TCEN OFFSET(1) NUMBITS(1) [
166            NotTempCompensated = 0,
167            TempCompensated = 1
168        ],
169        EN OFFSET(0) NUMBITS(1) [
171            GclkSourceDisable = 0,
172            GclkSourceEnable = 1
173        ]
174    ],
175
176    RC32kTuning [
177        COARSE OFFSET(16) NUMBITS(7) [],
179        FINE OFFSET(0) NUMBITS(6) []
181    ],
182
183    BodControl [
184        SFV OFFSET(31) NUMBITS(1) [
186            NotLocked = 0,
187            Locked = 1
188        ],
189        FCD OFFSET(30) NUMBITS(1) [
191            RedoFlashCalibration = 0,
192            DoNotRedoFlashCalibration = 1
193        ],
194        MODE OFFSET(16) NUMBITS(1) [
196            Continuous = 0,
197            Sampling = 1
198        ],
199        ACTION OFFSET(8) NUMBITS(2) [
201            No = 0,
202            Reset = 1,
203            Interrupt = 2
204        ],
205        HYST OFFSET(1) NUMBITS(1) [
207            No = 0,
208            Enabled = 1
209        ],
210        EN OFFSET(0) NUMBITS(1) [
212            Disabled = 0,
213            Enabled = 1
214        ]
215    ],
216
217    BodSamplingControl [
218        PSEL OFFSET(8) NUMBITS(4) [],
220        CSSEL OFFSET(1) NUMBITS(1) [
222            Rcsys = 0,
223            Ck32k = 1
224        ],
225        CEN OFFSET(0) NUMBITS(1) [
227            Stop = 0,
228            Start = 1
229        ]
230    ],
231
232    BodLevel [
233        RANGE OFFSET(31) NUMBITS(1) [
235            Standard = 0,
236            Low = 1
237        ],
238        VAL OFFSET(0) NUMBITS(6) []
240    ],
241
242    VoltageRegulatorConfig [
243        SFV OFFSET(31) NUMBITS(1) [
245            ReadWrite = 0,
246            ReadOnly = 1
247        ],
248        SSWEVT OFFSET(10) NUMBITS(1) [
250            NotPeripheralControl = 0,
251            PeripheralControl = 1
252        ],
253        SSW OFFSET(9) NUMBITS(1) [
255            NotStop = 0,
256            Stop = 1
257        ],
258        SSG OFFSET(8) NUMBITS(1) [
260            SpreadSpectrumDisable = 0,
261            SpreadSpectrumEnable = 1
262        ],
263        DIS OFFSET(0) NUMBITS(1) [
265            VoltageRegulatorDisable = 0,
266            VoltageRegulatorEnable = 1
267        ]
268    ],
269
270    RC1MClockConfig [
271        CLKCAL OFFSET(8) NUMBITS(5) [],
273        FCD OFFSET(7) NUMBITS(1) [
275            RedoFlashCalibration = 0,
276            DoNotRedoFlashCalibration = 1
277        ],
278        CLKOEN OFFSET(0) NUMBITS(1) [
280            NotOutput = 0,
281            Output = 1
282        ]
283    ],
284
285    BandgapControl [
286        ADCISEL OFFSET(0) NUMBITS(2) [
288            NoConnection = 0,
289            ADCVoltageReference = 2
290        ]
291    ],
292
293    BandgapStatus [
294        VREF OFFSET(18) NUMBITS(2) [
296            BothUsed = 0,
297            BandgapUsed = 1,
298            LowPowerBandgapUsed = 2,
299            NeitherUsed = 3
300        ],
301        LPBGRDY OFFSET(17) NUMBITS(1) [
303            NotReady = 0,
304            Ready = 1
305        ],
306        BGRDY OFFSET(16) NUMBITS(1) [
308            NotReady = 0,
309            Ready = 1
310        ],
311        BGBUFRDY OFFSET(0) NUMBITS(8) [
313            NotReady = 0,
314            Ready = 1
315        ]
316    ],
317
318    Backup [
319        DATA OFFSET(0) NUMBITS(32) []
320    ]
321];
322
323const BSCIF: StaticRef<BscifRegisters> =
324    unsafe { StaticRef::new(0x400F0400 as *const BscifRegisters) };
325
326pub fn enable_rc32k() {
328    let rc32kcr = BSCIF.rc32kcr.extract();
329    BSCIF
331        .unlock
332        .write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x24));
333    BSCIF.rc32kcr.modify_no_read(
337        rc32kcr,
338        RC32Control::EN32K::OutputEnable
339            + RC32Control::TCEN::TempCompensated
340            + RC32Control::EN::GclkSourceEnable,
341    );
342    while !BSCIF.rc32kcr.is_set(RC32Control::EN) {}
344
345    BSCIF
349        .unlock
350        .write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x28));
351    BSCIF
353        .rc32ktune
354        .write(RC32kTuning::COARSE.val(0x1d) + RC32kTuning::FINE.val(0x15));
355}
356
357pub fn rc32k_enabled() -> bool {
358    BSCIF.rc32kcr.is_set(RC32Control::EN)
359}
360
361pub fn setup_rc_1mhz() {
362    let rc1mcr = BSCIF.rc1mcr.extract();
363    BSCIF
365        .unlock
366        .write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x58));
367    BSCIF
369        .rc1mcr
370        .modify_no_read(rc1mcr, RC1MClockConfig::CLKOEN::Output);
371
372    while !BSCIF.rc1mcr.is_set(RC1MClockConfig::CLKOEN) {}
374}
375
376pub unsafe fn disable_rc_1mhz() {
377    let rc1mcr = BSCIF.rc1mcr.extract();
378    BSCIF
380        .unlock
381        .write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x58));
382    BSCIF
384        .rc1mcr
385        .modify_no_read(rc1mcr, RC1MClockConfig::CLKOEN::NotOutput);
386
387    while BSCIF.rc1mcr.is_set(RC1MClockConfig::CLKOEN) {}
389}