MCUXpresso_MCXA153/devices/MCXA153/drivers/fsl_waketimer.c
Yilin Sun 35e678394a
Initial commit v2.14.2
Signed-off-by: Yilin Sun <imi415@imi.moe>
2024-02-11 19:33:06 +08:00

254 lines
6.9 KiB
C

/*
* Copyright 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_waketimer.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.waketimer"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* brief Gets the instance from the base address
*
* param base WAKETIMER peripheral base address
*
* return The WAKETIMER instance
*/
static uint32_t WAKETIMER_GetInstance(WAKETIMER_Type *base);
/*!
* brief WAKETIMER generic IRQ handle function.
*
* param index WAKETIMER peripheral instance index.
*/
static void WAKETIMER_GenericIRQHandler(WAKETIMER_Type *base, waketimer_callback_t callback);
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of WAKETIMER peripheral base address. */
static WAKETIMER_Type *const s_waketimerBases[] = WAKETIMER_BASE_PTRS;
/* Array of WAKETIMER ISR. */
static waketimer_callback_t s_waketimerCallback[sizeof(s_waketimerBases) / sizeof(s_waketimerBases[0])];
/* Array of WAKETIMER IRQ number. */
static const IRQn_Type s_waketimerIRQ[] = WAKETIMER_IRQS;
/*******************************************************************************
* Code
******************************************************************************/
/* brief Function for getting the instance number of Waketimer. */
static uint32_t WAKETIMER_GetInstance(WAKETIMER_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_waketimerBases); instance++)
{
if (s_waketimerBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_waketimerBases));
return instance;
}
/*!
* brief Initializes an WAKETIMER.
* param base WAKETIMER peripheral base address.
*/
void WAKETIMER_Init(WAKETIMER_Type *base, const waketimer_config_t *config)
{
assert(NULL != base);
uint32_t index = WAKETIMER_GetInstance(base);
/* Halt timer */
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_CLR_WAKE_TIMER_MASK;
/* Set OSC divide */
if (config->enableOSCDivide)
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_OSC_DIV_ENA_MASK;
}
else
{
base->WAKE_TIMER_CTRL &= ~WAKETIMER_WAKE_TIMER_CTRL_OSC_DIV_ENA_MASK;
}
/* Set callback */
s_waketimerCallback[index] = config->callback;
/* Set interrupt */
if (config->enableInterrupt)
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
(void)EnableIRQ(s_waketimerIRQ[index]);
}
else
{
base->WAKE_TIMER_CTRL &= ~WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
(void)DisableIRQ(s_waketimerIRQ[index]);
}
}
/*!
* brief Deinitializes a WAKETIMER instance.
*
* This function deinitializes the WAKETIMER.
*
* param base WAKETIMER peripheral base address.
*/
void WAKETIMER_Deinit(WAKETIMER_Type *base)
{
assert(NULL != base);
uint32_t index = WAKETIMER_GetInstance(base);
/* Disable IRQ at NVIC Level */
(void)DisableIRQ(s_waketimerIRQ[index]);
}
/*!
* brief Fills in the WAKETIMER configuration structure with the default settings.
*
* The default values are:
* code
* config->enableInterrupt = true;
* config->enableOSCDivide = true;
* config->callback = NULL;
* endcode
* param config Pointer to the user configuration structure.
*/
void WAKETIMER_GetDefaultConfig(waketimer_config_t *config)
{
config->enableInterrupt = true;
config->enableOSCDivide = true;
config->callback = NULL;
}
/*!
* brief Enables the selected WAKETIMER interrupts.
*
* param base WAKETIMER peripheral base address
* param mask Mask value for interrupt events. See to #_waketimer_interrupt_enable
*/
void WAKETIMER_EnableInterrupts(WAKETIMER_Type *base, uint32_t mask)
{
assert(NULL != base);
if (0U != (mask & (uint32_t)kWAKETIMER_WakeInterruptEnable))
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
}
}
/*!
* brief Disable the selected WAKETIMER interrupts.
*
* param base WAKETIMER peripheral base address
* param mask Mask value for interrupt events. See to #_waketimer_interrupt_enable
*/
void WAKETIMER_DisableInterrupts(WAKETIMER_Type *base, uint32_t mask)
{
assert(NULL != base);
if (0U != (mask & (uint32_t)kWAKETIMER_WakeInterruptEnable))
{
base->WAKE_TIMER_CTRL &= ~WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
}
}
/*!
* brief Clear Status Interrupt Flag.
*
* This clears intrrupt status flag.
* Currently, only match interrupt flag can be cleared.
*
* param base WAKETIMER peripheral base address.
* param mask Mask value for flags to be cleared. See to #_waketimer_status_flags.
* return none
*/
void WAKETIMER_ClearStatusFlags(WAKETIMER_Type *base, uint32_t mask)
{
if (0U != (mask & (uint32_t)kWAKETIMER_WakeFlag))
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_WAKE_FLAG_MASK;
}
}
/*!
* brief Receive noticification when waketime countdown.
*
* If the interrupt for the waketime countdown is enabled, then a callback can be registered
* which will be invoked when the event is triggered
*
* param base WAKETIMER peripheral base address
* param callback Function to invoke when the event is triggered
*/
void WAKETIMER_SetCallback(WAKETIMER_Type *base, waketimer_callback_t callback)
{
assert(NULL != base);
uint32_t index = WAKETIMER_GetInstance(base);
s_waketimerCallback[index] = callback;
}
/*!
* brief Get current timer count value from WAKETIMER.
*
* This function will get a decimal timer count value.
* The RAW value of timer count is gray code format, will be translated to decimal data internally.
*
* param base WAKETIMER peripheral base address.
* return Value of WAKETIMER which will formated to decimal value.
*/
uint32_t WAKETIMER_GetCurrentTimerValue(WAKETIMER_Type *base)
{
uint32_t value1 = 0;
uint32_t value2 = 0;
do
{
value1 = base->WAKE_TIMER_CNT;
value2 = base->WAKE_TIMER_CNT;
} while (value1 != value2);
return value1;
}
static void WAKETIMER_GenericIRQHandler(WAKETIMER_Type *base, waketimer_callback_t callback)
{
/* Clear interrupt flag. */
WAKETIMER_ClearStatusFlags(base, (uint32_t)kWAKETIMER_WakeFlag);
if (callback != NULL)
{
callback();
}
}
#if defined(WAKETIMER0)
void WAKETIMER0_DriverIRQHandler(void);
void WAKETIMER0_DriverIRQHandler(void)
{
WAKETIMER_GenericIRQHandler(WAKETIMER0, s_waketimerCallback[0]);
SDK_ISR_EXIT_BARRIER;
}
#endif