1 /*
2 * Copyright 2018-2019 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_device_registers.h"
10 #include "fsl_adapter_timer.h"
11 #include "fsl_tpm.h"
12
13 #ifndef TIMER_ADAPTER_TPM1_ENABLE
14 #define TIMER_ADAPTER_TPM1_ENABLE (0)
15 #endif
16
17 #ifndef TIMER_ADAPTER_TPM2_ENABLE
18 #define TIMER_ADAPTER_TPM2_ENABLE (0)
19 #endif
20
21 typedef struct _hal_timer_handle_struct_t
22 {
23 uint32_t timeout;
24 uint32_t timerClock_Hz;
25 hal_timer_callback_t callback;
26 void *callbackParam;
27 #if (defined(TIMER_ADAPTER_TPM1_ENABLE) && (TIMER_ADAPTER_TPM1_ENABLE > 0U)) || \
28 (defined(TIMER_ADAPTER_TPM2_ENABLE) && (TIMER_ADAPTER_TPM2_ENABLE > 0U))
29 uint8_t instance;
30 #endif
31 } hal_timer_handle_struct_t;
32
33 /*******************************************************************************
34 * Variables
35 ******************************************************************************/
36
37 static TPM_Type *const s_TPMBase[] = TPM_BASE_PTRS;
38 static IRQn_Type const mTPMIrqId[] = TPM_IRQS;
39
40 #if (defined(TIMER_ADAPTER_TPM1_ENABLE) && (TIMER_ADAPTER_TPM1_ENABLE > 0U)) || \
41 (defined(TIMER_ADAPTER_TPM2_ENABLE) && (TIMER_ADAPTER_TPM2_ENABLE > 0U))
42 static hal_timer_handle_struct_t *s_halTimerState[sizeof(s_TPMBase) / sizeof(TPM_Type *)];
43 #else
44 static hal_timer_handle_struct_t *s_halTimerState[1];
45 #endif
46 /************************************************************************************
47 *************************************************************************************
48 * Private prototypes
49 *************************************************************************************
50 ************************************************************************************/
51
52 /************************************************************************************
53 *************************************************************************************
54 * Private memory declarations
55 *************************************************************************************
56 ************************************************************************************/
HAL_TimerInterruptHandle(uint8_t instance)57 static void HAL_TimerInterruptHandle(uint8_t instance)
58 {
59 TPM_ClearStatusFlags(s_TPMBase[instance], (uint32_t)kTPM_TimeOverflowFlag);
60 if (s_halTimerState[instance]->callback != NULL)
61 {
62 s_halTimerState[instance]->callback(s_halTimerState[instance]->callbackParam);
63 }
64 }
HAL_TimerGetInstance(hal_timer_handle_t halTimerHandle)65 static uint8_t HAL_TimerGetInstance(hal_timer_handle_t halTimerHandle)
66 {
67 #if (defined(TIMER_ADAPTER_TPM1_ENABLE) && (TIMER_ADAPTER_TPM1_ENABLE > 0U)) || \
68 (defined(TIMER_ADAPTER_TPM2_ENABLE) && (TIMER_ADAPTER_TPM2_ENABLE > 0U))
69 hal_timer_handle_struct_t *halTimerState = halTimerHandle;
70 return halTimerState->instance;
71 #else
72 return 0;
73 #endif
74 }
75
HAL_TimerHwInit(hal_timer_handle_t halTimerHandle)76 static void HAL_TimerHwInit(hal_timer_handle_t halTimerHandle)
77 {
78 hal_timer_handle_struct_t *halTimerState = halTimerHandle;
79 IRQn_Type irqId;
80 tpm_config_t tpmInfo;
81 uint8_t instance = 0;
82
83 assert(halTimerHandle);
84 TPM_GetDefaultConfig(&tpmInfo);
85 #if (defined(TIMER_ADAPTER_TPM1_ENABLE) && (TIMER_ADAPTER_TPM1_ENABLE > 0U)) || \
86 (defined(TIMER_ADAPTER_TPM2_ENABLE) && (TIMER_ADAPTER_TPM2_ENABLE > 0U))
87 instance = halTimerState->instance;
88 #endif
89 /* Initialize TPM module */
90 tpmInfo.prescale = kTPM_Prescale_Divide_128;
91 TPM_Init(s_TPMBase[instance], (void *)&tpmInfo);
92 TPM_StopTimer(s_TPMBase[instance]);
93
94 /* Set the timer to be in free-running mode */
95 s_TPMBase[instance]->MOD = 0xFFFF;
96 s_halTimerState[instance] = halTimerHandle;
97 (void)HAL_TimerUpdateTimeout(halTimerHandle, halTimerState->timeout);
98
99 /* Install ISR */
100 irqId = mTPMIrqId[instance];
101 TPM_EnableInterrupts(s_TPMBase[instance], (uint32_t)kTPM_TimeOverflowInterruptEnable);
102
103 NVIC_SetPriority(irqId, HAL_TIMER_ISR_PRIORITY);
104 (void)EnableIRQ(irqId);
105 }
106 void TPM0_IRQHandler(void);
107
TPM0_IRQHandler(void)108 void TPM0_IRQHandler(void)
109 {
110 HAL_TimerInterruptHandle(0);
111 SDK_ISR_EXIT_BARRIER;
112 }
113
114 #if (defined(TIMER_ADAPTER_TPM1_ENABLE) && (TIMER_ADAPTER_TPM1_ENABLE > 0U))
115 void TPM1_IRQHandler(void);
TPM1_IRQHandler(void)116 void TPM1_IRQHandler(void)
117 {
118 HAL_TimerInterruptHandle(1);
119 SDK_ISR_EXIT_BARRIER;
120 }
121 #endif /*TIMER_ADAPTER_TPM1_ENABLE*/
122
123 #if (defined(TIMER_ADAPTER_TPM2_ENABLE) && (TIMER_ADAPTER_TPM2_ENABLE > 0U))
124 void TPM2_IRQHandler(void);
TPM2_IRQHandler(void)125 void TPM2_IRQHandler(void)
126 {
127 HAL_TimerInterruptHandle(2);
128 SDK_ISR_EXIT_BARRIER;
129 }
130 #endif /*TIMER_ADAPTER_TPM2_ENABLE*/
131 /************************************************************************************
132 *************************************************************************************
133 * Public functions
134 *************************************************************************************
135 ************************************************************************************/
HAL_TimerInit(hal_timer_handle_t halTimerHandle,hal_timer_config_t * halTimerConfig)136 hal_timer_status_t HAL_TimerInit(hal_timer_handle_t halTimerHandle, hal_timer_config_t *halTimerConfig)
137 {
138 hal_timer_handle_struct_t *halTimerState = halTimerHandle;
139 tpm_config_t tpmInfo;
140
141 assert(sizeof(hal_timer_handle_struct_t) <= HAL_TIMER_HANDLE_SIZE);
142 assert(halTimerConfig);
143 assert(halTimerHandle);
144 assert(halTimerConfig->instance < (sizeof(s_TPMBase) / sizeof(TPM_Type *)));
145
146 halTimerState->timeout = halTimerConfig->timeout;
147 #if (defined(TIMER_ADAPTER_TPM1_ENABLE) && (TIMER_ADAPTER_TPM1_ENABLE > 0U)) || \
148 (defined(TIMER_ADAPTER_TPM2_ENABLE) && (TIMER_ADAPTER_TPM2_ENABLE > 0U))
149 halTimerState->instance = halTimerConfig->instance;
150 assert(s_TPMBase[halTimerState->instance]);
151 #endif
152 /* TPM clock divide by 128 */
153 tpmInfo.prescale = kTPM_Prescale_Divide_128;
154 halTimerState->timerClock_Hz = halTimerConfig->srcClock_Hz / (1UL << (uint8_t)tpmInfo.prescale);
155
156 HAL_TimerHwInit(halTimerHandle);
157 return kStatus_HAL_TimerSuccess;
158 }
HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)159 void HAL_TimerDeinit(hal_timer_handle_t halTimerHandle)
160 {
161 assert(halTimerHandle);
162 assert(halTimerHandle);
163
164 s_halTimerState[HAL_TimerGetInstance(halTimerHandle)] = NULL;
165 TPM_Deinit(s_TPMBase[HAL_TimerGetInstance(halTimerHandle)]);
166 }
167 /*************************************************************************************/
HAL_TimerEnable(hal_timer_handle_t halTimerHandle)168 void HAL_TimerEnable(hal_timer_handle_t halTimerHandle)
169 {
170 assert(halTimerHandle);
171 TPM_StartTimer(s_TPMBase[HAL_TimerGetInstance(halTimerHandle)], kTPM_SystemClock);
172 }
173
174 /*************************************************************************************/
HAL_TimerDisable(hal_timer_handle_t halTimerHandle)175 void HAL_TimerDisable(hal_timer_handle_t halTimerHandle)
176 {
177 assert(halTimerHandle);
178 TPM_StopTimer(s_TPMBase[HAL_TimerGetInstance(halTimerHandle)]);
179 }
180
181 /*************************************************************************************/
HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle,hal_timer_callback_t callback,void * callbackParam)182 void HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle, hal_timer_callback_t callback, void *callbackParam)
183 {
184 assert(halTimerHandle);
185 s_halTimerState[HAL_TimerGetInstance(halTimerHandle)]->callback = callback;
186 s_halTimerState[HAL_TimerGetInstance(halTimerHandle)]->callbackParam = callbackParam;
187 }
HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)188 uint32_t HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle)
189 {
190 assert(halTimerHandle);
191
192 return (uint32_t)COUNT_TO_USEC(((uint64_t)0xFFFF - (uint64_t)1000),
193 (s_halTimerState[HAL_TimerGetInstance(halTimerHandle)]->timerClock_Hz));
194 }
195 /* return micro us */
HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)196 uint32_t HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle)
197 {
198 assert(halTimerHandle);
199
200 return (uint32_t)COUNT_TO_USEC((uint64_t)TPM_GetCurrentTimerCount(s_TPMBase[HAL_TimerGetInstance(halTimerHandle)]),
201 (s_halTimerState[HAL_TimerGetInstance(halTimerHandle)]->timerClock_Hz));
202 }
203
HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle,uint32_t timeout)204 hal_timer_status_t HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle, uint32_t timeout)
205 {
206 uint32_t tickCount;
207 assert(halTimerHandle);
208
209 s_halTimerState[HAL_TimerGetInstance(halTimerHandle)]->timeout = timeout;
210 tickCount = (uint32_t)USEC_TO_COUNT((s_halTimerState[HAL_TimerGetInstance(halTimerHandle)]->timeout),
211 (s_halTimerState[HAL_TimerGetInstance(halTimerHandle)]->timerClock_Hz));
212 if ((tickCount < 1U) || (tickCount > 0xfff0U))
213 {
214 return kStatus_HAL_TimerOutOfRanger;
215 }
216
217 s_TPMBase[HAL_TimerGetInstance(halTimerHandle)]->CNT = 0;
218 TPM_SetTimerPeriod(s_TPMBase[HAL_TimerGetInstance(halTimerHandle)], tickCount);
219 return kStatus_HAL_TimerSuccess;
220 }
221
HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)222 void HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle)
223 {
224 assert(halTimerHandle);
225 HAL_TimerHwInit(halTimerHandle);
226 }
227
HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)228 void HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle)
229 {
230 assert(halTimerHandle);
231 }
232