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