pub use tm4c_hal::sysctl::*;
use crate::{
bb,
time::{Hertz, U32Ext},
};
use cortex_m::asm::nop;
pub struct Sysctl {
pub power_control: PowerControl,
pub clock_setup: ClockSetup,
}
pub struct PowerControl {
_0: (),
}
pub struct ClockSetup {
pub oscillator: Oscillator,
_0: (),
}
#[derive(Clone, Copy)]
pub enum Oscillator {
Main(CrystalFrequency, SystemClock),
PrecisionInternal(SystemClock),
LowFrequencyInternal(Divider),
}
#[derive(Clone, Copy)]
pub enum SystemClock {
UseOscillator(Divider),
UsePll(PllOutputFrequency),
}
#[derive(Clone, Copy)]
pub enum CrystalFrequency {
_4mhz,
_4_09mhz,
_4_91mhz,
_5mhz,
_5_12mhz,
_6mhz,
_6_14mhz,
_7_37mhz,
_8mhz,
_8_19mhz,
_10mhz,
_12mhz,
_12_2mhz,
_13_5mhz,
_14_3mhz,
_16mhz,
_16_3mhz,
_18mhz,
_20mhz,
_24mhz,
_25mhz,
}
impl Into<Hertz> for CrystalFrequency {
fn into(self) -> Hertz {
Hertz(match self {
CrystalFrequency::_4mhz => 4_000_000,
CrystalFrequency::_4_09mhz => 4_090_000,
CrystalFrequency::_4_91mhz => 4_910_000,
CrystalFrequency::_5mhz => 5_000_000,
CrystalFrequency::_5_12mhz => 5_120_000,
CrystalFrequency::_6mhz => 6_000_000,
CrystalFrequency::_6_14mhz => 6_140_000,
CrystalFrequency::_7_37mhz => 7_370_000,
CrystalFrequency::_8mhz => 8_000_000,
CrystalFrequency::_8_19mhz => 8_190_000,
CrystalFrequency::_10mhz => 10_000_000,
CrystalFrequency::_12mhz => 12_000_000,
CrystalFrequency::_12_2mhz => 12_200_000,
CrystalFrequency::_13_5mhz => 13_500_000,
CrystalFrequency::_14_3mhz => 14_300_000,
CrystalFrequency::_16mhz => 16_000_000,
CrystalFrequency::_16_3mhz => 16_300_000,
CrystalFrequency::_18mhz => 18_000_000,
CrystalFrequency::_20mhz => 20_000_000,
CrystalFrequency::_24mhz => 24_000_000,
CrystalFrequency::_25mhz => 25_000_000,
})
}
}
#[derive(Clone, Copy)]
pub enum PllOutputFrequency {
_120mhz,
_60mhz,
_48mhz,
_30mhz,
_24mhz,
_12mhz,
_6mhz,
}
impl Into<Hertz> for PllOutputFrequency {
fn into(self) -> Hertz {
Hertz(match self {
PllOutputFrequency::_120mhz => 120_000_000,
PllOutputFrequency::_60mhz => 60_000_000,
PllOutputFrequency::_48mhz => 48_000_000,
PllOutputFrequency::_30mhz => 30_000_000,
PllOutputFrequency::_24mhz => 24_000_000,
PllOutputFrequency::_12mhz => 12_000_000,
PllOutputFrequency::_6mhz => 6_000_000,
})
}
}
#[derive(Clone, Copy)]
pub enum Divider {
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
_5 = 5,
_6 = 6,
_7 = 7,
_8 = 8,
_9 = 9,
_10 = 10,
_11 = 11,
_12 = 12,
_13 = 13,
_14 = 14,
_15 = 15,
_16 = 16,
}
#[derive(Copy, Clone)]
pub enum Domain {
Watchdog1,
Watchdog0,
Timer5,
Timer4,
Timer3,
Timer2,
Timer1,
Timer0,
GpioQ,
GpioP,
GpioN,
GpioM,
GpioL,
GpioK,
GpioJ,
GpioH,
GpioG,
GpioF,
GpioE,
GpioD,
GpioC,
GpioB,
GpioA,
MicroDma,
Hibernation,
Uart7,
Uart6,
Uart5,
Uart4,
Uart3,
Uart2,
Uart1,
Uart0,
Ssi3,
Ssi2,
Ssi1,
Ssi0,
I2c3,
I2c2,
I2c1,
I2c0,
Usb,
Can,
Adc1,
Adc0,
AnalogComparator,
Eeprom,
Pwm0,
Pwm1,
Emac0,
Ephy0,
}
pub fn reset(_lock: &PowerControl, pd: Domain) {
let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
match pd {
Domain::Watchdog1 => unsafe {
bb::toggle_bit(&p.srwd, 1);
bb::spin_bit(&p.prwd, 1);
},
Domain::Watchdog0 => unsafe {
bb::toggle_bit(&p.srwd, 0);
bb::spin_bit(&p.prwd, 0);
},
Domain::Timer5 => unsafe {
bb::toggle_bit(&p.srtimer, 5);
bb::spin_bit(&p.prtimer, 5);
},
Domain::Timer4 => unsafe {
bb::toggle_bit(&p.srtimer, 4);
bb::spin_bit(&p.prtimer, 4);
},
Domain::Timer3 => unsafe {
bb::toggle_bit(&p.srtimer, 3);
bb::spin_bit(&p.prtimer, 3);
},
Domain::Timer2 => unsafe {
bb::toggle_bit(&p.srtimer, 2);
bb::spin_bit(&p.prtimer, 2);
},
Domain::Timer1 => unsafe {
bb::toggle_bit(&p.srtimer, 1);
bb::spin_bit(&p.prtimer, 1);
},
Domain::Timer0 => unsafe {
bb::toggle_bit(&p.srtimer, 0);
bb::spin_bit(&p.prtimer, 0);
},
Domain::GpioQ => unsafe {
bb::toggle_bit(&p.srgpio, 14);
bb::spin_bit(&p.prgpio, 14);
},
Domain::GpioP => unsafe {
bb::toggle_bit(&p.srgpio, 13);
bb::spin_bit(&p.prgpio, 13);
},
Domain::GpioN => unsafe {
bb::toggle_bit(&p.srgpio, 12);
bb::spin_bit(&p.prgpio, 12);
},
Domain::GpioM => unsafe {
bb::toggle_bit(&p.srgpio, 11);
bb::spin_bit(&p.prgpio, 11);
},
Domain::GpioL => unsafe {
bb::toggle_bit(&p.srgpio, 10);
bb::spin_bit(&p.prgpio, 10);
},
Domain::GpioK => unsafe {
bb::toggle_bit(&p.srgpio, 9);
bb::spin_bit(&p.prgpio, 9);
},
Domain::GpioJ => unsafe {
bb::toggle_bit(&p.srgpio, 8);
bb::spin_bit(&p.prgpio, 8);
},
Domain::GpioH => unsafe {
bb::toggle_bit(&p.srgpio, 7);
bb::spin_bit(&p.prgpio, 7);
},
Domain::GpioG => unsafe {
bb::toggle_bit(&p.srgpio, 6);
bb::spin_bit(&p.prgpio, 6);
},
Domain::GpioF => unsafe {
bb::toggle_bit(&p.srgpio, 5);
bb::spin_bit(&p.prgpio, 5);
},
Domain::GpioE => unsafe {
bb::toggle_bit(&p.srgpio, 4);
bb::spin_bit(&p.prgpio, 4);
},
Domain::GpioD => unsafe {
bb::toggle_bit(&p.srgpio, 3);
bb::spin_bit(&p.prgpio, 3);
},
Domain::GpioC => unsafe {
bb::toggle_bit(&p.srgpio, 2);
bb::spin_bit(&p.prgpio, 2);
},
Domain::GpioB => unsafe {
bb::toggle_bit(&p.srgpio, 1);
bb::spin_bit(&p.prgpio, 1);
},
Domain::GpioA => unsafe {
bb::toggle_bit(&p.srgpio, 0);
bb::spin_bit(&p.prgpio, 0);
},
Domain::MicroDma => unsafe {
bb::toggle_bit(&p.srdma, 0);
bb::spin_bit(&p.prdma, 0);
},
Domain::Hibernation => unsafe {
bb::toggle_bit(&p.srhib, 0);
bb::spin_bit(&p.prhib, 0);
},
Domain::Uart7 => unsafe {
bb::toggle_bit(&p.sruart, 7);
bb::spin_bit(&p.pruart, 7);
},
Domain::Uart6 => unsafe {
bb::toggle_bit(&p.sruart, 6);
bb::spin_bit(&p.pruart, 6);
},
Domain::Uart5 => unsafe {
bb::toggle_bit(&p.sruart, 5);
bb::spin_bit(&p.pruart, 5);
},
Domain::Uart4 => unsafe {
bb::toggle_bit(&p.sruart, 4);
bb::spin_bit(&p.pruart, 4);
},
Domain::Uart3 => unsafe {
bb::toggle_bit(&p.sruart, 3);
bb::spin_bit(&p.pruart, 3);
},
Domain::Uart2 => unsafe {
bb::toggle_bit(&p.sruart, 2);
bb::spin_bit(&p.pruart, 2);
},
Domain::Uart1 => unsafe {
bb::toggle_bit(&p.sruart, 1);
bb::spin_bit(&p.pruart, 1);
},
Domain::Uart0 => unsafe {
bb::toggle_bit(&p.sruart, 0);
bb::spin_bit(&p.pruart, 0);
},
Domain::Ssi3 => unsafe {
bb::toggle_bit(&p.srssi, 3);
bb::spin_bit(&p.prssi, 3);
},
Domain::Ssi2 => unsafe {
bb::toggle_bit(&p.srssi, 2);
bb::spin_bit(&p.prssi, 2);
},
Domain::Ssi1 => unsafe {
bb::toggle_bit(&p.srssi, 1);
bb::spin_bit(&p.prssi, 1);
},
Domain::Ssi0 => unsafe {
bb::toggle_bit(&p.srssi, 0);
bb::spin_bit(&p.prssi, 0);
},
Domain::I2c3 => unsafe {
bb::toggle_bit(&p.sri2c, 3);
bb::spin_bit(&p.pri2c, 3);
},
Domain::I2c2 => unsafe {
bb::toggle_bit(&p.sri2c, 2);
bb::spin_bit(&p.pri2c, 2);
},
Domain::I2c1 => unsafe {
bb::toggle_bit(&p.sri2c, 1);
bb::spin_bit(&p.pri2c, 1);
},
Domain::I2c0 => unsafe {
bb::toggle_bit(&p.sri2c, 0);
bb::spin_bit(&p.pri2c, 0);
},
Domain::Usb => unsafe {
bb::toggle_bit(&p.srusb, 0);
bb::spin_bit(&p.prusb, 0);
},
Domain::Can => unsafe {
bb::toggle_bit(&p.srcan, 0);
bb::spin_bit(&p.prcan, 0);
},
Domain::Adc1 => unsafe {
bb::toggle_bit(&p.sradc, 1);
bb::spin_bit(&p.pradc, 1);
},
Domain::Adc0 => unsafe {
bb::toggle_bit(&p.sradc, 0);
bb::spin_bit(&p.pradc, 0);
},
Domain::AnalogComparator => unsafe {
bb::toggle_bit(&p.sracmp, 0);
bb::spin_bit(&p.pracmp, 0);
},
Domain::Eeprom => unsafe {
bb::toggle_bit(&p.sreeprom, 0);
bb::spin_bit(&p.preeprom, 0);
},
Domain::Pwm0 => unsafe {
bb::toggle_bit(&p.srpwm, 0);
bb::spin_bit(&p.prpwm, 0);
},
Domain::Pwm1 => unsafe {
bb::toggle_bit(&p.srpwm, 1);
bb::spin_bit(&p.prpwm, 1);
},
Domain::Emac0 => unsafe {
bb::toggle_bit(&p.sremac, 0);
bb::spin_bit(&p.premac, 0);
},
Domain::Ephy0 => unsafe {
bb::toggle_bit(&p.srephy, 0);
bb::spin_bit(&p.prephy, 0);
},
}
}
pub fn control_power(_lock: &PowerControl, pd: Domain, run_mode: RunMode, state: PowerState) {
let on = match state {
PowerState::On => true,
PowerState::Off => false,
};
match run_mode {
RunMode::Run => control_run_power(pd, on),
RunMode::Sleep => control_sleep_power(pd, on),
RunMode::DeepSleep => control_deep_sleep_power(pd, on),
}
nop();
nop();
nop();
}
fn control_run_power(pd: Domain, on: bool) {
let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
match pd {
Domain::Watchdog1 => unsafe { bb::change_bit(&p.rcgcwd, 1, on) },
Domain::Watchdog0 => unsafe { bb::change_bit(&p.rcgcwd, 0, on) },
Domain::Timer5 => unsafe { bb::change_bit(&p.rcgctimer, 5, on) },
Domain::Timer4 => unsafe { bb::change_bit(&p.rcgctimer, 4, on) },
Domain::Timer3 => unsafe { bb::change_bit(&p.rcgctimer, 3, on) },
Domain::Timer2 => unsafe { bb::change_bit(&p.rcgctimer, 2, on) },
Domain::Timer1 => unsafe { bb::change_bit(&p.rcgctimer, 1, on) },
Domain::Timer0 => unsafe { bb::change_bit(&p.rcgctimer, 0, on) },
Domain::GpioQ => unsafe { bb::change_bit(&p.rcgcgpio, 14, on) },
Domain::GpioP => unsafe { bb::change_bit(&p.rcgcgpio, 13, on) },
Domain::GpioN => unsafe { bb::change_bit(&p.rcgcgpio, 12, on) },
Domain::GpioM => unsafe { bb::change_bit(&p.rcgcgpio, 11, on) },
Domain::GpioL => unsafe { bb::change_bit(&p.rcgcgpio, 10, on) },
Domain::GpioK => unsafe { bb::change_bit(&p.rcgcgpio, 9, on) },
Domain::GpioJ => unsafe { bb::change_bit(&p.rcgcgpio, 8, on) },
Domain::GpioH => unsafe { bb::change_bit(&p.rcgcgpio, 7, on) },
Domain::GpioG => unsafe { bb::change_bit(&p.rcgcgpio, 6, on) },
Domain::GpioF => unsafe { bb::change_bit(&p.rcgcgpio, 5, on) },
Domain::GpioE => unsafe { bb::change_bit(&p.rcgcgpio, 4, on) },
Domain::GpioD => unsafe { bb::change_bit(&p.rcgcgpio, 3, on) },
Domain::GpioC => unsafe { bb::change_bit(&p.rcgcgpio, 2, on) },
Domain::GpioB => unsafe { bb::change_bit(&p.rcgcgpio, 1, on) },
Domain::GpioA => unsafe { bb::change_bit(&p.rcgcgpio, 0, on) },
Domain::MicroDma => unsafe { bb::change_bit(&p.rcgcdma, 0, on) },
Domain::Hibernation => unsafe { bb::change_bit(&p.rcgchib, 0, on) },
Domain::Uart7 => unsafe { bb::change_bit(&p.rcgcuart, 7, on) },
Domain::Uart6 => unsafe { bb::change_bit(&p.rcgcuart, 6, on) },
Domain::Uart5 => unsafe { bb::change_bit(&p.rcgcuart, 5, on) },
Domain::Uart4 => unsafe { bb::change_bit(&p.rcgcuart, 4, on) },
Domain::Uart3 => unsafe { bb::change_bit(&p.rcgcuart, 3, on) },
Domain::Uart2 => unsafe { bb::change_bit(&p.rcgcuart, 2, on) },
Domain::Uart1 => unsafe { bb::change_bit(&p.rcgcuart, 1, on) },
Domain::Uart0 => unsafe { bb::change_bit(&p.rcgcuart, 0, on) },
Domain::Ssi3 => unsafe { bb::change_bit(&p.rcgcssi, 3, on) },
Domain::Ssi2 => unsafe { bb::change_bit(&p.rcgcssi, 2, on) },
Domain::Ssi1 => unsafe { bb::change_bit(&p.rcgcssi, 1, on) },
Domain::Ssi0 => unsafe { bb::change_bit(&p.rcgcssi, 0, on) },
Domain::I2c3 => unsafe { bb::change_bit(&p.rcgci2c, 3, on) },
Domain::I2c2 => unsafe { bb::change_bit(&p.rcgci2c, 2, on) },
Domain::I2c1 => unsafe { bb::change_bit(&p.rcgci2c, 1, on) },
Domain::I2c0 => unsafe { bb::change_bit(&p.rcgci2c, 0, on) },
Domain::Usb => unsafe { bb::change_bit(&p.rcgcusb, 0, on) },
Domain::Can => unsafe { bb::change_bit(&p.rcgccan, 0, on) },
Domain::Adc1 => unsafe { bb::change_bit(&p.rcgcadc, 1, on) },
Domain::Adc0 => unsafe { bb::change_bit(&p.rcgcadc, 0, on) },
Domain::AnalogComparator => unsafe { bb::change_bit(&p.rcgcacmp, 0, on) },
Domain::Eeprom => unsafe { bb::change_bit(&p.rcgceeprom, 0, on) },
Domain::Pwm0 => unsafe { bb::change_bit(&p.rcgcpwm, 0, on) },
Domain::Pwm1 => unsafe { bb::change_bit(&p.rcgcpwm, 1, on) },
Domain::Emac0 => unsafe { bb::change_bit(&p.rcgcemac, 0, on) },
Domain::Ephy0 => unsafe { bb::change_bit(&p.rcgcephy, 0, on) },
}
}
fn control_sleep_power(pd: Domain, on: bool) {
let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
match pd {
Domain::Watchdog1 => unsafe { bb::change_bit(&p.scgcwd, 1, on) },
Domain::Watchdog0 => unsafe { bb::change_bit(&p.scgcwd, 0, on) },
Domain::Timer5 => unsafe { bb::change_bit(&p.scgctimer, 5, on) },
Domain::Timer4 => unsafe { bb::change_bit(&p.scgctimer, 4, on) },
Domain::Timer3 => unsafe { bb::change_bit(&p.scgctimer, 3, on) },
Domain::Timer2 => unsafe { bb::change_bit(&p.scgctimer, 2, on) },
Domain::Timer1 => unsafe { bb::change_bit(&p.scgctimer, 1, on) },
Domain::Timer0 => unsafe { bb::change_bit(&p.scgctimer, 0, on) },
Domain::GpioQ => unsafe { bb::change_bit(&p.scgcgpio, 14, on) },
Domain::GpioP => unsafe { bb::change_bit(&p.scgcgpio, 13, on) },
Domain::GpioN => unsafe { bb::change_bit(&p.scgcgpio, 12, on) },
Domain::GpioM => unsafe { bb::change_bit(&p.scgcgpio, 11, on) },
Domain::GpioL => unsafe { bb::change_bit(&p.scgcgpio, 10, on) },
Domain::GpioK => unsafe { bb::change_bit(&p.scgcgpio, 9, on) },
Domain::GpioJ => unsafe { bb::change_bit(&p.scgcgpio, 8, on) },
Domain::GpioH => unsafe { bb::change_bit(&p.scgcgpio, 7, on) },
Domain::GpioG => unsafe { bb::change_bit(&p.scgcgpio, 6, on) },
Domain::GpioF => unsafe { bb::change_bit(&p.scgcgpio, 5, on) },
Domain::GpioE => unsafe { bb::change_bit(&p.scgcgpio, 4, on) },
Domain::GpioD => unsafe { bb::change_bit(&p.scgcgpio, 3, on) },
Domain::GpioC => unsafe { bb::change_bit(&p.scgcgpio, 2, on) },
Domain::GpioB => unsafe { bb::change_bit(&p.scgcgpio, 1, on) },
Domain::GpioA => unsafe { bb::change_bit(&p.scgcgpio, 0, on) },
Domain::MicroDma => unsafe { bb::change_bit(&p.scgcdma, 0, on) },
Domain::Hibernation => unsafe { bb::change_bit(&p.scgchib, 0, on) },
Domain::Uart7 => unsafe { bb::change_bit(&p.scgcuart, 7, on) },
Domain::Uart6 => unsafe { bb::change_bit(&p.scgcuart, 6, on) },
Domain::Uart5 => unsafe { bb::change_bit(&p.scgcuart, 5, on) },
Domain::Uart4 => unsafe { bb::change_bit(&p.scgcuart, 4, on) },
Domain::Uart3 => unsafe { bb::change_bit(&p.scgcuart, 3, on) },
Domain::Uart2 => unsafe { bb::change_bit(&p.scgcuart, 2, on) },
Domain::Uart1 => unsafe { bb::change_bit(&p.scgcuart, 1, on) },
Domain::Uart0 => unsafe { bb::change_bit(&p.scgcuart, 0, on) },
Domain::Ssi3 => unsafe { bb::change_bit(&p.scgcssi, 3, on) },
Domain::Ssi2 => unsafe { bb::change_bit(&p.scgcssi, 2, on) },
Domain::Ssi1 => unsafe { bb::change_bit(&p.scgcssi, 1, on) },
Domain::Ssi0 => unsafe { bb::change_bit(&p.scgcssi, 0, on) },
Domain::I2c3 => unsafe { bb::change_bit(&p.scgci2c, 3, on) },
Domain::I2c2 => unsafe { bb::change_bit(&p.scgci2c, 2, on) },
Domain::I2c1 => unsafe { bb::change_bit(&p.scgci2c, 1, on) },
Domain::I2c0 => unsafe { bb::change_bit(&p.scgci2c, 0, on) },
Domain::Usb => unsafe { bb::change_bit(&p.scgcusb, 0, on) },
Domain::Can => unsafe { bb::change_bit(&p.scgccan, 0, on) },
Domain::Adc1 => unsafe { bb::change_bit(&p.scgcadc, 1, on) },
Domain::Adc0 => unsafe { bb::change_bit(&p.scgcadc, 0, on) },
Domain::AnalogComparator => unsafe { bb::change_bit(&p.scgcacmp, 0, on) },
Domain::Eeprom => unsafe { bb::change_bit(&p.scgceeprom, 0, on) },
Domain::Pwm0 => unsafe { bb::change_bit(&p.scgcpwm, 0, on) },
Domain::Pwm1 => unsafe { bb::change_bit(&p.scgcpwm, 1, on) },
Domain::Emac0 => unsafe { bb::change_bit(&p.scgcemac, 0, on) },
Domain::Ephy0 => unsafe { bb::change_bit(&p.scgcephy, 0, on) },
}
}
fn control_deep_sleep_power(pd: Domain, on: bool) {
let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
match pd {
Domain::Watchdog1 => unsafe { bb::change_bit(&p.dcgcwd, 1, on) },
Domain::Watchdog0 => unsafe { bb::change_bit(&p.dcgcwd, 0, on) },
Domain::Timer5 => unsafe { bb::change_bit(&p.dcgctimer, 5, on) },
Domain::Timer4 => unsafe { bb::change_bit(&p.dcgctimer, 4, on) },
Domain::Timer3 => unsafe { bb::change_bit(&p.dcgctimer, 3, on) },
Domain::Timer2 => unsafe { bb::change_bit(&p.dcgctimer, 2, on) },
Domain::Timer1 => unsafe { bb::change_bit(&p.dcgctimer, 1, on) },
Domain::Timer0 => unsafe { bb::change_bit(&p.dcgctimer, 0, on) },
Domain::GpioQ => unsafe { bb::change_bit(&p.dcgcgpio, 14, on) },
Domain::GpioP => unsafe { bb::change_bit(&p.dcgcgpio, 13, on) },
Domain::GpioN => unsafe { bb::change_bit(&p.dcgcgpio, 12, on) },
Domain::GpioM => unsafe { bb::change_bit(&p.dcgcgpio, 11, on) },
Domain::GpioL => unsafe { bb::change_bit(&p.dcgcgpio, 10, on) },
Domain::GpioK => unsafe { bb::change_bit(&p.dcgcgpio, 9, on) },
Domain::GpioJ => unsafe { bb::change_bit(&p.dcgcgpio, 8, on) },
Domain::GpioH => unsafe { bb::change_bit(&p.dcgcgpio, 7, on) },
Domain::GpioG => unsafe { bb::change_bit(&p.dcgcgpio, 6, on) },
Domain::GpioF => unsafe { bb::change_bit(&p.dcgcgpio, 5, on) },
Domain::GpioE => unsafe { bb::change_bit(&p.dcgcgpio, 4, on) },
Domain::GpioD => unsafe { bb::change_bit(&p.dcgcgpio, 3, on) },
Domain::GpioC => unsafe { bb::change_bit(&p.dcgcgpio, 2, on) },
Domain::GpioB => unsafe { bb::change_bit(&p.dcgcgpio, 1, on) },
Domain::GpioA => unsafe { bb::change_bit(&p.dcgcgpio, 0, on) },
Domain::MicroDma => unsafe { bb::change_bit(&p.dcgcdma, 0, on) },
Domain::Hibernation => unsafe { bb::change_bit(&p.dcgchib, 0, on) },
Domain::Uart7 => unsafe { bb::change_bit(&p.dcgcuart, 7, on) },
Domain::Uart6 => unsafe { bb::change_bit(&p.dcgcuart, 6, on) },
Domain::Uart5 => unsafe { bb::change_bit(&p.dcgcuart, 5, on) },
Domain::Uart4 => unsafe { bb::change_bit(&p.dcgcuart, 4, on) },
Domain::Uart3 => unsafe { bb::change_bit(&p.dcgcuart, 3, on) },
Domain::Uart2 => unsafe { bb::change_bit(&p.dcgcuart, 2, on) },
Domain::Uart1 => unsafe { bb::change_bit(&p.dcgcuart, 1, on) },
Domain::Uart0 => unsafe { bb::change_bit(&p.dcgcuart, 0, on) },
Domain::Ssi3 => unsafe { bb::change_bit(&p.dcgcssi, 3, on) },
Domain::Ssi2 => unsafe { bb::change_bit(&p.dcgcssi, 2, on) },
Domain::Ssi1 => unsafe { bb::change_bit(&p.dcgcssi, 1, on) },
Domain::Ssi0 => unsafe { bb::change_bit(&p.dcgcssi, 0, on) },
Domain::I2c3 => unsafe { bb::change_bit(&p.dcgci2c, 3, on) },
Domain::I2c2 => unsafe { bb::change_bit(&p.dcgci2c, 2, on) },
Domain::I2c1 => unsafe { bb::change_bit(&p.dcgci2c, 1, on) },
Domain::I2c0 => unsafe { bb::change_bit(&p.dcgci2c, 0, on) },
Domain::Usb => unsafe { bb::change_bit(&p.dcgcusb, 0, on) },
Domain::Can => unsafe { bb::change_bit(&p.dcgccan, 0, on) },
Domain::Adc1 => unsafe { bb::change_bit(&p.dcgcadc, 1, on) },
Domain::Adc0 => unsafe { bb::change_bit(&p.dcgcadc, 0, on) },
Domain::AnalogComparator => unsafe { bb::change_bit(&p.dcgcacmp, 0, on) },
Domain::Eeprom => unsafe { bb::change_bit(&p.dcgceeprom, 0, on) },
Domain::Pwm0 => unsafe { bb::change_bit(&p.dcgcpwm, 0, on) },
Domain::Pwm1 => unsafe { bb::change_bit(&p.dcgcpwm, 1, on) },
Domain::Emac0 => unsafe { bb::change_bit(&p.dcgcemac, 0, on) },
Domain::Ephy0 => unsafe { bb::change_bit(&p.dcgcephy, 0, on) },
}
}
pub trait SysctlExt {
fn constrain(self) -> Sysctl;
}
impl SysctlExt for tm4c129x::SYSCTL {
fn constrain(self) -> Sysctl {
Sysctl {
power_control: PowerControl { _0: () },
clock_setup: ClockSetup {
oscillator: Oscillator::PrecisionInternal(SystemClock::UseOscillator(Divider::_1)),
_0: (),
},
}
}
}
impl ClockSetup {
pub fn freeze(self) -> Clocks {
let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
let osc: Hertz;
let sysclk: Hertz;
match self.oscillator {
Oscillator::PrecisionInternal(SystemClock::UseOscillator(div)) => {
osc = 16_000_000.hz();
sysclk = (osc.0 / (div as u32)).hz();
p.rsclkcfg.modify(|_, w| {
w.osysdiv().bits(div as u16 - 1);
w
});
}
Oscillator::PrecisionInternal(SystemClock::UsePll(output_frequency)) => {
osc = 16_000_000.hz();
sysclk = output_frequency.into();
p.rsclkcfg.modify(|_, w| w.pllsrc().piosc());
p.pllfreq0.modify(|_, w| {
w.pllpwr().set_bit();
w.mfrac().bits(0);
w.mint().bits(30);
w
});
p.pllfreq1.modify(|_, w| {
w.q().bits(0);
w.n().bits(0);
w
});
p.rsclkcfg.modify(|_, w| w.newfreq().set_bit());
let (xbcht, xbce, xws) = match sysclk.0 {
f if f <= 16_000_000 => (0, true, 0),
f if f <= 40_000_000 => (2, false, 1),
f if f <= 60_000_000 => (3, false, 2),
f if f <= 80_000_000 => (4, false, 3),
f if f <= 100_000_000 => (5, false, 4),
f if f <= 120_000_000 => (6, false, 5),
_ => unreachable!(),
};
p.memtim0.modify(|_, w| {
unsafe {
w.fbcht().bits(xbcht);
w.ebcht().bits(xbcht);
w.fbce().bit(xbce);
w.ebce().bit(xbce);
w.fws().bits(xws);
w.ews().bits(xws);
}
w
});
while p.pllstat.read().lock().bit_is_clear() {
cortex_m::asm::nop();
}
p.rsclkcfg.modify(|_, w| {
w.usepll().set_bit();
w.memtimu().set_bit();
w.psysdiv().bits((480_000_000 / sysclk.0 - 1) as u16);
w
});
}
Oscillator::Main(crystal_frequency, SystemClock::UseOscillator(div)) => {
osc = crystal_frequency.into();
sysclk = (osc.0 / (div as u32)).hz();
p.moscctl.modify(|_, w| {
w.oscrng().set_bit();
w.noxtal().clear_bit();
w.pwrdn().clear_bit();
w
});
let (xbcht, xbce, xws) = match sysclk.0 {
f if f < 16_000_000 => (0, true, 0),
f if f < 40_000_000 => (2, false, 1),
_ => unreachable!(),
};
p.memtim0.modify(|_, w| {
unsafe {
w.fbcht().bits(xbcht);
w.ebcht().bits(xbcht);
w.fbce().bit(xbce);
w.ebce().bit(xbce);
w.fws().bits(xws);
w.ews().bits(xws);
}
w
});
while p.ris.read().moscpupris().bit_is_clear() {
cortex_m::asm::nop();
}
p.rsclkcfg.modify(|_, w| {
w.oscsrc().mosc();
w.memtimu().set_bit();
w.osysdiv().bits(div as u16 - 1);
w
});
}
Oscillator::Main(crystal_frequency, SystemClock::UsePll(output_frequency)) => {
osc = crystal_frequency.into();
sysclk = output_frequency.into();
p.moscctl.modify(|_, w| {
w.oscrng().set_bit();
w.noxtal().clear_bit();
w.pwrdn().clear_bit();
w
});
while p.ris.read().moscpupris().bit_is_clear() {
cortex_m::asm::nop();
}
p.rsclkcfg.modify(|_, w| w.pllsrc().mosc());
p.pllfreq1.modify(|_, w| {
w.q().bits(0);
w.n().bits(4);
w
});
p.pllfreq0.modify(|_, w| {
w.mfrac().bits(0);
w.mint().bits(96);
w
});
p.pllfreq0.modify(|_, w| w.pllpwr().set_bit());
while p.pllstat.read().lock().bit_is_clear() {
cortex_m::asm::nop();
}
let (xbcht, xbce, xws) = match sysclk.0 {
f if f <= 16_000_000 => (0, true, 0),
f if f <= 40_000_000 => (2, false, 1),
f if f <= 60_000_000 => (3, false, 2),
f if f <= 80_000_000 => (4, false, 3),
f if f <= 100_000_000 => (5, false, 4),
f if f <= 120_000_000 => (6, false, 5),
_ => unreachable!(),
};
p.memtim0.modify(|_, w| {
unsafe {
w.fbcht().bits(xbcht);
w.ebcht().bits(xbcht);
w.fbce().bit(xbce);
w.ebce().bit(xbce);
w.fws().bits(xws);
w.ews().bits(xws);
}
w
});
p.rsclkcfg.modify(|_, w| {
w.usepll().set_bit();
w.memtimu().set_bit();
w.psysdiv().bits((480_000_000 / sysclk.0 - 1) as u16);
w
});
}
Oscillator::LowFrequencyInternal(_div) => unimplemented!(),
}
Clocks { osc, sysclk }
}
}
impl PowerControl {}
pub mod chip_id {
pub use tm4c_hal::sysctl::chip_id::*;
pub fn get() -> Result<ChipId, Error> {
let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
let did0 = p.did0.read();
if did0.ver().bits() != 0x01 {
return Err(Error::UnknownDid0Ver(did0.ver().bits()));
}
let device_class = match did0.class().bits() {
0x05 => DeviceClass::StellarisBlizzard,
0x0a => DeviceClass::Snowflake,
_ => DeviceClass::Unknown,
};
let major = did0.maj().bits();
let minor = did0.min().bits();
let did1 = p.did1.read();
if did1.ver().bits() != 0x01 {
return Err(Error::UnknownDid1Ver(did1.ver().bits()));
}
let part_no = match did1.prtno().bits() {
0x1F => PartNo::Tm4c1294ncpdt,
45 => PartNo::Tm4c129encpdt,
e => PartNo::Unknown(e),
};
let pin_count = match did1.pincnt().bits() {
0 => PinCount::_28,
1 => PinCount::_48,
2 => PinCount::_100,
3 => PinCount::_64,
4 => PinCount::_144,
5 => PinCount::_157,
6 => PinCount::_168,
_ => PinCount::Unknown,
};
let temp_range = match did1.temp().bits() {
0 => TempRange::Commercial,
1 => TempRange::Industrial,
2 => TempRange::Extended,
3 => TempRange::IndustrialOrExtended,
_ => TempRange::Unknown,
};
let package = match did1.pkg().bits() {
0 => Package::Soic,
1 => Package::Lqfp,
2 => Package::Bga,
_ => Package::Unknown,
};
let rohs_compliant = did1.rohs().bit_is_set();
let qualification = match did1.qual().bits() {
0 => Qualification::EngineeringSample,
1 => Qualification::PilotProduction,
2 => Qualification::FullyQualified,
_ => Qualification::Unknown,
};
Ok(ChipId {
device_class,
major,
minor,
pin_count,
temp_range,
package,
rohs_compliant,
qualification,
part_no,
})
}
}