1 /*
2  * Copyright  2018-2019 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_plu.h"
9 
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.plu"
13 #endif
14 
15 /*******************************************************************************
16  * Prototypes
17  ******************************************************************************/
18 
19 /*!
20  * @brief Gets the instance from the base address
21  *
22  * @param base PLU peripheral base address
23  *
24  * @return The PLU instance
25  */
26 static uint32_t PLU_GetInstance(PLU_Type *base);
27 
28 /*******************************************************************************
29  * Variables
30  ******************************************************************************/
31 /*! @brief Pointers to PLU bases for each instance. */
32 static PLU_Type *const s_pluBases[] = PLU_BASE_PTRS;
33 
34 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
35 /*! @brief Pointers to PLU clocks for each instance. */
36 static const clock_ip_name_t s_pluClocks[] = PLU_CLOCKS;
37 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
38 
39 #if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
40 /*! @brief Pointers to PLU resets for each instance. */
41 static const reset_ip_name_t s_lpuResets[] = PLU_RSTS_N;
42 #endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
43 
44 /*******************************************************************************
45  * Code
46  ******************************************************************************/
PLU_GetInstance(PLU_Type * base)47 static uint32_t PLU_GetInstance(PLU_Type *base)
48 {
49     uint32_t instance;
50     uint32_t pluArrayCount = (sizeof(s_pluBases) / sizeof(s_pluBases[0]));
51 
52     /* Find the instance index from base address mappings. */
53     for (instance = 0; instance < pluArrayCount; instance++)
54     {
55         if (s_pluBases[instance] == base)
56         {
57             break;
58         }
59     }
60 
61     assert(instance < pluArrayCount);
62 
63     return instance;
64 }
65 
66 /*!
67  * brief Ungates the PLU clock and reset the module.
68  *
69  * note This API should be called at the beginning of the application using the PLU driver.
70  *
71  * param base PLU peripheral base address
72  */
PLU_Init(PLU_Type * base)73 void PLU_Init(PLU_Type *base)
74 {
75 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
76     /* Enable the PLU peripheral clock */
77     CLOCK_EnableClock(s_pluClocks[PLU_GetInstance(base)]);
78 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
79 
80 #if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
81     /* Reset the module. */
82     RESET_PeripheralReset(s_lpuResets[PLU_GetInstance(base)]);
83 #endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
84 }
85 
86 /*!
87  * brief Gate the PLU clock
88  *
89  * param base PLU peripheral base address
90  */
PLU_Deinit(PLU_Type * base)91 void PLU_Deinit(PLU_Type *base)
92 {
93 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
94     /* Gate the module clock */
95     CLOCK_DisableClock((s_pluClocks[PLU_GetInstance(base)]));
96 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
97 }
98 
99 #if defined(FSL_FEATURE_PLU_HAS_WAKEINT_CTRL_REG) && FSL_FEATURE_PLU_HAS_WAKEINT_CTRL_REG
100 /*!
101  * @brief Gets an available pre-defined settings for wakeup/interrupt control.
102  *
103  * This function initializes the initial configuration structure with an available settings. The default values are:
104  * @code
105  *   config->filterMode = kPLU_WAKEINT_FILTER_MODE_BYPASS;
106  *   config->clockSource = kPLU_WAKEINT_FILTER_CLK_SRC_1MHZ_LPOSC;
107  * @endcode
108  * @param config Pointer to configuration structure.
109  */
PLU_GetDefaultWakeIntConfig(plu_wakeint_config_t * config)110 void PLU_GetDefaultWakeIntConfig(plu_wakeint_config_t *config)
111 {
112     /* Initializes the configure structure to zero. */
113     (void)memset(config, 0, sizeof(*config));
114 
115     config->filterMode  = kPLU_WAKEINT_FILTER_MODE_BYPASS;
116     config->clockSource = kPLU_WAKEINT_FILTER_CLK_SRC_1MHZ_LPOSC;
117 }
118 
119 /*!
120  * @brief Enable PLU outputs wakeup/interrupt request.
121  *
122  * This function enables Any of the eight selected PLU outputs to contribute to an asynchronous wake-up or an interrupt
123  * request.
124  *
125  * Note: If a PLU_CLKIN is provided, the raw wake-up/interrupt request will be set on the rising-edge of the PLU_CLKIN
126  * whenever the raw request signal is high. This registered signal will be glitch-free and just use the default wakeint
127  * config by PLU_GetDefaultWakeIntConfig(). If not, have to specify the filter mode and clock source to eliminate the
128  * glitches caused by long and widely disparate delays through the network of LUTs making up the PLU. This way may
129  * increase power consumption in low-power operating modes and inject delay before the wake-up/interrupt request is
130  * generated.
131  *
132  * @param base PLU peripheral base address.
133  * @param interruptMask PLU interrupt mask (see @ref _plu_interrupt_mask enumeration).
134  * @param config Pointer to configuration structure (see @ref plu_wakeint_config_t typedef enumeration)
135  */
PLU_EnableWakeIntRequest(PLU_Type * base,uint32_t interruptMask,const plu_wakeint_config_t * config)136 void PLU_EnableWakeIntRequest(PLU_Type *base, uint32_t interruptMask, const plu_wakeint_config_t *config)
137 {
138     uint32_t tmp32 = 0U;
139 
140     tmp32 = PLU_WAKEINT_CTRL_FILTER_MODE(config->filterMode) | PLU_WAKEINT_CTRL_FILTER_CLKSEL(config->clockSource) |
141             PLU_WAKEINT_CTRL_MASK(interruptMask);
142 
143     base->WAKEINT_CTRL = tmp32;
144 }
145 
146 /*!
147  * @brief Clear the latched interrupt
148  *
149  * This function clears the wake-up/interrupt request flag latched by PLU_LatchInterrupt()
150  *
151  * Note: It is not necessary for the PLU bus clock to be enabled in order to write-to or read-back this bit.
152  *
153  * @param base PLU peripheral base address.
154  */
PLU_ClearLatchedInterrupt(PLU_Type * base)155 void PLU_ClearLatchedInterrupt(PLU_Type *base)
156 {
157     base->WAKEINT_CTRL |= PLU_WAKEINT_CTRL_INTR_CLEAR_MASK;
158     /* It will take a delay of up to 1.5 PLU_CLKIN clock cycles before this write-to-clear takes effect. */
159     while (PLU_WAKEINT_CTRL_INTR_CLEAR_MASK == (base->WAKEINT_CTRL & PLU_WAKEINT_CTRL_INTR_CLEAR_MASK))
160     {
161     }
162 }
163 #endif /* FSL_FEATURE_PLU_HAS_WAKEINT_CTRL_REG */
164