1 /*
2  * Copyright 2018-2019, 2023 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_common.h"
10 #include "fsl_device_registers.h"
11 #include "fsl_adapter_timer.h"
12 #include "fsl_lpit.h"
13 
14 typedef struct _hal_timer_handle_struct_t
15 {
16     uint32_t timeout;
17     uint32_t timerClock_Hz;
18     hal_timer_callback_t callback;
19     void *callbackParam;
20     uint8_t instance;
21 } hal_timer_handle_struct_t;
22 
23 /*******************************************************************************
24  * Variables
25  ******************************************************************************/
26 
27 static LPIT_Type *const s_LpitBase[] = LPIT_BASE_PTRS;
28 
29 static hal_timer_handle_t s_timerHandle[sizeof(s_LpitBase) / sizeof(LPIT_Type *)];
30 /************************************************************************************
31 *************************************************************************************
32 * Private prototypes
33 *************************************************************************************
34 ************************************************************************************/
35 
36 /************************************************************************************
37 *************************************************************************************
38 * Private memory declarations
39 *************************************************************************************
40 ************************************************************************************/
HAL_TimerInterruptHandle(uint8_t instance)41 static void HAL_TimerInterruptHandle(uint8_t instance)
42 {
43     hal_timer_handle_struct_t *halTimerState = (hal_timer_handle_struct_t *)s_timerHandle[instance];
44 
45     LPIT_ClearStatusFlags(s_LpitBase[halTimerState->instance], (uint32_t)kLPIT_Channel0TimerFlag);
46     if (halTimerState->callback != NULL)
47     {
48         halTimerState->callback(halTimerState->callbackParam);
49     }
50 }
51 #if defined(LPIT0)
52 void LPIT0_IRQHandler(void);
LPIT0_IRQHandler(void)53 void LPIT0_IRQHandler(void)
54 {
55     HAL_TimerInterruptHandle(0);
56     SDK_ISR_EXIT_BARRIER;
57 }
58 #endif
59 #if defined(LPIT1)
60 void LPIT1_IRQHandler(void);
LPIT1_IRQHandler(void)61 void LPIT1_IRQHandler(void)
62 {
63     HAL_TimerInterruptHandle(1);
64     SDK_ISR_EXIT_BARRIER;
65 }
66 #endif
67 /************************************************************************************
68 *************************************************************************************
69 * Public functions
70 *************************************************************************************
71 ************************************************************************************/
HAL_TimerInit(hal_timer_handle_t halTimerHandle,hal_timer_config_t * halTimerConfig)72 hal_timer_status_t HAL_TimerInit(hal_timer_handle_t halTimerHandle, hal_timer_config_t *halTimerConfig)
73 {
74     IRQn_Type instanceIrq[][FSL_FEATURE_LPIT_TIMER_COUNT] = LPIT_IRQS;
75     IRQn_Type irqId;
76     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
77     /* Structure of initialize LPIT */
78     lpit_config_t lpitConfig;
79 
80     assert(sizeof(hal_timer_handle_struct_t) == HAL_TIMER_HANDLE_SIZE);
81     assert(halTimerConfig);
82     assert(halTimerHandle);
83     assert(halTimerConfig->instance < (sizeof(s_LpitBase) / sizeof(LPIT_Type *)));
84 
85     halTimerState->timeout  = halTimerConfig->timeout;
86     halTimerState->instance = halTimerConfig->instance;
87     irqId                   = instanceIrq[halTimerState->instance][0];
88     /*
89      * lpitConfig.enableRunInDebug = false;
90      */
91     LPIT_GetDefaultConfig(&lpitConfig);
92     assert(s_LpitBase[halTimerState->instance]);
93     /* Init llpit module */
94     LPIT_Init(s_LpitBase[halTimerState->instance], &lpitConfig);
95     halTimerState->timerClock_Hz = halTimerConfig->srcClock_Hz;
96     /* Set timer period for channel 0 */
97     LPIT_SetTimerPeriod(s_LpitBase[halTimerState->instance], kLPIT_Chnl_0,
98                         (uint32_t)USEC_TO_COUNT(halTimerState->timeout, halTimerState->timerClock_Hz));
99     /* Enable timer interrupts for channel 0 */
100     LPIT_EnableInterrupts(s_LpitBase[halTimerState->instance], (uint32_t)kLPIT_Channel0TimerInterruptEnable);
101     s_timerHandle[halTimerState->instance] = halTimerHandle;
102     NVIC_SetPriority((IRQn_Type)irqId, HAL_TIMER_ISR_PRIORITY);
103     (void)EnableIRQ(irqId);
104     return kStatus_HAL_TimerSuccess;
105 }
106 
107 /*************************************************************************************/
HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)108 void HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)
109 {
110     assert(halTimerHandle);
111     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
112     s_timerHandle[halTimerState->instance]   = NULL;
113     LPIT_Deinit(s_LpitBase[halTimerState->instance]);
114 }
115 
116 /*************************************************************************************/
HAL_TimerEnable(hal_timer_handle_t halTimerHandle)117 void HAL_TimerEnable(hal_timer_handle_t halTimerHandle)
118 {
119     assert(halTimerHandle);
120     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
121     LPIT_StartTimer(s_LpitBase[halTimerState->instance], kLPIT_Chnl_0);
122 }
123 
124 /*************************************************************************************/
HAL_TimerDisable(hal_timer_handle_t halTimerHandle)125 void HAL_TimerDisable(hal_timer_handle_t halTimerHandle)
126 {
127     assert(halTimerHandle);
128     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
129     LPIT_StopTimer(s_LpitBase[halTimerState->instance], kLPIT_Chnl_0);
130 }
131 
132 /*************************************************************************************/
HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle,hal_timer_callback_t callback,void * callbackParam)133 void HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle, hal_timer_callback_t callback, void *callbackParam)
134 {
135     assert(halTimerHandle);
136     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
137     halTimerState->callback                  = callback;
138     halTimerState->callbackParam             = callbackParam;
139 }
140 
HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)141 uint32_t HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)
142 {
143     uint32_t reserveCount;
144     uint64_t retValue;
145     uint32_t reserveMs = 4U;
146     assert(halTimerHandle);
147     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
148     reserveCount                             = (uint32_t)MSEC_TO_COUNT((reserveMs), (halTimerState->timerClock_Hz));
149 
150     retValue = COUNT_TO_USEC(((uint64_t)0xFFFFFFFF - (uint64_t)reserveCount), (uint64_t)halTimerState->timerClock_Hz);
151     return (uint32_t)((retValue > 0xFFFFFFFFU) ? (0xFFFFFFFFU - reserveMs * 1000U) : (uint32_t)retValue);
152 }
153 /* return micro us */
HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)154 uint32_t HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)
155 {
156     assert(halTimerHandle);
157     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
158     return (uint32_t)COUNT_TO_USEC(
159         (uint64_t)LPIT_GetCurrentTimerCount(s_LpitBase[halTimerState->instance], kLPIT_Chnl_0),
160         halTimerState->timerClock_Hz);
161 }
162 
HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle,uint32_t timeout)163 hal_timer_status_t HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle, uint32_t timeout)
164 {
165     uint32_t tickCount;
166     assert(halTimerHandle);
167     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
168     halTimerState->timeout                   = timeout;
169     tickCount = (uint32_t)USEC_TO_COUNT(halTimerState->timeout, halTimerState->timerClock_Hz);
170     if ((tickCount < 1U) || (tickCount > 0xfffffff0U))
171     {
172         return kStatus_HAL_TimerOutOfRanger;
173     }
174     LPIT_SetTimerPeriod(s_LpitBase[halTimerState->instance], kLPIT_Chnl_0, tickCount);
175     return kStatus_HAL_TimerSuccess;
176 }
177 
HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)178 void HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)
179 {
180     assert(halTimerHandle);
181 }
182 
HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)183 void HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)
184 {
185     assert(halTimerHandle);
186 }
187