516 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			516 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | 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 "chip_reg_base.h"
 | ||
|  | #include "hw_reg_api.h"
 | ||
|  | 
 | ||
|  | #include "ahb.h"
 | ||
|  | #include "gp_timer.h"
 | ||
|  | #include "rtc_hw.h"
 | ||
|  | #include "uart.h"
 | ||
|  | #include "wdt_hw.h"
 | ||
|  | #include "cpu.h"
 | ||
|  | 
 | ||
|  | #include "iot_clock.h"
 | ||
|  | #include "dbg_io.h"
 | ||
|  | #include "iot_rtc.h"
 | ||
|  | #include "iot_irq.h"
 | ||
|  | #include "iot_wdg.h"
 | ||
|  | 
 | ||
|  | #include "iot_errno_api.h"
 | ||
|  | #include "iot_rtc_api.h"
 | ||
|  | 
 | ||
|  | #include "dtest_printf.h"
 | ||
|  | 
 | ||
|  | #define DTEST_RTC_MS_TO_RTC_TICK(x)         (((x) << 12) / 125)
 | ||
|  | #define DTEST_RTC_S_TO_RTC_TICK(x)          ((x) << 15)
 | ||
|  | #define DTEST_RTC_TICK_TO_MS(x)             (((x) >> 12) * 125)
 | ||
|  | #define DTEST_RTC_TICK_TO_S(x)              ((x) >> 15)
 | ||
|  | 
 | ||
|  | #define DTEST_RTC_SCRATCH_INDEX             0
 | ||
|  | /* Several counting cycles may be lost due to cross clock domain problems */ | ||
|  | #define DTEST_RTC_OPT_CNT_COMPENSATION      4
 | ||
|  | 
 | ||
|  | #define DTEST_RTC_CASE_TIMER_CNT_GET_SET    (1 << 0)
 | ||
|  | #define DTEST_RTC_CASE_TIMER_PAUSE_REGAIN   (1 << 1)
 | ||
|  | #define DTEST_RTC_CASE_TIMER_START_STOP     (1 << 2)
 | ||
|  | #define DTEST_RTC_CASE_TIMER_INTERRUPT      (1 << 3)
 | ||
|  | #define DTEST_RTC_CASE_TIMER_CASCADE        (1 << 4)
 | ||
|  | #define DTEST_RTC_CASE_TIMER_ACCURACY       (1 << 5)
 | ||
|  | #define DTEST_RTC_CASE_WDG_RESET            (1 << 6)
 | ||
|  | 
 | ||
|  | static uint32_t dtest_rtc_cnt_get_set_test() | ||
|  | { | ||
|  |     uint32_t cnt_tmr0_0, cnt_tmr1_0, cnt_tmr0_1, cnt_tmr1_1, cnt_d0, cnt_d1; | ||
|  |     uint32_t delay_us = 1000000; | ||
|  |     uint32_t rtc_tick_us = DTEST_RTC_MS_TO_RTC_TICK(delay_us / 1000); | ||
|  | 
 | ||
|  |     dcase_start("rtc timer cnt value get and set\n"); | ||
|  | 
 | ||
|  |     /* get rtc timer counter value */ | ||
|  |     cnt_tmr0_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("first time get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_0, cnt_tmr1_0); | ||
|  | 
 | ||
|  |     dprintf("gptimer delay %dus, rtc tick:%d\n", delay_us, rtc_tick_us); | ||
|  |     iot_delay_us(delay_us); | ||
|  |     cnt_tmr0_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("after delay get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_1, cnt_tmr1_1); | ||
|  | 
 | ||
|  |     cnt_d0 = cnt_tmr0_1 - cnt_tmr0_0; | ||
|  |     cnt_d1 = cnt_tmr1_1 - cnt_tmr1_0; | ||
|  |     dprintf("get cnt diff, timer0:%d, timer1:%d\n", cnt_d0, cnt_d1); | ||
|  |     if (cnt_d0 < rtc_tick_us || cnt_d1 < rtc_tick_us) { | ||
|  |         dprintf("rtc count value is less than the delay time\n"); | ||
|  |         goto fail; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* set rtc timer cuonter value */ | ||
|  |     dprintf("set rtc timer0/1 counter value to 0\n"); | ||
|  |     rtc_timer_cnt_value_set(RTC_TIMER_ID_0, 0x00); | ||
|  |     rtc_timer_cnt_value_set(RTC_TIMER_ID_1, 0x00); | ||
|  |     dprintf("gptimer delay %dus, rtc tick:%d\n", delay_us, rtc_tick_us); | ||
|  |     iot_delay_us(delay_us); | ||
|  |     cnt_tmr0_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("after delay get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_1, cnt_tmr1_1); | ||
|  |     if ((cnt_tmr0_1 < rtc_tick_us || cnt_tmr1_1 < rtc_tick_us) | ||
|  |         || (cnt_tmr0_1 >= 2 * rtc_tick_us || cnt_tmr1_1 >= 2 * rtc_tick_us)) { | ||
|  |         dprintf("rtc count value deviates from the expected value\n"); | ||
|  |         goto fail; | ||
|  |     } | ||
|  | 
 | ||
|  |     dcase_success(); | ||
|  |     return ERR_OK; | ||
|  | fail: | ||
|  |     dcase_failed(); | ||
|  |     return ERR_FAIL; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t dtest_rtc_pause_regain_test() | ||
|  | { | ||
|  |     uint32_t cnt_tmr0_0, cnt_tmr1_0, cnt_tmr0_1, cnt_tmr1_1, cnt_d0, cnt_d1; | ||
|  |     uint32_t delay_us = 1000000; | ||
|  |     uint32_t rtc_tick_us = DTEST_RTC_MS_TO_RTC_TICK(delay_us / 1000); | ||
|  | 
 | ||
|  |     dcase_start("rtc timer pause and regain\n"); | ||
|  | 
 | ||
|  |     /* pause and regain test */ | ||
|  |     cnt_tmr0_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("beform pause get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_0, cnt_tmr1_0); | ||
|  | 
 | ||
|  |     dprintf("pause rtc timer0/1 and delay %dus\n", delay_us); | ||
|  |     rtc_timer_cnt_pause(RTC_TIMER_ID_0, 1); | ||
|  |     rtc_timer_cnt_pause(RTC_TIMER_ID_1, 1); | ||
|  |     dprintf("timer delay %dus, rtc tick:%d\n", delay_us, rtc_tick_us); | ||
|  |     iot_delay_us(delay_us); | ||
|  |     cnt_tmr0_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("after pause get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_1, cnt_tmr1_1); | ||
|  | 
 | ||
|  |     cnt_d0 = cnt_tmr0_1 - cnt_tmr0_0; | ||
|  |     cnt_d1 = cnt_tmr1_1 - cnt_tmr1_0; | ||
|  |     dprintf("get cnt diff, timer0:%d, timer1:%d\n", cnt_d0, cnt_d1); | ||
|  |     if (cnt_d0 >= rtc_tick_us || cnt_d1 >= rtc_tick_us) { | ||
|  |         dprintf("pause rtc timer failed\n"); | ||
|  |         goto fail; | ||
|  |     } | ||
|  | 
 | ||
|  |     dprintf("regain rtc timer0/1 and delay %dus\n", delay_us); | ||
|  |     rtc_timer_cnt_pause(RTC_TIMER_ID_0, 0); | ||
|  |     rtc_timer_cnt_pause(RTC_TIMER_ID_1, 0); | ||
|  |     dprintf("timer delay %dus, rtc tick:%d\n", delay_us, rtc_tick_us); | ||
|  |     iot_delay_us(delay_us); | ||
|  |     cnt_tmr0_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("after regain get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_0, cnt_tmr1_0); | ||
|  | 
 | ||
|  |     cnt_d0 = cnt_tmr0_0 - cnt_tmr0_1; | ||
|  |     cnt_d1 = cnt_tmr1_0 - cnt_tmr1_1; | ||
|  |     dprintf("get cnt diff, timer0:%d, timer1:%d\n", cnt_d0, cnt_d1); | ||
|  |     if (cnt_d0 + DTEST_RTC_OPT_CNT_COMPENSATION < rtc_tick_us || | ||
|  |         cnt_d1 + DTEST_RTC_OPT_CNT_COMPENSATION< rtc_tick_us) { | ||
|  |         dprintf("regain rtc timer failed\n"); | ||
|  |         goto fail; | ||
|  |     } | ||
|  | 
 | ||
|  |     dcase_success(); | ||
|  |     return ERR_OK; | ||
|  | fail: | ||
|  |     dcase_failed(); | ||
|  |     return ERR_FAIL; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t dtest_rtc_start_stop_test() | ||
|  | { | ||
|  |     uint32_t cnt_tmr0_0, cnt_tmr1_0, cnt_tmr0_1, cnt_tmr1_1, cnt_d0, cnt_d1; | ||
|  |     uint32_t delay_us = 1000000; | ||
|  |     uint32_t rtc_tick_us = DTEST_RTC_MS_TO_RTC_TICK(delay_us / 1000); | ||
|  | 
 | ||
|  |     dcase_start("rtc timer start and stop\n"); | ||
|  | 
 | ||
|  |     /* start and stop test */ | ||
|  |     cnt_tmr0_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("beform stop get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_0, cnt_tmr1_0); | ||
|  | 
 | ||
|  |     dprintf("stop rtc timer0/1 and delay %dus\n", delay_us); | ||
|  |     rtc_timer_cnt_disable(RTC_TIMER_ID_0); | ||
|  |     rtc_timer_cnt_disable(RTC_TIMER_ID_1); | ||
|  |     dprintf("timer delay %dus, rtc tick:%d\n", delay_us, rtc_tick_us); | ||
|  |     iot_delay_us(delay_us); | ||
|  |     cnt_tmr0_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_1 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("after stop get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_1, cnt_tmr1_1); | ||
|  | 
 | ||
|  |     cnt_d0 = cnt_tmr0_1 - cnt_tmr0_0; | ||
|  |     cnt_d1 = cnt_tmr1_1 - cnt_tmr1_0; | ||
|  |     dprintf("get cnt diff, timer0:%d, timer1:%d\n", cnt_d0, cnt_d1); | ||
|  |     if (cnt_d0 >= rtc_tick_us || cnt_d1 >= rtc_tick_us) { | ||
|  |         dprintf("stop rtc timer failed\n"); | ||
|  |         goto fail; | ||
|  |     } | ||
|  | 
 | ||
|  |     dprintf("restart rtc timer0/1 and delay %dus, rtc tick:%d\n", delay_us, rtc_tick_us); | ||
|  |     rtc_timer_cnt_enable(RTC_TIMER_ID_0); | ||
|  |     rtc_timer_cnt_enable(RTC_TIMER_ID_1); | ||
|  |     iot_delay_us(delay_us); | ||
|  |     cnt_tmr0_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     cnt_tmr1_0 = rtc_timer_cnt_value_get(RTC_TIMER_ID_1); | ||
|  |     dprintf("after restart get cnt value, timer0:%d, timer1:%d\n", cnt_tmr0_0, cnt_tmr1_0); | ||
|  | 
 | ||
|  |     if (cnt_tmr0_0 < cnt_tmr0_1 && cnt_tmr1_0 < cnt_tmr1_1) { | ||
|  |         dprintf("cnt enable will start form 0!!!\n"); | ||
|  |     } | ||
|  | 
 | ||
|  |     cnt_d0 = cnt_tmr0_0 - cnt_tmr0_1; | ||
|  |     cnt_d1 = cnt_tmr1_0 - cnt_tmr1_1; | ||
|  |     dprintf("get cnt diff, timer0:%d, timer1:%d\n", cnt_d0, cnt_d1); | ||
|  |     if (cnt_d0 + DTEST_RTC_OPT_CNT_COMPENSATION < rtc_tick_us || | ||
|  |         cnt_d1 + DTEST_RTC_OPT_CNT_COMPENSATION < rtc_tick_us) { | ||
|  |         dprintf("restart rtc timer failed\n"); | ||
|  |         goto fail; | ||
|  |     } | ||
|  | 
 | ||
|  |     dcase_success(); | ||
|  |     return ERR_OK; | ||
|  | fail: | ||
|  |     dcase_failed(); | ||
|  |     return ERR_FAIL; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t dtest_rtc_interrupt_handle(uint32_t vector, iot_addrword_t data) | ||
|  | { | ||
|  |     uint32_t scratch_val = ahb_scratch_reg_get(DTEST_RTC_SCRATCH_INDEX);; | ||
|  | 
 | ||
|  |     dprintf("interrupt trigger, vector:%d, data:%d\n", vector, data); | ||
|  | 
 | ||
|  |     if (vector == HAL_VECTOR_RTC_TMR_0 && data == RTC_TIMER_ID_0) { | ||
|  |         dprintf("timer 0 interrupt\n"); | ||
|  |     } else if (vector == HAL_VECTOR_RTC_TMR_1 && data == RTC_TIMER_ID_1) { | ||
|  |         dprintf("timer 1 interrupt\n"); | ||
|  |     } else { | ||
|  |         dprintf("interrupt source or data error\n"); | ||
|  |         IOT_ASSERT(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     rtc_timer_int_clear(data); | ||
|  |     ahb_scratch_reg_set(DTEST_RTC_SCRATCH_INDEX, scratch_val | (1 << data)); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t dtest_rtc_interrupt_test() | ||
|  | { | ||
|  |     uint8_t i; | ||
|  |     uint32_t vector, temp; | ||
|  |     uint32_t wait_delay_us = 100000, wait_cnt_max = 70; //7s
 | ||
|  |     iot_irq_t rtc_irq[RTC_TIMER_ID_MAX]; | ||
|  |     uint32_t delay_us = 3 * 1000 * 1000;    //3s
 | ||
|  |     uint32_t rtc_tick_us = DTEST_RTC_MS_TO_RTC_TICK(delay_us / 1000); | ||
|  | 
 | ||
|  |     dcase_start("rtc interrupt test\n"); | ||
|  | 
 | ||
|  |     /* init scratch register */ | ||
|  |     ahb_scratch_reg_set(DTEST_RTC_SCRATCH_INDEX, 0); | ||
|  | 
 | ||
|  |     /* rtc interrupt trigger condition set */ | ||
|  |     rtc_timer_cnt_disable(RTC_TIMER_ID_0); | ||
|  |     rtc_timer_cnt_disable(RTC_TIMER_ID_1); | ||
|  |     /* timer0 sets the count value by the compensation value */ | ||
|  |     temp = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     temp = 0xffffffff - temp - rtc_tick_us; | ||
|  |     rtc_timer_cnt_compensate_set(RTC_TIMER_ID_0, 1, temp); | ||
|  |     /* timer1 sets the interrupt by modifying the threshold */ | ||
|  |     rtc_timer_cnt_value_max_set(RTC_TIMER_ID_1, rtc_tick_us); | ||
|  |     rtc_timer_cnt_value_set(RTC_TIMER_ID_1, 0x00); | ||
|  |     /* enable cnt */ | ||
|  |     rtc_timer_cnt_enable(RTC_TIMER_ID_0); | ||
|  |     rtc_timer_cnt_enable(RTC_TIMER_ID_1); | ||
|  | 
 | ||
|  |     /* rtc interrupt enable */ | ||
|  |     rtc_timer_int_clear(RTC_TIMER_ID_0); | ||
|  |     rtc_timer_int_clear(RTC_TIMER_ID_1); | ||
|  |     rtc_timer_int_enable(RTC_TIMER_ID_0); | ||
|  |     rtc_timer_int_enable(RTC_TIMER_ID_1); | ||
|  | 
 | ||
|  |     /* interrupt handle create */ | ||
|  |     for (i = RTC_TIMER_ID_0; i < RTC_TIMER_ID_MAX; i++) { | ||
|  |         vector = rtc_timer_get_vector(i); | ||
|  |         rtc_irq[i] = iot_interrupt_create(vector, HAL_INTR_PRI_6, | ||
|  |             (iot_addrword_t)i, dtest_rtc_interrupt_handle); | ||
|  |         iot_interrupt_attach(rtc_irq[i]); | ||
|  |         iot_interrupt_unmask(rtc_irq[i]); | ||
|  |     } | ||
|  | 
 | ||
|  |     /* waiting interrupt function exit */ | ||
|  |     i = 0; | ||
|  |     while (ahb_scratch_reg_get(DTEST_RTC_SCRATCH_INDEX) != 0x3) { | ||
|  |         iot_delay_us(wait_delay_us); | ||
|  |         i++; | ||
|  |         if (i >= wait_cnt_max) { | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  |     rtc_timer_int_disable(RTC_TIMER_ID_0); | ||
|  |     rtc_timer_int_disable(RTC_TIMER_ID_1); | ||
|  | 
 | ||
|  |     if (i >= wait_cnt_max) { | ||
|  |         dcase_failed(); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     dcase_success(); | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t dtest_rtc_cascade_test() | ||
|  | { | ||
|  |     uint64_t cnt = 0, cnt_expect; | ||
|  |     uint32_t delay_us = 1 * 1000 * 1000;    //1s
 | ||
|  |     uint32_t rtc_tick_us = DTEST_RTC_MS_TO_RTC_TICK(delay_us / 1000); | ||
|  |     uint32_t cnt_h, cnt_l; | ||
|  | 
 | ||
|  |     dcase_start("rtc cascade test\n"); | ||
|  |     rtc_deinit(); | ||
|  |     rtc_init(RTC_INIT_MODE_CASCADE); | ||
|  | 
 | ||
|  |     /* reconfigure to ensure that the count value exceeding MAX_UINT32 */ | ||
|  |     dprintf("reconfigure to ensure that the count value exceeding MAX_UINT32\n"); | ||
|  |     rtc_timer_cnt_disable(RTC_TIMER_ID_0); | ||
|  | //    rtc_timer_cnt_disable(RTC_TIMER_ID_1);
 | ||
|  |     rtc_timer_cnt_value_set(RTC_TIMER_ID_0, 0xffffffff); | ||
|  |     rtc_timer_cnt_value_set(RTC_TIMER_ID_1, 0); | ||
|  |     rtc_timer_cnt_enable(RTC_TIMER_ID_0); | ||
|  | //    rtc_timer_cnt_enable(RTC_TIMER_ID_1);
 | ||
|  | 
 | ||
|  |     /* delay sometime */ | ||
|  |     dprintf("gptimer delay %dus, rtc tick:%d\n", delay_us, rtc_tick_us); | ||
|  |     iot_delay_us(delay_us); | ||
|  | 
 | ||
|  |     cnt = rtc_cascade_cnt_get(); | ||
|  |     cnt_h = (cnt >> 32) & 0xffffffff; | ||
|  |     cnt_l = cnt & 0xffffffff; | ||
|  |     dprintf("get rtc cascade cnt:%d(H), %d(L)\n", cnt_h, cnt_l); | ||
|  |     dprintf("get rtc cascade cnt:%llu\n", cnt); | ||
|  |     cnt_expect = (uint64_t)0xffffffff + (uint64_t)rtc_tick_us; | ||
|  |     cnt_h = (cnt_expect >> 32) & 0xffffffff; | ||
|  |     cnt_l = cnt_expect & 0xffffffff; | ||
|  |     dprintf("get rtc cascade cnt expect:%d(H), %d(L)\n", cnt_h, cnt_l); | ||
|  |     dprintf("get rtc cascade cnt expect:%llu\n", cnt_expect); | ||
|  |     if (cnt + DTEST_RTC_OPT_CNT_COMPENSATION <= cnt_expect || | ||
|  |         cnt_h != 1) { | ||
|  |         dprintf("timer cnt less than expected\n"); | ||
|  |         goto fail; | ||
|  |     } | ||
|  | 
 | ||
|  |     dcase_success(); | ||
|  |     return ERR_OK; | ||
|  | fail: | ||
|  |     dcase_failed(); | ||
|  |     return ERR_FAIL; | ||
|  | } | ||
|  | 
 | ||
|  | extern struct uart_ctrl uart_e_ctrl; | ||
|  | static uint32_t dtest_rtc_accuracy_test() | ||
|  | { | ||
|  |     uint32_t cnt_old, cnt_new, cnt_d; | ||
|  |     uint32_t ms_old, ms_new, ms_d; | ||
|  |     uint32_t sec_old, sec_new, sec_d; | ||
|  |     uint32_t delay_us = 3600000000; // 1*60*60*1000*1000 = 1th
 | ||
|  |     uint32_t rtc_tick_us = DTEST_RTC_MS_TO_RTC_TICK(delay_us / 1000), tick_diff; | ||
|  | 
 | ||
|  |     dcase_start("rtc accuracy test\n"); | ||
|  | 
 | ||
|  |     for (uint8_t i = 0; i < 3; i++) { | ||
|  |         wdg_deinit(i); | ||
|  |     } | ||
|  |     rtc_timer_cnt_value_set(RTC_TIMER_ID_0, 0); | ||
|  | 
 | ||
|  |     uart_e_ctrl.putc(0, 'a'); | ||
|  |     uart_e_ctrl.putc(0, 'a'); | ||
|  |     uart_e_ctrl.putc(0, 'a'); | ||
|  |     uart_e_ctrl.putc(0, '\n'); | ||
|  |     cnt_old = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     uart_e_ctrl.putc(0, 'b'); | ||
|  |     uart_e_ctrl.putc(0, '\n'); | ||
|  |     for (uint8_t i = 0; i < 24; i++) { | ||
|  |         iot_delay_us(delay_us); | ||
|  |     } | ||
|  |     cnt_new = rtc_timer_cnt_value_get(RTC_TIMER_ID_0); | ||
|  |     uart_e_ctrl.putc(0, 'c'); | ||
|  |     uart_e_ctrl.putc(0, '\n'); | ||
|  | 
 | ||
|  |     ms_old = DTEST_RTC_TICK_TO_MS(cnt_old); | ||
|  |     sec_old = DTEST_RTC_TICK_TO_S(cnt_old); | ||
|  |     dprintf("get first second:%lu, ms:%lu, cnt:%lu\n", sec_old, ms_old, cnt_old); | ||
|  | 
 | ||
|  |     dprintf("gptimer delay %ds(%dms)\n", delay_us / 1000 / 1000, delay_us / 1000); | ||
|  | 
 | ||
|  |     ms_new = DTEST_RTC_TICK_TO_MS(cnt_new); | ||
|  |     sec_new = DTEST_RTC_TICK_TO_S(cnt_new); | ||
|  |     dprintf("get last second:%lu, ms:%lu, cnt:%lu\n", sec_new, ms_new, cnt_new); | ||
|  | 
 | ||
|  |     sec_d = sec_new - sec_old; | ||
|  |     ms_d = ms_new - ms_old; | ||
|  |     cnt_d = cnt_new - cnt_old; | ||
|  |     dprintf("second diff:%lu, ms diff:%lu, cnt diff:%lu\n", sec_d, ms_d, cnt_d); | ||
|  |     tick_diff = ((rtc_tick_us > cnt_d) ? (rtc_tick_us - cnt_d) : (cnt_d - rtc_tick_us)); | ||
|  |     dprintf("cnt diff:%lu, expect:%lu, diff:%lu\n", cnt_d, rtc_tick_us, tick_diff); | ||
|  | 
 | ||
|  |     dcase_success(); | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | extern void wdg_eb_enable(uint8_t cpu); | ||
|  | static uint32_t dtest_rtc_wdg_rst_test() | ||
|  | { | ||
|  |     uint8_t core = cpu_get_mhartid(); | ||
|  |     uint32_t rst_delay = 3; | ||
|  |     volatile uint32_t *rtc_reg_ptr = (volatile uint32_t *)(RTC_TMR0_BASEADDR); | ||
|  | 
 | ||
|  |     dcase_start("rtc watchdog reset test\n"); | ||
|  | 
 | ||
|  |     dprintf("rtc register dump:\n"); | ||
|  |     for (uint8_t i = 0; i < 28 / 4; i++) { | ||
|  |         iot_printf("\t%p:\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", rtc_reg_ptr, | ||
|  |             *rtc_reg_ptr, *(rtc_reg_ptr + 1), *(rtc_reg_ptr + 2), *(rtc_reg_ptr + 3)); | ||
|  |         rtc_reg_ptr += 4; | ||
|  |     } | ||
|  | 
 | ||
|  |     dprintf("module will be reset by wdg after %ds\n", rst_delay); | ||
|  | 
 | ||
|  |     wdg_eb_enable(core); | ||
|  |     wdg_set_cmp(core, SYS_CLK_VAL); | ||
|  |     wdg_set_timeout_cmp(core, rst_delay * 10); | ||
|  |     wdg_set_cpurst_cmp(core, rst_delay * 10); | ||
|  |     wdg_set_fullrst_cmp(core, rst_delay); | ||
|  |     wdg_cnt_enable(core); | ||
|  |     wdg_enable(core); | ||
|  | 
 | ||
|  |     while(1) { | ||
|  |         iot_delay_us(500 * 1000); | ||
|  |         iot_printf("."); | ||
|  |     } | ||
|  | 
 | ||
|  |     dcase_success(); | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | static void dtest_rtc_main() | ||
|  | { | ||
|  |     uint32_t case_group = 0, failed_cnt = 0; | ||
|  | 
 | ||
|  |     dbg_uart_init(); | ||
|  | 
 | ||
|  |     dconfig(); | ||
|  |     dstart(); | ||
|  |     dversion(); | ||
|  | 
 | ||
|  |     if (dtest_get_case_group(&case_group) < 0) { | ||
|  |         case_group = 0xffffffff; | ||
|  |     } | ||
|  |     dprintf("get case group:0x%08X\n", case_group); | ||
|  | 
 | ||
|  |     gp_timer_init(); | ||
|  |     gp_timer_set(0, 0xffffffff, 0); | ||
|  |     gp_timer_start(0); | ||
|  | 
 | ||
|  |     rtc_init(RTC_INIT_MODE_TIMER); | ||
|  | 
 | ||
|  |     if (case_group & DTEST_RTC_CASE_TIMER_CNT_GET_SET) { | ||
|  |         if (dtest_rtc_cnt_get_set_test()) { | ||
|  |             failed_cnt++; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (case_group & DTEST_RTC_CASE_TIMER_PAUSE_REGAIN) { | ||
|  |         if (dtest_rtc_pause_regain_test()) { | ||
|  |             failed_cnt++; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (case_group & DTEST_RTC_CASE_TIMER_START_STOP) { | ||
|  |         if (dtest_rtc_start_stop_test()) { | ||
|  |             failed_cnt++; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (case_group & DTEST_RTC_CASE_TIMER_INTERRUPT) { | ||
|  |         if (dtest_rtc_interrupt_test()) { | ||
|  |             failed_cnt++; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (case_group & DTEST_RTC_CASE_TIMER_CASCADE) { | ||
|  |         if (dtest_rtc_cascade_test()) { | ||
|  |             failed_cnt++; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* manual test */ | ||
|  | //    if (case_group & DTEST_RTC_CASE_TIMER_ACCURACY) {
 | ||
|  |     if (0) { | ||
|  |         if (dtest_rtc_accuracy_test()) { | ||
|  |             failed_cnt++; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* manual test, use gdb dump register after wdg reset */ | ||
|  | //    if (case_group & DTEST_RTC_CASE_WDG_RESET) {
 | ||
|  |     if (0) { | ||
|  |         if (dtest_rtc_wdg_rst_test()) { | ||
|  |             failed_cnt++; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (failed_cnt) { | ||
|  |         dprintf("rtc dtest failed\n"); | ||
|  |     } else { | ||
|  |         dprintf("rtc dtest succeed\n"); | ||
|  |     } | ||
|  | 
 | ||
|  |     dend(); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | int main(void) | ||
|  | { | ||
|  |     dtest_rtc_main(); | ||
|  |     return 0; | ||
|  | } |