1 /***************************************************************************//**
2 * \file cy_trigmux.c
3 * \version 1.30
4 *
5 * \brief Trigger mux API.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2016-2020 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24
25 #include "cy_device.h"
26
27 #if defined (CY_IP_MXSPERI) || defined (CY_IP_MXPERI)
28
29 #include "cy_trigmux.h"
30
31 #define CY_TRIGMUX_IS_TRIGTYPE_VALID(trigType) (((trigType) == TRIGGER_TYPE_EDGE) || \
32 ((trigType) == TRIGGER_TYPE_LEVEL))
33
34 #define CY_TRIGMUX_V1_IS_CYCLES_VALID(cycles) (CY_TRIGGER_INFINITE >= (cycles))
35 #define CY_TRIGMUX_V2_IS_CYCLES_VALID(cycles) ((CY_TRIGGER_DEACTIVATE == (cycles)) || \
36 (CY_TRIGGER_TWO_CYCLES == (cycles)) || \
37 (CY_TRIGGER_INFINITE == (cycles)))
38 #define CY_TRIGMUX_IS_CYCLES_VALID(cycles) ((CY_PERI_V1 && CY_TRIGMUX_V1_IS_CYCLES_VALID(cycles)) || \
39 CY_TRIGMUX_V2_IS_CYCLES_VALID(cycles))
40
41 #define CY_TRIGMUX_INTRIG_MASK (PERI_TR_CMD_GROUP_SEL_Msk | PERI_TR_GR_TR_OUT_CTL_TR_SEL_Msk)
42 #define CY_TRIGMUX_IS_INTRIG_VALID(inTrg) (0UL == ((inTrg) & (uint32_t)~CY_TRIGMUX_INTRIG_MASK))
43
44 #define CY_TRIGMUX_OUTTRIG_MASK (PERI_TR_CMD_OUT_SEL_Msk | PERI_TR_CMD_GROUP_SEL_Msk | CY_PERI_TR_CTL_SEL_Msk)
45 #define CY_TRIGMUX_IS_OUTTRIG_VALID(outTrg) ((0UL == ((outTrg) & (uint32_t)~CY_TRIGMUX_OUTTRIG_MASK)) && \
46 (0UL != ((outTrg) & PERI_TR_CMD_OUT_SEL_Msk)))
47
48 #define CY_TRIGMUX_ONETRIG_MASK (PERI_V2_TR_CMD_OUT_SEL_Msk | PERI_V2_TR_CMD_GROUP_SEL_Msk | CY_PERI_TR_CTL_SEL_Msk)
49
50 #if defined (CY_IP_MXSPERI)
51 #define CY_TRIGMUX_ONETRIG_GR_START 0x10UL /* trigger 1-1 group [16-31] */
52 #define CY_TRIGMUX_IS_ONETRIG_VALID(oneTrg) ((0UL == ((oneTrg) & (uint32_t)~CY_TRIGMUX_ONETRIG_MASK)) && \
53 (0UL != ((oneTrg) & PERI_V2_TR_CMD_OUT_SEL_Msk)) && \
54 (0UL != (_FLD2VAL(PERI_V2_TR_CMD_GROUP_SEL, oneTrg) & (uint32_t)CY_TRIGMUX_ONETRIG_GR_START)))
55 #else
56 #define CY_TRIGMUX_IS_ONETRIG_VALID(oneTrg) ((0UL == ((oneTrg) & (uint32_t)~CY_TRIGMUX_ONETRIG_MASK)) && \
57 (0UL != ((oneTrg) & PERI_V2_TR_CMD_OUT_SEL_Msk)) && \
58 (0UL != ((oneTrg) & (PERI_V2_TR_CMD_GROUP_SEL_Msk & (uint32_t)~PERI_TR_CMD_GROUP_SEL_Msk))))
59 #endif
60
61 #define CY_TRIGMUX_TRIGLINE_MASK (PERI_TR_CMD_OUT_SEL_Msk | CY_PERI_TR_CMD_GROUP_SEL_Msk | CY_PERI_TR_CTL_SEL_Msk)
62 #define CY_TRIGMUX_IS_TRIGLINE_VALID(trgLn) (0U == ((trgLn) & (uint32_t)~CY_TRIGMUX_TRIGLINE_MASK))
63
64 #define CY_TRIGMUX_TR_CTL(outTrig) (PERI_TR_GR_TR_CTL(_FLD2VAL(CY_PERI_TR_CMD_GROUP_SEL, outTrig), \
65 _FLD2VAL(CY_PERI_TR_CTL_SEL, outTrig)))
66
67
68 /*******************************************************************************
69 * Function Name: Cy_TrigMux_Connect
70 ****************************************************************************//**
71 *
72 * Connects an input trigger source and output trigger.
73 *
74 * \param inTrig
75 * An input selection for the trigger mux.
76 * - Bit 30 should be cleared.
77 * - Bit 12 should be cleared.
78 * - Bits 11:8 represent the trigger group selection.
79 * - Bits 7:0 select the input trigger signal for the specified trigger multiplexer.
80 *
81 * \param outTrig
82 * The output of the trigger mux. This refers to the consumer of the trigger mux.
83 * - Bit 30 should be set.
84 * - Bit 12 should be cleared.
85 * - Bits 11:8 represent the trigger group selection.<br>
86 * For PERI_ver1:
87 * - Bits 6:0 select the output trigger number in the trigger group.<br>
88 * For PERI_ver2:
89 * - Bits 7:0 select the output trigger number in the trigger group.
90 *
91 * \param invert
92 * - true: The output trigger is inverted.
93 * - false: The output trigger is not inverted.
94 *
95 * \param trigType The trigger signal type.
96 * - TRIGGER_TYPE_EDGE: The trigger is synchronized to the consumer blocks clock
97 * and a two-cycle pulse is generated on this clock.
98 * - TRIGGER_TYPE_LEVEL: The trigger is a simple level output.
99 *
100 * \return status:
101 * - CY_TRIGMUX_SUCCESS: The connection is made successfully.
102 * - CY_TRIGMUX_BAD_PARAM: Some parameter is invalid.
103 *
104 * \funcusage
105 * \snippet trigmux/snippet/main.c snippet_Cy_TrigMux_Connect
106 *
107 *******************************************************************************/
Cy_TrigMux_Connect(uint32_t inTrig,uint32_t outTrig,bool invert,en_trig_type_t trigType)108 cy_en_trigmux_status_t Cy_TrigMux_Connect(uint32_t inTrig, uint32_t outTrig, bool invert, en_trig_type_t trigType)
109 {
110 cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
111 CY_ASSERT_L3(CY_TRIGMUX_IS_TRIGTYPE_VALID(trigType));
112 CY_ASSERT_L2(CY_TRIGMUX_IS_INTRIG_VALID(inTrig));
113 CY_ASSERT_L2(CY_TRIGMUX_IS_OUTTRIG_VALID(outTrig));
114
115 /* inTrig and outTrig should be in the same group */
116 if ((inTrig & PERI_TR_CMD_GROUP_SEL_Msk) == (outTrig & PERI_TR_CMD_GROUP_SEL_Msk))
117 {
118 uint32_t interruptState = Cy_SysLib_EnterCriticalSection();
119
120 CY_TRIGMUX_TR_CTL(outTrig) = (CY_TRIGMUX_TR_CTL(outTrig) &
121 (uint32_t)~(PERI_TR_GR_TR_OUT_CTL_TR_SEL_Msk |
122 PERI_TR_GR_TR_OUT_CTL_TR_INV_Msk |
123 PERI_TR_GR_TR_OUT_CTL_TR_EDGE_Msk)) |
124 (_VAL2FLD(PERI_TR_GR_TR_OUT_CTL_TR_SEL, inTrig) |
125 _BOOL2FLD(PERI_TR_GR_TR_OUT_CTL_TR_INV, invert) |
126 _VAL2FLD(PERI_TR_GR_TR_OUT_CTL_TR_EDGE, trigType));
127
128 Cy_SysLib_ExitCriticalSection(interruptState);
129
130 retVal = CY_TRIGMUX_SUCCESS;
131 }
132
133 return retVal;
134 }
135
136
137 /*******************************************************************************
138 * Function Name: Cy_TrigMux_Select
139 ****************************************************************************//**
140 *
141 * Enables and configures the specified 1-to-1 trigger line. For PERI_ver2 only.
142 *
143 * \param outTrig
144 * The 1to1 trigger line.
145 * - Bit 30 should be set.
146 * - Bit 12 should be set.
147 * - Bits 11:8 represent the 1-to-1 trigger group selection.
148 * - Bits 7:0 select the trigger line number in the trigger group.
149 *
150 * \param invert
151 * - true: The trigger signal is inverted.
152 * - false: The trigger signal is not inverted.
153 *
154 * \param trigType The trigger signal type.
155 * - TRIGGER_TYPE_EDGE: The trigger is synchronized to the consumer blocks clock
156 * and a two-cycle pulse is generated on this clock.
157 * - TRIGGER_TYPE_LEVEL: The trigger is a simple level output.
158 *
159 * \return status:
160 * - CY_TRIGMUX_SUCCESS: The selection is made successfully.
161 * - CY_TRIGMUX_BAD_PARAM: Some parameter is invalid.
162 *
163 * \funcusage
164 * \snippet trigmux/snippet/main.c snippet_Cy_TrigMux_Select
165 *
166 *******************************************************************************/
Cy_TrigMux_Select(uint32_t outTrig,bool invert,en_trig_type_t trigType)167 cy_en_trigmux_status_t Cy_TrigMux_Select(uint32_t outTrig, bool invert, en_trig_type_t trigType)
168 {
169 cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
170
171 CY_ASSERT_L3(CY_TRIGMUX_IS_TRIGTYPE_VALID(trigType));
172 CY_ASSERT_L2(CY_TRIGMUX_IS_ONETRIG_VALID(outTrig));
173
174 if (!CY_PERI_V1)
175 {
176 uint32_t interruptState;
177
178 interruptState = Cy_SysLib_EnterCriticalSection();
179
180 CY_TRIGMUX_TR_CTL(outTrig) = (CY_TRIGMUX_TR_CTL(outTrig) &
181 (uint32_t)~(PERI_TR_1TO1_GR_V2_TR_CTL_TR_INV_Msk |
182 PERI_TR_1TO1_GR_V2_TR_CTL_TR_EDGE_Msk)) |
183 (PERI_TR_1TO1_GR_V2_TR_CTL_TR_SEL_Msk |
184 _BOOL2FLD(PERI_TR_1TO1_GR_V2_TR_CTL_TR_INV, invert) |
185 _VAL2FLD(PERI_TR_1TO1_GR_V2_TR_CTL_TR_EDGE, trigType));
186
187 Cy_SysLib_ExitCriticalSection(interruptState);
188
189 retVal = CY_TRIGMUX_SUCCESS;
190 }
191
192 return retVal;
193 }
194
195
196 /*******************************************************************************
197 * Function Name: Cy_TrigMux_Deselect
198 ****************************************************************************//**
199 *
200 * Disables the specified 1-to-1 trigger line. For PERI_ver2 only.
201 *
202 * \param outTrig
203 * The 1to1 trigger line.
204 * - Bit 30 should be set.
205 * - Bit 12 should be set.
206 * - Bits 11:8 represent the 1-to-1 trigger group selection.
207 * - Bits 7:0 select the trigger line number in the trigger group.
208 *
209 * \return status:
210 * - CY_TRIGMUX_SUCCESS: The deselection is made successfully.
211 * - CY_TRIGMUX_BAD_PARAM: Some parameter is invalid.
212 *
213 * \funcusage
214 * \snippet trigmux/snippet/main.c snippet_Cy_TrigMux_Deselect
215 *
216 *******************************************************************************/
Cy_TrigMux_Deselect(uint32_t outTrig)217 cy_en_trigmux_status_t Cy_TrigMux_Deselect(uint32_t outTrig)
218 {
219 cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
220
221 CY_ASSERT_L2(CY_TRIGMUX_IS_ONETRIG_VALID(outTrig));
222
223 if (!CY_PERI_V1)
224 {
225 uint32_t interruptState;
226
227 interruptState = Cy_SysLib_EnterCriticalSection();
228
229 CY_TRIGMUX_TR_CTL(outTrig) &= (uint32_t)~(PERI_TR_1TO1_GR_V2_TR_CTL_TR_SEL_Msk |
230 PERI_TR_1TO1_GR_V2_TR_CTL_TR_INV_Msk |
231 PERI_TR_1TO1_GR_V2_TR_CTL_TR_EDGE_Msk);
232
233 Cy_SysLib_ExitCriticalSection(interruptState);
234
235 retVal = CY_TRIGMUX_SUCCESS;
236 }
237
238 return retVal;
239 }
240
241
242 /*******************************************************************************
243 * Function Name: Cy_TrigMux_SetDebugFreeze
244 ****************************************************************************//**
245 *
246 * Enables/disables the Debug Freeze feature for the specified trigger
247 * multiplexer or 1-to-1 trigger line. For PERI_ver2 only.
248 *
249 * \param outTrig
250 * The output of the trigger mux or dedicated 1-to-1 trigger line.
251 * - Bit 30 should be set.
252 * - For PERI_ver1 Bits 11:8 represent the trigger group selection.
253 * - For PERI_ver2 Bits 12:8 represent the trigger group selection.
254 * - Bits 7:0 select the output trigger number in the trigger group.
255 *
256 * \param enable
257 * - true: The Debug Freeze feature is enabled.
258 * - false: The Debug Freeze feature is disabled.
259 *
260 * \return status:
261 * - CY_TRIGMUX_SUCCESS: The operation is made successfully.
262 * - CY_TRIGMUX_BAD_PARAM: The outTrig parameter is invalid.
263 *
264 * \funcusage
265 * \snippet trigmux/snippet/main.c snippet_Cy_TrigMux_SetDebugFreeze
266 *
267 *******************************************************************************/
Cy_TrigMux_SetDebugFreeze(uint32_t outTrig,bool enable)268 cy_en_trigmux_status_t Cy_TrigMux_SetDebugFreeze(uint32_t outTrig, bool enable)
269 {
270 cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
271
272 if (!CY_PERI_V1)
273 {
274 uint32_t interruptState;
275
276 interruptState = Cy_SysLib_EnterCriticalSection();
277
278 if (enable)
279 {
280 CY_TRIGMUX_TR_CTL(outTrig) |= PERI_TR_GR_V2_TR_CTL_DBG_FREEZE_EN_Msk;
281 }
282 else
283 {
284 CY_TRIGMUX_TR_CTL(outTrig) &= (uint32_t)~PERI_TR_GR_V2_TR_CTL_DBG_FREEZE_EN_Msk;
285 }
286
287 Cy_SysLib_ExitCriticalSection(interruptState);
288
289 retVal = CY_TRIGMUX_SUCCESS;
290 }
291
292 return retVal;
293 }
294
295
296 /*******************************************************************************
297 * Function Name: Cy_TrigMux_SwTrigger
298 ****************************************************************************//**
299 *
300 * This function generates a software trigger on an input trigger line.
301 * All output triggers connected to this input trigger will be triggered.
302 * The function also verifies that there is no activated trigger before
303 * generating another activation.
304 *
305 * \param trigLine
306 * The input of the trigger mux.
307 * - Bit 30 represents if the signal is an input/output. When this bit is set,
308 * the trigger activation is for an output trigger from the trigger multiplexer.
309 * When this bit is reset, the trigger activation is for an input trigger to
310 * the trigger multiplexer.<br>
311 * - For PERI_ver1 Bits 11:8 represent the trigger group selection.<br>
312 * - For PERI_ver2 Bits 12:8 represent the trigger group selection.<br>
313 * In case of output trigger line (bit 30 is set):<br>
314 * For PERI_ver1:
315 * - Bits 6:0 select the output trigger number in the trigger group.<br>
316 * For PERI_ver2:
317 * - Bits 7:0 select the output trigger number in the trigger group.<br>
318 * In case of input trigger line (bit 30 is unset):
319 * - Bits 7:0 select the input trigger signal for the trigger multiplexer.
320 *
321 * \param cycles
322 * The number of "Clk_Peri" cycles during which the trigger remains activated.<br>
323 * For PERI_ver1: The valid range of cycles is 1 ... 254.<br>
324 * For PERI_ver2: The only valid value of cycles is 2 (\ref CY_TRIGGER_TWO_CYCLES).<br>
325 * Also there are special values (supported with both PERI_ver1 and PERI_ver2):
326 * - CY_TRIGGER_INFINITE - trigger remains activated until the user deactivates it by
327 * calling this function with CY_TRIGGER_DEACTIVATE parameter.
328 * - CY_TRIGGER_DEACTIVATE - this is used to deactivate the trigger activated by
329 * calling this function with CY_TRIGGER_INFINITE parameter.
330 *
331 * \return status:
332 * - CY_TRIGMUX_SUCCESS: The trigger is successfully activated/deactivated.
333 * - CY_TRIGMUX_INVALID_STATE: The trigger is already activated/not active.
334 * - CY_TRIGMUX_BAD_PARAM: Some parameter is invalid.
335 *
336 * \funcusage
337 * \snippet trigmux/snippet/main.c snippet_Cy_TrigMux_SwTrigger
338 *
339 *******************************************************************************/
Cy_TrigMux_SwTrigger(uint32_t trigLine,uint32_t cycles)340 cy_en_trigmux_status_t Cy_TrigMux_SwTrigger(uint32_t trigLine, uint32_t cycles)
341 {
342 cy_en_trigmux_status_t retVal = CY_TRIGMUX_INVALID_STATE;
343
344 CY_ASSERT_L2(CY_TRIGMUX_IS_TRIGLINE_VALID(trigLine));
345 CY_ASSERT_L2(CY_TRIGMUX_IS_CYCLES_VALID(cycles));
346
347 if (CY_TRIGGER_DEACTIVATE != cycles)
348 {
349 /* Activate the trigger if it is not in the active state. */
350 if (PERI_TR_CMD_ACTIVATE_Msk != (PERI_TR_CMD & PERI_TR_CMD_ACTIVATE_Msk))
351 {
352
353 uint32_t trCmd = (trigLine & (PERI_TR_CMD_TR_SEL_Msk |
354 PERI_TR_CMD_OUT_SEL_Msk |
355 CY_PERI_TR_CMD_GROUP_SEL_Msk)) |
356 PERI_TR_CMD_ACTIVATE_Msk;
357
358 retVal = CY_TRIGMUX_SUCCESS;
359
360 if (CY_PERI_V1) /* mxperi_v1 */
361 {
362 PERI_TR_CMD = trCmd | _VAL2FLD(PERI_TR_CMD_COUNT, cycles);
363 }
364 else if (CY_TRIGGER_TWO_CYCLES == cycles) /* mxperi_v2 or later, 2 cycles pulse */
365 {
366 PERI_TR_CMD = trCmd | PERI_V2_TR_CMD_TR_EDGE_Msk;
367 }
368 else if (CY_TRIGGER_INFINITE == cycles) /* mxperi_v2 or later, infinite activating */
369 {
370 PERI_TR_CMD = trCmd;
371 }
372 else /* mxperi_v2 or later, invalid cycles value */
373 {
374 retVal = CY_TRIGMUX_BAD_PARAM;
375 }
376 }
377 }
378 else
379 {
380 /* Forcibly deactivate the trigger if it is in the active state. */
381 if (PERI_TR_CMD_ACTIVATE_Msk == (PERI_TR_CMD & PERI_TR_CMD_ACTIVATE_Msk))
382 {
383 PERI_TR_CMD = 0UL;
384
385 retVal = CY_TRIGMUX_SUCCESS;
386 }
387 }
388
389 return retVal;
390 }
391
392 #endif /* CY_IP_MXSPERI, CY_IP_MXPERI */
393
394 /* [] END OF FILE */
395