use hk32c030xx_pac::{
flash::regs::IntVecOffset,
pwr::regs::Cr,
rcc::regs::{Ahbenr, Apb1enr, Bdcr, Cir},
FLASH, PWR, RCC,
};
pub enum RccAhbPeriph {
All,
GpioF,
GpioD,
GpioC,
GpioB,
GpioA,
Crc,
Flitf,
Sram,
Dma,
}
pub fn rcc_ahb_clock_cmd(rcc_ahbperiph: RccAhbPeriph, newstate: bool) {
RCC.ahbenr().modify(|w| match rcc_ahbperiph {
RccAhbPeriph::All => w.0 = if newstate { 0x5E0055 } else { 0 },
RccAhbPeriph::GpioF => w.set_iopfen(newstate),
RccAhbPeriph::GpioD => w.set_iopden(newstate),
RccAhbPeriph::GpioC => w.set_iopcen(newstate),
RccAhbPeriph::GpioB => w.set_iopben(newstate),
RccAhbPeriph::GpioA => w.set_iopaen(newstate),
RccAhbPeriph::Crc => w.set_crcen(newstate),
RccAhbPeriph::Flitf => w.set_flitfen(newstate),
RccAhbPeriph::Sram => w.set_sramen(newstate),
RccAhbPeriph::Dma => w.set_dmaen(newstate),
});
}
pub fn rcc_ahb_clock_all(newstate: bool) {
let val = if newstate { 0x5E0055 } else { 0 };
RCC.ahbenr().write_value(Ahbenr(val));
}
pub enum RccApb2Periph {
SysCfg,
TempSen,
Adc,
Tim1,
Spi1,
Uart1,
Tim15,
Tim16,
Tim17,
DbgMcu,
}
pub fn rcc_apb2_clock_cmd(rcc_apb2periph: RccApb2Periph, newstate: bool) {
RCC.apb2enr().modify(|w| match rcc_apb2periph {
RccApb2Periph::SysCfg => w.set_syscfgen(newstate),
RccApb2Periph::TempSen => w.set_tempsen(newstate),
RccApb2Periph::Adc => w.set_adcen(newstate),
RccApb2Periph::Tim1 => w.set_tim1en(newstate),
RccApb2Periph::Spi1 => w.set_spi1en(newstate),
RccApb2Periph::Uart1 => w.set_uart1en(newstate),
RccApb2Periph::Tim15 => w.set_tim15en(newstate),
RccApb2Periph::Tim16 => w.set_tim16en(newstate),
RccApb2Periph::Tim17 => w.set_tim17en(newstate),
RccApb2Periph::DbgMcu => w.set_dbgen(newstate),
});
}
pub enum RccApb1Periph {
Tim2,
Tim3,
Tim6,
Tim14,
Wwdg,
Spi2,
Uart2,
Uart3,
I2c1,
I2c2,
Pwr,
}
pub fn rcc_apb1_clock_cmd(rcc_apb1periph: RccApb1Periph, newstate: bool) {
RCC.apb1enr().modify(|w| match rcc_apb1periph {
RccApb1Periph::Tim2 => w.set_tim2en(newstate),
RccApb1Periph::Tim3 => w.set_tim3en(newstate),
RccApb1Periph::Tim6 => w.set_tim6en(newstate),
RccApb1Periph::Tim14 => w.set_tim14en(newstate),
RccApb1Periph::Wwdg => w.set_wwdgen(newstate),
RccApb1Periph::Spi2 => w.set_spi2en(newstate),
RccApb1Periph::Uart2 => w.set_uart2en(newstate),
RccApb1Periph::Uart3 => w.set_uart3en(newstate),
RccApb1Periph::I2c1 => w.set_i2c1en(newstate),
RccApb1Periph::I2c2 => w.set_i2c2en(newstate),
RccApb1Periph::Pwr => w.set_pwren(newstate),
});
}
fn sys_set_clock_to_hsi_64m() {
RCC.cfgr4().modify(|w| w.set_hsi64on(true));
while !RCC.cfgr4().read().hsi64rdy() {}
FLASH.acr().modify(|w| w.set_prftbe(true));
FLASH.acr().modify(|w| w.set_latency(0x2));
RCC.cfgr().modify(|w| w.set_hpre(0));
RCC.cfgr().modify(|w| w.set_ppre(0));
RCC.cfgr4().modify(|w| w.set_esss(true));
RCC.cfgr4().modify(|w| w.set_esw(0x2));
while RCC.cfgr4().read().esws() != 2 {}
}
pub fn sys_init(vect_tab_offset: u32) {
RCC.cr().modify(|w| w.set_hsion(true));
RCC.cfgr().modify(|w| {
w.set_sw(0);
w.set_hpre(0);
w.set_ppre(0);
w.set_mco(0);
w.set_mcopre(0);
});
RCC.cr().modify(|w| {
w.set_hseon(false);
w.set_csson(false);
w.set_pllon(false);
});
RCC.cr().modify(|w| w.set_hsebyp(false));
RCC.cfgr3().modify(|w| {
w.set_uart1sw(0);
w.set_i2c1sw(false);
w.set_uart2sw(0);
w.set_uart3sw(0);
w.set_adcsw(false);
});
RCC.cr2().modify(|w| w.set_hsi16on(false));
RCC.cir().write_value(Cir(0));
FLASH
.int_vec_offset()
.write_value(IntVecOffset(vect_tab_offset));
unsafe { (0x400210E0 as *mut u32).write_volatile(0x1F37923A) }
RCC.apb1enr().write_value(Apb1enr(0x10000000));
PWR.cr().write_value(Cr(0x00000100));
RCC.bdcr().write_value(Bdcr(0x00000018));
unsafe { (0x400028F0 as *mut u32).write_volatile(0x00009000) }
let ptr_u32 = 0x40021024 as *mut u32;
let ptr_u16 = 0x1ffff9a4 as *mut u16;
unsafe {
let val_u32 = ptr_u32.read_volatile();
let val_u16 = ptr_u16.read_volatile();
ptr_u32.write_volatile(val_u32 | val_u16 as u32);
}
RCC.csr().modify(|w| w.set_lsion(true));
sys_set_clock_to_hsi_64m();
}