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