1 /***************************************************************************//**
2 * \file cyhal_interconnect.c
3 *
4 * \brief
5 * Provides a high level interface for interacting with the internal digital
6 * routing on the chip. This is a wrapper around the lower level PDL API.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2018-2021 Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation
12 *
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 *     http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27 
28 #include "cyhal_interconnect.h"
29 #include "cyhal_gpio_impl.h"
30 
31 #if defined(__cplusplus)
32 extern "C"
33 {
34 #endif
35 
36 #if (CYHAL_DRIVER_AVAILABLE_INTERCONNECT)
37 
38 // Helpers for creating Cy_TrigMux_* inputs
39 #define CY_TRIGMUX_INPUT_LINE(mux_group, source_idx) (uint32_t)(((uint32_t)mux_group) << 8 | source_idx)
40 #define CY_TRIGMUX_OUTPUT_LINE(mux_group, dest_idx) (uint32_t)(0x40000000 |  ((uint32_t)mux_group) << 8 | dest_idx)
41 #define CY_SELECT_OUTPUT_LINE(mux_group, dest_idx) (uint32_t)(0x40001000 | ((uint32_t)mux_group) << 8 | dest_idx)
42 
43 typedef enum
44 {
45     CYHAL_CONNECT_TYPE_VALIDATE,
46     CYHAL_CONNECT_TYPE_CONNECT,
47     CYHAL_CONNECT_TYPE_DISCONNECT,
48 } cyhal_connect_type_t;
49 
50 // Only define if there are actual trigger signals
51 #if defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI)
52 #if (CY_IP_MXPERI_VERSION >= 2u) || (CY_IP_M0S8PERI_VERSION >= 1u) || (CY_IP_MXSPERI >= 1u)
_cyhal_get_first_1to1_mux_idx(void)53 static int8_t _cyhal_get_first_1to1_mux_idx(void)
54 {
55     for(uint8_t idx = 0; idx < (sizeof(cyhal_is_mux_1to1)/sizeof(cyhal_is_mux_1to1[0])); idx++)
56     {
57         if(cyhal_is_mux_1to1[idx])
58             return idx;
59     }
60 
61     return -1;
62 }
63 #endif
64 
65 // Reads peri trigmux register and returns the selected input line (0 is
66 // default if no line has been selected)
_cyhal_read_mux_input_idx(uint8_t mux_group,uint8_t mux_output_idx)67 static uint8_t _cyhal_read_mux_input_idx(uint8_t mux_group, uint8_t mux_output_idx)
68 {
69 #if (CY_IP_MXPERI_VERSION >= 2u) || (CY_IP_M0S8PERI_VERSION >= 1u) || (CY_IP_MXSPERI >= 1u)
70     const int8_t MUX_GROUP_1TO1_OFFSET = _cyhal_get_first_1to1_mux_idx();
71     const uint8_t FIRST_1TO1_MUX_GROUP_IDX = 16;
72 #endif
73 
74     uint32_t mux_reg = 0;
75 #if (CY_IP_MXPERI_VERSION == 2u) || (CY_IP_M0S8PERI_VERSION == 1u) || (CY_IP_MXSPERI >= 1u)
76     // M0S8 has no 1to1 muxes but the table is still valid
77     if(cyhal_is_mux_1to1[mux_group])
78     {
79         // There are up to 16 regular mux groups and up to 16 1to1 mux groups
80         // (in PSoC™ 6).  PERI_TR_GR_TR_CTL starts at the first regular mux so
81         // offset by 16 if reading a 1to1 mux.
82         mux_reg = PERI_TR_GR_TR_CTL(mux_group - MUX_GROUP_1TO1_OFFSET + FIRST_1TO1_MUX_GROUP_IDX, mux_output_idx);
83     }
84     else
85     {
86         mux_reg = PERI_TR_GR_TR_CTL(mux_group, mux_output_idx);
87     }
88 #else // CY_IP_MXPERI_VERSION == 1
89     mux_reg = PERI_TR_GR_TR_CTL(mux_group, mux_output_idx);
90 #endif
91 
92 
93 #if (CY_IP_MXPERI_VERSION >= 1u) || (CY_IP_MXSPERI >= 1u)
94     return _FLD2VAL(PERI_TR_GR_TR_OUT_CTL_TR_SEL, mux_reg);
95 #elif CY_IP_M0S8PERI_VERSION == 1u
96     return _FLD2VAL(PERI_TR_CTL_TR_SEL, mux_reg);
97 #endif
98 }
99 
100 #if (CY_IP_MXPERI_VERSION >= 2u) || (CY_IP_M0S8PERI_VERSION == 1u) || (CY_IP_MXSPERI >= 1u)
_cyhal_interconnect_change_connection_direct(uint8_t mux_group,uint8_t mux_group_1to1_offset,uint8_t source_idx,uint8_t dest_idx,cyhal_signal_type_t type,bool connect)101 static cy_rslt_t _cyhal_interconnect_change_connection_direct(
102     uint8_t mux_group, uint8_t mux_group_1to1_offset, uint8_t source_idx, uint8_t dest_idx, cyhal_signal_type_t type, bool connect)
103 {
104 #if CY_IP_M0S8PERI_VERSION == 1u
105     CY_UNUSED_PARAMETER(type);
106     CY_UNUSED_PARAMETER(mux_group_1to1_offset);
107 #endif
108 
109     if(cyhal_is_mux_1to1[mux_group])
110     {
111 #if (CY_IP_MXPERI_VERSION >= 2u) || (CY_IP_MXSPERI >= 1u)
112         // Cy_TrigMux_Select assumes the mux_group idx param starts from the
113         // first 1to1 mux (so first 1to1 mux is 0)
114         uint32_t out_trig = CY_SELECT_OUTPUT_LINE(mux_group - mux_group_1to1_offset, dest_idx);
115 
116         if(connect)
117             return Cy_TrigMux_Select(out_trig, false, (en_trig_type_t)type);
118         else
119             return Cy_TrigMux_Deselect(out_trig);
120 #else
121         return (connect)
122             ? CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION
123             : CYHAL_INTERCONNECT_RSLT_CANNOT_DISCONNECT;
124 #endif
125     }
126     else
127     {
128         uint32_t in_trig = CY_TRIGMUX_INPUT_LINE(mux_group, source_idx);
129         uint32_t out_trig = CY_TRIGMUX_OUTPUT_LINE(mux_group, dest_idx);
130 
131         if(connect)
132         {
133 #if (CY_IP_MXPERI_VERSION >= 2u) || (CY_IP_MXSPERI >= 1u)
134             return Cy_TrigMux_Connect(in_trig, out_trig, false, (en_trig_type_t)type);
135 #else
136             return Cy_TrigMux_Connect(in_trig, out_trig);
137 #endif
138         }
139         else
140         {
141             // No Cy_TrigMux_Disconnect so just clear register of found
142             // mux input line.
143             PERI_TR_GR_TR_CTL(mux_group, dest_idx) = 0;
144             return CY_RSLT_SUCCESS;
145         }
146     }
147 }
148 #elif CY_IP_MXPERI_VERSION == 1u
149 /* Change a HAL trigger connection where a mux is involved */
_cyhal_interconnect_change_connection_direct(uint8_t mux,uint8_t input_idx,uint8_t output_idx,cyhal_signal_type_t type,bool connect)150 static cy_rslt_t _cyhal_interconnect_change_connection_direct(uint8_t mux, uint8_t input_idx, uint8_t output_idx, cyhal_signal_type_t type, bool connect)
151 {
152     if (connect)
153     {
154         uint32_t in_trig = CY_TRIGMUX_INPUT_LINE(mux, input_idx);
155         uint32_t out_trig = CY_TRIGMUX_OUTPUT_LINE(mux, output_idx);
156 
157         return Cy_TrigMux_Connect(in_trig, out_trig, false, (en_trig_type_t)type);
158     }
159     else
160     {
161         PERI_TR_GR_TR_CTL(mux, output_idx) = 0;
162         return CY_RSLT_SUCCESS;
163     }
164 }
165 
166 /* Change a HAL trigger connection where 2 muxes are involved */
_cyhal_interconnect_change_connection_indirect(uint8_t source_mux_group,uint8_t source_mux_input_idx,uint8_t source_mux_output_idx,uint8_t dest_mux_group,uint8_t dest_mux_input_idx,uint8_t dest_mux_output_idx,cyhal_signal_type_t type,bool connect)167 static cy_rslt_t _cyhal_interconnect_change_connection_indirect(uint8_t source_mux_group, uint8_t source_mux_input_idx, uint8_t source_mux_output_idx,
168     uint8_t dest_mux_group, uint8_t dest_mux_input_idx, uint8_t dest_mux_output_idx, cyhal_signal_type_t type, bool connect)
169 {
170     if(connect)
171     {
172         // Construct Cy_TrigMux_Connect trigger inputs for both source and dest muxes
173         uint32_t source_mux_in_trig = CY_TRIGMUX_INPUT_LINE(source_mux_group, source_mux_input_idx);
174         uint32_t source_mux_out_trig = CY_TRIGMUX_OUTPUT_LINE(source_mux_group, source_mux_output_idx);
175 
176         uint32_t dest_mux_in_trig = CY_TRIGMUX_INPUT_LINE(dest_mux_group, dest_mux_input_idx);
177         uint32_t dest_mux_out_trig = CY_TRIGMUX_OUTPUT_LINE(dest_mux_group, dest_mux_output_idx);
178 
179         if(_cyhal_read_mux_input_idx(dest_mux_group, dest_mux_output_idx) != 0)
180         {
181             return CYHAL_INTERCONNECT_RSLT_ALREADY_CONNECTED;
182         }
183 
184         cy_rslt_t result = Cy_TrigMux_Connect(source_mux_in_trig, source_mux_out_trig, false, (en_trig_type_t)type);
185         if (CY_RSLT_SUCCESS == result)
186             result = Cy_TrigMux_Connect(dest_mux_in_trig, dest_mux_out_trig, false, (en_trig_type_t)type);
187         return result;
188     }
189     else
190     {
191         // No Cy_TrigMux_Disconnect so just clear registers of found muxes
192         PERI_TR_GR_TR_CTL(source_mux_group, source_mux_output_idx) = 0;
193         PERI_TR_GR_TR_CTL(dest_mux_group, dest_mux_output_idx) = 0;
194         return CY_RSLT_SUCCESS;
195     }
196 }
197 #endif /* #if CY_IP_MXPERI_VERSION == 2u || CY_IP_M0S8PERI_VERSION == 1u */
198 
199 // Since both connect and disconnect need to derive mux group(s) and trigger
200 // indices, use this func to avoid duplicate code.
_cyhal_interconnect_check_connection(cyhal_source_t source,cyhal_dest_t dest,cyhal_connect_type_t connect)201 static cy_rslt_t _cyhal_interconnect_check_connection(cyhal_source_t source, cyhal_dest_t dest, cyhal_connect_type_t connect)
202 {
203     cyhal_internal_source_t internal_src = _CYHAL_TRIGGER_GET_SOURCE_SIGNAL(source);
204     cyhal_signal_type_t type = _CYHAL_TRIGGER_GET_SOURCE_TYPE(source);
205 #if CY_IP_MXPERI_VERSION >= 2u || CY_IP_M0S8PERI_VERSION >= 1u || CY_IP_MXSPERI >= 1u
206     const int8_t mux_group_1to1_offset = _cyhal_get_first_1to1_mux_idx();
207 
208     // cyhal_dest_to_mux stores 1to1 triggers with bit 8 set and the lower 7
209     // bits as the offset into the 1to1 triggers (so 128 is 1to1 mux index 0)
210     // but here we need the actual group offset for all the triggers.
211     uint8_t mux_group = cyhal_dest_to_mux[dest];
212     if(mux_group & 0x80)
213         mux_group = mux_group_1to1_offset + (mux_group & ~0x80);
214 
215     uint8_t dest_idx = cyhal_mux_dest_index[dest];
216 
217     // Search through table of mux input trigger lines
218     for (uint16_t source_idx = 0; source_idx < cyhal_sources_per_mux[mux_group]; source_idx++)
219     {
220         if(cyhal_mux_to_sources[mux_group][source_idx] == internal_src)
221         {
222             // 1to1 triggers muxes source and dest indices must match
223             if(cyhal_is_mux_1to1[mux_group] && (source_idx != dest_idx))
224             {
225                 return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
226             }
227 
228             // Check if the mux is already configured (possibly from a
229             // different source)
230             if(CYHAL_CONNECT_TYPE_DISCONNECT != connect
231                 && _cyhal_read_mux_input_idx(mux_group, dest_idx) != 0)
232             {
233                 return CYHAL_INTERCONNECT_RSLT_ALREADY_CONNECTED;
234             }
235 
236             return (connect == CYHAL_CONNECT_TYPE_VALIDATE)
237                 ? CY_RSLT_SUCCESS
238                 : _cyhal_interconnect_change_connection_direct(mux_group, mux_group_1to1_offset, source_idx, dest_idx, type, connect == CYHAL_CONNECT_TYPE_CONNECT);
239         }
240     }
241     return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
242 #elif CY_IP_MXPERI_VERSION == 1u
243     uint8_t dest_mux_group = cyhal_dest_to_mux[dest];
244     uint8_t dest_mux_output_idx = cyhal_mux_dest_index[dest];
245 
246     // Special case 1: DW sources connect to USB_DMA_BURSTEND destinations directly
247     // through mux 9 so handle here.
248     if(dest_mux_group == 9)
249     {
250         if((internal_src < _CYHAL_TRIGGER_CPUSS_DW0_TR_OUT0) || (internal_src > _CYHAL_TRIGGER_CPUSS_DW1_TR_OUT15))
251             return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
252 
253         if((dest < CYHAL_TRIGGER_USB_DMA_BURSTEND0) || (dest > CYHAL_TRIGGER_USB_DMA_BURSTEND7))
254             return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
255 
256         uint16_t mux9_input_idx = (uint16_t)(internal_src - _CYHAL_TRIGGER_CPUSS_DW0_TR_OUT0) + 1;
257         uint16_t mux9_output_idx = (uint16_t)(dest - CYHAL_TRIGGER_USB_DMA_BURSTEND0);
258 
259         uint8_t set_input_idx = _cyhal_read_mux_input_idx(9, mux9_output_idx);
260         if ((CYHAL_CONNECT_TYPE_DISCONNECT != connect) && (set_input_idx != 0))
261             return CYHAL_INTERCONNECT_RSLT_ALREADY_CONNECTED;
262         else if ((CYHAL_CONNECT_TYPE_DISCONNECT == connect) && (set_input_idx == 0))
263             return CYHAL_INTERCONNECT_RSLT_CANNOT_DISCONNECT;
264         else
265         {
266             return (connect == CYHAL_CONNECT_TYPE_VALIDATE)
267                 ? CY_RSLT_SUCCESS
268                 : _cyhal_interconnect_change_connection_direct(9, mux9_input_idx, mux9_output_idx, type, connect == CYHAL_CONNECT_TYPE_CONNECT);
269         }
270     }
271 
272     // Special case 2: UDB_TR_DW_ACK destinations have no destinations side mux
273     // and are instead only connected through mux 10. Handle those connections
274     // here (while handling all other connections through mux 10 later).
275     if((dest_mux_group == 10) && (dest >= CYHAL_TRIGGER_UDB_TR_DW_ACK0) && (dest <= CYHAL_TRIGGER_UDB_TR_DW_ACK7))
276     {
277         if((internal_src < _CYHAL_TRIGGER_CPUSS_DW0_TR_OUT0) || (internal_src > _CYHAL_TRIGGER_CPUSS_DW1_TR_OUT15))
278             return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
279 
280         uint16_t mux10_input_idx = (uint16_t)(internal_src - _CYHAL_TRIGGER_CPUSS_DW0_TR_OUT0) + 1;
281         uint16_t mux10_output_idx = (uint16_t)(dest - CYHAL_TRIGGER_UDB_TR_DW_ACK0);
282 
283         uint8_t set_input_idx = _cyhal_read_mux_input_idx(10, mux10_output_idx);
284         if ((CYHAL_CONNECT_TYPE_DISCONNECT != connect) && (set_input_idx != 0))
285             return CYHAL_INTERCONNECT_RSLT_ALREADY_CONNECTED;
286         else if ((CYHAL_CONNECT_TYPE_DISCONNECT == connect) && (set_input_idx == 0))
287             return CYHAL_INTERCONNECT_RSLT_CANNOT_DISCONNECT;
288         else
289         {
290             return (connect == CYHAL_CONNECT_TYPE_VALIDATE)
291                 ? CY_RSLT_SUCCESS
292                 : _cyhal_interconnect_change_connection_direct(10, mux10_input_idx, mux10_output_idx, type, connect == CYHAL_CONNECT_TYPE_CONNECT);
293         }
294     }
295 
296     // Since PSoC™ 6 BLE devices w/ trigmux vers1 have a 1to1 relationship
297     // between peripheral sources and reduction trigger muxes (besides DW which
298     // connects to trig mux 9 and 10, handled above) it is possible to search
299     // through source mux tables to find the idx required.
300     uint16_t source_mux_group = 0;
301     uint16_t source_mux_input_idx = 0;
302     bool found_source_mux_info = false;
303     for(source_mux_group = 10; source_mux_group < 15; source_mux_group++)
304     {
305         for(source_mux_input_idx = 0; source_mux_input_idx < cyhal_sources_per_mux[source_mux_group]; source_mux_input_idx++)
306         {
307             if(cyhal_mux_to_sources[source_mux_group][source_mux_input_idx] == internal_src)
308             {
309                 found_source_mux_info = true;
310                 break;
311             }
312         }
313         if(found_source_mux_info)
314             break;
315     }
316 
317     if(!found_source_mux_info)
318         return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
319 
320     // Construct the cyhal_internal_source_t range that contains all possible inputs
321     // from the source mux to the dest mux. Not every cyhal_internal_source_t in this
322     // range will go to the dest mux but dest_mux_input_line_low and
323     // dest_mux_input_line_high will be used in the next step to find which inputs can.
324     cyhal_internal_source_t dest_mux_input_line_low;
325     cyhal_internal_source_t dest_mux_input_line_high;
326     switch (source_mux_group)
327     {
328         case 10:
329             dest_mux_input_line_low = _CYHAL_TRIGGER_TR_GROUP10_OUTPUT0;
330             dest_mux_input_line_high = _CYHAL_TRIGGER_TR_GROUP10_OUTPUT7;
331             break;
332         case 11:
333             dest_mux_input_line_low = _CYHAL_TRIGGER_TR_GROUP11_OUTPUT0;
334             dest_mux_input_line_high = _CYHAL_TRIGGER_TR_GROUP11_OUTPUT15;
335             break;
336         case 12:
337             dest_mux_input_line_low = _CYHAL_TRIGGER_TR_GROUP12_OUTPUT0;
338             dest_mux_input_line_high = _CYHAL_TRIGGER_TR_GROUP12_OUTPUT9;
339             break;
340         case 13:
341             dest_mux_input_line_low = _CYHAL_TRIGGER_TR_GROUP13_OUTPUT0;
342             dest_mux_input_line_high = _CYHAL_TRIGGER_TR_GROUP13_OUTPUT17;
343             break;
344         case 14:
345             dest_mux_input_line_low = _CYHAL_TRIGGER_TR_GROUP14_OUTPUT0;
346             dest_mux_input_line_high = _CYHAL_TRIGGER_TR_GROUP14_OUTPUT15;
347             break;
348         default:
349             return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
350     }
351 
352     // Search through the dest mux source table to find the low and high
353     // indices of the valid inputs from the source mux to the dest mux. These
354     // indices will correspond to, and be between, dest_mux_input_line_low and
355     // dest_mux_input_line_high (but not necessarily the whole range). If e.g
356     // only source mux output lines 8-9 go to the dest mux this will be
357     // reflected by setting source_mux_start_idx to 8
358     uint16_t dest_mux_input_line_low_idx = 10000;
359     uint16_t dest_mux_input_line_high_idx = 0;
360     uint16_t source_mux_start_idx = 0;
361     for(uint16_t i = 0; i < cyhal_sources_per_mux[dest_mux_group]; i++)
362     {
363         if((cyhal_mux_to_sources[dest_mux_group][i] >= dest_mux_input_line_low) &&
364                 (cyhal_mux_to_sources[dest_mux_group][i] <= dest_mux_input_line_high))
365         {
366             if(dest_mux_input_line_low_idx > i)
367             {
368                 dest_mux_input_line_low_idx = i;
369                 source_mux_start_idx = (uint16_t)(cyhal_mux_to_sources[dest_mux_group][i] - dest_mux_input_line_low);
370             }
371 
372             if(dest_mux_input_line_high_idx < i)
373                 dest_mux_input_line_high_idx = i;
374         }
375     }
376 
377     // Construct possible output trigger lines from the source mux starting at
378     // the first input line found in the previous step. Since source mux output
379     // lines can be arbitrarily selected and may already be in use, read the
380     // source mux register to check if an output is free.
381     uint8_t source_mux_output_idx = 0;
382     uint8_t dest_mux_input_idx = 0;
383     bool found_connection = false;
384     for(source_mux_output_idx = source_mux_start_idx; source_mux_output_idx < (source_mux_start_idx + (dest_mux_input_line_high_idx - dest_mux_input_line_low_idx + 1)); source_mux_output_idx++)
385     {
386         // If connecting: Check if possible output trigger is free.
387         if((connect != CYHAL_CONNECT_TYPE_DISCONNECT) && _cyhal_read_mux_input_idx(source_mux_group, source_mux_output_idx) == 0)
388         {
389             dest_mux_input_idx = dest_mux_input_line_low_idx + source_mux_output_idx - source_mux_start_idx;
390 
391             found_connection = true;
392             break;
393         }
394         // If disconnecting: We have already used this source mux output line
395         // and it matches the inputted source. Since disconnecting only
396         // requires output idx info (for both muxes) nothing needs to be
397         // calculated here.
398         else if((connect == CYHAL_CONNECT_TYPE_DISCONNECT) && _cyhal_read_mux_input_idx(source_mux_group, source_mux_output_idx) == source_mux_input_idx)
399         {
400             found_connection = true;
401             break;
402         }
403     }
404 
405     if(!found_connection)
406     {
407         return (connect == CYHAL_CONNECT_TYPE_DISCONNECT)
408             ? CYHAL_INTERCONNECT_RSLT_CANNOT_DISCONNECT
409             : CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
410     }
411 
412     return (connect == CYHAL_CONNECT_TYPE_VALIDATE)
413         ? CY_RSLT_SUCCESS
414         : _cyhal_interconnect_change_connection_indirect(source_mux_group, source_mux_input_idx, source_mux_output_idx,
415             dest_mux_group, dest_mux_input_idx, dest_mux_output_idx, type, connect == CYHAL_CONNECT_TYPE_CONNECT);
416 #else
417 #error Unrecognized PERI version
418 #endif
419 }
420 
421 #endif /* defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI) */
422 
_cyhal_connect_signal(cyhal_source_t source,cyhal_dest_t dest)423 cy_rslt_t _cyhal_connect_signal(cyhal_source_t source, cyhal_dest_t dest)
424 {
425 #if defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI)
426     return _cyhal_interconnect_check_connection(source, dest, CYHAL_CONNECT_TYPE_CONNECT);
427 #else
428     CY_UNUSED_PARAMETER(source);
429     CY_UNUSED_PARAMETER(dest);
430     return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
431 #endif /* defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI) */
432 }
433 
_cyhal_disconnect_signal(cyhal_source_t source,cyhal_dest_t dest)434 cy_rslt_t _cyhal_disconnect_signal(cyhal_source_t source, cyhal_dest_t dest)
435 {
436 #if defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI)
437     return _cyhal_interconnect_check_connection(source, dest, CYHAL_CONNECT_TYPE_DISCONNECT);
438 #else
439     CY_UNUSED_PARAMETER(source);
440     CY_UNUSED_PARAMETER(dest);
441     return CYHAL_INTERCONNECT_RSLT_INVALID_CONNECTION;
442 #endif /* defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI) */
443 }
444 
_cyhal_can_connect_signal(cyhal_source_t source,cyhal_dest_t dest)445 bool _cyhal_can_connect_signal(cyhal_source_t source, cyhal_dest_t dest)
446 {
447 #if defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI)
448     return (CY_RSLT_SUCCESS == _cyhal_interconnect_check_connection(source, dest, CYHAL_CONNECT_TYPE_VALIDATE));
449 #else
450     CY_UNUSED_PARAMETER(source);
451     CY_UNUSED_PARAMETER(dest);
452     return false;
453 #endif /* defined(CY_IP_M0S8PERI_TR) || defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI) */
454 }
455 
456 #endif /* CYHAL_DRIVER_AVAILABLE_INTERCONNECT */
457 
cyhal_connect_pin(const cyhal_resource_pin_mapping_t * pin_connection,uint8_t drive_mode)458 cy_rslt_t cyhal_connect_pin(const cyhal_resource_pin_mapping_t *pin_connection, uint8_t drive_mode)
459 {
460     cyhal_gpio_t pin = pin_connection->pin;
461     GPIO_PRT_Type *port = Cy_GPIO_PortToAddr(CYHAL_GET_PORT(pin));
462     en_hsiom_sel_t hsiom = pin_connection->hsiom;
463 
464     Cy_GPIO_Pin_FastInit(port, CYHAL_GET_PIN(pin), drive_mode, 1, hsiom);
465     // Force output to enable pulls.
466     switch (drive_mode)
467     {
468         case CY_GPIO_DM_PULLUP:
469             Cy_GPIO_Write(port, CYHAL_GET_PIN(pin), 1);
470             break;
471         case CY_GPIO_DM_PULLDOWN:
472             Cy_GPIO_Write(port, CYHAL_GET_PIN(pin), 0);
473             break;
474         default:
475             /* do nothing */
476             break;
477     }
478 
479     return CY_RSLT_SUCCESS;
480 }
481 
cyhal_disconnect_pin(cyhal_gpio_t pin)482 cy_rslt_t cyhal_disconnect_pin(cyhal_gpio_t pin)
483 {
484     GPIO_PRT_Type *port = Cy_GPIO_PortToAddr(CYHAL_GET_PORT(pin));
485     Cy_GPIO_Pin_FastInit(port, CYHAL_GET_PIN(pin), CY_GPIO_DM_HIGHZ, 1, HSIOM_SEL_GPIO);
486     return CY_RSLT_SUCCESS;
487 }
488 
489 #if defined(__cplusplus)
490 }
491 #endif
492