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_ftm.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 FTM_Type *const s_FtmBase[] = FTM_BASE_PTRS;
28 
29 static hal_timer_handle_t s_timerHandle[sizeof(s_FtmBase) / sizeof(FTM_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     FTM_ClearStatusFlags(s_FtmBase[instance], (uint32_t)kFTM_TimeOverflowFlag);
46     if (halTimerState->callback != NULL)
47     {
48         halTimerState->callback(halTimerState->callbackParam);
49     }
50 }
51 
52 void FTM0_IRQHandler(void);
FTM0_IRQHandler(void)53 void FTM0_IRQHandler(void)
54 {
55     HAL_TimerInterruptHandle(0);
56     SDK_ISR_EXIT_BARRIER;
57 }
58 
59 void FTM1_IRQHandler(void);
FTM1_IRQHandler(void)60 void FTM1_IRQHandler(void)
61 {
62     HAL_TimerInterruptHandle(1);
63     SDK_ISR_EXIT_BARRIER;
64 }
65 
66 void FTM2_IRQHandler(void);
FTM2_IRQHandler(void)67 void FTM2_IRQHandler(void)
68 {
69     HAL_TimerInterruptHandle(2);
70     SDK_ISR_EXIT_BARRIER;
71 }
72 
73 /************************************************************************************
74 *************************************************************************************
75 * Public functions
76 *************************************************************************************
77 ************************************************************************************/
HAL_TimerInit(hal_timer_handle_t halTimerHandle,hal_timer_config_t * halTimerConfig)78 hal_timer_status_t HAL_TimerInit(hal_timer_handle_t halTimerHandle, hal_timer_config_t *halTimerConfig)
79 {
80     IRQn_Type mFTMIrqId[]                    = FTM_IRQS;
81     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
82     IRQn_Type irqId;
83     ftm_config_t ftmInfo;
84     FTM_Type *FTMBaseAddr;
85 
86     assert(sizeof(hal_timer_handle_struct_t) == HAL_TIMER_HANDLE_SIZE);
87     assert(halTimerConfig);
88     assert(halTimerHandle);
89     assert(halTimerConfig->instance < (sizeof(s_FtmBase) / sizeof(FTM_Type *)));
90 
91     halTimerState->timeout  = halTimerConfig->timeout;
92     halTimerState->instance = halTimerConfig->instance;
93     FTMBaseAddr             = (FTM_Type *)s_FtmBase[halTimerState->instance];
94     assert(FTMBaseAddr);
95     FTM_GetDefaultConfig(&ftmInfo);
96     /* FTM clock divide by 128 */
97     ftmInfo.prescale = kFTM_Prescale_Divide_128;
98     /* Initialize FTM module */
99     (void)FTM_Init(FTMBaseAddr, &ftmInfo);
100     FTM_StopTimer(FTMBaseAddr);
101     halTimerState->timerClock_Hz = halTimerConfig->srcClock_Hz / (1UL << (uint32_t)ftmInfo.prescale);
102     /* Set the timer to be in free-running mode */
103     FTMBaseAddr->MOD = 0xFFFF;
104     if (USEC_TO_COUNT(halTimerState->timeout, halTimerState->timerClock_Hz) > 0xFFFFU)
105     {
106         return kStatus_HAL_TimerOutOfRanger;
107     }
108     /* Configure channel to Software compare; output pin not used */
109     FTM_SetTimerPeriod(FTMBaseAddr, (uint32_t)USEC_TO_COUNT(halTimerState->timeout, halTimerState->timerClock_Hz));
110     /* Install ISR */
111     irqId = mFTMIrqId[halTimerState->instance];
112     FTM_EnableInterrupts(FTMBaseAddr, (uint32_t)kFTM_TimeOverflowInterruptEnable);
113     NVIC_SetPriority((IRQn_Type)irqId, HAL_TIMER_ISR_PRIORITY);
114     s_timerHandle[halTimerState->instance] = halTimerHandle;
115     (void)EnableIRQ(irqId);
116     return kStatus_HAL_TimerSuccess;
117 }
HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)118 void HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)
119 {
120     assert(halTimerHandle);
121     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
122     s_timerHandle[halTimerState->instance]   = NULL;
123     FTM_Deinit(s_FtmBase[halTimerState->instance]);
124 }
125 /*************************************************************************************/
HAL_TimerEnable(hal_timer_handle_t halTimerHandle)126 void HAL_TimerEnable(hal_timer_handle_t halTimerHandle)
127 {
128     assert(halTimerHandle);
129     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
130     FTM_StartTimer(s_FtmBase[halTimerState->instance], kFTM_SystemClock);
131 }
132 
133 /*************************************************************************************/
HAL_TimerDisable(hal_timer_handle_t halTimerHandle)134 void HAL_TimerDisable(hal_timer_handle_t halTimerHandle)
135 {
136     assert(halTimerHandle);
137     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
138     FTM_StopTimer(s_FtmBase[halTimerState->instance]);
139 }
140 
141 /*************************************************************************************/
142 /*************************************************************************************/
HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle,hal_timer_callback_t callback,void * callbackParam)143 void HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle, hal_timer_callback_t callback, void *callbackParam)
144 {
145     assert(halTimerHandle);
146     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
147     halTimerState->callback                  = callback;
148     halTimerState->callbackParam             = callbackParam;
149 }
150 
HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)151 uint32_t HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)
152 {
153     uint32_t reserveCount;
154     uint64_t retValue;
155     uint32_t reserveMs = 4U;
156     assert(halTimerHandle);
157     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
158     reserveCount                             = (uint32_t)MSEC_TO_COUNT((reserveMs), (halTimerState->timerClock_Hz));
159 
160     retValue = COUNT_TO_USEC(((uint64_t)0xFFFFFFFF - (uint64_t)reserveCount), (uint64_t)halTimerState->timerClock_Hz);
161     return (uint32_t)((retValue > 0xFFFFFFFFU) ? (0xFFFFFFFFU - reserveMs * 1000U) : (uint32_t)retValue);
162 }
163 /* return micro us */
HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)164 uint32_t HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)
165 {
166     assert(halTimerHandle);
167     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
168     return (uint32_t)COUNT_TO_USEC((uint64_t)FTM_GetCurrentTimerCount(s_FtmBase[halTimerState->instance]),
169                                    halTimerState->timerClock_Hz);
170 }
171 
HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle,uint32_t timeout)172 hal_timer_status_t HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle, uint32_t timeout)
173 {
174     uint32_t tickCount;
175     hal_timer_status_t state;
176     assert(halTimerHandle);
177     hal_timer_handle_struct_t *halTimerState = halTimerHandle;
178 
179     halTimerState->timeout = timeout;
180     tickCount              = (uint32_t)USEC_TO_COUNT(halTimerState->timeout, halTimerState->timerClock_Hz);
181 
182     if ((tickCount < 1U) || (tickCount > 0xfff0U))
183     {
184         state = kStatus_HAL_TimerOutOfRanger;
185     }
186     else
187     {
188         FTM_SetTimerPeriod(s_FtmBase[halTimerState->instance], tickCount);
189         state = kStatus_HAL_TimerSuccess;
190     }
191 
192     return state;
193 }
194 
HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)195 void HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)
196 {
197     assert(halTimerHandle);
198 }
199 
HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)200 void HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)
201 {
202     assert(halTimerHandle);
203 }
204