apollo3/
clkgen.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Power Reset Clock Interrupt controller driver.
6
7use kernel::utilities::registers::interfaces::{ReadWriteable, Writeable};
8use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite};
9use kernel::utilities::StaticRef;
10
11const CLKGEN_BASE: StaticRef<ClkGenRegisters> =
12    unsafe { StaticRef::new(0x4000_4000 as *const ClkGenRegisters) };
13
14register_structs! {
15    pub ClkGenRegisters {
16        (0x00 => calxt: ReadWrite<u32>),
17        (0x04 => calrc: ReadWrite<u32>),
18        (0x08 => acalctr: ReadWrite<u32>),
19        (0x0c => octrl: ReadWrite<u32>),
20        (0x10 => clkout: ReadWrite<u32>),
21        (0x14 => clkkey: ReadWrite<u32>),
22        (0x18 => cctrl: ReadWrite<u32>),
23        (0x1c => status: ReadWrite<u32>),
24        (0x20 => hfadj: ReadWrite<u32>),
25        (0x24 => _reserved0),
26        (0x28 => clockenstat: ReadWrite<u32>),
27        (0x2c => clocken2stat: ReadWrite<u32>),
28        (0x30 => clocken3stat: ReadWrite<u32>),
29        (0x34 => freqctrl: ReadWrite<u32>),
30        (0x38 => _reserved1),
31        (0x3c => blebucktonadj: ReadWrite<u32, BLEBUCKTONADJ::Register>),
32        (0x40 => _reserved2),
33        (0x100 => intrpten: ReadWrite<u32>),
34        (0x104 => intrptstat: ReadWrite<u32>),
35        (0x108 => intrptclr: ReadWrite<u32>),
36        (0x10c => intrptset: ReadWrite<u32>),
37        (0x110 => @END),
38    }
39}
40
41register_bitfields![u32,
42    BLEBUCKTONADJ [
43        TONLOWTHRESHOLD OFFSET(0) NUMBITS(10) [],
44        TONHIGHTHRESHOLD OFFSET(10) NUMBITS(10) [],
45        TONADJUSTPERIOD OFFSET(20) NUMBITS(2) [],
46        TONADJUSTEN OFFSET(22) NUMBITS(1) [
47            DISABLE = 0x0,
48            ENALBE = 0x1
49        ],
50        ZEROLENDETECTTRIM OFFSET(23) NUMBITS(4) [],
51        ZEROLENDETECTEN OFFSET(23) NUMBITS(4) []
52    ]
53];
54
55pub enum ClockFrequency {
56    Freq48MHz,
57}
58
59pub struct ClkGen {
60    registers: StaticRef<ClkGenRegisters>,
61}
62
63impl ClkGen {
64    pub const fn new() -> ClkGen {
65        ClkGen {
66            registers: CLKGEN_BASE,
67        }
68    }
69
70    pub fn set_clock_frequency(&self, frequency: ClockFrequency) {
71        let regs = self.registers;
72
73        match frequency {
74            ClockFrequency::Freq48MHz => {
75                // Magic numbers from the HAL
76                regs.clkkey.set(71);
77                regs.cctrl.set(0);
78                regs.clkkey.set(0);
79            }
80        }
81    }
82
83    pub fn enable_ble(&self) {
84        let regs = self.registers;
85
86        regs.blebucktonadj
87            .modify(BLEBUCKTONADJ::TONADJUSTEN::DISABLE);
88    }
89}