1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017, 2023 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef FSL_TSTMR_H_
9 #define FSL_TSTMR_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup tstmr_driver
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /* Component ID definition, used by tools. */
23 #ifndef FSL_COMPONENT_ID
24 #define FSL_COMPONENT_ID "platform.drivers.tstmr"
25 #endif
26 
27 /*! @name Driver version */
28 /*! @{ */
29 #define FSL_TSTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */
30                                                          /*! @} */
31 
32 /*******************************************************************************
33  * API
34  ******************************************************************************/
35 
36 #if defined(__cplusplus)
37 extern "C" {
38 #endif
39 
40 /*!
41  * @brief Reads the time stamp.
42  *
43  * This function reads the low and high registers and returns the 56-bit free running
44  * counter value. This can be read by software at any time to determine the software ticks.
45  * TSTMR registers can be read with 32-bit accesses only. The TSTMR LOW read should occur first,
46  * followed by the TSTMR HIGH read.
47  *
48  * @param base TSTMR peripheral base address.
49  *
50  * @return The 56-bit time stamp value.
51  */
TSTMR_ReadTimeStamp(TSTMR_Type * base)52 static inline uint64_t TSTMR_ReadTimeStamp(TSTMR_Type *base)
53 {
54     uint32_t reg_l;
55     uint32_t reg_h;
56     uint32_t regPrimask = DisableGlobalIRQ();
57     /* A complete read operation should include both TSTMR LOW and HIGH reads. If a HIGH read does not follow a LOW
58      * read, then any other Time Stamp value read will be locked at a fixed value. The TSTMR LOW read should occur
59      * first, followed by the TSTMR HIGH read.
60      * */
61     reg_l = base->L;
62     __DMB();
63     reg_h = base->H;
64 
65     EnableGlobalIRQ(regPrimask);
66 
67     return (uint64_t)reg_l | (((uint64_t)reg_h) << 32U);
68 }
69 
70 /*!
71  * @brief Delays for a specified number of microseconds.
72  *
73  * This function repeatedly reads the timestamp register and waits for the user-specified
74  * delay value.
75  *
76  * @param base      TSTMR peripheral base address.
77  * @param delayInUs Delay value in microseconds.
78  */
TSTMR_DelayUs(TSTMR_Type * base,uint64_t delayInUs)79 static inline void TSTMR_DelayUs(TSTMR_Type *base, uint64_t delayInUs)
80 {
81 #if defined(TSTMR_CLOCK_FREQUENCY_MHZ)
82     uint64_t startTime = TSTMR_ReadTimeStamp(base);
83     while (TSTMR_ReadTimeStamp(base) - startTime < TSTMR_CLOCK_FREQUENCY_MHZ * delayInUs)
84     {
85     }
86 #else
87     assert(0);
88 #endif
89 }
90 
91 #if defined(__cplusplus)
92 }
93 #endif
94 
95 /*! @}*/
96 
97 #endif /* FSL_TSTMR_H_ */
98