1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_xbara.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.xbara"
18 #endif
19
20 /* Macros for entire XBARA_CTRL register. */
21 #define XBARA_CTRLx(base, index) (((volatile uint16_t *)(&((base)->CTRL0)))[(index)])
22
23 typedef union
24 {
25 uint8_t _u8[2];
26 uint16_t _u16;
27 } xbara_u8_u16_t;
28
29 /*******************************************************************************
30 * Prototypes
31 ******************************************************************************/
32
33 /*!
34 * @brief Get the XBARA instance from peripheral base address.
35 *
36 * @param base XBARA peripheral base address.
37 * @return XBARA instance.
38 */
39 static uint32_t XBARA_GetInstance(XBARA_Type *base);
40
41 /*******************************************************************************
42 * Variables
43 ******************************************************************************/
44
45 /* Array of XBARA peripheral base address. */
46 static XBARA_Type *const s_xbaraBases[] = XBARA_BASE_PTRS;
47
48 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
49 /* Array of XBARA clock name. */
50 static const clock_ip_name_t s_xbaraClock[] = XBARA_CLOCKS;
51 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
52
53 /*******************************************************************************
54 * Code
55 ******************************************************************************/
56
XBARA_GetInstance(XBARA_Type * base)57 static uint32_t XBARA_GetInstance(XBARA_Type *base)
58 {
59 uint32_t instance;
60
61 /* Find the instance index from base address mappings. */
62 for (instance = 0; instance < ARRAY_SIZE(s_xbaraBases); instance++)
63 {
64 if (s_xbaraBases[instance] == base)
65 {
66 break;
67 }
68 }
69
70 assert(instance < ARRAY_SIZE(s_xbaraBases));
71
72 return instance;
73 }
74
75 /*!
76 * brief Initializes the XBARA module.
77 *
78 * This function un-gates the XBARA clock.
79 *
80 * param base XBARA peripheral address.
81 */
XBARA_Init(XBARA_Type * base)82 void XBARA_Init(XBARA_Type *base)
83 {
84 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
85 /* Enable XBARA module clock. */
86 CLOCK_EnableClock(s_xbaraClock[XBARA_GetInstance(base)]);
87 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
88 }
89
90 /*!
91 * brief Shuts down the XBARA module.
92 *
93 * This function disables XBARA clock.
94 *
95 * param base XBARA peripheral address.
96 */
XBARA_Deinit(XBARA_Type * base)97 void XBARA_Deinit(XBARA_Type *base)
98 {
99 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
100 /* Disable XBARA module clock. */
101 CLOCK_DisableClock(s_xbaraClock[XBARA_GetInstance(base)]);
102 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
103 }
104
105 /*!
106 * brief Sets a connection between the selected XBARA_IN[*] input and the XBARA_OUT[*] output signal.
107 *
108 * This function connects the XBARA input to the selected XBARA output.
109 * If more than one XBARA module is available, only the inputs and outputs from the same module
110 * can be connected.
111 *
112 * Example:
113 code
114 XBARA_SetSignalsConnection(XBARA, kXBARA_InputPIT_TRG0, kXBARA_OutputDMAMUX18);
115 endcode
116 *
117 * param base XBARA peripheral address.
118 * param input XBARA input signal.
119 * param output XBARA output signal.
120 */
XBARA_SetSignalsConnection(XBARA_Type * base,xbar_input_signal_t input,xbar_output_signal_t output)121 void XBARA_SetSignalsConnection(XBARA_Type *base, xbar_input_signal_t input, xbar_output_signal_t output)
122 {
123 xbara_u8_u16_t regVal;
124 uint8_t byteInReg;
125 uint8_t outputIndex = (uint8_t)output;
126
127 byteInReg = outputIndex % 2U;
128
129 regVal._u16 = XBARA_SELx(base, outputIndex);
130
131 regVal._u8[byteInReg] = (uint8_t)input;
132
133 XBARA_SELx(base, outputIndex) = regVal._u16;
134 }
135
136 /*!
137 * brief Gets the active edge detection status.
138 *
139 * This function gets the active edge detect status of all XBARA_OUTs. If the
140 * active edge occurs, the return value is asserted. When the interrupt or the DMA
141 * functionality is enabled for the XBARA_OUTx, this field is 1 when the interrupt
142 * or DMA request is asserted and 0 when the interrupt or DMA request has been
143 * cleared.
144 *
145 * param base XBARA peripheral address.
146 * return the mask of these status flag bits.
147 */
XBARA_GetStatusFlags(XBARA_Type * base)148 uint32_t XBARA_GetStatusFlags(XBARA_Type *base)
149 {
150 uint32_t status_flag;
151
152 status_flag = ((uint32_t)base->CTRL0 & (XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK));
153
154 status_flag |= (((uint32_t)base->CTRL1 & (XBARA_CTRL1_STS2_MASK | XBARA_CTRL1_STS3_MASK)) << 16U);
155
156 return status_flag;
157 }
158
159 /*!
160 * brief Clears the edge detection status flags of relative mask.
161 *
162 * param base XBARA peripheral address.
163 * param mask the status flags to clear.
164 */
XBARA_ClearStatusFlags(XBARA_Type * base,uint32_t mask)165 void XBARA_ClearStatusFlags(XBARA_Type *base, uint32_t mask)
166 {
167 uint16_t regVal;
168
169 /* Assign regVal to CTRL0 register's value */
170 regVal = (base->CTRL0);
171 /* Perform this command to avoid writing 1 into interrupt flag bits */
172 regVal &= (uint16_t)(~(XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK));
173 /* Write 1 to interrupt flag bits corresponding to mask */
174 regVal |= (uint16_t)(mask & (XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK));
175 /* Write regVal value into CTRL0 register */
176 base->CTRL0 = regVal;
177
178 /* Assign regVal to CTRL1 register's value */
179 regVal = (base->CTRL1);
180 /* Perform this command to avoid writing 1 into interrupt flag bits */
181 regVal &= (uint16_t)(~(XBARA_CTRL1_STS2_MASK | XBARA_CTRL1_STS3_MASK));
182 /* Write 1 to interrupt flag bits corresponding to mask */
183 regVal |= (uint16_t)((mask >> 16U) & (XBARA_CTRL1_STS2_MASK | XBARA_CTRL1_STS3_MASK));
184 /* Write regVal value into CTRL1 register */
185 base->CTRL1 = regVal;
186 }
187
188 /*!
189 * brief Configures the XBARA control register.
190 *
191 * This function configures an XBARA control register. The active edge detection
192 * and the DMA/IRQ function on the corresponding XBARA output can be set.
193 *
194 * Example:
195 code
196 xbara_control_config_t userConfig;
197 userConfig.activeEdge = kXBARA_EdgeRising;
198 userConfig.requestType = kXBARA_RequestInterruptEnalbe;
199 XBARA_SetOutputSignalConfig(XBARA, kXBARA_OutputDMAMUX18, &userConfig);
200 endcode
201 *
202 * param base XBARA peripheral address.
203 * param output XBARA output number.
204 * param controlConfig Pointer to structure that keeps configuration of control register.
205 */
XBARA_SetOutputSignalConfig(XBARA_Type * base,xbar_output_signal_t output,const xbara_control_config_t * controlConfig)206 void XBARA_SetOutputSignalConfig(XBARA_Type *base,
207 xbar_output_signal_t output,
208 const xbara_control_config_t *controlConfig)
209 {
210 uint8_t outputIndex = (uint8_t)output;
211 uint8_t regIndex;
212 uint8_t byteInReg;
213 xbara_u8_u16_t regVal;
214
215 assert(outputIndex < (uint32_t)FSL_FEATURE_XBARA_INTERRUPT_COUNT);
216
217 regIndex = outputIndex / 2U;
218 byteInReg = outputIndex % 2U;
219
220 regVal._u16 = XBARA_CTRLx(base, regIndex);
221
222 /* Don't clear the status flags. */
223 regVal._u16 &= (uint16_t)(~(XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK));
224
225 regVal._u8[byteInReg] = (uint8_t)(XBARA_CTRL0_EDGE0(controlConfig->activeEdge) |
226 (uint16_t)(((uint32_t)controlConfig->requestType) << XBARA_CTRL0_DEN0_SHIFT));
227
228 XBARA_CTRLx(base, regIndex) = regVal._u16;
229 }
230