1 /*
2  * Copyright 2018-2021 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_lptmr.h"
13 
14 /*! @brief Definition to determine LPTMR timer whether use free running mode*/
15 #ifndef LPTMR_USE_FREE_RUNNING
16 #define LPTMR_USE_FREE_RUNNING (0)
17 #endif
18 
19 typedef struct _hal_timer_handle_struct_t
20 {
21     uint32_t timeout;
22     uint32_t timerClock_Hz;
23     hal_timer_callback_t callback;
24     void *callbackParam;
25     uint8_t instance;
26 } hal_timer_handle_struct_t;
27 
28 /*******************************************************************************
29  * Variables
30  ******************************************************************************/
31 
32 static LPTMR_Type *const s_LptmrBase[] = LPTMR_BASE_PTRS;
33 
34 static hal_timer_handle_t s_timerHandle[sizeof(s_LptmrBase) / sizeof(LPTMR_Type *)];
35 /************************************************************************************
36 *************************************************************************************
37 * Private memory declarations
38 *************************************************************************************
39 ************************************************************************************/
HAL_TimerInterruptHandle(uint8_t instance)40 static void HAL_TimerInterruptHandle(uint8_t instance)
41 {
42     hal_timer_handle_struct_t *halTimerState = (hal_timer_handle_struct_t *)s_timerHandle[instance];
43     uint32_t lptmrIntFlag;
44 
45     if (NULL == halTimerState)
46     {
47         return;
48     }
49 
50     lptmrIntFlag = LPTMR_GetStatusFlags(s_LptmrBase[instance]);
51     LPTMR_ClearStatusFlags(s_LptmrBase[instance], (uint32_t)kLPTMR_TimerCompareFlag);
52 
53     if (0U != lptmrIntFlag)
54     {
55         if (halTimerState->callback != NULL)
56         {
57             halTimerState->callback(halTimerState->callbackParam);
58         }
59     }
60 }
61 
62 void PWT_LPTMR0_IRQHandler(void);
PWT_LPTMR0_IRQHandler(void)63 void PWT_LPTMR0_IRQHandler(void)
64 {
65     HAL_TimerInterruptHandle(0);
66     SDK_ISR_EXIT_BARRIER;
67 }
68 void LPTMR0_IRQHandler(void);
LPTMR0_IRQHandler(void)69 void LPTMR0_IRQHandler(void)
70 {
71     HAL_TimerInterruptHandle(0);
72     SDK_ISR_EXIT_BARRIER;
73 }
74 
75 #if (FSL_FEATURE_SOC_LPTMR_COUNT > 1)
76 void LPTMR1_IRQHandler(void);
LPTMR1_IRQHandler(void)77 void LPTMR1_IRQHandler(void)
78 {
79     HAL_TimerInterruptHandle(1);
80     SDK_ISR_EXIT_BARRIER;
81 }
82 #endif
83 
84 void LPTMR0_LPTMR1_IRQHandler(void);
LPTMR0_LPTMR1_IRQHandler(void)85 void LPTMR0_LPTMR1_IRQHandler(void)
86 {
87     HAL_TimerInterruptHandle(0);
88 #if (defined(FSL_FEATURE_SOC_LPTMR_COUNT) && (FSL_FEATURE_SOC_LPTMR_COUNT > 1))
89     HAL_TimerInterruptHandle(1);
90 #endif /* (FSL_FEATURE_SOC_LPTMR_COUNT > 1) */
91     SDK_ISR_EXIT_BARRIER;
92 }
93 /************************************************************************************
94 *************************************************************************************
95 * Public functions
96 *************************************************************************************
97 ************************************************************************************/
HAL_TimerInit(hal_timer_handle_t halTimerHandle,hal_timer_config_t * halTimerConfig)98 hal_timer_status_t HAL_TimerInit(hal_timer_handle_t halTimerHandle, hal_timer_config_t *halTimerConfig)
99 {
100     IRQn_Type mLptmrIrqId[] = LPTMR_IRQS;
101     IRQn_Type irqId;
102     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
103     /* Structure of initialize LPTMR */
104     lptmr_config_t lptmrConfig;
105 
106     assert(sizeof(hal_timer_handle_struct_t) == HAL_TIMER_HANDLE_SIZE);
107     assert(halTimerConfig);
108     assert(halTimerHandle);
109     assert(halTimerConfig->instance < (sizeof(s_LptmrBase) / sizeof(LPTMR_Type *)));
110 
111     halTimerState->timeout  = halTimerConfig->timeout;
112     halTimerState->instance = halTimerConfig->instance;
113     irqId                   = mLptmrIrqId[halTimerState->instance];
114 
115     LPTMR_GetDefaultConfig(&lptmrConfig);
116 
117     /* If the lptmr does not want to use the default clock source, clockSrcSelect need to be configured by users. */
118     lptmrConfig.prescalerClockSource = (lptmr_prescaler_clock_select_t)halTimerConfig->clockSrcSelect;
119 
120 #if (defined(LPTMR_USE_FREE_RUNNING) && (LPTMR_USE_FREE_RUNNING > 0))
121     lptmrConfig.enableFreeRunning = true;
122 #endif
123     /* Initialize the LPTMR */
124     LPTMR_Init(s_LptmrBase[halTimerState->instance], &lptmrConfig);
125     halTimerState->timerClock_Hz = halTimerConfig->srcClock_Hz;
126     /*
127      * Set timer period.
128      * Note : the parameter "ticks" of LPTMR_SetTimerPeriod should be equal or greater than 1.
129      */
130     LPTMR_SetTimerPeriod(s_LptmrBase[halTimerState->instance],
131                          (uint32_t)USEC_TO_COUNT(halTimerState->timeout, halTimerState->timerClock_Hz));
132 
133     /* Enable timer interrupt */
134     LPTMR_EnableInterrupts(s_LptmrBase[halTimerState->instance], (uint32_t)kLPTMR_TimerInterruptEnable);
135 
136     s_timerHandle[halTimerState->instance] = halTimerHandle;
137 
138     NVIC_SetPriority((IRQn_Type)irqId, HAL_TIMER_ISR_PRIORITY);
139     (void)EnableIRQ(irqId);
140     return kStatus_HAL_TimerSuccess;
141 }
142 
HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)143 void HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)
144 {
145     assert(halTimerHandle);
146     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
147     s_timerHandle[halTimerState->instance]   = NULL;
148     LPTMR_Deinit(s_LptmrBase[halTimerState->instance]);
149 }
150 /*************************************************************************************/
HAL_TimerEnable(hal_timer_handle_t halTimerHandle)151 void HAL_TimerEnable(hal_timer_handle_t halTimerHandle)
152 {
153     assert(halTimerHandle);
154     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
155     LPTMR_StartTimer(s_LptmrBase[halTimerState->instance]);
156 }
157 
158 /*************************************************************************************/
HAL_TimerDisable(hal_timer_handle_t halTimerHandle)159 void HAL_TimerDisable(hal_timer_handle_t halTimerHandle)
160 {
161 #if !(defined(LPTMR_USE_FREE_RUNNING) && (LPTMR_USE_FREE_RUNNING > 0))
162     assert(halTimerHandle);
163     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
164     LPTMR_StopTimer(s_LptmrBase[halTimerState->instance]);
165 #endif
166 }
167 
168 /*************************************************************************************/
HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle,hal_timer_callback_t callback,void * callbackParam)169 void HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle, hal_timer_callback_t callback, void *callbackParam)
170 {
171     assert(halTimerHandle);
172     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
173     halTimerState->callback                  = callback;
174     halTimerState->callbackParam             = callbackParam;
175 }
176 
HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)177 uint32_t HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)
178 {
179     uint32_t reserveCount;
180     uint64_t retValue;
181     uint32_t reserveMs = 4U;
182     assert(halTimerHandle);
183     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
184     reserveCount                             = (uint32_t)MSEC_TO_COUNT((reserveMs), (halTimerState->timerClock_Hz));
185 
186     retValue = COUNT_TO_USEC(((uint64_t)0xFFFFFFFF - (uint64_t)reserveCount), (uint64_t)halTimerState->timerClock_Hz);
187     return (uint32_t)((retValue > 0xFFFFFFFFU) ? (0xFFFFFFFFU - reserveMs * 1000U) : (uint32_t)retValue);
188 }
189 /* return micro us */
HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)190 uint32_t HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)
191 {
192     assert(halTimerHandle);
193     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
194     uint32_t flags                           = LPTMR_GetStatusFlags(s_LptmrBase[halTimerState->instance]);
195     uint32_t count                           = 0U;
196 
197 #if !(defined(LPTMR_USE_FREE_RUNNING) && (LPTMR_USE_FREE_RUNNING > 0))
198     if (flags != 0U)
199     {
200         /* If HAL_TimerGetCurrentTimerCount is called from masked interrupt
201          * context, then it's possible the TCF flag is set, meaning the CNT
202          * register is reset. In such case, the current count value is not
203          * correct. We need to add the current compare value to the count
204          * This is true only when TFC is not set (not free running) */
205         count =
206             (uint32_t)COUNT_TO_USEC((uint64_t)s_LptmrBase[halTimerState->instance]->CMR, halTimerState->timerClock_Hz);
207         count += (uint32_t)COUNT_TO_USEC((uint64_t)LPTMR_GetCurrentTimerCount(s_LptmrBase[halTimerState->instance]),
208                                          halTimerState->timerClock_Hz);
209         LPTMR_ClearStatusFlags(s_LptmrBase[halTimerState->instance], flags);
210     }
211     else
212 #endif /* LPTMR_USE_FREE_RUNNING */
213     {
214         count = (uint32_t)COUNT_TO_USEC((uint64_t)LPTMR_GetCurrentTimerCount(s_LptmrBase[halTimerState->instance]),
215                                         halTimerState->timerClock_Hz);
216     }
217 
218     return count;
219 }
220 
HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle,uint32_t timeout)221 hal_timer_status_t HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle, uint32_t timeout)
222 {
223     uint32_t tickCount;
224 #if (defined(LPTMR_USE_FREE_RUNNING) && (LPTMR_USE_FREE_RUNNING > 0))
225     uint64_t totalCount = 0;
226 #endif
227     assert(halTimerHandle);
228     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
229     halTimerState->timeout                   = timeout + 1U;
230     tickCount = (uint32_t)USEC_TO_COUNT(halTimerState->timeout, halTimerState->timerClock_Hz);
231     if ((tickCount < 1U) || (tickCount > 0xfffffff0U))
232     {
233         return kStatus_HAL_TimerOutOfRanger;
234     }
235     tickCount += 1U;
236 #if (defined(LPTMR_USE_FREE_RUNNING) && (LPTMR_USE_FREE_RUNNING > 0))
237     totalCount = (uint64_t)tickCount + (uint64_t)LPTMR_GetCurrentTimerCount(s_LptmrBase[halTimerState->instance]);
238     if (totalCount > 0xffffffff)
239     {
240         tickCount = totalCount - 0xffffffff;
241     }
242     else
243     {
244         tickCount = totalCount;
245     }
246 
247 #endif
248     LPTMR_SetTimerPeriod(s_LptmrBase[halTimerState->instance], tickCount);
249     return kStatus_HAL_TimerSuccess;
250 }
251 
HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)252 void HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)
253 {
254     assert(halTimerHandle);
255 }
256 
HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)257 void HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)
258 {
259     assert(halTimerHandle);
260 }
261