| | |
| | | |
| | | /* SYS Timer */ |
| | | |
| | | uint32_t sys_timer_freq = 0; |
| | | |
| | | void sys_timer_open(void) |
| | | { |
| | | // DIV = 1 (max: ~68.8s, resolution: ~16ns) |
| | | // DIV = 16 (max: ~1101.2s, resolution: ~256ns) |
| | | // DIV = 256 (max: ~17620.3s resolution: ~65us) |
| | | struct DUAL_TIMER_CFG_T sys_timer_cfg = { |
| | | .type = DUAL_TIMER_TYPE_FREERUNNING, |
| | | .prescale = DUAL_TIMER_PRESCALE_DIV1, |
| | | .prescale = SYS_TIMER_DIV == 1 ? DUAL_TIMER_PRESCALE_DIV1 : (SYS_TIMER_DIV == 16 ? DUAL_TIMER_PRESCALE_DIV16 : DUAL_TIMER_PRESCALE_DIV256), |
| | | .width = DUAL_TIMER_SIZE_32BIT, |
| | | .int_en = false, |
| | | .load = 0xffffffff, |
| | |
| | | |
| | | dual_timer_open(DUAL_TIMER_ID0, &sys_timer_cfg); |
| | | dual_timer_start(DUAL_TIMER_ID0, sys_timer_cfg.load); |
| | | uint16_t div = sys_timer_cfg.prescale == DUAL_TIMER_PRESCALE_DIV1 ? 1 : sys_timer_cfg.prescale == DUAL_TIMER_PRESCALE_DIV16 ? 16 : 256; |
| | | sys_timer_freq = clock_get_frequency(CLOCK_APB_CLK) / div; |
| | | } |
| | | |
| | | void sys_timer_close(void) |
| | |
| | | dual_timer_close(DUAL_TIMER_ID0); |
| | | } |
| | | |
| | | #if defined(__ICCARM__) |
| | | #pragma default_function_attributes = __ramfunc |
| | | #endif |
| | | uint32_t sys_timer_get(void) |
| | | { |
| | | return -dual_timer_get(DUAL_TIMER_ID0); |
| | | } |
| | | #if defined(__ICCARM__) |
| | | #pragma default_function_attributes = |
| | | #endif |
| | | |
| | | // max: 68829 us (DIV = 1) |
| | | void sys_timer_delay_us(uint32_t time_us) |
| | |
| | | NVIC_SetPriority(SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ |
| | | SysTick->VAL = 0; /* A write of any value clears the field to 0 */ |
| | | SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ |
| | | // Store SysTick counter |
| | | sys_tick_env.load = ticks; |
| | | } |
| | | |
| | | uint32_t sys_tick_us(void) |
| | |
| | | return sys_tick_env.count; |
| | | } |
| | | |
| | | void sys_tick_callback_set(void (*callback)(void)) |
| | | void sys_tick_callback_set(void (*callback)(uint32_t elapsed_ticks)) |
| | | { |
| | | sys_tick_env.callback = callback; |
| | | } |
| | |
| | | return elapse_ms; |
| | | } |
| | | |
| | | uint32_t sys_tick_elapse_ticks(void) |
| | | { |
| | | uint32_t lock = int_lock(); |
| | | |
| | | uint32_t load = SysTick->LOAD + 1; |
| | | uint32_t val = SysTick->VAL; |
| | | |
| | | uint32_t flag_pending = REG_READ(0xE000ED04) & (1 << 26); |
| | | if (flag_pending) |
| | | { |
| | | val = 0; |
| | | } |
| | | else if (val == 0) |
| | | { |
| | | val = load; |
| | | } |
| | | |
| | | int_unlock(lock); |
| | | |
| | | return load - val; |
| | | } |
| | | |
| | | static uint32_t used_cnt; |
| | | void sys_tick_pause(void) |
| | | { |
| | | // Stop SysTick |
| | |
| | | val = load; |
| | | } |
| | | |
| | | // Store SysTick counter |
| | | sys_tick_env.load = load; |
| | | // SysTick->VAL cannot be set |
| | | sys_tick_env.elapse += (load - val); |
| | | used_cnt = load - val; |
| | | } |
| | | |
| | | void sys_tick_resume(void) |
| | | { |
| | | sys_tick_start(sys_tick_env.load); |
| | | |
| | | uint32_t slp_cnt = high_xtal_off_time(); |
| | | uint32_t slp_cnt = xtal_38m4_off_time(); |
| | | uint32_t cnt = slp_cnt / sys_tick_env.load; |
| | | sys_tick_env.elapse += (slp_cnt - cnt * sys_tick_env.load); |
| | | while (sys_tick_env.elapse >= sys_tick_env.load) |
| | |
| | | } |
| | | |
| | | sys_tick_env.count += cnt; |
| | | if ((sys_tick_env.callback != NULL) && (cnt)) |
| | | slp_cnt += used_cnt; |
| | | if ((sys_tick_env.callback != NULL) && (slp_cnt)) |
| | | { |
| | | sys_tick_env.callback(); |
| | | sys_tick_env.callback(slp_cnt); |
| | | } |
| | | } |
| | | |
| | |
| | | sys_tick_env.count++; |
| | | if (sys_tick_env.callback != NULL) |
| | | { |
| | | sys_tick_env.callback(); |
| | | sys_tick_env.callback(sys_tick_env.load); |
| | | } |
| | | // board_led_off(BOARD_LED_2); |
| | | } |
| | | |
| | | void sys_reset(uint32_t error) |
| | | { |
| | | //LOG_INFO(TRACE_MODULE_DRIVER, "system reboot%x", error); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "system reboot%x", error); |
| | | |
| | | delay_us(10000); |
| | | |
| | | // reboot |
| | | reset_module(RESET_MODULE_REBOOT); |
| | | } |
| | | void delay_US(uint32_t nTimer) |
| | | { |
| | | uint32_t i=0; |
| | | for(i=0;i<nTimer;i++){ |
| | | __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); |
| | | __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); |
| | | __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); |
| | | __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); |
| | | __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); |
| | | __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); |
| | | __NOP();__NOP();__NOP();__NOP(); |
| | | } |
| | | } |
| | | void delay_ms(uint32_t nTimer) |
| | | { |
| | | uint32_t i=1000*nTimer; |
| | | delay_US(i); |
| | | } |
| | | |
| | | void delay_us(uint32_t cnt) |
| | | { |
| | | #define SYSTEM_CLOCK_MHZ 62.4 |
| | |
| | | "bhi loop%=\n" |
| | | "pop {r4,r5}\n" |
| | | "exit%=:\n" |
| | | : |
| | | : [mult_hi] "i"(SYSTEM_CLOCK_MULT_HI), [mult_lo] "i"(SYSTEM_CLOCK_MULT_LO), [shift] "i"(SYSTEM_CLOCK_LSLS_BITS), [adjust] "i"(AAPCS_PREP_CYCLES), |
| | | [decr] "i"(DELAY_LOOP_CYCLES)); |
| | | : |
| | | : [mult_hi] "i"(SYSTEM_CLOCK_MULT_HI), [mult_lo] "i"(SYSTEM_CLOCK_MULT_LO), [shift] "i"(SYSTEM_CLOCK_LSLS_BITS), [adjust] "i"(AAPCS_PREP_CYCLES), |
| | | [decr] "i"(DELAY_LOOP_CYCLES)); |
| | | |
| | | #if defined(__GNUC__) && !defined(__ARMCC_VERSION) |
| | | __asm volatile(".syntax divided\n"); |