rt-thread-official/bsp/nuvoton/libraries/n9h30/rtt_port/drv_systick.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 */