openwch/ch32v307

Read clock ticks count

JoseSacristan opened this issue · 1 comments

Does anyone know why this function returns 0 instead of the current number of cycles (ticks) of the clock?

unsigned long read_cycles(void)
{
    unsigned long cycles;
    asm volatile ("rdcycle %0" : "=r" (cycles));
    return cycles;
}

In Arm architecture we have implemented this function and want the same functionality for riscv:

uint64_t MicroUp() 
{
        uint32_t ms = HAL_GetTick();
        uint32_t st = SysTick->VAL;
        uint32_t sl = SysTick->LOAD;

        // Did rollover while reading SysTick->VAL?
        if (ms != HAL_GetTick()) {
            ms = HAL_GetTick();
            st = SysTick->VAL;
        }

        uint32_t Mi=((sl-st)*1000l)/sl;

        return ms * 1000 + Mi;
}

At present, the kernel of our 307 chip has not added the function of csr clock counting for the time being, you can use systick or timer or other ways to get the system clock number. Below is an example of using systick, but once you use systick counting, you'd better not use our own delay function, because it's based on systick, and if you call Delay_Ms or Delay_Us, it will lead to inaccurate clock counting. Of course, it doesn't hurt if you use these two delay functions outside of the program segment you want to measure.

#include "debug.h"

/* Global typedef */

/* Global define */

/* Global Variable */

volatile uint32_t uwtick = 0U;

void SystickInit() {
    SysTick->CMP = (SystemCoreClock)/1000L-1;
    SysTick->CTLR |= 1UL << 1|1UL << 2|1UL << 3 | 1UL << 4 | 1UL << 5 | 1UL;
    NVIC_SetPriority(SysTicK_IRQn, 0xff);
    NVIC_EnableIRQ(SysTicK_IRQn);
}

uint64_t read_cycle() {
    return (((uint64_t) SysTick->CMP - (uint64_t) SysTick->CNT) * 1000L
            / (uint64_t) SysTick->CMP)
            + ((uint64_t) uwtick * (SystemCoreClock) / 1000L - 1);
}

static void delay_us(uint32_t delay_us) {
    volatile unsigned int num;
    volatile unsigned int t;

    for (num = 0; num < delay_us; num++) {
        t = 11;
        while (t != 0)
        {
            t--;
        }
    }
}

static void delay_ms(uint16_t delay_ms) {
    volatile unsigned int num;
    for (num = 0; num < delay_ms; num++) {
        delay_us(1000);
    }
}

/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void) {
    unsigned long temp;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID());
    printf("This is printf example\r\n");

    SystickInit();
    while(1)
    {
        printf("%lx\r\n",read_cycle());
        delay_ms(1000);
    }
}

__attribute__((interrupt("WCH-Interrupt-fast"))) void SysTick_Handler(){
    uwtick += 1;
    SysTick->SR = 0;
}