1 | /* |
2 | * Copyright (c) 2015, Freescale Semiconductor, Inc. |
3 | * Copyright 2016-2017 NXP |
4 | * All rights reserved. |
5 | * |
6 | * SPDX-License-Identifier: BSD-3-Clause |
7 | */ |
8 | |
9 | #include "fsl_pit.h" |
10 | |
11 | /* Component ID definition, used by tools. */ |
12 | #ifndef FSL_COMPONENT_ID |
13 | #define FSL_COMPONENT_ID "platform.drivers.pit" |
14 | #endif |
15 | |
16 | /******************************************************************************* |
17 | * Prototypes |
18 | ******************************************************************************/ |
19 | /*! |
20 | * @brief Gets the instance from the base address to be used to gate or ungate the module clock |
21 | * |
22 | * @param base PIT peripheral base address |
23 | * |
24 | * @return The PIT instance |
25 | */ |
26 | static uint32_t PIT_GetInstance(PIT_Type *base); |
27 | |
28 | /******************************************************************************* |
29 | * Variables |
30 | ******************************************************************************/ |
31 | /*! @brief Pointers to PIT bases for each instance. */ |
32 | static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS; |
33 | |
34 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
35 | /*! @brief Pointers to PIT clocks for each instance. */ |
36 | static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS; |
37 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
38 | |
39 | /******************************************************************************* |
40 | * Code |
41 | ******************************************************************************/ |
42 | static uint32_t PIT_GetInstance(PIT_Type *base) |
43 | { |
44 | uint32_t instance; |
45 | |
46 | /* Find the instance index from base address mappings. */ |
47 | for (instance = 0; instance < ARRAY_SIZE(s_pitBases); instance++) |
48 | { |
49 | if (s_pitBases[instance] == base) |
50 | { |
51 | break; |
52 | } |
53 | } |
54 | |
55 | assert(instance < ARRAY_SIZE(s_pitBases)); |
56 | |
57 | return instance; |
58 | } |
59 | |
60 | /*! |
61 | * brief Ungates the PIT clock, enables the PIT module, and configures the peripheral for basic operations. |
62 | * |
63 | * note This API should be called at the beginning of the application using the PIT driver. |
64 | * |
65 | * param base PIT peripheral base address |
66 | * param config Pointer to the user's PIT config structure |
67 | */ |
68 | void PIT_Init(PIT_Type *base, const pit_config_t *config) |
69 | { |
70 | assert(NULL != config); |
71 | |
72 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
73 | /* Ungate the PIT clock*/ |
74 | CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]); |
75 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
76 | |
77 | #if defined(FSL_FEATURE_PIT_HAS_MDIS) && FSL_FEATURE_PIT_HAS_MDIS |
78 | /* Enable PIT timers */ |
79 | base->MCR &= ~PIT_MCR_MDIS_MASK; |
80 | #endif |
81 | |
82 | #if defined(FSL_FEATURE_PIT_TIMER_COUNT) && (FSL_FEATURE_PIT_TIMER_COUNT) |
83 | /* Clear all status bits for all channels to make sure the status of all TCTRL registers is clean. */ |
84 | for (uint8_t i = 0U; i < (uint32_t)FSL_FEATURE_PIT_TIMER_COUNT; i++) |
85 | { |
86 | base->CHANNEL[i].TCTRL &= ~(PIT_TCTRL_TEN_MASK | PIT_TCTRL_TIE_MASK | PIT_TCTRL_CHN_MASK); |
87 | } |
88 | #endif /* FSL_FEATURE_PIT_TIMER_COUNT */ |
89 | |
90 | /* Config timer operation when in debug mode */ |
91 | if (true == config->enableRunInDebug) |
92 | { |
93 | base->MCR &= ~PIT_MCR_FRZ_MASK; |
94 | } |
95 | else |
96 | { |
97 | base->MCR |= PIT_MCR_FRZ_MASK; |
98 | } |
99 | } |
100 | |
101 | /*! |
102 | * brief Gates the PIT clock and disables the PIT module. |
103 | * |
104 | * param base PIT peripheral base address |
105 | */ |
106 | void PIT_Deinit(PIT_Type *base) |
107 | { |
108 | #if defined(FSL_FEATURE_PIT_HAS_MDIS) && FSL_FEATURE_PIT_HAS_MDIS |
109 | /* Disable PIT timers */ |
110 | base->MCR |= PIT_MCR_MDIS_MASK; |
111 | #endif |
112 | |
113 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
114 | /* Gate the PIT clock*/ |
115 | CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]); |
116 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
117 | } |
118 | |
119 | #if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER |
120 | |
121 | /*! |
122 | * brief Reads the current lifetime counter value. |
123 | * |
124 | * The lifetime timer is a 64-bit timer which chains timer 0 and timer 1 together. |
125 | * Timer 0 and 1 are chained by calling the PIT_SetTimerChainMode before using this timer. |
126 | * The period of lifetime timer is equal to the "period of timer 0 * period of timer 1". |
127 | * For the 64-bit value, the higher 32-bit has the value of timer 1, and the lower 32-bit |
128 | * has the value of timer 0. |
129 | * |
130 | * param base PIT peripheral base address |
131 | * |
132 | * return Current lifetime timer value |
133 | */ |
134 | uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base) |
135 | { |
136 | uint32_t valueH = 0U; |
137 | uint32_t valueL = 0U; |
138 | |
139 | /* LTMR64H should be read before LTMR64L */ |
140 | valueH = base->LTMR64H; |
141 | valueL = base->LTMR64L; |
142 | |
143 | return (((uint64_t)valueH << 32U) + (uint64_t)(valueL)); |
144 | } |
145 | |
146 | #endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */ |
147 |