Files
2026-06-06 16:49:48 +08:00

220 lines
7.3 KiB
C

/*!
* \file xc_drv_aotimer.c
*
* \brief Target xinchip aotimer driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "xc_drv_aotimer.h"
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
static bool aotimer_rst_flag = false;
/*------------------------------------------------------------------------------------
Func Prototype
-------------------------------------------------------------------------------------*/
aotimer_handler_callback aotimer_n_callback[2] = {aotimer0_callback,
aotimer1_callback};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
**************************************************************************************
* @brief xc_aotimer_init
* @details Example Initialize the aotimer according to its number
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
* @param[in] *init_cfg : This is the structure parameter that the AOTimer initializes
* @param[out] void
* @retval void
***************************************************************************************
*/
void xc_aotimer_init(uint8_t reg_idx, AOTimer_InitCfg_t *init_cfg)
{
if (aotimer_rst_flag == false) {
cprao_aon_clken_grctl__timer_ao_pclk_en__setf(ENABLE);
aotimer_rst_flag = true;
}
//The clocks for ao timer0 and ao timer1 need to be turned on at the same time.
if (AOTIMER0_IDX == reg_idx) {
cprao_aon_clken_grctl__timer0_ao_pclk_en__setf(ENABLE);
cprao_aon_clken_grctl__timer1_ao_pclk_en__setf(ENABLE);
} else if (AOTIMER1_IDX == reg_idx) {
cprao_aon_clken_grctl__timer0_ao_pclk_en__setf(ENABLE);
cprao_aon_clken_grctl__timer1_ao_pclk_en__setf(ENABLE);
}
cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE);
aotimer_tcr__tes__setf(reg_idx, DISABLE);
aotimer_tcr__tms__setf(reg_idx, (uint8_t)init_cfg->aotimer_mode);
(void)aotimer_tic__tic__getf(reg_idx);
}
/**
**************************************************************************************
* @brief xc_aotimer_us_to_ticks
* @details Returns the number of ticks according to the time to be set by the aotimer
* @param[in] us : Time set by the timer (Microsecond is the smallest unit)
* @param[out] void
* @retval ticks ( Tick count )
***************************************************************************************
*/
static uint32_t xc_aotimer_us_to_ticks(uint32_t us)
{
uint32_t ticks = AOTIMER_TICK_CAL(us);
if (ticks < AOTIMER_MIN_TLC_VAL)
ticks = AOTIMER_MIN_TLC_VAL;
return ticks;
}
/**
**************************************************************************************
* @brief xc_aotimer_set_value
* @details Set the timing time according to the aotimer number
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
* @param[in] us : Time set by the timer (Microsecond is the smallest unit)
* @param[out] void
* @retval void
***************************************************************************************
*/
void xc_aotimer_set_value(uint8_t reg_idx, uint32_t us)
{
uint32_t ticks = xc_aotimer_us_to_ticks(us);
aotimer_tcr__tes__setf(reg_idx, AOTIMER_TCR_TES_DISABLE);
aotimer_tlc_set(reg_idx, ticks);
}
/**
**************************************************************************************
* @brief xc_aotimer_start
* @details Start the timer according to the aotimer number
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
* @param[out] void
* @retval void
***************************************************************************************
*/
void xc_aotimer_start(uint8_t reg_idx)
{
NVIC_EnableIRQ( (IRQn_Type)(TIMER_AO0_IRQn+reg_idx) );
aotimer_tcr__tim__setf(reg_idx, 0);
aotimer_tcr__tes__setf(reg_idx, ENABLE);
// Wait for timer enable
while(aotimer_tcr__tes__getf(reg_idx) != ENABLE)
{
__nop();
}
}
/**
**************************************************************************************
* @brief xc_aotimer_stop
* @details Stop the timer according to the aotimer number
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
* @param[out] void
* @retval void
***************************************************************************************
*/
void xc_aotimer_stop(uint8_t reg_idx)
{
aotimer_tcr__tes__setf(reg_idx, DISABLE);
}
/**
**************************************************************************************
* @brief AOTIMER0_Handler
* @details AOTIMER0 Interrupt function
* @param[in] void
* @param[out] void
* @retval void
***************************************************************************************
*/
void AOTIMER0_Handler(void)
{
cprao_aon_reg1__timer_ao_sleep_clksw__setf(0);
(void)aotimer_tic__tic__getf(AOTIMER0_IDX);
if (aotimer_n_callback[0] != NULL)
aotimer_n_callback[0](NULL);
}
/**
**************************************************************************************
* @brief AOTIMER1_Handler
* @details AOTIMER1 Interrupt function
* @param[in] void
* @param[out] void
* @retval void
***************************************************************************************
*/
void AOTIMER1_Handler(void)
{
cprao_aon_reg1__timer_ao_sleep_clksw__setf(0);
(void)aotimer_tic__tic__getf(AOTIMER1_IDX);
if (aotimer_n_callback[1] != NULL)
aotimer_n_callback[1](NULL);
}
/**
**************************************************************************************
* @brief aotimer0_callback
* @details AOTIMER0 Interrupt the callback function
* @param[in] void
* @param[out] void
* @retval void
***************************************************************************************
*/
__WEAK void aotimer0_callback(void *context)
{ /* AOTimer0 中断回调处理事件 */
}
/**
**************************************************************************************
* @brief aotimer1_callback
* @details AOTIMER1 Interrupt the callback function
* @param[in] void
* @param[out] void
* @retval void
***************************************************************************************
*/
__WEAK void aotimer1_callback(void *context)
{ /* AOTimer1 中断回调处理事件 */
}