hk32-partial-hal 0.3.1

HK32 partial HAL
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() {
    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    /* Enable HSI */
    // RCC->CFGR4 |= ((uint32_t)RCC_CFGR4_HSI64ON);
    RCC.cfgr4().modify(|w| w.set_hsi64on(true));

    /* Wait till HSE is ready and if Time out is reached exit */
    while !RCC.cfgr4().read().hsi64rdy() {}

    //   /* Enable Prefetch Buffer */
    //   FLASH->ACR |= FLASH_ACR_PRFTBE;
    FLASH.acr().modify(|w| w.set_prftbe(true));

    //   /* Flash 1 wait state */
    //   ACRreg = FLASH->ACR ;
    //   ACRreg &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    //   FLASH->ACR = (uint32_t)(FLASH_Latency_2|ACRreg);
    FLASH.acr().modify(|w| w.set_latency(0x2));

    //   /* HCLK = SYSCLK */
    //   RCC->CFGR |= (uint32_t)0x0 << RCC_CFGR_HPRE_Pos;
    RCC.cfgr().modify(|w| w.set_hpre(0));

    //   /* PCLK = HCLK */
    //   RCC->CFGR |= (uint32_t)0x0 << RCC_CFGR_PPRE_Pos;
    RCC.cfgr().modify(|w| w.set_ppre(0));

    //   /* Select HSI64 as system clock source */
    //   RCC->CFGR4 |= RCC_CFGR4_ESSS;
    RCC.cfgr4().modify(|w| w.set_esss(true));

    //   RCC->CFGR4 &= ~(RCC_CFGR4_ESW);
    //   RCC->CFGR4 |= (uint32_t)0x2 << RCC_CFGR4_ESW_Pos;
    RCC.cfgr4().modify(|w| w.set_esw(0x2));

    //   /* Wait till HSI is used as system clock source */
    //   while ((RCC->CFGR4 & (uint32_t)RCC_CFGR4_ESWS) != ((uint32_t)0x2 << RCC_CFGR4_ESWS_Pos)){}
    while RCC.cfgr4().read().esws() != 2 {}
}

pub fn sys_init(vect_tab_offset: u32) {
    /* Set HSION bit */
    // RCC->CR |= (uint32_t)0x00000001;
    RCC.cr().modify(|w| w.set_hsion(true));

    /* Reset SW[1:0], HPRE[3:0], PPRE[2:0] MCO[3:0] and MCOSEL[2:0] bits */
    // RCC->CFGR &= (uint32_t)0x00FFF80C;
    RCC.cfgr().modify(|w| {
        w.set_sw(0);
        w.set_hpre(0);
        w.set_ppre(0);
        w.set_mco(0);
        w.set_mcopre(0);
    });

    /* Reset HSEON, CSSON and PLLON bits */
    // RCC->CR &= (uint32_t)0xFEF6FFFF;
    RCC.cr().modify(|w| {
        w.set_hseon(false);
        w.set_csson(false);
        w.set_pllon(false);
    });

    /* Reset HSEBYP bit */
    // RCC->CR &= (uint32_t)0xFFFBFFFF;
    RCC.cr().modify(|w| w.set_hsebyp(false));

    /* Reset UART1SW[1:0], I2C1SW bits ,UART2SW[1:0],UART3SW[1:0],ADCSW*/
    // RCC->CFGR3 &= (uint32_t)0xFCFCFEEC;
    RCC.cfgr3().modify(|w| {
        w.set_uart1sw(0);
        w.set_i2c1sw(false);
        w.set_uart2sw(0);
        w.set_uart3sw(0);
        w.set_adcsw(false);
    });

    /* Reset HSI16 bit */
    // RCC->CR2 &= (uint32_t)0xFFFFFFFE;
    RCC.cr2().modify(|w| w.set_hsi16on(false));

    /* Disable all interrupts */
    // RCC->CIR = 0x00000000;
    RCC.cir().write_value(Cir(0));

    // FLASH->INT_VEC_OFFSET = VECT_TAB_OFFSET;   // 设置中断向量偏移
    FLASH
        .int_vec_offset()
        .write_value(IntVecOffset(vect_tab_offset));

    /* congfig HSE Drive*/
    // *(uint32_t*)(0x400210E0) = 0x1F37923A;
    unsafe { (0x400210E0 as *mut u32).write_volatile(0x1F37923A) }

    /* congfig LSE Drive */
    // RCC->APB1ENR = 0x10000000;
    RCC.apb1enr().write_value(Apb1enr(0x10000000));
    // PWR->CR = 0x00000100;
    PWR.cr().write_value(Cr(0x00000100));

    // RCC->BDCR = 0x00000018;
    RCC.bdcr().write_value(Bdcr(0x00000018));

    // *(uint32_t*)(0x400028F0) = 0x00009000;
    unsafe { (0x400028F0 as *mut u32).write_volatile(0x00009000) }

    // *(uint32_t *)0x40021024 = ((*(uint32_t *)0x40021024 & 0xFFFFFF03) | *(uint16_t *)0x1ffff9a4 );//Lsi load
    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 |= RCC_CSR_LSION;//Lsion
    RCC.csr().modify(|w| w.set_lsion(true));

    /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
    sys_set_clock_to_hsi_64m();
}