上电时间计算

前言:

CH573/582上电到运行第一个初始化的时间最快约53ms左右;592最快约22ms左右。

注意将串口免按键功能关闭。

思路:

上电之后从启动文件启动,直接跳转到60M主频进行运行,然后在main函数中翻转io进行判断时间。

测试工具,使用功耗计测试(可以看到上电的波形和运行到翻转io的波形)。

代码(CH582):

启动文件:

startup.s
.section	.init,"ax",@progbits
	.global	_start
	.align	1
_start:
	j	handle_reset

    .section    .vector,"ax",@progbits
    .align  1
_vector_base:
    .option norvc;

    .word   0
    .word   0
    .word   NMI_Handler                 /* NMI Handler */
    .word   HardFault_Handler           /* Hard Fault Handler */
    .word   0xF5F9BDA9
    .word   Ecall_M_Mode_Handler        /* 5 */
    .word   0
    .word   0
    .word   Ecall_U_Mode_Handler		/* 8 */
    .word   Break_Point_Handler			/* 9 */
    .word   0
    .word   0
    .word   SysTick_Handler            /* SysTick Handler */
    .word   0
    .word   SW_Handler                 /* SW Handler */
    .word   0
    /* External Interrupts */
    .word   TMR0_IRQHandler            /* 0:  TMR0 */
    .word   GPIOA_IRQHandler           /* GPIOA */
    .word   GPIOB_IRQHandler           /* GPIOB */
    .word   SPI0_IRQHandler            /* SPI0 */
    .word   BB_IRQHandler              /* BLEB */
    .word   LLE_IRQHandler             /* BLEL */
    .word   USB_IRQHandler             /* USB */
    .word   USB2_IRQHandler			   /* USB2 */
    .word   TMR1_IRQHandler            /* TMR1 */
    .word   TMR2_IRQHandler            /* TMR2 */
    .word   UART0_IRQHandler           /* UART0 */
    .word   UART1_IRQHandler           /* UART1 */
    .word   RTC_IRQHandler             /* RTC */
    .word   ADC_IRQHandler             /* ADC */
    .word   I2C_IRQHandler 			   /* I2C */
    .word   PWMX_IRQHandler            /* PWMX */
    .word   TMR3_IRQHandler            /* TMR3 */
    .word   UART2_IRQHandler           /* UART2 */
    .word   UART3_IRQHandler           /* UART3 */
    .word   WDOG_BAT_IRQHandler        /* WDOG_BAT */

    .option rvc;

    .section    .vector_handler, "ax", @progbits
    .weak   NMI_Handler
    .weak   HardFault_Handler
    .weak   Ecall_M_Mode_Handler
    .weak   Ecall_U_Mode_Handler
    .weak   Break_Point_Handler
    .weak   SysTick_Handler
    .weak   SW_Handler
    .weak   TMR0_IRQHandler
    .weak   GPIOA_IRQHandler
    .weak   GPIOB_IRQHandler
    .weak   SPI0_IRQHandler
    .weak   BB_IRQHandler
    .weak   LLE_IRQHandler
    .weak   USB_IRQHandler
    .weak   USB2_IRQHandler
    .weak   TMR1_IRQHandler
    .weak   TMR2_IRQHandler
    .weak   UART0_IRQHandler
    .weak   UART1_IRQHandler
    .weak   RTC_IRQHandler
    .weak   ADC_IRQHandler
    .weak   I2C_IRQHandler
    .weak   PWMX_IRQHandler
    .weak   TMR3_IRQHandler
    .weak   UART2_IRQHandler
    .weak   UART3_IRQHandler
    .weak   WDOG_BAT_IRQHandler

NMI_Handler:
HardFault_Handler:
Ecall_M_Mode_Handler:
Ecall_U_Mode_Handler:
Break_Point_Handler:
SysTick_Handler:
SW_Handler:
TMR0_IRQHandler:
GPIOA_IRQHandler:
GPIOB_IRQHandler:
SPI0_IRQHandler:
BB_IRQHandler:
LLE_IRQHandler:
USB_IRQHandler:
USB2_IRQHandler:
TMR1_IRQHandler:
TMR2_IRQHandler:
UART0_IRQHandler:
UART1_IRQHandler:
RTC_IRQHandler:
ADC_IRQHandler:
I2C_IRQHandler:
PWMX_IRQHandler:
TMR3_IRQHandler:
UART2_IRQHandler:
UART3_IRQHandler:
WDOG_BAT_IRQHandler: 
1:  
	j 1b

	.section	.handle_reset,"ax",@progbits
	.weak	handle_reset
	.align	1
handle_reset:
.option push 
.option	norelax 
	la gp, __global_pointer$
.option	pop 
1:
	la sp, _eusrstack 


2:
    la a0, _highcode_copy_lma
    la a1, _highcode_copy_start
    la a2, _highcode_copy_end
    bgeu a1, a2, 2f
1:
    lw t0, (a0)
    sw t0, (a1)
    addi a0, a0, 4
    addi a1, a1, 4
    bltu a1, a2, 1b

	jal SystemInit


/* Load highcode code  section from flash to RAM */

/*
2:
    la a0, _highcode_lma
    la a1, _highcode_vma_start
    la a2, _highcode_vma_end
    bgeu a1, a2, 2f
1:
    lw t0, (a0)
    sw t0, (a1)
    addi a0, a0, 4
    addi a1, a1, 4
    bltu a1, a2, 1b

2:
	la a0, _data_lma
	la a1, _data_vma
	la a2, _edata
	bgeu a1, a2, 2f
1:
	lw t0, (a0)
	sw t0, (a1)
	addi a0, a0, 4
	addi a1, a1, 4
	bltu a1, a2, 1b
2:

	la a0, _sbss
	la a1, _ebss
	bgeu a0, a1, 2f
1:
	sw zero, (a0)
	addi a0, a0, 4
	bltu a0, a1, 1b
	*/

2:
	/* 流水线控制位 & 动态预测控制位 */
	li t0, 0x1f
	csrw 0xbc0, t0
	/* 打开嵌套中断、硬件压栈功能 */
	li t0, 0x3
	csrw 0x804, t0
	
    li t0, 0x88
    csrs mstatus, t0
	la t0, _vector_base

	/* 配置向量表模式为绝对地址模式 */
    ori t0, t0, 3
	csrw mtvec, t0

	la t0, main
	csrw mepc, t0
	
	
	mret

跳转并配置时钟c文件:

soctestct.c
 /*
 * soctest.c
 *
 *  Created on: Jan 4, 2024
 *      Author: OWNER
 */

#include "soctestct.h"


typedef enum
{
  CLK_FLASH_4 = 0X01,
  CLK_FLASH_5 = 0X05,
  CLK_FLASH_6 = 0X02,
  CLK_FLASH_7 = 0X06,
  CLK_FLASH_8 = 0X03,
  CLK_FLASH_9 = 0X07,

  AHB_READY_SHORT = 0X00,
  AHB_READY_NORMAL = 0X40,
  AHB_READY_LONG = 0X80,
  AHB_READY_LONGER = 0XC0,

  AHB_SAMPLE_NORMAL = 0X00,
  AHB_SAMPLE_DELAY = 0X10,
  AHB_SAMPLE_BEFORE = 0X20,

  AHB_SCSWIDTH_3 = 0X00,
  AHB_SCSWIDTH_2 = 0X08,

}FLASH_CLKTypeDef;


extern uint32_t _highcode_lma;
extern uint32_t _highcode_vma_start;
extern uint32_t _highcode_vma_end;

extern uint32_t _data_lma;
extern uint32_t _data_vma;
extern uint32_t _edata;

extern uint32_t _sbss;
extern uint32_t _ebss;


__attribute__((section(".highcode_copy")))
static void __attribute__((noinline)) copy_section(uint32_t * p_load, uint32_t * p_vma, uint32_t * p_vma_end)
{
    while(p_vma <= p_vma_end)
    {
        *p_vma = *p_load;
        ++p_load;
        ++p_vma;
    }
}

__attribute__((section(".highcode_copy")))
static void __attribute__((noinline)) zero_section(uint32_t * start, uint32_t * end)
{
    uint32_t * p_zero = start;

    while(p_zero <= end)
    {
        *p_zero = 0;
        ++p_zero;
    }
}


__attribute__((section(".highcode_copy")))
void mySystemInit(void) {
    uint32_t i;
    uint8_t sc = 0x46;
    sys_safe_access_enable();
    R8_PLL_CONFIG &= ~(1 << 5); //
    sys_safe_access_disable();

    sys_safe_access_enable();
    R8_HFCK_PWR_CTRL |= RB_CLK_PLL_PON | RB_CLK_XT32M_PON;
    sys_safe_access_disable();

//    if(sc & 0x20)  // HSE div
//    {
//        if(!(R8_HFCK_PWR_CTRL & RB_CLK_XT32M_PON))
//        {
//            sys_safe_access_enable();
//            R8_HFCK_PWR_CTRL |= RB_CLK_XT32M_PON; // HSE power on
//            sys_safe_access_disable();
////            for(i = 0; i < 1200; i++)
////            {
//                __nop();
//                __nop();
////            }
//        }
//
//        sys_safe_access_enable();
//        R16_CLK_SYS_CFG = (0 << 6) | (sc & 0x1f);
//        __nop();
//        __nop();
//        __nop();
//        __nop();
//        sys_safe_access_disable();
//        sys_safe_access_enable();
//        SAFEOPERATE;
//        R8_FLASH_CFG = 0X51;
//        sys_safe_access_disable();
//    }

     if(sc & 0x40) // PLL div
    {
        if(!(R8_HFCK_PWR_CTRL & RB_CLK_PLL_PON))
        {
            sys_safe_access_enable();
            R8_HFCK_PWR_CTRL |= RB_CLK_PLL_PON; // PLL power on
            sys_safe_access_disable();
            for(i = 0; i < 2000; i++)
            {
                __nop();
                __nop();
            }
        }
        sys_safe_access_enable();
        R16_CLK_SYS_CFG = (1 << 6) | (sc & 0x1f);
        sys_safe_access_disable();
        __nop();
        __nop();
        __nop();
        __nop();

        if(sc == CLK_SOURCE_PLL_80MHz)
        {
            sys_safe_access_enable();
            R8_FLASH_CFG = 0X02;
            sys_safe_access_disable();
        }
        else
        {
            sys_safe_access_enable();
            R8_FLASH_CFG = 0X55;
            sys_safe_access_disable();
        }
    }
//    else
//    {
//        sys_safe_access_enable();
//        R16_CLK_SYS_CFG |= RB_CLK_SYS_MOD;
//        sys_safe_access_disable();
//    }
    //更改FLASH clk的驱动能力
    sys_safe_access_enable();
    R8_PLL_CONFIG |= 1 << 7;
    sys_safe_access_disable();



    copy_section(&_highcode_lma, &_highcode_vma_start, &_highcode_vma_end);
    copy_section(&_data_lma, &_data_vma, &_edata);
    zero_section(&_sbss, &_ebss);

//    R32_PB_OUT |= 1<<0;
//    R32_PB_PD_DRV &= ~(1<<0);
//    R32_PB_DIR |= 1<<0;
//    mDelaymS(1);
//    R32_PB_CLR |= 1<<0;
//    mDelaymS(1);
//    R32_PB_OUT |= 1<<0;
//    mDelaymS(1);
//    R32_PB_CLR |= 1<<0;
}

void SystemInit(void){
    mySystemInit();
}

跳转并配置时钟h文件:

socttestct.h
/*
 * soctest.h
 *
 *  Created on: Jan 4, 2024
 *      Author: OWNER
 */

#ifndef SRC_INCLUDE_SOCTEST_H_
#define SRC_INCLUDE_SOCTEST_H_

#include "CH58x_common.h"

#define DEFINE_FAST_IRQ_HANDLER(irq_handler) void irq_handler() __attribute__((interrupt("WCH-Interrupt-fast")))

DEFINE_FAST_IRQ_HANDLER(NMI_Handler);
DEFINE_FAST_IRQ_HANDLER(HardFault_Handler);
DEFINE_FAST_IRQ_HANDLER(Ecall_U_Mode_Handler);
DEFINE_FAST_IRQ_HANDLER(SysTick_Handler);
DEFINE_FAST_IRQ_HANDLER(SW_Handler);
DEFINE_FAST_IRQ_HANDLER(TMR0_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(GPIOA_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(GPIOB_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(SPI0_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(BB_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(LLE_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(USB_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(TMR1_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(TMR2_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(UART0_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(UART1_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(RTC_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(ADC_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(PWMX_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(TMR3_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(UART2_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(UART3_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(I2C_IRQHandler);
DEFINE_FAST_IRQ_HANDLER(WDOG_BAT_IRQHandler);


void SystemInit(void);

void mySystemInit(void);

#endif /* SRC_INCLUDE_SOCTEST_H_ */

 

posted @ 2024-04-03 10:15  SweetTea_lllpc  阅读(146)  评论(0编辑  收藏  举报