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