93 lines
2.4 KiB
C
93 lines
2.4 KiB
C
|
/**************************************************************************//**
|
||
|
*
|
||
|
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2020-11-11 Wayne First version
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
#include "rtthread.h"
|
||
|
#include "NuMicro.h"
|
||
|
#include "drv_sys.h"
|
||
|
#include "nu_timer.h"
|
||
|
|
||
|
#define USE_TIMER 4
|
||
|
|
||
|
/* Concatenate */
|
||
|
#define _CONCAT2_(x, y) x##y
|
||
|
#define _CONCAT3_(x, y, z) x##y##z
|
||
|
#define CONCAT2(x, y) _CONCAT2_(x, y)
|
||
|
#define CONCAT3(x, y, z) _CONCAT3_(x,y,z)
|
||
|
|
||
|
/* Concatenate the macros of timer instance for driver usage. */
|
||
|
#define SYSTICK_IRQ CONCAT2(IRQ_TMR, USE_TIMER )
|
||
|
|
||
|
#define SYSTICK_CLKEN CONCAT3(TIMER, USE_TIMER, CKEN)
|
||
|
|
||
|
#define SYSTICK_RST CONCAT3(TIMER, USE_TIMER, RST)
|
||
|
|
||
|
static void nu_systick_isr(int vector, void *param)
|
||
|
{
|
||
|
rt_tick_increase();
|
||
|
TIMER_ClearIntFlag(USE_TIMER);
|
||
|
}
|
||
|
|
||
|
void rt_hw_systick_init(void)
|
||
|
{
|
||
|
nu_sys_ipclk_enable(SYSTICK_CLKEN);
|
||
|
|
||
|
nu_sys_ip_reset(SYSTICK_RST);
|
||
|
|
||
|
// Set timer frequency
|
||
|
TIMER_Open(USE_TIMER, TIMER_PERIODIC_MODE, RT_TICK_PER_SECOND);
|
||
|
|
||
|
// Enable timer interrupt
|
||
|
TIMER_EnableInt(USE_TIMER);
|
||
|
|
||
|
rt_hw_interrupt_install(SYSTICK_IRQ, nu_systick_isr, RT_NULL, "systick");
|
||
|
rt_hw_interrupt_set_priority(SYSTICK_IRQ, IRQ_LEVEL_1);
|
||
|
rt_hw_interrupt_umask(SYSTICK_IRQ);
|
||
|
|
||
|
TIMER_Start(USE_TIMER);
|
||
|
} /* rt_hw_systick_init */
|
||
|
|
||
|
void rt_hw_us_delay(rt_uint32_t us)
|
||
|
{
|
||
|
rt_uint32_t ticks;
|
||
|
rt_uint32_t told, tnow, tcnt = 0;
|
||
|
rt_uint32_t cmp = TIMER_GetCompareData(USE_TIMER);
|
||
|
|
||
|
ticks = us * cmp / (1000000 / RT_TICK_PER_SECOND);
|
||
|
told = TIMER_GetCounter(USE_TIMER);
|
||
|
while (1)
|
||
|
{
|
||
|
/* Timer counter is increment. */
|
||
|
tnow = TIMER_GetCounter(USE_TIMER);
|
||
|
if (tnow != told)
|
||
|
{
|
||
|
/* 0 -- old === now -------- cmp */
|
||
|
if (tnow > told)
|
||
|
{
|
||
|
tcnt += tnow - told;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* 0 == now --- old ======== cmp */
|
||
|
tcnt += cmp - told + tnow;
|
||
|
}
|
||
|
told = tnow;
|
||
|
|
||
|
/* Timeout */
|
||
|
if (tcnt >= ticks)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} /* rt_hw_us_delay */
|