use kernel::utilities::registers::interfaces::{Readable, Writeable};
use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
use kernel::utilities::StaticRef;
#[repr(C)]
struct BscifRegisters {
ier: WriteOnly<u32, Interrupt::Register>,
idr: WriteOnly<u32, Interrupt::Register>,
imr: ReadOnly<u32, Interrupt::Register>,
isr: ReadOnly<u32, Interrupt::Register>,
icr: WriteOnly<u32, Interrupt::Register>,
pclksr: ReadOnly<u32, PowerClocksStatus::Register>,
unlock: WriteOnly<u32, Unlock::Register>,
_reserved0: u32,
oscctrl32: ReadWrite<u32, Oscillator32Control::Register>,
rc32kcr: ReadWrite<u32, RC32Control::Register>,
rc32ktune: ReadWrite<u32, RC32kTuning::Register>,
bod33ctrl: ReadWrite<u32, BodControl::Register>,
bod33level: ReadWrite<u32, BodLevel::Register>,
bod33sampling: ReadWrite<u32, BodSamplingControl::Register>,
bod18ctrl: ReadWrite<u32, BodControl::Register>,
bot18level: ReadWrite<u32, BodLevel::Register>,
bod18sampling: ReadWrite<u32, BodSamplingControl::Register>,
vregcr: ReadWrite<u32, VoltageRegulatorConfig::Register>,
_reserved1: [u32; 4],
rc1mcr: ReadWrite<u32, RC1MClockConfig::Register>,
_reserved2: u32,
bgctrl: ReadWrite<u32, BandgapControl::Register>,
bgsr: ReadOnly<u32, BandgapStatus::Register>,
_reserved3: [u32; 4],
br0: ReadOnly<u32, Backup::Register>,
br1: ReadOnly<u32, Backup::Register>,
br2: ReadOnly<u32, Backup::Register>,
br3: ReadOnly<u32, Backup::Register>,
}
register_bitfields![u32,
Interrupt [
LPBGRDY 12,
VREGOK 10,
SSWRDY 9,
BOD18SYNRDY 8,
BOD33SYNRDY 7,
BOD18DET 6,
BOD33DET 5,
RC32SAT 4,
RC32KREFE 3,
RC32KLOCK 2,
RC32KRDY 1,
OSC32RDY 0
],
PowerClocksStatus [
LPBGRDY 12,
RC1MRDY 11,
VREGOK 10,
SSWRDY 9,
BOD18SYNRDY 8,
BOD33SYNRDY 7,
BOD18DET 6,
BOD33DET 5,
RC32SAT 4,
RC32KREFE 3,
RC32KLOCK 2,
RC32KRDY 1,
OSC32RDY 0
],
Unlock [
KEY OFFSET(24) NUMBITS(8) [],
ADDR OFFSET(0) NUMBITS(10) []
],
Oscillator32Control [
STARTUP OFFSET(16) NUMBITS(3) [
Time0ms = 0,
Time1ms = 1,
Time72ms = 2,
Time143ms = 3,
Time570ms = 4,
Time1100ms = 5,
Time2300ms = 6,
Time4600ms = 7
],
SELCURR OFFSET(12) NUMBITS(4) [
CrystalCurrent50nA = 0,
CrystalCurrent75nA = 1,
CrystalCurrent100nA = 2,
CrystalCurrent125nA = 3,
CrystalCurrent150nA = 4,
CrystalCurrent175nA = 5,
CrystalCurrent200nA = 6,
CrystalCurrent225nA = 7,
CrystalCurrent250nA = 8,
CrystalCurrent275nA = 9,
CrystalCurrent300nA = 10,
CrystalCurrent325nA = 11,
CrystalCurrent350nA = 12,
CrystalCurrent375nA = 13,
CrystalCurrent400nA = 14,
CrystalCurrent425nA = 15
],
MODE OFFSET(8) NUMBITS(3) [
ExternalClock = 0,
CrystalMode = 1,
AmplitudeCrystalMode = 3,
CrystalHighCurrentMode = 4,
AmplitudeCrystalHighCurrentMode = 5
],
EN1K OFFSET(3) NUMBITS(1) [
OutputDisable = 0,
OutputEnable = 1
],
EN32K OFFSET(2) NUMBITS(1) [
OutputDisable = 0,
OutputEnable = 1
],
OSC32EN OFFSET(0) NUMBITS(1) [
OscillatorDisable = 0,
OscillatorEnable = 1
]
],
RC32Control [
FCD OFFSET(7) NUMBITS(1) [
ReloadCalib = 0,
KeepCalib = 1
],
REF OFFSET(5) NUMBITS(1) [
Osc32kReference = 0,
GclkReference = 1
],
MODE OFFSET(4) NUMBITS(1) [
OpenLoop = 0,
ClosedLoop = 1
],
EN1K OFFSET(3) NUMBITS(1) [
OutputDisable = 0,
OutputEnable = 1
],
EN32K OFFSET(2) NUMBITS(1) [
OutputDisable = 0,
OutputEnable = 1
],
TCEN OFFSET(1) NUMBITS(1) [
NotTempCompensated = 0,
TempCompensated = 1
],
EN OFFSET(0) NUMBITS(1) [
GclkSourceDisable = 0,
GclkSourceEnable = 1
]
],
RC32kTuning [
COARSE OFFSET(16) NUMBITS(7) [],
FINE OFFSET(0) NUMBITS(6) []
],
BodControl [
SFV OFFSET(31) NUMBITS(1) [
NotLocked = 0,
Locked = 1
],
FCD OFFSET(30) NUMBITS(1) [
RedoFlashCalibration = 0,
DoNotRedoFlashCalibration = 1
],
MODE OFFSET(16) NUMBITS(1) [
Continuous = 0,
Sampling = 1
],
ACTION OFFSET(8) NUMBITS(2) [
No = 0,
Reset = 1,
Interrupt = 2
],
HYST OFFSET(1) NUMBITS(1) [
No = 0,
Enabled = 1
],
EN OFFSET(0) NUMBITS(1) [
Disabled = 0,
Enabled = 1
]
],
BodSamplingControl [
PSEL OFFSET(8) NUMBITS(4) [],
CSSEL OFFSET(1) NUMBITS(1) [
Rcsys = 0,
Ck32k = 1
],
CEN OFFSET(0) NUMBITS(1) [
Stop = 0,
Start = 1
]
],
BodLevel [
RANGE OFFSET(31) NUMBITS(1) [
Standard = 0,
Low = 1
],
VAL OFFSET(0) NUMBITS(6) []
],
VoltageRegulatorConfig [
SFV OFFSET(31) NUMBITS(1) [
ReadWrite = 0,
ReadOnly = 1
],
SSWEVT OFFSET(10) NUMBITS(1) [
NotPeripheralControl = 0,
PeripheralControl = 1
],
SSW OFFSET(9) NUMBITS(1) [
NotStop = 0,
Stop = 1
],
SSG OFFSET(8) NUMBITS(1) [
SpreadSpectrumDisable = 0,
SpreadSpectrumEnable = 1
],
DIS OFFSET(0) NUMBITS(1) [
VoltageRegulatorDisable = 0,
VoltageRegulatorEnable = 1
]
],
RC1MClockConfig [
CLKCAL OFFSET(8) NUMBITS(5) [],
FCD OFFSET(7) NUMBITS(1) [
RedoFlashCalibration = 0,
DoNotRedoFlashCalibration = 1
],
CLKOEN OFFSET(0) NUMBITS(1) [
NotOutput = 0,
Output = 1
]
],
BandgapControl [
ADCISEL OFFSET(0) NUMBITS(2) [
NoConnection = 0,
ADCVoltageReference = 2
]
],
BandgapStatus [
VREF OFFSET(18) NUMBITS(2) [
BothUsed = 0,
BandgapUsed = 1,
LowPowerBandgapUsed = 2,
NeitherUsed = 3
],
LPBGRDY OFFSET(17) NUMBITS(1) [
NotReady = 0,
Ready = 1
],
BGRDY OFFSET(16) NUMBITS(1) [
NotReady = 0,
Ready = 1
],
BGBUFRDY OFFSET(0) NUMBITS(8) [
NotReady = 0,
Ready = 1
]
],
Backup [
DATA OFFSET(0) NUMBITS(32) []
]
];
const BSCIF: StaticRef<BscifRegisters> =
unsafe { StaticRef::new(0x400F0400 as *const BscifRegisters) };
pub fn enable_rc32k() {
let rc32kcr = BSCIF.rc32kcr.extract();
BSCIF
.unlock
.write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x24));
BSCIF.rc32kcr.modify_no_read(
rc32kcr,
RC32Control::EN32K::OutputEnable
+ RC32Control::TCEN::TempCompensated
+ RC32Control::EN::GclkSourceEnable,
);
while !BSCIF.rc32kcr.is_set(RC32Control::EN) {}
BSCIF
.unlock
.write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x28));
BSCIF
.rc32ktune
.write(RC32kTuning::COARSE.val(0x1d) + RC32kTuning::FINE.val(0x15));
}
pub fn rc32k_enabled() -> bool {
BSCIF.rc32kcr.is_set(RC32Control::EN)
}
pub fn setup_rc_1mhz() {
let rc1mcr = BSCIF.rc1mcr.extract();
BSCIF
.unlock
.write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x58));
BSCIF
.rc1mcr
.modify_no_read(rc1mcr, RC1MClockConfig::CLKOEN::Output);
while !BSCIF.rc1mcr.is_set(RC1MClockConfig::CLKOEN) {}
}
pub unsafe fn disable_rc_1mhz() {
let rc1mcr = BSCIF.rc1mcr.extract();
BSCIF
.unlock
.write(Unlock::KEY.val(0xAA) + Unlock::ADDR.val(0x58));
BSCIF
.rc1mcr
.modify_no_read(rc1mcr, RC1MClockConfig::CLKOEN::NotOutput);
while BSCIF.rc1mcr.is_set(RC1MClockConfig::CLKOEN) {}
}