1 /*
2 * Copyright 2021-2023 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef FSL_NETC_TIMER_H_
8 #define FSL_NETC_TIMER_H_
9
10 #include "fsl_netc.h"
11 #include "fsl_netc_soc.h"
12 #include "netc_hw/fsl_netc_hw.h"
13
14 #if !(defined(__GNUC__) || defined(__ICCARM__))
15 #pragma region api_timer
16 #endif
17 //////////////////////////////////////
18 // Group for the Timer
19 //////////////////////////////////////
20 /*!
21 * @defgroup netc_timer NETC Timer Driver
22 * @details Group for Timer API and data structure.
23 * API starts with NETC_Timer.
24 * Parameter starts with netc_timer_handle_t.
25 * This driver provides the API to enable IEEE1588 timer. After timer initialzation, the timestamp in frame transmission
26 * will use it as reference. There're timer adjustment APIs to synchronize time with other system. The separate
27 * ALARM/FIPER/ExtTrigger APIs can generate output pulse or capture input pulse timestamp for local system time
28 * synchronization.
29 * @ingroup netc_api
30 */
31
32 /*!
33 * @defgroup netc_timer_init Timer initialization module
34 * @details IEEE1588 Timer Initialization.
35 * @ingroup netc_timer
36 */
37 /*!
38 * @defgroup netc_timer_adjust Timer adjustment module
39 * @details IEEE1588 Timer adjustment.
40 * @ingroup netc_timer
41 */
42 /*!
43 * @defgroup netc_timer_local_sync Local time synchronization module
44 * @details Generate output pulse or capture input pulse timestamp to check the local system time synchronization.
45 *
46 * @ingroup netc_timer
47 */
48 #if !(defined(__GNUC__) || defined(__ICCARM__))
49 #pragma endregion api_timer
50 #endif
51
52 /*******************************************************************************
53 * Definitions
54 ******************************************************************************/
55
56 #if !(defined(__GNUC__) || defined(__ICCARM__))
57 #pragma region netc_timer_init
58 #endif
59 /*! @addtogroup netc_timer_init
60 * @{
61 */
62
63 /*!
64 * @brief Timer interrupt flags
65 */
66 typedef enum _netc_timer_irq_flags
67 {
68 kNETC_TimerFiper1IrqFlag = ENETC_PF_TMR_TMR_TEVENT_PP1EN_MASK, /*!< Periodic pulse 1 interrupt. */
69 kNETC_TimerFiper2IrqFlag = ENETC_PF_TMR_TMR_TEVENT_PP2EN_MASK, /*!< Periodic pulse 2 interrupt. */
70 kNETC_TimerFiper3IrqFlag = ENETC_PF_TMR_TMR_TEVENT_PP3EN_MASK, /*!< Periodic pulse 3 interrupt. */
71 kNETC_TimerAlarm1IrqFlag = ENETC_PF_TMR_TMR_TEVENT_ALM1EN_MASK, /*!< Alarm 1 interrupt. */
72 kNETC_TimerAlarm2IrqFlag = ENETC_PF_TMR_TMR_TEVENT_ALM2EN_MASK, /*!< Alarm 2 interrupt. */
73 kNETC_TimerExtTrig1ThresholdIrqFlag =
74 ENETC_PF_TMR_TMR_TEVENT_ETS1_THREN_MASK, /*!< External trigger 1 timestamp FIFO threshold hit interrupt.
75 */
76 kNETC_TimerExtTrig2ThresholdIrqFlag =
77 ENETC_PF_TMR_TMR_TEVENT_ETS2_THREN_MASK, /*!< External trigger 2 timestamp FIFO threshold hit interrupt.
78 */
79 kNETC_TimerExtTrig1TsAvailIrqFlag =
80 ENETC_PF_TMR_TMR_TEVENT_ETS1EN_MASK, /*!< External trigger 1 new timestamp available interrupt. */
81 kNETC_TimerExtTrig2TsAvailIrqFlag =
82 ENETC_PF_TMR_TMR_TEVENT_ETS2EN_MASK, /*!< External trigger 2 new timestamp available interrupt. */
83 kNETC_TimerExtTrig1OverflowIrqFlag =
84 ENETC_PF_TMR_TMR_TEVENT_ETS1_OVEN_MASK, /*!< External trigger 1 timestamp FIFO overflow interrupt. */
85 kNETC_TimerExtTrig2OverflowIrqFlag =
86 ENETC_PF_TMR_TMR_TEVENT_ETS2_OVEN_MASK, /*!< External trigger 2 timestamp FIFO overflow interrupt. */
87 } netc_timer_irq_flags_t;
88
89 typedef struct _netc_timer_handle netc_timer_handle_t;
90
91 /*!
92 * @brief Timer handler structure
93 */
94 struct _netc_timer_handle
95 {
96 netc_timer_hw_t hw; /*!< Hardware register map resource. */
97 uint32_t timerFreq; /*!< Timer clock frequency(Hz). */
98 uint8_t entryNum; /*!< MSIX entry number. */
99 };
100
101 /*!
102 * @brief Enumeration for NETC timer reference clock
103 */
104 typedef enum _netc_timer_ref_clk
105 {
106 kNETC_TimerExtRefClk = 0,
107 kNETC_TimerSystemClk,
108 } netc_timer_ref_clk_t;
109
110 /*!
111 * @brief Structure to configure timer
112 */
113 typedef struct _netc_timer_config
114 {
115 bool clkOutputPhase; /*!< True: Inverted divided clock is output, False: Non-inverted divided clock is output. */
116 bool clkInputPhase; /*!< True: Inverted frequency tuned timer input clock, False: Non-inverted frequency tuned timer
117 input clock. */
118 bool enableTimer; /*!< True: Enable 1588 timer, False: Disable 1588 timer, use default counter. */
119 bool atomicMode; /*!< True: Allow atomic updates to TMR_PERIOD and TMR_ADD, False: Disable it. */
120 netc_timer_ref_clk_t clockSelect; /*!< Timer reference clock. */
121 uint32_t refClkHz; /*!< Timer reference clock frequency in Hz. */
122 int32_t defaultPpb; /*!< Default ppb. */
123 netc_msix_entry_t *msixEntry; /*!< MSIX table entry array. */
124 uint8_t entryNum; /*!< MSIX entry number. */
125 } netc_timer_config_t;
126
127 /*! @} */ // end of netc_timer_init
128 #if !(defined(__GNUC__) || defined(__ICCARM__))
129 #pragma endregion netc_timer_init
130 #endif
131
132 #if !(defined(__GNUC__) || defined(__ICCARM__))
133 #pragma region netc_timer_local_sync
134 #endif
135 /*! @addtogroup netc_timer_local_sync
136 * @{
137 */
138
139 /*!
140 * @brief Enumeration for NETC timer alarm index
141 */
142 typedef enum _netc_timer_alarm_index
143 {
144 kNETC_TimerAlarm1 = 0,
145 kNETC_TimerAlarm2,
146 } netc_timer_alarm_index_t;
147
148 /*!
149 * @brief Structure to configure timer alarm
150 */
151 typedef struct _netc_timer_alarm_t
152 {
153 bool enableInterrupt; /*!< Enable/Disable ALARM interrupt enable. */
154 bool polarity; /*!< True: Active low output, False: Active high output. */
155 bool pulseGenSync; /*!< True: ALARM output asserted synchronous to timer generated clock, False: ALARM output
156 asserted immediately. */
157 uint8_t pulseWidth; /*!< Pulse width in number of timer generated clocks the alarm will be active for. */
158 } netc_timer_alarm_t;
159
160 /*!
161 * @brief Enumeration for NETC timer FIPER index
162 */
163 typedef enum _netc_timer_fiper_index
164 {
165 kNETC_TimerFiper1 = 0,
166 kNETC_TimerFiper2,
167 kNETC_TimerFiper3,
168 } netc_timer_fiper_index_t;
169
170 /*!
171 * @brief Structure to configure timer FIPER
172 */
173 typedef struct _netc_timer_fiper_config
174 {
175 bool startCondition; /*!< True: FIPER is enabled through timer enable and alarm getting set, False: FIPER is enabled
176 through timer enable. */
177 bool fiper1Loopback; /*!< True: FIPER1 pulse is looped back into Trigger1 input, False: Trigger1 input is based
178 upon normal external trigger input. */
179 bool fiper2Loopback; /*!< True: FIPER2 pulse is looped back into Trigger2 input, False: Trigger2 input is based
180 upon normal external trigger input. */
181 uint16_t prescale; /*!< Output FIPER pulse clock is generated by dividing the timer input clock by this number. Must
182 be an even value. */
183 } netc_timer_fiper_config_t;
184
185 /*!
186 * @brief Structure to set and start timer FIPER
187 */
188 typedef struct _netc_timer_fiper
189 {
190 bool enableInterrupt; /*!< Enable/Disable FIPER interrupt interrupt. */
191 bool pulseGenSync; /*!< True: FIPER output asserted synchronous to timer generated clock, False: FIPER output
192 asserted immediately. */
193 uint8_t pulseWidth; /*!< FIPER pulse width. */
194 uint32_t pulsePeriod; /*!< Interval of FIPER pulses. */
195 } netc_timer_fiper_t;
196
197 /*!
198 * @brief Structure to configure external pulse trigger timestamp
199 */
200 typedef struct _netc_timer_ext_pulse_trig
201 {
202 bool polarity; /*!< Time stamp on the falling(true)/rising(false) edge of the external trigger. */
203 bool enableFifoOverflowInterrupt; /*!< Enable/Disable FIFO Overflow interrupt. */
204 bool enableFifoThresholdHitInterrupt; /*!< Enable/Disable FIFO Threshold Hit interrupt. */
205 bool enableTsAvailInterrupt; /*!< Enable/Disable timestamp capture interrupt. */
206 } netc_timer_ext_trig_t;
207
208 /*! @} */ // end of netc_timer_local_sync
209 #if !(defined(__GNUC__) || defined(__ICCARM__))
210 #pragma endregion netc_timer_local_sync
211 #endif
212
213 #if defined(__cplusplus)
214 extern "C" {
215 #endif
216
217 /*******************************************************************************
218 * API
219 ******************************************************************************/
220
221 #if !(defined(__GNUC__) || defined(__ICCARM__))
222 #pragma region netc_timer_init
223 #endif
224 /*! @addtogroup netc_timer_init
225 * @{
226 */
227
228 /*!
229 * @brief Initialize the NETC PTP1588 timer
230 *
231 * @param handle NETC timer handle.
232 * @param config The configuration of the timer.
233 * @return status_t
234 */
235 status_t NETC_TimerInit(netc_timer_handle_t *handle, const netc_timer_config_t *config);
236
237 /*!
238 * @brief Deinitialize the NETC PTP1588 timer
239 *
240 * @param handle NETC timer handle.
241 */
242 void NETC_TimerDeinit(netc_timer_handle_t *handle);
243
244 /*!
245 * @brief Initialize a NETC PTP1588 timer handle
246 *
247 * @param handle NETC timer handle.
248 */
249 void NETC_TimerInitHandle(netc_timer_handle_t *handle);
250
251 /*!
252 * @brief Enable/Disable the NETC PTP1588 timer
253 *
254 * @param handle NETC timer handle.
255 * @param enable Whether enable the PTP1588 timer.
256 */
257 void NETC_TimerEnable(netc_timer_handle_t *handle, bool enable);
258
259 /*! @} */ // end of netc_timer_init
260 #if !(defined(__GNUC__) || defined(__ICCARM__))
261 #pragma endregion netc_timer_init
262 #endif
263
264 #if !(defined(__GNUC__) || defined(__ICCARM__))
265 #pragma region netc_timer_local_sync
266 #endif
267 /*! @addtogroup netc_timer_local_sync
268 * @{
269 */
270
271 /*!
272 * @brief Configure the timer alarm feature
273 *
274 * @param handle NETC timer handle.
275 * @param alarmId The alarm index.
276 * @param alarm The timer alarm configuration structure.
277 */
278 void NETC_TimerConfigureAlarm(netc_timer_handle_t *handle,
279 netc_timer_alarm_index_t alarmId,
280 const netc_timer_alarm_t *alarm);
281
282 /*!
283 * @brief Start the alarm with specified time after alarm feature is configured
284 * This function can generate a pulse on a GPIO and/or an interrupt at specified future time.
285 * It also can trigger FIPER at specified time.
286 *
287 * @param handle NETC timer handle.
288 * @param alarmId The alarm index.
289 * @param nanosecond The time in nanosecond to generate alarm pulse.
290 */
291 void NETC_TimerStartAlarm(netc_timer_handle_t *handle, netc_timer_alarm_index_t alarmId, uint64_t nanosecond);
292
293 /*!
294 * @brief Stop the alarm before/after it's fired
295 * This function can deactivate alarm.
296 *
297 * @param handle NETC timer handle.
298 * @param alarmId The alarm index.
299 */
300 void NETC_TimerStopAlarm(netc_timer_handle_t *handle, netc_timer_alarm_index_t alarmId);
301
302 /*!
303 * @brief Configure the timer FIPER feature
304 *
305 * @param handle NETC timer handle.
306 * @param config The timer FIPER configuration structure.
307 */
308 void NETC_TimerConfigureFIPER(netc_timer_handle_t *handle, const netc_timer_fiper_config_t *config);
309
310 /*!
311 * @brief Start the timer FIPER to generate pulse
312 * This function can generate a periodic(Fixed Period-FIPER) pulse on a GPIO pin and/or an interrupt to the host.
313 *
314 * @param handle NETC timer handle.
315 * @param fiperId The timer FIPER index.
316 * @param fiper The timer FIPER configuration structure.
317 */
318 void NETC_TimerStartFIPER(netc_timer_handle_t *handle,
319 netc_timer_fiper_index_t fiperId,
320 const netc_timer_fiper_t *fiper);
321
322 /*!
323 * @brief Stop the timer FIPER to generate pulse
324 *
325 * @param handle NETC timer handle.
326 * @param fiperId The timer FIPER index.
327 */
328 void NETC_TimerStopFIPER(netc_timer_handle_t *handle, netc_timer_fiper_index_t fiperId);
329
330 /*!
331 * @brief Configure the external pulse trigger timestamp capture
332 *
333 * @param handle NETC timer handle.
334 * @param extTrigId The timer FIPER index.
335 * @param extTrig The external pulse trigger configuration structure.
336 */
337 void NETC_TimerConfigureExtPulseTrig(netc_timer_handle_t *handle,
338 netc_timer_exttrig_index_t extTrigId,
339 const netc_timer_ext_trig_t *extTrig);
340
341 /*!
342 * @brief Set timestamp FIFO threshold of the external pulse trigger timestamp capture
343 *
344 * @param handle NETC timer handle.
345 * @param threshold Timestamp FIFO threshold.
346 * @return status_t
347 */
348 status_t NETC_TimerSetTsFifoThreshold(netc_timer_handle_t *handle, uint8_t threshold);
349
350 /*!
351 * @brief Read the timestamp captured by external pulse trigger in FIFO
352 *
353 * @param handle NETC timer handle.
354 * @param extTrigId The timer FIPER index.
355 * @param nanosecond Timestamp in nanosecond.
356 * @return status_t
357 */
358 status_t NETC_TimerReadExtPulseCaptureTime(netc_timer_handle_t *handle,
359 netc_timer_exttrig_index_t extTrigId,
360 uint64_t *nanosecond);
361
362 /*!
363 * @brief Clear timer interrupt flags
364 *
365 * @param handle NETC timer handle.
366 * @param flags Timer interrupt flags. This is a logical OR of enumeration :: netc_timer_irq_flags_t.
367 */
NETC_TimerClearInterruptStatus(netc_timer_handle_t * handle,uint32_t flags)368 static inline void NETC_TimerClearInterruptStatus(netc_timer_handle_t *handle, uint32_t flags)
369 {
370 handle->hw.base->TMR_TEVENT = flags;
371 }
372
373 /*!
374 * @brief Set the global MSIX mask status
375 *
376 * This function masks/unmasks global MSIX message.
377 * Mask - All of the vectors are masked, regardless of their per-entry mask bit states.
378 * Unmask - Each entry's mask status determines whether the vector is masked or not.
379 *
380 * @param handle The timer handle
381 * @param mask The mask state. True: Mask, False: Unmask.
382 * @return status_t
383 */
384 status_t NETC_TimerMsixSetGlobalMask(netc_timer_handle_t *handle, bool mask);
385
386 /*!
387 * @brief Set the MSIX entry mask status for specified entry
388 *
389 * This function masks/unmasks MSIX message for specified entry.
390 *
391 * @param handle NETC timer handle.
392 * @param entryIdx The entry index in the table.
393 * @param mask The mask state. True: Mask, False: Unmask.
394 * @return status_t
395 */
396 status_t NETC_TimerMsixSetEntryMask(netc_timer_handle_t *handle, uint8_t entryIdx, bool mask);
397
398 /*!
399 * @brief Get the MSIX pending status in MSIX PBA table
400 *
401 * This function is to get the entry pending status from MSIX PBA table. If interrupt occurs but masked by vector
402 * control of entry, pending bit in PBA will be set.
403 *
404 * @param handle NETC timer handle.
405 * @param pbaIdx The index of PBA array with 64-bit unit.
406 * @param status Pending status bit mask, bit n for entry n.
407 * @return status_t
408 */
409 status_t NETC_TimerMsixGetPendingStatus(netc_timer_handle_t *handle, uint8_t pbaIdx, uint64_t *status);
410
411 /*! @} */ // end of netc_timer_local_sync
412 #if !(defined(__GNUC__) || defined(__ICCARM__))
413 #pragma endregion netc_timer_local_sync
414 #endif
415
416 #if !(defined(__GNUC__) || defined(__ICCARM__))
417 #pragma region netc_timer_adjust
418 #endif
419 /*! @addtogroup netc_timer_adjust
420 * @{
421 */
422
423 /*!
424 * @brief Get the timer's current or default time
425 *
426 * @param base NETC timer base address.
427 * @param nanosecond Time in nanosecond.
428 */
429 void NETC_TimerGetTime(ENETC_PF_TMR_Type *base, uint64_t *nanosecond);
430
431 /*!
432 * @brief Get the timer's current time
433 *
434 * @param handle NETC timer handle.
435 * @param nanosecond Time in nanosecond.
436 */
437 void NETC_TimerGetCurrentTime(netc_timer_handle_t *handle, uint64_t *nanosecond);
438
439 /*!
440 * @brief Get the timer's freerunning time
441 *
442 * @param handle NETC timer handle.
443 * @param nanosecond Time in nanosecond.
444 */
445 void NETC_TimerGetFreeRunningTime(netc_timer_handle_t *handle, uint64_t *nanosecond);
446
447 /*!
448 * @brief Correct the current timer
449 * @note Need stop all mechanims based on 1588 timers during call this API. To take time gate scheduling as example,
450 * if the port is enabled with TGS and it contains an operational list, user need to call
451 * SWT_TxPortTGSEnable()/SWT_TxPortTGSEnable() to disable the port time gate before call this API, and re-enable
452 * and configure the port TGS after the execution of this API.
453 *
454 * @param handle NETC timer handle.
455 * @param nanosecond Time in nanosecond.
456 */
457 void NETC_TimerAddOffset(netc_timer_handle_t *handle, int64_t nanosecond);
458
459 /*!
460 * @brief Adjust the timer frequency
461 *
462 * @param handle NETC timer handle.
463 * @param ppb Parts per billion.
464 */
465 void NETC_TimerAdjustFreq(netc_timer_handle_t *handle, int32_t ppb);
466
467 /*!
468 * @brief Get the free running and synchronized current time with an atomic read
469 *
470 * @param handle NETC timer handle.
471 * @param frt The free-running time in nanosecond.
472 * @param srt The synchronized current time in nanosecond.
473 */
474 void NETC_TimerGetFrtSrtTime(netc_timer_handle_t *handle, uint64_t *frt, uint64_t *srt);
475
476 /*! @} */ // end of netc_timer_adjust
477 #if !(defined(__GNUC__) || defined(__ICCARM__))
478 #pragma endregion netc_timer_adjust
479 #endif
480
481 #if defined(__cplusplus)
482 }
483 #endif
484 #endif /* FSL_NETC_TIMER_H_ */
485