Files
kunlun/dtest/dtest3/kl3_gp_timer_test/kl3_gptmr_test.c
2024-09-28 14:24:04 +08:00

482 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "iot_bitops.h"
#include "os_lock.h"
#include "iot_config.h"
#include "dtest_printf.h"
#include "cpu.h"
#include "ahb.h"
#include "iot_gptmr_api.h"
#include "iot_spinlock.h"
#include "gp_timer.h"
#if HW_PLATFORM > HW_PLATFORM_SIMU
#include "dbg_io.h"
#endif
#include "iot_io.h"
#include "gpio_hw.h"
#include "hw_reg_api.h"
#include "iot_gpio.h"
#include "gtmr_reg.h"
uint32_t gp_timer_reg_read(uint32_t reg);
void gp_timer_reg_write(uint32_t reg, uint32_t data);
#define GPTMR_TEST_SPINLOCK 5
uint32_t g_tmr_count = 0;
extern void _core_start(void);
uint32_t gp_timer_get_current_val(uint8_t);
uint8_t gptmr_isr(iot_addrword_t data)
{
g_tmr_count++;
return 0;
}
void gptmr_core2_loop(void)
{
uint32_t cur_cpu = cpu_get_mhartid(), next_cnt = 0, loop, spinlock = GPTMR_TEST_SPINLOCK;
iot_spinlock_lock(spinlock, cur_cpu);
dprintf("CPU %d : Start!!!\n", cur_cpu);
iot_spinlock_unlock(spinlock, cur_cpu);
iot_gp_timer_set(0, 0xFFFFFFFF, 1);
iot_gp_timer_start(0);
for(;;) {
if (next_cnt < gp_timer_get_current_val(0)) {
iot_spinlock_lock(spinlock, cur_cpu);
dprintf("I'm CPU %d : tmr 0 count %d\n", cur_cpu, next_cnt);
iot_spinlock_unlock(spinlock, cur_cpu);
next_cnt += 2000000;
}
loop = 0;
while(loop++ < 100000) __asm volatile ("nop\n");
}
}
#define COUNTER_TIMER_ID 0
void gptmr_div_freq_test()
{
uint32_t tmp;
uint32_t timer0_val, timer1_val, timer2_val;
dcase_start("gp_timer div freq test\n");
/* 时钟1M分频系数1 */
tmp = gp_timer_reg_read(CFG_GTMR0_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR0_TICK_SEL, tmp, 1); //1m tick sel
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR, tmp);
/* 分频 1 */
gp_timer_reg_write(CFG_GTMR0_DIV_ADDR, 1);
gp_timer_set(0, 1000000, 0);
/* 时钟25M分频系数1 */
tmp = gp_timer_reg_read(CFG_GTMR1_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR0_TICK_SEL, tmp, 0); //25m tick sel
gp_timer_reg_write(CFG_GTMR1_CTRL_CFG_ADDR, tmp);
/* 分频 1 */
gp_timer_reg_write(CFG_GTMR1_DIV_ADDR, 1);
gp_timer_set(1, 100000000, 0);
/* 时钟25M分频系数5 */
tmp = gp_timer_reg_read(CFG_GTMR2_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR0_TICK_SEL, tmp, 0); //25m tick sel
gp_timer_reg_write(CFG_GTMR2_CTRL_CFG_ADDR, tmp);
/* 分频 5 */
gp_timer_reg_write(CFG_GTMR2_DIV_ADDR, 5);
gp_timer_set(2, 100000000, 0);
/* 启动 */
gp_timer_start(0);
gp_timer_start(1);
gp_timer_start(2);
while(!(gp_timer_get_int_status(0) & TMR0_INT_RAW_MASK));
gp_timer_stop(0);
gp_timer_stop(1);
gp_timer_stop(2);
/* timer0_val 1000000 */
timer0_val = gp_timer_get_current_val(0);
/* timer1_val 25000000 左右 */
timer1_val = gp_timer_get_current_val(1);
/* timer2_val 5000000 左右 */
timer2_val = gp_timer_get_current_val(2);
dprintf("timer0 val:%u timer1 val:%u timer2 val:%u\n",
timer0_val, timer1_val, timer2_val);
gp_timer_clear_int_status(0);
/* 时钟切回1m */
tmp = gp_timer_reg_read(CFG_GTMR1_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR0_TICK_SEL, tmp, 1); //1m tick sel
gp_timer_reg_write(CFG_GTMR1_CTRL_CFG_ADDR, tmp);
tmp = gp_timer_reg_read(CFG_GTMR2_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR0_TICK_SEL, tmp, 1); //1m tick sel
gp_timer_reg_write(CFG_GTMR2_CTRL_CFG_ADDR, tmp);
}
void gptmr_repeat_test()
{
uint32_t repeat_cnt = 0;
dcase_start("gp_timer repeat test\n");
gp_timer_init();
gp_timer_set(0, 1000000, 1);
gp_timer_set(1, 5000000, 0);
gp_timer_start(0);
gp_timer_start(1);
while(repeat_cnt < 3) {
if (gp_timer_get_int_status(0) & TMR0_INT_RAW_MASK) {
gp_timer_clear_int_status(0);
repeat_cnt++;
}
if (gp_timer_get_int_status(1) & TMR1_INT_RAW_MASK) {
gp_timer_clear_int_status(1);
break;
}
}
if (repeat_cnt != 3) {
dcase_failed();
} else {
dcase_success();
}
gp_timer_stop(0);
}
void gptmr_start_pause_stop_test()
{
/* 使用timer0作为计时timer1用作测试 */
uint32_t timer1_val1, timer1_val2, tmp;
dcase_start("gp_timer start pause stop test\n");
gp_timer_init();
/* 启动timer1 100s */
gp_timer_set(1, 100000000, 1);
gp_timer_start(1);
/* 获取当前timer1的计数值 */
timer1_val1 = gp_timer_get_current_val(1);
dprintf("start timer1 start: val:%u\n", timer1_val1);
/* 计时1s钟 */
gp_timer_set(COUNTER_TIMER_ID, 1000000, 1);
gp_timer_start(COUNTER_TIMER_ID);
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
timer1_val2 = gp_timer_get_current_val(1);
dprintf("start timer1 end: val:%u\n", timer1_val2);
/* 数值没有变则timer没有启动 */
if (timer1_val1 == timer1_val2) {
dcase_failed();
return;
}
/* 停止timer1 */
gp_timer_stop(1);
/* 获取当前timer1的计数值 */
timer1_val1 = gp_timer_get_current_val(1);
dprintf("stop timer1 start: val:%u\n", timer1_val1);
/* 计时1s */
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
timer1_val2 = gp_timer_get_current_val(1);
dprintf("stop timer1 end: val:%u\n", timer1_val2);
/* 数值变化了则timer没有停止 */
if (timer1_val1 != timer1_val2) {
dcase_failed();
return;
}
/* 启动timer1 */
gp_timer_set(1, 100000000, 1);
gp_timer_start(1);
/* 获取当前timer1的计数值 */
timer1_val1 = gp_timer_get_current_val(1);
dprintf("pause timer1 val:%u\n", timer1_val1);
/* 计时1s钟 */
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
timer1_val2 = gp_timer_get_current_val(1);
dprintf("pause timer1 start: val:%u\n", timer1_val2);
/* 数值没有变则timer没有启动 */
if (timer1_val1 == timer1_val2) {
dcase_failed();
return;
}
/* 暂停timer1 */
tmp = gp_timer_reg_read(CFG_GTMR1_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR1_PAUSE_CFG, tmp, 1);
gp_timer_reg_write(CFG_GTMR1_CTRL_CFG_ADDR, tmp);
/* 获取当前timer1的计数值 */
timer1_val1 = gp_timer_get_current_val(1);
dprintf("pause timer1 val:%u\n", timer1_val1);
/* 计时1s */
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
timer1_val2 = gp_timer_get_current_val(1);
dprintf("pause timer1 end: val:%u\n", timer1_val2);
/* 数值变化了则timer没有暂停 */
if (timer1_val1 != timer1_val2) {
dcase_failed();
return;
}
/* 取消暂停 */
tmp = gp_timer_reg_read(CFG_GTMR1_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR1_PAUSE_CFG, tmp, 0);
gp_timer_reg_write(CFG_GTMR1_CTRL_CFG_ADDR, tmp);
gp_timer_stop(COUNTER_TIMER_ID);
gp_timer_stop(1);
dcase_success();
}
void gptmr_interrupt_test()
{
uint32_t cur_cpu = cpu_get_mhartid();
uint32_t timer_id1, timer_id2;
dcase_start("gp_timer interrupt test\n");
iot_gp_timer_init();
timer_id1 = iot_gp_timer_create(cur_cpu, NULL, gptmr_isr, 0);
iot_gp_timer_set(timer_id1, 1000000, 0);
iot_gp_timer_start(timer_id1);
timer_id2 = iot_gp_timer_create(cur_cpu, NULL, gptmr_isr, 0);
iot_gp_timer_set(timer_id2, 2000000, 0);
iot_gp_timer_start(timer_id2);
while(gp_timer_get_current_val(timer_id2) < 1500000) {
if (g_tmr_count > 0) {
dcase_success();
iot_gp_timer_stop(timer_id1);
iot_gp_timer_stop(timer_id2);
return;
}
}
dcase_failed();
}
void gptmr_precision_test()
{
uint32_t cpu_cycle1, cpu_cycle2;
dcase_start("gp_timer precision test\n");
/* 计时1s钟 */
gp_timer_set(COUNTER_TIMER_ID, 1000000, 0);
gp_timer_start(COUNTER_TIMER_ID);
cpu_cycle1 = cpu_get_mcycle();
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
cpu_cycle2 = cpu_get_mcycle();
dprintf("gp_timer delta: 1000000 cpu_cycle delta:%u\n",
cpu_cycle2 - cpu_cycle1);
}
void gptmr_gpio_latch_test()
{
#define TEST_TIMER_ID 3
#define INPUT_GPIO 28
uint32_t value1, value2;
dcase_start("gp_timer gpio_latch test\n");
/* 开始计时 */
gp_timer_set(TEST_TIMER_ID, 0xffffffff, 0);
gp_timer_set_gpio_latch(TEST_TIMER_ID, INPUT_GPIO);
gp_timer_start(TEST_TIMER_ID);
hw_gpio_api_table.gpio_init();
hw_gpio_api_table.set_gpio_mode(INPUT_GPIO, GPIO_OUTPUT);
/* 输入管脚拉低,开始计数 */
hw_gpio_api_table.set_value(INPUT_GPIO, 0);
gp_timer_set(COUNTER_TIMER_ID, 1000000, 0);
gp_timer_start(COUNTER_TIMER_ID);
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
/* 输入管脚拉高,停止计数 */
hw_gpio_api_table.set_value(INPUT_GPIO, 1);
value1 = gp_timer_get_current_val(TEST_TIMER_ID);
dprintf("gp_timer value1: %d\n", value1);
gp_timer_set(COUNTER_TIMER_ID, 1000000, 0);
gp_timer_start(COUNTER_TIMER_ID);
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
value2 = gp_timer_get_current_val(TEST_TIMER_ID);
dprintf("gp_timer value2:%u\n", value2);
gp_timer_stop(COUNTER_TIMER_ID);
gp_timer_stop(TEST_TIMER_ID);
if (value1 == value2) {
dcase_success();
} else {
dcase_failed();
}
#undef TEST_TIMER_ID
#undef INPUT_GPIO
}
void gp_timer_reg_write(uint32_t reg, uint32_t data);
uint32_t gp_timer_reg_read(uint32_t reg);
void gptmr_64bit_timer(void)
{
#define DELAY_TIMER_ID 2
#define TIMER_64BIT_ID0 0
#define TIMER_64BIT_ID1 1
uint32_t tmp;
dcase_start("gp_timer 64bit timer test\n");
gp_timer_reg_write(CFG_TMR64_SEL_ADDR, 0x1);
/* timer 0 low 32bit timer 1 high 32bit */
gp_timer_set(TIMER_64BIT_ID0, 1098, 0);
gp_timer_set(TIMER_64BIT_ID1, 1, 0);
/* 切换时钟为25m */
tmp = gp_timer_reg_read(CFG_GTMR0_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR0_TICK_SEL, tmp, 0); //25m tick sel
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR, tmp);
gp_timer_start(TIMER_64BIT_ID0);
/* 打印间隔 1s */
gp_timer_set(DELAY_TIMER_ID, 1000000, 1);
gp_timer_start(DELAY_TIMER_ID);
while(1) {
while(!(gp_timer_get_int_status(DELAY_TIMER_ID) & TMR2_INT_RAW_MASK));
gp_timer_clear_int_status(DELAY_TIMER_ID);
dprintf("64bit timer value high: [%u] low:[%u]\n",
gp_timer_get_current_val(TIMER_64BIT_ID1), gp_timer_get_current_val(TIMER_64BIT_ID0));
if (gp_timer_get_int_status(TIMER_64BIT_ID0) & TMR0_INT_STS_MASK) {
dprintf("64bit timer interrupt status OK\n");
dcase_success();
gp_timer_clear_int_status(TIMER_64BIT_ID0);
break;
}
}
gp_timer_stop(DELAY_TIMER_ID);
/* 切换为32bit timer */
gp_timer_reg_write(CFG_TMR64_SEL_ADDR, 0x0);
}
void gptmr_core0_loop(void)
{
uint32_t cur_cpu = cpu_get_mhartid(), next_cnt = 0, loop, spinlock = GPTMR_TEST_SPINLOCK;
iot_spinlock_lock(spinlock, cur_cpu);
dprintf("CPU %d : Start!!!\n", cur_cpu);
iot_spinlock_unlock(spinlock, cur_cpu);
dstart();
dversion();
gp_timer_init();
gptmr_div_freq_test();
gptmr_repeat_test();
gptmr_start_pause_stop_test();
gptmr_precision_test();
gptmr_gpio_latch_test();
gptmr_64bit_timer();
gptmr_interrupt_test();
dend();
iot_gp_timer_set(0, 0xFFFFFFFF, 1);
iot_gp_timer_start(0);
for(;;) {
if (next_cnt < gp_timer_get_current_val(0)) {
iot_spinlock_lock(spinlock, cur_cpu);
dprintf("I'm CPU %d : tmr 0 count %d\n", cur_cpu, next_cnt);
iot_spinlock_unlock(spinlock, cur_cpu);
next_cnt += 1100000;
}
loop = 0;
while(loop++ < 100000) __asm volatile ("nop\n");
}
}
void gptmr_core1_loop()
{
uint32_t cur_cpu = cpu_get_mhartid(), id, loop, last_cnt = 0, spinlock = GPTMR_TEST_SPINLOCK;
iot_gp_timer_init();
id = iot_gp_timer_create(cur_cpu, NULL, gptmr_isr, 0);
iot_gp_timer_set(id, 1000000, 1);
iot_gp_timer_start(id);
iot_spinlock_lock(spinlock, cur_cpu);
dprintf("Test tmr%d @ cpu%d\n", id, cur_cpu);
iot_spinlock_unlock(spinlock, cur_cpu);
for(;;) {
if (last_cnt != g_tmr_count) {
iot_spinlock_lock(spinlock, cur_cpu);
dprintf("I'm CPU %d : tmr %d interrupts %d times.\n", cur_cpu, id, g_tmr_count);
iot_spinlock_unlock(spinlock, cur_cpu);
last_cnt = g_tmr_count;
}
loop = 0;
while(loop++ < 100000) __asm volatile ("nop\n");
}
return;
}
#include "clk.h"
int main(void)
{
gp_timer_set(COUNTER_TIMER_ID, 1000000, 0);
gp_timer_start(COUNTER_TIMER_ID);
while(!(gp_timer_get_int_status(COUNTER_TIMER_ID) & TMR0_INT_RAW_MASK));
gp_timer_clear_int_status(COUNTER_TIMER_ID);
uint32_t cur_cpu = cpu_get_mhartid();
if(cur_cpu == 0) {
clk_system_clock_tree_config(CLK_FRQ_GP_IDX_FAST);
dbg_uart_init();
// ahb_core2_set_start((uint32_t)_core_start);
//
// ahb_core2_enable();
//
// ahb_core2_reset();
gptmr_core0_loop();
} else if (cur_cpu == 2) {
ahb_core1_set_start((uint32_t)_core_start);
ahb_core1_enable();
ahb_core1_reset();
gptmr_core2_loop();
} else {
gptmr_core1_loop();
}
return 0;
}