#include "board.h" void lvd_init(void) { M0P_LVD->CR = (0x0<<15) | // IE, interrupt 0:off; 1:on; (0x1<<14) | // HTEN, high level trigger LVD 0:off; 1:on(means voltage lower than expected value); (0x0<<13) | // RTEN, rising edge trigger LVD 0:off; 1:on; (0x0<<12) | // FTEN, falling edge trigger LVD 0:off; 1:on; (0x7<< 9) | // Debounce_time(be effective when FLTEN=1), 0:7us; 1:14us; .... 7:28.8ms (0x1<< 8) | // FLTEN, digital filter 0:off; 1:on; (0x7<< 4) | // VTDS, 0:1.8V; 1:1.9V; 2:2.0V; 3:2.1V; 4:2.2V; 5:2.3V; 6:2.4; 7:2.5 ....; (0x0<< 2) | // SOURCE_SEL, 0:AVCC; 1:PC13; 2:PB08; 3:PB07; (0x1<< 1) | // ACT, 0:interrupt; 1:system reset; (0x0<< 0); // LVDEN, 0:off; 1:on; M0P_LVD->CR_f.LVDEN = 0x1u; } #if defined(SYSCLK_4M_MODE) uint32_t SystemCoreClock = 4000000; #elif defined(SYSCLK_8M_MODE) uint32_t SystemCoreClock = 8000000; #elif defined(SYSCLK_16M_MODE) uint32_t SystemCoreClock = 16000000; #endif void SystemInit(void) { M0P_SYSCTRL->PERI_CLKEN0 = 0x80800030u; // enable I2C clocks because it need clock for synchronous reset M0P_SYSCTRL->PERI_CLKEN1 = 0x00000000u; // reset all peripheral M0P_RESET->PERI_RESET0 = 0x40000000; M0P_RESET->PERI_RESET1 = 0x00000000; // release reset M0P_RESET->PERI_RESET0 = 0x7F7F6FFF; M0P_RESET->PERI_RESET1 = 0x00000318; // disable all peripherals clock except FLASH M0P_SYSCTRL->PERI_CLKEN0 = 0x80800000u; // restore peripheral clock to default NVIC->ICPR[0U] = 0xFFFFFFFFu; // clear all pending IRQ lvd_init(); /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ #endif #ifdef VECT_TAB_OFFSET SCB->VTOR = VECT_TAB_OFFSET; #else SCB->VTOR = 0x0u; #endif M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 1; // PA13:SWDIO pull-up (default SWD_USE_IO==0, PA13,PA14 is for SWD, following cfg is bypassed) // PA14:SWCLK pull-up M0P_GPIO->PADIR = 0xFFFFu; // 0:output; 1:input M0P_GPIO->PAADS = 0x0000u; // 0:digital; 1:analog M0P_GPIO->PAPU = 0x0000u; // 0:no pull; 1:pull-up M0P_GPIO->PAPD = 0xFFFFu; // 0:no pull; 1:pull-down M0P_GPIO->PBDIR = 0xFFFFu; // 0:output; 1:input M0P_GPIO->PBADS = 0x0000u; // 0:digital; 1:analog M0P_GPIO->PBPU = 0x0000u; // 0:no pull; 1:pull-up M0P_GPIO->PBPD = 0xFFFFu; // 0:no pull; 1:pull-down // PC14:XTL(used, input, digital, no-pull) // PC15:XTL(unused) M0P_GPIO->PCDIR = 0xFFFFu; // 0:output; 1:input M0P_GPIO->PCADS = 0x0000u; // 0:digital; 1:analog M0P_GPIO->PCPU = 0x0000u; // 0:no pull; 1:pull-up M0P_GPIO->PCPD = 0xBFFFu; // 0:no pull; 1:pull-down M0P_GPIO->PDDIR = 0xFFFFu; // 0:output; 1:input M0P_GPIO->PDADS = 0x0000u; // 0:digital; 1:analog M0P_GPIO->PDPU = 0x0000u; // 0:no pull; 1:pull-up M0P_GPIO->PDPD = 0xFFFFu; // 0:no pull; 1:pull-down M0P_GPIO->PBDIR = 0xFFFFu; // PB07 输入 M0P_GPIO->PBADS = 0x0000u; // PB07 数字模式 M0P_GPIO->PBPU = 0x0000u; // PB07 不上拉 M0P_GPIO->PBPD = 0xFFFFu; // PB07 下拉 // PF00,PF01:XTH(unused) M0P_GPIO->PFDIR = 0xFFFFu; // 0:output; 1:input M0P_GPIO->PFADS = 0x0000u; // 0:digital; 1:analog M0P_GPIO->PFPU = 0x0000u; // 0:no pull; 1:pull-up M0P_GPIO->PFPD = 0xFFFFu; // 0:no pull; 1:pull-down M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 0; M0P_SYSCTRL->SYSCTRL2 = 0X5A5A; M0P_SYSCTRL->SYSCTRL2 = 0XA5A5; M0P_SYSCTRL->SYSCTRL1 = (0x0<<8) | // SWD_USE_IO, 0:SWD; 1:GPIO; (0x1<<6) | // LOCKUP_EN, 0:off; 1:on(invalid instruction lead to reset); (0x0<<5) | // RTC_LPW, RTC low power 0:off; 1:on(can not access RTC regiseters); (0x1<<3) | // XTL_ALWAYS_ON, 0:allow to disable XTL; 1:forbid to disable XTL; (0x1<<2) | // EXTL_EN, 0:crystal for XTL; 1:no crystal, direct XTL from PC14; (0x1<<1); // EXTH_EN, 0:crystal for XTH; 1:no crystal, direct XTH from PF00; // HC32L19x support 4 levels priority only //NVIC_SetPriorityGrouping(5); // 5:2 preemption-priority bits + 2 sub-priority bits; 3:4+0; 7:0+4; // default clock is RCH, not modify RCH until switch to RCL // XTL=32.768KHz PC14 from MS1030 TSTO1 // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 1; // M0P_GPIO->PCADS |= 0xC000U; // analog // M0P_GPIO->PCPU &= 0x3FFFu; // 0:no pull; 1:pull-up // M0P_GPIO->PCPD &= 0x3FFFu; // 0:no pull; 1:pull-down // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 0; // M0P_SYSCTRL->XTL_CR = (3<<4) | // STARTUP, startup clocks, 0:256; 1:1024; 2:4096; 3:16384; // (2<<2) | // AMP_SEL, 0~3 // (3<<0); // DRIVER, 0~3 // no XTH PF00 PF01 // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 1; // M0P_GPIO->PFDIR |= 0x0003U; // input // M0P_GPIO->PFADS &= 0xFFFCU; // digital // M0P_GPIO->PFPU &= 0xFFFCu; // 0:no pull; 1:pull-up // M0P_GPIO->PFPD |= 0x0003u; // 0:no pull; 1:pull-down // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 0; // M0P_SYSCTRL->XTH_CR = (3<<4) | // STARTUP, startup clocks, 0:256; 1:1024; 2:4096; 3:16384; // (0<<2) | // XTH_FSEL, 0:4M~8M; 1:8M~16M; 2:16M~24M; 3:24M~32M; // (0<<0); // DRIVER, 0~3 // RCL = 38.4K M0P_SYSCTRL->RCL_CR = (3<<10) | // clock startup time, 0: 4 clocks; 1: 16 clocks; 2: 64 clocks; 3: 256 clocks; (*((volatile uint16_t*) (0x00100C20ul))); // TRIM, 38.4KHz // (*((volatile uint16_t*) (0x00100C22ul))); // TRIM, 32.768KHz // select system clock, AHB clock and APB clock // set XTL RCL ON, RCH is default ON, and keep it M0P_SYSCTRL->SYSCTRL2 = 0X5A5A; M0P_SYSCTRL->SYSCTRL2 = 0XA5A5; M0P_SYSCTRL->SYSCTRL0 = (0<<11) | // PCLK_PRS, PCLK is, 0:HCLK; 1:HCLK/2; 2:HCLK/4; 3:HCLK/8; (0<<8) | // HCLK_PRS, HCLK is, 0:SystemClk; 1:SystemClk/2; 2:Systemclk/4; .... 7:SystemClk/128; (0<<5) | // CLKSW, SystemClk is 0: RCH(default); 1: XTH; 2: RCL; 3: XTL; 4: PLL; (0<<4) | // PLL_EN, 0:OFF; 1:ON; (1<<3) | // XTL_EN, 0:OFF; 1:ON; (1<<2) | // RCL_EN, 0:OFF; 1:ON; (0<<1) | // XTH_EN, 0:OFF; 1:ON; (1<<0); // RCH_EN, 0:OFF; 1:ON; RCH must be ON at first while(!M0P_SYSCTRL->RCL_CR_f.STABLE){ // wait until RCL is ready } // 1) switch to RCL at first M0P_SYSCTRL->SYSCTRL2 = 0X5A5A; M0P_SYSCTRL->SYSCTRL2 = 0XA5A5; M0P_SYSCTRL->SYSCTRL0_f.CLKSW = 2; // switch system clock to 0: RCH; 1: XTH; 2: RCL; 3: XTL; 4: PLL; // 2) decrease Flash latency after decreasing frequency M0P_FLASH->BYPASS = 0X5A5A; M0P_FLASH->BYPASS = 0XA5A5; M0P_FLASH->CR_f.WAIT = 0; // 0:Frequency<=24MHz; 1:24MHz< Frequency<=48HHz; 2:48MHzSYSCTRL2 = 0X5A5A; M0P_SYSCTRL->SYSCTRL2 = 0XA5A5; M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = 0; // 3.1) RCH = 4M or 8M or 16M #if defined(SYSCLK_4M_MODE) M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C08ul))); // 4MHz #elif defined(SYSCLK_8M_MODE) M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C06ul))); // 8MHz #elif defined(SYSCLK_16M_MODE) M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C04ul))); // 16MHz #endif // 3.2) set RCH ON M0P_SYSCTRL->SYSCTRL2 = 0X5A5A; M0P_SYSCTRL->SYSCTRL2 = 0XA5A5; M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = 1; while(!M0P_SYSCTRL->RCH_CR_f.STABLE){ // wait until RCH is ready } // 4) increase Flash latency before increasing frequency(default MSI is 4MHz after reset) M0P_FLASH->BYPASS = 0X5A5A; M0P_FLASH->BYPASS = 0XA5A5; M0P_FLASH->CR_f.WAIT = 0; // 0:Frequency<=24MHz; 1:24MHz< Frequency<=48HHz; 2:48MHzSYSCTRL2 = 0X5A5A; M0P_SYSCTRL->SYSCTRL2 = 0XA5A5; M0P_SYSCTRL->SYSCTRL0_f.CLKSW = 0; // 0: RCH; 1: XTH; 2: RCL; 3: XTL; 4: PLL; #ifndef RCL_38p4K_ENABLE // 6) set RCL OFF M0P_SYSCTRL->SYSCTRL2 = 0X5A5A; M0P_SYSCTRL->SYSCTRL2 = 0XA5A5; M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = 0; #endif } void IRQMutEnable(IRQn_Type IRQn, uint32_t Priority) { rt_base_t level; level = rt_hw_interrupt_disable(); NVIC_SetPriority(IRQn, Priority); // set interrupt priority NVIC_EnableIRQ(IRQn); // enable interrrupt rt_hw_interrupt_enable(level); } /* SysTick configuration */ // systick is 4194.304ms(4MHz) or 2097.152ms(8MHz) interval void systick_init(void) { // IRQMutEnable(SysTick_IRQn, IRQnPriority0); // set SYSTICK period 1ms //#if defined(SYSCLK_4M_MODE) // SysTick->LOAD = 4000000 - 1; //#elif defined(SYSCLK_8M_MODE) // SysTick->LOAD = 8000000 - 1; //#elif defined(SYSCLK_16M_MODE) // SysTick->LOAD = 16000000 - 1; //#endif SysTick->LOAD = 0x00FFFFFF; SysTick->VAL = 0UL; SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk) | // systick clksource is HCLK // (SysTick_CTRL_TICKINT_Msk) | // systick interrupt enable (SysTick_CTRL_ENABLE_Msk); // systick enable } //void get_tick(uint32_t *tick, uint32_t *sub) //{ // uint32_t pre_tick; // //// rt_enter_critical(); // pre_tick = rt_tick_get(); // *sub = SysTick->VAL; // *tick = rt_tick_get(); // // if (pre_tick!=*tick){ // *sub = SysTick->VAL; // } //// rt_exit_critical(); //} /** * This function will delay for some us, but not release CPU. * * @param us the delay time of us, us < 4194304(4MHz) or 2097152(8MHz) or 1048576(16MHz) */ //modified by yuewei 20260306 start /* void us_delay(uint32_t us) { uint32_t start, now, delta, us_tick; start = SysTick->VAL; #if defined(SYSCLK_4M_MODE) us_tick = us*4; #elif defined(SYSCLK_8M_MODE) us_tick = us*8; #elif defined(SYSCLK_16M_MODE) us_tick = us*16; #endif do { now = SysTick->VAL; delta = start > now ? start - now : 0x1000000 + start - now; } while(delta < us_tick); } */ /** * @brief 基于_nop_()的微秒延时函数 * @param us: 要延时的微秒数(建议范围:1~1000,过长会导致CPU空转) * @return 无 */ __attribute__((optnone))//add by yuewei to void not work in O1 void us_delay(uint32_t us) { uint32_t i, j, CPU_FREQ_MHZ; #if defined(SYSCLK_4M_MODE) CPU_FREQ_MHZ = 4; #elif defined(SYSCLK_8M_MODE) CPU_FREQ_MHZ = 8; #elif defined(SYSCLK_16M_MODE) CPU_FREQ_MHZ = 16; #endif // 外层循环:控制总延时us数 for (i = 0; i < us; i++) { // 内层循环:凑够1us的NOP次数(CPU_FREQ_MHZ = 主频(MHz)) for (j = 0; j < CPU_FREQ_MHZ; j++) { __NOP(); // 执行1次空指令,占用1个CPU时钟周期 } } } //modified by yuewei 20260306 end uint32_t expire_systick = 0x80000000u; // SysTick-VAL is count-down every clock // [us] < 2097152(4MHz) or 1048576(8MHz) void CalExpireTime(uint32_t us) { uint32_t new_systick; uint32_t delta; #if defined(SYSCLK_4M_MODE) us *= 4; #elif defined(SYSCLK_8M_MODE) us *= 8; #elif defined(SYSCLK_16M_MODE) us *= 16; #endif new_systick = (SysTick->VAL - us) & 0xFFFFFFu; if (expire_systick&0x80000000u){ expire_systick = new_systick; } else { delta = (expire_systick - new_systick) & 0xFFFFFFu; if (delta<0x800000u){ expire_systick = new_systick; } } } void WaitExpireTime(void) { uint32_t delta; if (expire_systick&0x80000000u){ return; } while(1){ delta = (expire_systick - SysTick->VAL) & 0xFFFFFFu; if (delta<0x800000u){ expire_systick = 0x80000000u; return; } } } //uint32_t dbg_chk_runtime_start_tp; //uint32_t dbg_chk_runtime_end_tp; //uint32_t dbg_chk_runtime_diff_tp; //uint32_t dbg_chk_runtime_flag=0; //uint32_t dbg_chk_runtime_diff_max=0; // //// time range must be less than 4095 ms //void DebugChkRuntime(uint32_t mode, uint32_t op) //{ // uint32_t tick, sub; // uint32_t diff_tick; // // get_tick(&tick, &sub); // // if (mode&0x1UL) { // dbg_chk_runtime_start_tp = (tick<<20) | sub; // } // // if (mode&0x2UL) { // dbg_chk_runtime_end_tp = sub | (tick<<20); // diff_tick = (dbg_chk_runtime_end_tp>>20) - (dbg_chk_runtime_start_tp>>20); // if (diff_tick>>31){ // diff_tick += (0x1u<<12); // } // diff_tick *= (SysTick->LOAD + 1); // dbg_chk_runtime_diff_tp = (dbg_chk_runtime_start_tp&0xfffff) - (dbg_chk_runtime_end_tp&0xfffff) + diff_tick; // if (dbg_chk_runtime_diff_tp > op) { // dbg_chk_runtime_flag |= 0x1; // } // // if (dbg_chk_runtime_diff_tp > dbg_chk_runtime_diff_max) { // dbg_chk_runtime_diff_max = dbg_chk_runtime_diff_tp; // } // // if (mode&(0x1UL<<31)) { // rt_kprintf("***start:0x%x->end:0x%x(%d clock elapsed)***\n", dbg_chk_runtime_start_tp, dbg_chk_runtime_end_tp, dbg_chk_runtime_diff_tp); // } // // if (mode&0x4UL){ // dbg_chk_runtime_start_tp = dbg_chk_runtime_end_tp; // } // } //} //void SysTick_Handler(void) //{ // rt_interrupt_enter(); // //// extern void ADC1_StartSingleSequence(void); //// ADC1_StartSingleSequence(); // // rt_tick_increase(); // // rt_interrupt_leave(); //} // //void rt_system_power_manager(void) //{ // __WFI(); //} /** * This function will initial board. */ //void rt_hw_board_init() //{ // /* Heap initialization */ //#if defined(RT_USING_HEAP) // rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); //#endif // // lvd_init(); // //#if defined(RT_USING_FINSH) // extern void finsh_drv_init(void); // finsh_drv_init(); //#endif // // rt_hw_systick_init(); // //#if defined(RT_USING_IDLE_HOOK) && defined(RT_USING_CPU_USAGE) // extern void cpu_usage_init(void); // cpu_usage_init(); //#endif // // /* Board underlying hardware initialization */ //#ifdef RT_USING_COMPONENTS_INIT // rt_components_board_init(); //#endif //}