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