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 | |
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 | */ |
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 | */ |
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 | */ |
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 | */ |
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 | */ |
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 | */ |
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 | |