use hk32f0301mxxc_pac::{
flash::regs::IntVecOffset,
rcc::regs::{Ahbenr, Cir},
FLASH, RCC,
};
pub enum RccAhbPeriph {
All,
GpioD,
GpioC,
GpioB,
GpioA,
Crc,
Flitf,
Sram,
}
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::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),
});
}
pub fn rcc_ahb_clock_all(newstate: bool) {
let val = if newstate { 0x1E0054 } else { 0 };
RCC.ahbenr().write_value(Ahbenr(val));
}
pub enum RccApb2Periph {
SysCfg,
Adc,
Tim1,
Spi,
Uart1,
DbgMcu,
}
pub fn rcc_apb2_clock_cmd(rcc_apb2periph: RccApb2Periph, newstate: bool) {
RCC.apbenr2().modify(|w| match rcc_apb2periph {
RccApb2Periph::SysCfg => w.set_syscfgen(newstate),
RccApb2Periph::Adc => w.set_adcen(newstate),
RccApb2Periph::Tim1 => w.set_tim1en(newstate),
RccApb2Periph::Spi => w.set_spien(newstate),
RccApb2Periph::Uart1 => w.set_uart1en(newstate),
RccApb2Periph::DbgMcu => w.set_dbgmcuen(newstate),
});
}
pub enum RccApb1Periph {
Tim2,
Tim6,
Wwdg,
Awu,
Uart2,
I2c,
Pwr,
IOMUX,
}
pub fn rcc_apb1_clock_cmd(rcc_apb1periph: RccApb1Periph, newstate: bool) {
RCC.apbenr1().modify(|w| match rcc_apb1periph {
RccApb1Periph::Tim2 => w.set_tim2en(newstate),
RccApb1Periph::Tim6 => w.set_tim6en(newstate),
RccApb1Periph::Wwdg => w.set_wwdgen(newstate),
RccApb1Periph::Uart2 => w.set_uart2en(newstate),
RccApb1Periph::I2c => w.set_i2cen(newstate),
RccApb1Periph::Pwr => w.set_pwren(newstate),
RccApb1Periph::Awu => w.set_awuen(newstate),
RccApb1Periph::IOMUX => w.set_iomuxen(newstate),
});
}
fn sys_set_clock_to_hsi_48m() {
RCC.cr().modify(|w| w.set_hsion(true));
RCC.cfgr4().modify(|w| w.set_flitfclk_pre(0x07));
while !RCC.cr().read().hsirdy() {}
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.cfgr().modify(|w| w.set_sw(0));
while RCC.cfgr().read().sws() != 0 {}
}
fn hsi_trimming_value_load() {
unsafe {
let hsi_value_ptr = 0x1FFFF10C as *const u32;
let hsi_value = hsi_value_ptr.read();
let mut temp = RCC.cr().read().0 & 0xFFFFC003;
if (hsi_value & 0xFFFF) == (0xFFFF - ((hsi_value >> 16) & 0xFFFF)) {
let mut hsical = hsi_value & 0xFF;
hsical = hsical >> 2;
let hsitrim = (hsi_value >> 8) & 0xFF;
temp |= hsitrim << 8;
temp |= hsical << 2;
RCC.cr().write_value(hk32f0301mxxc_pac::rcc::regs::Cr(temp));
}
}
}
fn pmu_trimming_value_load() {
unsafe {
let bgp_value_ptr = 0x1FFFF114 as *const u32;
let ldo_value_ptr = 0x1FFFF118 as *const u32;
let lpldo_value_ptr = 0x1FFFF11C as *const u32;
let bgp_value = bgp_value_ptr.read();
let ldo_value = ldo_value_ptr.read();
let lpldo_value = lpldo_value_ptr.read();
let pwr_bgp_ptr = 0x40007070 as *mut u32;
let lbgp = (bgp_value >> 8) & 0x1F;
let mbgp = bgp_value & 0x1F;
let ldo_run_temp = ldo_value & 0xFF;
let ldo_lpr_temp = (ldo_value >> 8) & 0xFF;
let lpldo_lpr_temp = (lpldo_value >> 8) & 0xFF;
RCC.apbenr1().modify(|w| w.set_pwren(true));
if (bgp_value & 0xFFFF) == (0xFFFF - ((bgp_value >> 16) & 0xFFFF)) {
let pwr_cr_ptr = 0x4000704C as *mut u32;
let bgp_temp = (lbgp << 8) | mbgp;
*pwr_cr_ptr = 0x00001985;
*pwr_cr_ptr = 0x00000429;
*pwr_bgp_ptr = bgp_temp;
*pwr_cr_ptr = 0x0000FFFF;
*pwr_cr_ptr = 0x0000FFFF;
}
if (ldo_value & 0xFFFF) == (0xFFFF - ((ldo_value >> 16) & 0xFFFF)) {
let pwr_cr_ptr = 0x4000704C as *mut u32;
let pwr_ldo_run_ptr = 0x40007060 as *mut u32;
let pwr_ldo_lpr_ptr = 0x40007064 as *mut u32;
*pwr_cr_ptr = 0x00001985;
*pwr_cr_ptr = 0x00000429;
*pwr_ldo_run_ptr = ldo_run_temp;
*pwr_ldo_lpr_ptr = ldo_lpr_temp;
*pwr_cr_ptr = 0x0000FFFF;
*pwr_cr_ptr = 0x0000FFFF;
}
if ((lpldo_value >> 8) & 0xFF) == (0xFF - ((lpldo_value >> 24) & 0xFF)) {
let pwr_cr_ptr = 0x4000704C as *mut u32;
let pwr_lpldo_lpr_ptr = 0x4000706C as *mut u32;
*pwr_cr_ptr = 0x00001985;
*pwr_cr_ptr = 0x00000429;
*pwr_lpldo_lpr_ptr = lpldo_lpr_temp;
*pwr_cr_ptr = 0x0000FFFF;
*pwr_cr_ptr = 0x0000FFFF;
}
}
}
pub fn sys_init(vect_tab_offset: u32) {
RCC.cr().modify(|w| w.set_hsion(true));
RCC.cfgr().modify(|w| w.set_hpre(0));
RCC.cfgr().modify(|w| w.set_ppre(0));
RCC.cfgr().modify(|w| w.set_mco(0));
RCC.cfgr().modify(|w| w.set_sw(0));
RCC.cfgr3().modify(|w| w.set_uart1sw(0));
RCC.cfgr3().modify(|w| w.set_uart2sw(0));
RCC.cfgr3().modify(|w| w.set_i2csw(false));
RCC.cir().write_value(Cir(0));
FLASH
.int_vec_offset()
.write_value(IntVecOffset(vect_tab_offset));
hsi_trimming_value_load();
pmu_trimming_value_load();
sys_set_clock_to_hsi_48m();
}