xiuos/Ubiquitous/XiZi_AIoT/services/drivers/rk-3568/ethernet/hal_timer.c

307 lines
6.7 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd.
*/
#include "hal_base.h"
#include "hal_def.h"
#include "hal_timer.h"
/** @addtogroup RK_HAL_Driver
* @{
*/
/** @addtogroup TIMER
* @{
*/
/** @defgroup TIMER_How_To_Use How To Use
* @{
The TIMER driver can be used as follows:
- IT mode: Resgister TIMER handler.
- Initialize the TIMER by calling HAL_TIMER_Init():
- Set TIMER count by calling HAL_TIMER_SetCount().
- Start the TIMER by calling HAL_TIMER_Start() or HAL_TIMER_Start_IT().
- Stop the TIMER by calling HAL_TIMER_Stop() or HAL_TIMER_Stop_IT().
SYS_TIMER
- SYS_TIMER is a rk timer fixed to serve the delay system. Invoke HAL_TIMER_SysTimerInit() to init.
@} */
/** @defgroup TIMER_Private_Definition Private Definition
* @{
*/
/********************* Private MACRO Definition ******************************/
#define TIMER_CONTROLREG_TIMER_MODE_FREE_RUNNING (0x0U << TIMER_CONTROLREG_TIMER_MODE_SHIFT)
#define TIMER_CONTROLREG_TIMER_ENABLE_ENABLED (0x1U << TIMER_CONTROLREG_TIMER_ENABLE_SHIFT)
#define TIMER_CONTROLREG_TIMER_ENABLE_DISABLED (0x0U << TIMER_CONTROLREG_TIMER_ENABLE_SHIFT)
#define TIMER_CONTROLREG_TIMER_INT_MASK_UNMASK (0x1U << TIMER_CONTROLREG_TIMER_INT_MASK_SHIFT)
/********************* Private Structure Definition **************************/
/********************* Private Variable Definition ***************************/
/********************* Private Function Definition ***************************/
/** @} */
/********************* Public Function Definition ****************************/
/** @defgroup TIMER_Exported_Functions_Group4 Init and DeInit Functions
This section provides functions allowing to init and deinit module as follows:
* @{
*/
/**
* @brief Timer init.
* @param pReg: Choose TIMER.
* @param mode: Choose TIMER mode.
* @return HAL_Status.
*/
HAL_Status HAL_TIMER_Init(struct TIMER_REG *pReg, eTIMER_MODE mode)
{
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
#ifdef SYS_TIMER
if (pReg == SYS_TIMER) {
return HAL_BUSY;
}
#endif
WRITE_REG(pReg->CONTROLREG, mode << TIMER_CONTROLREG_TIMER_MODE_SHIFT);
return HAL_OK;
}
/**
* @brief System Timer init.
* @return HAL_Status.
* @attention this API allow direct use in the HAL layer. SYS_TTIMER is used for delay system.
*/
HAL_Status HAL_TIMER_SysTimerInit(struct TIMER_REG *pReg)
{
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
if (READ_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK)) {
return HAL_OK;
}
WRITE_REG(pReg->CONTROLREG, TIMER_FREE_RUNNING);
pReg->LOAD_COUNT[0] = 0xFFFFFFFFU;
pReg->LOAD_COUNT[1] = 0xFFFFFFFFU;
CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_INT_MASK_MASK);
SET_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
return HAL_OK;
}
/**
* @brief Timer deinit.
* @param pReg: Choose TIMER.
* @return HAL_Status.
*/
HAL_Status HAL_TIMER_DeInit(struct TIMER_REG *pReg)
{
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
#ifdef SYS_TIMER
if (pReg == SYS_TIMER) {
return HAL_BUSY;
}
#endif
WRITE_REG(pReg->CONTROLREG, 0);
return HAL_OK;
}
/** @} */
/** @defgroup TIMER_Exported_Functions_Group5 Other Functions
* @{
*/
/**
* @brief Start TIMER counter.
* @param pReg: Choose TIMER.
* @return HAL_Status.
*/
HAL_Status HAL_TIMER_Start(struct TIMER_REG *pReg)
{
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
#ifdef SYS_TIMER
if (pReg == SYS_TIMER) {
return HAL_BUSY;
}
#endif
CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_INT_MASK_MASK);
SET_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
return HAL_OK;
}
/**
* @brief Stop TIMER counter.
* @param pReg: Choose TIMER.
* @return HAL_Status.
* Just disable TIMER, and keep TIMER configuration.
*/
HAL_Status HAL_TIMER_Stop(struct TIMER_REG *pReg)
{
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
#ifdef SYS_TIMER
if (pReg == SYS_TIMER) {
return HAL_BUSY;
}
#endif
CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
return HAL_OK;
}
/**
* @brief Start TIMER counter in interrupt mode.
* @param pReg: Choose TIMER.
* @return HAL_Status.
*/
HAL_Status HAL_TIMER_Start_IT(struct TIMER_REG *pReg)
{
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
#ifdef SYS_TIMER
if (pReg == SYS_TIMER) {
return HAL_BUSY;
}
#endif
SET_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_ENABLED | TIMER_CONTROLREG_TIMER_INT_MASK_UNMASK);
return HAL_OK;
}
/**
* @brief Stop TIMER counter in interrupt mode.
* @param pReg: Choose TIMER.
* @return HAL_Status.
* Just disable TIMER, and keep TIMER configuration.
*/
HAL_Status HAL_TIMER_Stop_IT(struct TIMER_REG *pReg)
{
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
#ifdef SYS_TIMER
if (pReg == SYS_TIMER) {
return HAL_BUSY;
}
#endif
CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
return HAL_OK;
}
/**
* @brief Set TIMER count number.
* @param pReg: Choose TIMER.
* @param timerCount: TIMER counter loading number.
* @return HAL_Status.
* Set timer count number.
*/
HAL_Status HAL_TIMER_SetCount(struct TIMER_REG *pReg, uint64_t timerCount)
{
uint64_t loadCount = 0;
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
#ifdef SYS_TIMER
if (pReg == SYS_TIMER) {
return HAL_BUSY;
}
#endif
loadCount = timerCount;
pReg->LOAD_COUNT[0] = (loadCount & 0xffffffff);
pReg->LOAD_COUNT[1] = ((loadCount >> 32) & 0xffffffff);
return HAL_OK;
}
/**
* @brief Get TIMER count number.
* @param pReg: Choose TIMER.
* @return uint64_t: Current conut number.
*/
HAL_SECTION_SRAM_CODE
uint64_t HAL_TIMER_GetCount(struct TIMER_REG *pReg)
{
uint32_t high, low, temp;
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
do {
high = pReg->CURRENT_VALUE[1];
low = pReg->CURRENT_VALUE[0];
temp = pReg->CURRENT_VALUE[1];
} while (high != temp);
return ((uint64_t)high << 32) | low;
}
/**
* @brief Clear TIMER interrupt status.
* @param pReg: Choose TIMER.
* @return HAL_Status: HAL_OK.
*/
HAL_Status HAL_TIMER_ClrInt(struct TIMER_REG *pReg)
{
uint32_t timeOut = 1000;
HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
pReg->INTSTATUS = 0x1;
while (pReg->INTSTATUS && timeOut) {
timeOut--;
}
if (timeOut == 0) {
return HAL_TIMEOUT;
} else {
return HAL_OK;
}
}
/**
* @brief TIMER0 interrupt handler.
* @return HAL_Status: HAL_OK.
* Clear interrupt status.
*/
__attribute__((weak)) HAL_Status HAL_TIMER0_Handler(void)
{
HAL_TIMER_ClrInt(TIMER0);
return HAL_OK;
}
/**
* @brief TIMER1 interrupt handler.
* @return HAL_Status: HAL_OK.
* Clear interrupt status.
*/
__attribute__((weak)) HAL_Status HAL_TIMER1_Handler(void)
{
HAL_TIMER_ClrInt(TIMER1);
return HAL_OK;
}
/** @} */
/** @} */
/** @} */