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