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