1 /*
2 * Copyright (c) 2016, 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_pwt.h"
10
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.pwt"
14 #endif
15
16 /*******************************************************************************
17 * Prototypes
18 ******************************************************************************/
19 /*!
20 * @brief Gets the instance from the base address
21 *
22 * @param base PWT peripheral base address
23 *
24 * @return The PWT instance
25 */
26 static uint32_t PWT_GetInstance(PWT_Type *base);
27
28 /*******************************************************************************
29 * Variables
30 ******************************************************************************/
31 /*! @brief Pointers to PWT bases for each instance. */
32 static PWT_Type *const s_pwtBases[] = PWT_BASE_PTRS;
33
34 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
35 /*! @brief Pointers to PWT clocks for each instance. */
36 static const clock_ip_name_t s_pwtClocks[] = PWT_CLOCKS;
37 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
38
39 /*******************************************************************************
40 * Code
41 ******************************************************************************/
PWT_GetInstance(PWT_Type * base)42 static uint32_t PWT_GetInstance(PWT_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_pwtBases); instance++)
48 {
49 if (s_pwtBases[instance] == base)
50 {
51 break;
52 }
53 }
54
55 assert(instance < ARRAY_SIZE(s_pwtBases));
56
57 return instance;
58 }
59
60 /*!
61 * brief Ungates the PWT clock and configures the peripheral for basic operation.
62 *
63 * note This API should be called at the beginning of the application using the PWT driver.
64 *
65 * param base PWT peripheral base address
66 * param config Pointer to the user configuration structure.
67 */
PWT_Init(PWT_Type * base,const pwt_config_t * config)68 void PWT_Init(PWT_Type *base, const pwt_config_t *config)
69 {
70 assert(config);
71
72 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
73 /* Ungate the PWT module clock*/
74 CLOCK_EnableClock(s_pwtClocks[PWT_GetInstance(base)]);
75 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
76
77 /* Reset the module */
78 PWT_Reset(base);
79
80 /*
81 * Clear all interrupt, disable the counter, config the first counter load enable bit,
82 * enable module interrupt bit.
83 */
84 base->CS = PWT_CS_FCTLE(config->enableFirstCounterLoad) | PWT_CS_PWTIE_MASK;
85
86 /* Set clock source, prescale and input source */
87 base->CR = PWT_CR_PCLKS(config->clockSource) | PWT_CR_PRE(config->prescale) | PWT_CR_PINSEL(config->inputSelect);
88 }
89
90 /*!
91 * brief Gates the PWT clock.
92 *
93 * param base PWT peripheral base address
94 */
PWT_Deinit(PWT_Type * base)95 void PWT_Deinit(PWT_Type *base)
96 {
97 /* Disable the counter */
98 base->CS &= (uint8_t)(~PWT_CS_PWTEN_MASK);
99
100 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
101 /* Gate the PWT clock */
102 CLOCK_DisableClock(s_pwtClocks[PWT_GetInstance(base)]);
103 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
104 }
105
106 /*!
107 * brief Fills in the PWT configuration structure with the default settings.
108 *
109 * The default values are:
110 * code
111 * config->clockSource = kPWT_BusClock;
112 * config->prescale = kPWT_Prescale_Divide_1;
113 * config->inputSelect = kPWT_InputPort_0;
114 * config->enableFirstCounterLoad = false;
115 * endcode
116 * param config Pointer to the user configuration structure.
117 */
PWT_GetDefaultConfig(pwt_config_t * config)118 void PWT_GetDefaultConfig(pwt_config_t *config)
119 {
120 assert(config);
121
122 /* Initializes the configure structure to zero. */
123 (void)memset(config, 0, sizeof(*config));
124
125 /* Use the IP Bus clock as source clock for the PWT submodule */
126 config->clockSource = kPWT_BusClock;
127 /* Clock source prescale is set to divide by 1*/
128 config->prescale = kPWT_Prescale_Divide_1;
129 /* PWT input signal coming from Port 0 */
130 config->inputSelect = kPWT_InputPort_0;
131 /* Do not load the first counter values to the corresponding registers */
132 config->enableFirstCounterLoad = false;
133 }
134