1 /***************************************************************************//**
2 * \file cyhal_dma_dmac.c
3 *
4 * \brief
5 * Implements a high level interface for interacting with the Infineon DMAC.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation
11 *
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 *     http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26 
27 #include "cyhal_dma.h"
28 #include "cyhal_dma_dmac.h"
29 #include "cyhal_dma_impl.h"
30 #include "cyhal_hwmgr_impl.h"
31 #include "cyhal_interconnect.h"
32 #include "cyhal_syspm.h"
33 #include "cyhal_utils.h"
34 #include "cyhal_irq_impl.h"
35 #include "cyhal_triggers.h"
36 
37 #if defined(__cplusplus)
38 extern "C" {
39 #endif
40 
41 #if (_CYHAL_DRIVER_AVAILABLE_DMA_DMAC)
42 
43 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC)
44 #define DMAC0_IRQn                  (cpuss_interrupts_dmac_0_IRQn)
45 #define GET_RESOURCE_DATA(x)        (x.dmac)
46 typedef DMAC_Type                   cyhal_dmac_hw_type;
47 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
48 #define DMAC0_IRQn                  (cpuss_interrupt_dma_IRQn)
49 #define GET_RESOURCE_DATA(x)        (x)
50 #define CY_TRIGGER_TWO_CYCLES       (2)
51 typedef DMAC_Type                   cyhal_dmac_hw_type;
52 #elif defined(CY_IP_MXAHBDMAC)
53 #define DMAC0_IRQn                  (cpuss_interrupts_dmac0_0_IRQn)
54 #define DMAC1_IRQn                  (cpuss_interrupts_dmac1_0_IRQn)
55 #define GET_RESOURCE_DATA(x)        (x.dmac)
56 typedef MXAHBDMAC_Type              cyhal_dmac_hw_type;
57 #elif defined(CY_IP_MXSAXIDMAC)
58 #define DMAC0_IRQn                  (m55appcpuss_interrupts_axidmac_0_IRQn)
59 typedef SAXI_DMAC_Type              cyhal_dmac_hw_type;
60 #define GET_RESOURCE_DATA(x)        (x.dmac)
61 #endif
62 
63 #if defined (AXI_DMAC_CH_NR)
64 #if APPCPUSS_AXIDMAC1_PRESENT
65 #define NUM_DMAC0_CHANNELS          (APPCPUSS_AXIDMAC0_CH_NR)
66 #define NUM_DMAC_CHANNELS           (APPCPUSS_AXIDMAC0_CH_NR + APPCPUSS_AXIDMAC1_CH_NR)
67 #else
68 #define NUM_DMAC0_CHANNELS          (APPCPUSS_AXIDMAC0_CH_NR)
69 #define NUM_DMAC_CHANNELS           (APPCPUSS_AXIDMAC0_CH_NR)
70 #endif
71 #elif defined(CPUSS_DMAC0_CH_NR) && defined(CPUSS_DMAC1_CH_NR) && (CPUSS_DMAC0_PRESENT > 0) && (CPUSS_DMAC1_PRESENT > 0)
72 #define NUM_DMAC_CHANNELS           (CPUSS_DMAC0_CH_NR + CPUSS_DMAC1_CH_NR)
73 #define NUM_DMAC0_CHANNELS          (CPUSS_DMAC0_CH_NR)
74 #elif defined(CPUSS_DMAC_CH_NR)
75 #define NUM_DMAC_CHANNELS           (CPUSS_DMAC_CH_NR)
76 #define CPUSS_DMAC0_CH_NR           (CPUSS_DMAC_CH_NR)
77 #define NUM_DMAC0_CHANNELS          (CPUSS_DMAC_CH_NR)
78 #define CYHAL_TRIGGER_CPUSS_DMAC0_TR_IN0   (CYHAL_TRIGGER_CPUSS_DMAC_TR_IN0)
79 #define _CYHAL_TRIGGER_CPUSS_DMAC0_TR_OUT0 (_CYHAL_TRIGGER_CPUSS_DMAC_TR_OUT0)
80 #endif
81 
82 //Wrappers for PDL functions and Macros for AXI DMAC differences
83 #if defined(CY_IP_MXSAXIDMAC)
84 #define _cyhal_dmac_channel_enable(base, channel)   Cy_AXIDMAC_Channel_Enable(base, channel)
85 #define _cyhal_dmac_channel_disable(base, channel)  Cy_AXIDMAC_Channel_Disable(base, channel)
86 #define _cyhal_dmac_get_active_channel(base)        Cy_AXIDMAC_GetActiveChannel(base)
87 #define _cyhal_dmac_channel_get_interrupt_status_masked(base, channel) Cy_AXIDMAC_Channel_GetInterruptStatusMasked(base, channel)
88 #define _CYHAL_DMAC_CHANNEL_ENABLED        (CY_AXIDMAC_CHANNEL_ENABLED)
89 #define _CYHAL_DMAC_CHANNEL_DISABLED       (CY_AXIDMAC_CHANNEL_DISABLED)
90 #define _CYHAL_DMAC_DESCR            (CY_AXIDMAC_DESCR)
91 #define _CYHAL_DMAC_M_LOOP           (CY_AXIDMAC_M_LOOP)
92 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Msk   (SAXI_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Msk)
93 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Msk   (SAXI_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Msk)
94 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE        (SAXI_DMAC_CH_DESCR_CTL_TR_IN_TYPE)
95 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE       (SAXI_DMAC_CH_DESCR_CTL_TR_OUT_TYPE)
96 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Pos    (SAXI_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Pos)
97 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Pos    (SAXI_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Pos)
98 #define _CYHAL_TRIGGER_CPUSS_ZERO                  (CYHAL_TRIGGER_M33SYSCPUSS_ZERO)
99 #elif defined(CY_IP_MXAHBDMAC) || defined(CY_IP_M0S8CPUSSV3_DMAC) || defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC)
100 #define _cyhal_dmac_channel_enable(base, channel)   Cy_DMAC_Channel_Enable(base, channel)
101 #define _cyhal_dmac_channel_disable(base, channel)  Cy_DMAC_Channel_Disable(base, channel)
102 #define _cyhal_dmac_get_active_channel(base)        Cy_DMAC_GetActiveChannel(base)
103 #define _cyhal_dmac_channel_get_interrupt_status_masked(base, channel) Cy_DMAC_Channel_GetInterruptStatusMasked(base, channel)
104 #define _CYHAL_DMAC_CHANNEL_ENABLED        (CY_DMAC_CHANNEL_ENABLED)
105 #define _CYHAL_DMAC_CHANNEL_DISABLED       (CY_DMAC_CHANNEL_DISABLED)
106 #define _CYHAL_DMAC_DESCR            (CY_DMAC_DESCR)
107 #define _CYHAL_DMAC_X_LOOP           (CY_DMAC_X_LOOP)
108 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Msk    (DMAC_CH_V2_DESCR_CTL_TR_IN_TYPE_Msk)
109 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Msk   (DMAC_CH_V2_DESCR_CTL_TR_OUT_TYPE_Msk)
110 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE        (DMAC_CH_V2_DESCR_CTL_TR_IN_TYPE)
111 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE       (DMAC_CH_V2_DESCR_CTL_TR_OUT_TYPE)
112 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Pos    (DMAC_CH_V2_DESCR_CTL_TR_IN_TYPE_Pos)
113 #define _CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Pos   (DMAC_CH_V2_DESCR_CTL_TR_OUT_TYPE_Pos)
114 #define _CYHAL_TRIGGER_CPUSS_ZERO                  (CYHAL_TRIGGER_CPUSS_ZERO)
115 #endif
116 
117 
118 static cyhal_dma_t* _cyhal_dma_dmac_config_structs[NUM_DMAC_CHANNELS];
119 
120 /** Default dmac descriptor config */
121 #if defined(CY_IP_MXSAXIDMAC)
122 static const cy_stc_axidmac_descriptor_config_t _cyhal_dma_dmac_default_descriptor_config =
123 #else
124 static const cy_stc_dmac_descriptor_config_t _cyhal_dma_dmac_default_descriptor_config =
125 #endif
126 {
127     .srcAddress = 0,                                // Overriden by cyhal_dma_cfg_t.src_addr
128     .dstAddress = 0,                                // Overriden by cyhal_dma_cfg_t.dst_addr
129 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
130     .dataSize = CY_DMAC_WORD,                       // Overridden by cyhal_dma_cfg_t.transfer_width
131     .dstTransferSize = CY_DMAC_TRANSFER_SIZE_DATA,  // Overriden by direction
132     .srcTransferSize = CY_DMAC_TRANSFER_SIZE_DATA,  // Overriden by direction
133     .retrigger = CY_DMAC_RETRIG_IM,
134     .interruptType = CY_DMAC_DESCR,                 // Overridden by cyhal_dma_cfg_t.action
135     .triggerOutType = CY_DMAC_DESCR_CHAIN,          // Overridden by [en/dis]able_output()
136     .channelState = CY_DMAC_CHANNEL_ENABLED,
137     .triggerInType = CY_DMAC_DESCR,                 // Overridden by cyhal_dma_cfg_t.action & [dis]connect_digital()
138     .dataPrefetch = false,
139     .descriptorType = CY_DMAC_1D_TRANSFER,          // Overriden by cyhal_dma_cfg_t.burst_size
140     .srcXincrement = 1U,                            // Overriden by cyhal_dma_cfg_t.src_increment
141     .dstXincrement = 1U,                            // Overriden by cyhal_dma_cfg_t.dst_increment
142     .xCount = 1UL,                                  // Overriden by cyhal_dma_cfg_t.length/burst_size
143     .srcYincrement = 1U,                            // Overriden by cyhal_dma_cfg_t.burst_size
144     .dstYincrement = 1U,                            // Overriden by cyhal_dma_cfg_t.burst_size
145     .yCount = 1UL,                                  // Overriden by cyhal_dma_cfg_t.length
146     .nextDescriptor = 0,
147 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
148     .dataSize = CY_DMAC_WORD,                       // Overridden by cyhal_dma_cfg_t.transfer_width
149     .dstTransferSize = CY_DMAC_TRANSFER_SIZE_DATA,  // Overriden by direction
150     .srcTransferSize = CY_DMAC_TRANSFER_SIZE_DATA,  // Overriden by direction
151     .retrigger = CY_DMAC_RETRIG_IM,
152     .triggerType = CY_DMAC_SINGLE_DESCR,
153     .dataCount = 1,                                 // Overriden by cyhal_dma_cfg_t.length
154     .dstAddrIncrement = true,                       // Overriden by cyhal_dma_cfg_t.dst_increment
155     .srcAddrIncrement = true,                       // Overriden by cyhal_dma_cfg_t.src_increment
156     .interrupt = true,
157     .preemptable = true,
158     .flipping = false,
159 #elif defined(CY_IP_MXSAXIDMAC)
160     .retrigger = CY_AXIDMAC_RETRIG_IM,
161     .interruptType = CY_AXIDMAC_DESCR,              // Overridden by cyhal_dma_cfg_t.action
162     .triggerOutType = CY_AXIDMAC_DESCR_CHAIN,       // Overridden by [en/dis]able_output()
163     .channelState = CY_AXIDMAC_CHANNEL_DISABLED,
164     .triggerInType = CY_AXIDMAC_DESCR,              // Overridden by cyhal_dma_cfg_t.action & [dis]connect_digital()
165     .dataPrefetch = false,
166     .descriptorType = CY_AXIDMAC_1D_MEMORY_COPY,    // Overriden by cyhal_dma_cfg_t.burst_size
167     .mCount = 1U,                                   // Overriden by cyhal_dma_cfg_t.length
168     .srcXincrement = 0U,                            // Overriden by cyhal_dma_cfg_t.src_increment
169     .dstXincrement = 0U,                            // Overriden by cyhal_dma_cfg_t.dst_increment
170     .xCount = 1UL,                                  // Overriden by cyhal_dma_cfg_t.length/burst_size
171     .srcYincrement = 0U,
172     .dstYincrement = 0U,
173     .yCount = 1UL,
174     .nextDescriptor = NULL,
175 #endif
176 };
177 
178 /** Default dmac channel config */
179 #if defined(CY_IP_MXSAXIDMAC)
180 static const cy_stc_axidmac_channel_config_t _cyhal_dma_dmac_default_channel_config =
181 #else
182 static const cy_stc_dmac_channel_config_t _cyhal_dma_dmac_default_channel_config =
183 #endif
184 {
185     .priority = 1,                          // Overriden by config().priority
186     .enable = false,
187 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
188     .bufferable = false,
189     .descriptor = 0,                        // Overriden by config()
190 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
191     .descriptor = CY_DMAC_DESCRIPTOR_PING,  // Overriden by config()
192 #endif
193 };
194 
195 static bool _cyhal_dma_dmac_pm_transition_pending = false;
196 
197 #if CYHAL_DRIVER_AVAILABLE_SYSPM
198 static bool _cyhal_dma_dmac_pm_callback(cyhal_syspm_callback_state_t state, cyhal_syspm_callback_mode_t mode, void* callback_arg);
199 
200 static cyhal_syspm_callback_data_t _cyhal_dma_dmac_pm_callback_args = {
201     .callback = &_cyhal_dma_dmac_pm_callback,
202     .states = (cyhal_syspm_callback_state_t)(CYHAL_SYSPM_CB_CPU_DEEPSLEEP | CYHAL_SYSPM_CB_CPU_DEEPSLEEP_RAM | CYHAL_SYSPM_CB_SYSTEM_HIBERNATE),
203     .next = NULL,
204     .args = NULL,
205     .ignore_modes = (cyhal_syspm_callback_mode_t)(CYHAL_SYSPM_BEFORE_TRANSITION | CYHAL_SYSPM_AFTER_DS_WFI_TRANSITION),
206 };
207 
_cyhal_dma_dmac_has_enabled(void)208 static bool _cyhal_dma_dmac_has_enabled(void)
209 {
210     for (uint8_t i = 0; i < NUM_DMAC_CHANNELS; i++)
211         if (NULL != _cyhal_dma_dmac_config_structs[i])
212             return true;
213     return false;
214 }
215 
_cyhal_dma_dmac_pm_callback(cyhal_syspm_callback_state_t state,cyhal_syspm_callback_mode_t mode,void * callback_arg)216 static bool _cyhal_dma_dmac_pm_callback(cyhal_syspm_callback_state_t state, cyhal_syspm_callback_mode_t mode, void* callback_arg)
217 {
218     CY_UNUSED_PARAMETER(state);
219     CY_UNUSED_PARAMETER(callback_arg);
220     bool block_transition = false;
221     switch(mode)
222     {
223         case CYHAL_SYSPM_CHECK_READY:
224             for (uint8_t i = 0; (i < NUM_DMAC_CHANNELS) && !block_transition; i++)
225             {
226                 block_transition |= (_cyhal_dma_dmac_config_structs[i] != NULL) && _cyhal_dma_dmac_is_busy(_cyhal_dma_dmac_config_structs[i]);
227             }
228             _cyhal_dma_dmac_pm_transition_pending = !block_transition;
229             break;
230         case CYHAL_SYSPM_CHECK_FAIL:
231         case CYHAL_SYSPM_AFTER_TRANSITION:
232             _cyhal_dma_dmac_pm_transition_pending = false;
233             break;
234         default:
235             CY_ASSERT(false);
236             break;
237     }
238     return _cyhal_dma_dmac_pm_transition_pending;
239 }
240 #endif
241 
242 /** Gets the dmac configuration struct offset */
_cyhal_dma_dmac_get_cfg_offset(const cyhal_dma_t * obj)243 static inline uint8_t _cyhal_dma_dmac_get_cfg_offset(const cyhal_dma_t* obj)
244 {
245     return (obj->resource.block_num * NUM_DMAC0_CHANNELS) + obj->resource.channel_num;
246 }
247 
248 /** Sets the dmac configuration struct */
_cyhal_dma_dmac_set_obj(cyhal_dma_t * obj)249 static inline void _cyhal_dma_dmac_set_obj(cyhal_dma_t *obj)
250 {
251     _cyhal_dma_dmac_config_structs[_cyhal_dma_dmac_get_cfg_offset(obj)] = obj;
252 }
253 
254 /** Zeros the dmac configuration struct */
_cyhal_dma_dmac_free_obj(cyhal_dma_t * obj)255 static inline void _cyhal_dma_dmac_free_obj(cyhal_dma_t *obj)
256 {
257     _cyhal_dma_dmac_config_structs[_cyhal_dma_dmac_get_cfg_offset(obj)] = NULL;
258 }
259 
260 /** Gets the dmac configuration struct from block and channel */
_cyhal_dma_dmac_get_obj(uint8_t block,uint8_t channel)261 static inline cyhal_dma_t* _cyhal_dma_dmac_get_obj(uint8_t block, uint8_t channel)
262 {
263 #if defined(CY_IP_MXSAXIDMAC)
264     return _cyhal_dma_dmac_config_structs[(block * APPCPUSS_AXIDMAC0_CH_NR) + channel];
265 #else
266     return _cyhal_dma_dmac_config_structs[(block * CPUSS_DMAC0_CH_NR) + channel];
267 #endif
268 }
269 
270 /** Gets the dmac block number from irq number */
271 /** This should never be called from a non-dma IRQn */
_cyhal_dma_dmac_get_block_from_irqn(_cyhal_system_irq_t irqn)272 static inline uint8_t _cyhal_dma_dmac_get_block_from_irqn(_cyhal_system_irq_t irqn)
273 {
274     uint8_t diff = irqn - DMAC0_IRQn;
275     CY_ASSERT(diff < NUM_DMAC_CHANNELS);
276     if (diff < NUM_DMAC0_CHANNELS)
277         return 0;
278 #if (NUM_DMAC0_CHANNELS < NUM_DMAC_CHANNELS)
279     if (diff < NUM_DMAC_CHANNELS)
280         return 1;
281 #endif
282     else
283     {
284         // Should never reach here. Just silencing compiler warnings.
285         CY_ASSERT(false);
286         return 0xFF;
287     }
288 }
289 
290 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
291 /** Gets the dmac channel number from irq number */
292 /** This should never be called from a non-dma IRQn */
_cyhal_dma_dmac_get_channel_from_irqn(_cyhal_system_irq_t irqn)293 static inline uint8_t _cyhal_dma_dmac_get_channel_from_irqn(_cyhal_system_irq_t irqn)
294 {
295     uint8_t diff = irqn - DMAC0_IRQn;
296     CY_ASSERT(diff < NUM_DMAC_CHANNELS);
297     if (diff < NUM_DMAC0_CHANNELS)
298         return diff;
299 #if (NUM_DMAC0_CHANNELS < NUM_DMAC_CHANNELS)
300     else
301         return diff - NUM_DMAC0_CHANNELS;
302 #endif
303     // Should never reach here. Just silencing compiler warnings.
304     CY_ASSERT(false);
305     return 0xFF;
306 }
307 #endif
308 
309 /** Gets the irqn corresponding to a particular cyhal_dma_t config struct */
_cyhal_dma_dmac_get_irqn(cyhal_dma_t * obj)310 static inline _cyhal_system_irq_t _cyhal_dma_dmac_get_irqn(cyhal_dma_t *obj)
311 {
312     #if defined(CY_IP_M0S8CPUSSV3_DMAC)
313         CY_UNUSED_PARAMETER(obj);
314         /* This IP has a single ganged IRQ for all DMA channels */
315         return DMAC0_IRQn;
316     #else
317         return (_cyhal_system_irq_t)((uint8_t)DMAC0_IRQn + _cyhal_dma_dmac_get_cfg_offset(obj));
318     #endif
319 }
320 
321 /** Gets the dmac base pointer from block number */
_cyhal_dma_dmac_get_base(uint8_t block_num)322 static inline cyhal_dmac_hw_type* _cyhal_dma_dmac_get_base(uint8_t block_num)
323 {
324 #if defined(CY_IP_MXSAXIDMAC)
325     CY_UNUSED_PARAMETER(block_num);
326     return SAXI_DMAC;
327 #elif defined(CPUSS_DMAC0_CH_NR) && !defined(CPUSS_DMAC1_CH_NR)
328     CY_UNUSED_PARAMETER(block_num);
329     return DMAC;
330 #elif defined(CPUSS_DMAC0_CH_NR) && defined(CPUSS_DMAC1_CH_NR)
331     return (block_num == 0) ? MXAHBDMAC0 : MXAHBDMAC1;
332 #else
333     //Should never get here
334     #error "Error: No corresponding base type"
335 #endif
336 }
337 
338 /** Uses tables provided as part of the hal interconnect driver to determine mux
339  * trigger group and mux trigger index and then construct the trigger line
340  * input parameter to Cy_TrigMux_SwTrigger. */
_cyhal_dma_dmac_get_trigger_line(uint8_t block_num,uint8_t channel_num)341 static inline uint32_t _cyhal_dma_dmac_get_trigger_line(uint8_t block_num, uint8_t channel_num)
342 {
343     /* cyhal_dest_t triggers are guaranteed to be sorted by trigger type, block
344      * num, then channel num, therefore, we can just directly find the proper
345      * trigger by calculating an offset. */
346 #if defined(CY_IP_MXSAXIDMAC)
347     cyhal_dest_t trigger = (cyhal_dest_t)(CYHAL_TRIGGER_M55APPCPUSS_AXIDMAC_TR_IN0 + (block_num * APPCPUSS_AXIDMAC0_CH_NR) + channel_num);
348 #else
349     cyhal_dest_t trigger = (cyhal_dest_t)(CYHAL_TRIGGER_CPUSS_DMAC0_TR_IN0 + (block_num * CPUSS_DMAC0_CH_NR) + channel_num);
350 #endif
351     uint32_t trigger_line = 0;
352 
353     /* One to one triggers have bit 8 set in cyhal_dest_to_mux but
354      * Cy_TrigMux_SwTrigger wants the trigger group field to have bit 5 set to
355      * denote one to one triggers. */
356     uint8_t trig_group = cyhal_dest_to_mux[trigger];
357     /* If hal one to one triggers bit is set: mask it out and set pdl one to
358      * one bit */
359     if(trig_group & _CYHAL_DMA_TRIGGERS_1TO1_MASK)
360         trig_group = (trig_group & ~_CYHAL_DMA_TRIGGERS_1TO1_MASK) | _CYHAL_DMA_PDL_TRIGGERS_1TO1_MASK;
361 
362     /* Construct trigger line which consists of three fields packed into a
363      * uint32_t:
364      * Bits   30: Input/output bit. Set to 1 for output.
365      * Bits 12-8: Trigger group selection.
366      * Bits  7-0: Select the output trigger number in the trigger group. */
367 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
368     trigger_line = PERI_TR_CMD_OUT_SEL_Msk | ((uint32_t)trig_group << 8) | cyhal_mux_dest_index[trigger];
369 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
370     trigger_line =  PERI_TR_CTL_TR_OUT_Msk | ((uint32_t)trig_group << 8) | cyhal_mux_dest_index[trigger];
371 #endif
372 
373 #if (((CY_IP_MXSPERI_INSTANCES) == 2U) && defined(CY_IP_MXSAXIDMAC))
374     /* Bits   16: The PERI 1 instance.
375         The trigger input for AXIDMAC is located on PERI 1
376     */
377     trigger_line |= PERI_INSTANCE_1_IDENT_Msk;
378 #endif
379 
380     return trigger_line;
381 }
382 
383 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
384 /** Convert PDL interrupt cause to hal dma event */
_cyhal_dma_dmac_convert_interrupt_cause(cyhal_dma_t * obj,uint32_t cause)385 static inline cyhal_dma_event_t _cyhal_dma_dmac_convert_interrupt_cause(cyhal_dma_t *obj, uint32_t cause)
386 {
387     static const cyhal_dma_event_t hal[] =
388     {
389         CYHAL_DMA_TRANSFER_COMPLETE,
390         CYHAL_DMA_SRC_BUS_ERROR,
391         CYHAL_DMA_DST_BUS_ERROR,
392         CYHAL_DMA_SRC_MISAL,
393         CYHAL_DMA_DST_MISAL,
394         CYHAL_DMA_CURR_PTR_NULL,
395         CYHAL_DMA_ACTIVE_CH_DISABLED,
396         CYHAL_DMA_DESCR_BUS_ERROR
397     };
398 
399     cyhal_dma_event_t hal_rslt = CYHAL_DMA_NO_INTR;
400     for (uint8_t i = 0; cause > 0 && i < sizeof(hal)/sizeof(cyhal_dma_event_t); i++)
401     {
402         if ((cause & (1 << i)) > 0)
403         hal_rslt |= hal[i];
404     }
405 
406     if ((uint32_t)(hal_rslt & CYHAL_DMA_TRANSFER_COMPLETE) > 0 && obj->expected_bursts > 0)
407     {
408         obj->expected_bursts--;
409         if (0 == obj->expected_bursts)
410         {
411             hal_rslt |= CYHAL_DMA_DESCRIPTOR_COMPLETE;
412         #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
413             obj->expected_bursts = (GET_RESOURCE_DATA(obj->descriptor_config).interruptType == _CYHAL_DMAC_X_LOOP)
414                 ? GET_RESOURCE_DATA(obj->descriptor_config).yCount
415                 : 1;
416         #elif defined(CY_IP_MXSAXIDMAC)
417             obj->expected_bursts = (GET_RESOURCE_DATA(obj->descriptor_config).interruptType == _CYHAL_DMAC_M_LOOP)
418                 ? GET_RESOURCE_DATA(obj->descriptor_config).xCount
419                 : 1;
420         #else
421             obj->expected_bursts = 1;
422         #endif
423         }
424     }
425 
426     return hal_rslt;
427 }
428 #endif
429 
430 /** DMAC irq handler */
_cyhal_dma_dmac_irq_handler(void)431 static void _cyhal_dma_dmac_irq_handler(void)
432 {
433     /* Use irqn to get appropriate config structure */
434     _cyhal_system_irq_t irqn = _cyhal_irq_get_active();
435     uint8_t block = _cyhal_dma_dmac_get_block_from_irqn(irqn);
436 #if defined(CY_IP_MXSAXIDMAC)
437     SAXI_DMAC_Type* base = _cyhal_dma_dmac_get_base(block);
438 #else
439     DMAC_Type* base = _cyhal_dma_dmac_get_base(block);
440 #endif
441 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
442     uint8_t channel = _cyhal_dma_dmac_get_channel_from_irqn(irqn);
443     cyhal_dma_t *obj = _cyhal_dma_dmac_get_obj(block, channel);
444 
445     /* Get interrupt type and call users event callback if they have enabled that event */
446     uint32_t cause = _cyhal_dmac_channel_get_interrupt_status_masked(base, channel);
447     cyhal_dma_event_t event_type = _cyhal_dma_dmac_convert_interrupt_cause(obj, cause);
448     uint32_t events_to_callback = event_type & obj->irq_cause;
449     if(obj->callback_data.callback != NULL && events_to_callback)
450     {
451         ((cyhal_dma_event_callback_t)obj->callback_data.callback)(obj->callback_data.callback_arg, (cyhal_dma_event_t)events_to_callback);
452     }
453 
454     /* Clear all interrupts */
455 #if defined(CY_IP_MXSAXIDMAC)
456     Cy_AXIDMAC_Channel_ClearInterrupt(base, channel, CY_AXIDMAC_INTR_MASK);
457 #else
458     Cy_DMAC_Channel_ClearInterrupt(base, channel, CY_DMAC_INTR_MASK);
459 #endif
460 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
461     uint32_t channels = Cy_DMAC_GetInterruptStatusMasked(base);
462     for(int i = 0 ; ((uint32_t)(1 << i)) <= channels ; i++)
463     {
464         cyhal_dma_t *obj = _cyhal_dma_dmac_get_obj(block, i);
465         if (obj != NULL)
466         {
467             if (((channels & (1 << i)) != 0) && (obj->callback_data.callback != NULL))
468             {
469                 ((cyhal_dma_event_callback_t)obj->callback_data.callback)(obj->callback_data.callback_arg, CYHAL_DMA_TRANSFER_COMPLETE);
470             }
471         }
472     }
473     Cy_DMAC_ClearInterrupt(_cyhal_dma_dmac_get_base(block), channels);
474 #endif
475 }
476 
_cyhal_dma_dmac_get_src(uint8_t block_num,uint8_t channel_num)477 static cyhal_source_t _cyhal_dma_dmac_get_src(uint8_t block_num, uint8_t channel_num)
478 {
479 #if defined(CY_IP_MXSAXIDMAC)
480     return (cyhal_source_t)_CYHAL_TRIGGER_CREATE_SOURCE((_CYHAL_TRIGGER_M55APPCPUSS_AXIDMAC_TR_OUT0 + (block_num * APPCPUSS_AXIDMAC0_CH_NR) + channel_num), CYHAL_SIGNAL_TYPE_EDGE);
481 #else
482     return (cyhal_source_t)_CYHAL_TRIGGER_CREATE_SOURCE((_CYHAL_TRIGGER_CPUSS_DMAC0_TR_OUT0 + (block_num * CPUSS_DMAC0_CH_NR) + channel_num), CYHAL_SIGNAL_TYPE_EDGE);
483 #endif
484 }
485 
_cyhal_dma_dmac_get_dest(uint8_t block_num,uint8_t channel_num)486 static cyhal_dest_t _cyhal_dma_dmac_get_dest(uint8_t block_num, uint8_t channel_num)
487 {
488 #if defined(CY_IP_MXSAXIDMAC)
489     return (cyhal_dest_t)(CYHAL_TRIGGER_M55APPCPUSS_AXIDMAC_TR_IN0 + (block_num * APPCPUSS_AXIDMAC0_CH_NR) + channel_num);
490 #else
491     return (cyhal_dest_t)(CYHAL_TRIGGER_CPUSS_DMAC0_TR_IN0 + (block_num * CPUSS_DMAC0_CH_NR) + channel_num);
492 #endif
493 }
494 
_cyhal_dma_dmac_stage(cyhal_dma_t * obj)495 static cy_rslt_t _cyhal_dma_dmac_stage(cyhal_dma_t *obj)
496 {
497     cyhal_dmac_hw_type* base = _cyhal_dma_dmac_get_base(obj->resource.block_num);
498 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
499     #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
500     SCB_CleanDCache_by_Addr((void *)&(obj->descriptor), sizeof(obj->descriptor));
501     #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
502 #if defined(CY_IP_MXSAXIDMAC)
503     cy_en_axidmac_descriptor_type_t descr_type = GET_RESOURCE_DATA(&obj->descriptor_config)->descriptorType;
504     GET_RESOURCE_DATA(&obj->descriptor_config)->descriptorType = CY_AXIDMAC_3D_MEMORY_COPY;
505     cy_rslt_t rslt = Cy_AXIDMAC_Descriptor_Init(GET_RESOURCE_DATA(&obj->descriptor), GET_RESOURCE_DATA(&obj->descriptor_config));
506     Cy_AXIDMAC_Descriptor_SetDescriptorType(GET_RESOURCE_DATA(&obj->descriptor), descr_type);
507     GET_RESOURCE_DATA(&obj->descriptor_config)->descriptorType = descr_type;
508 #else
509     cy_rslt_t rslt = Cy_DMAC_Descriptor_Init(GET_RESOURCE_DATA(&obj->descriptor), GET_RESOURCE_DATA(&obj->descriptor_config));
510 #endif
511 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
512     cy_rslt_t rslt = Cy_DMAC_Descriptor_Init(base, obj->resource.channel_num, obj->descriptor, GET_RESOURCE_DATA(&obj->descriptor_config));
513 #endif
514 #if defined(CY_IP_MXSAXIDMAC)
515     if(CY_AXIDMAC_SUCCESS != rslt)
516 #else
517     if(CY_DMAC_SUCCESS != rslt)
518 #endif
519         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
520 
521     /* Setup channel and enable */
522     #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
523     SCB_CleanDCache_by_Addr((void *)&(obj->channel_config), sizeof(obj->channel_config));
524     #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
525 #if defined(CY_IP_MXSAXIDMAC)
526     if(CY_AXIDMAC_SUCCESS != Cy_AXIDMAC_Channel_Init(base, obj->resource.channel_num, GET_RESOURCE_DATA(&obj->channel_config)))
527 #else
528     if(CY_DMAC_SUCCESS != Cy_DMAC_Channel_Init(base, obj->resource.channel_num, GET_RESOURCE_DATA(&obj->channel_config)))
529 #endif
530         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
531 
532 #if defined(CY_IP_MXSAXIDMAC)
533     Cy_AXIDMAC_Channel_SetInterruptMask(base, obj->resource.channel_num, CY_AXIDMAC_INTR_MASK);
534 #elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
535     Cy_DMAC_Channel_SetInterruptMask(base, obj->resource.channel_num, CY_DMAC_INTR_MASK);
536 #endif
537 #if defined(CY_IP_MXSAXIDMAC)
538     Cy_AXIDMAC_Enable(base);
539 #else
540     Cy_DMAC_Enable(base);
541 #endif
542 
543 #if defined(CY_IP_MXSAXIDMAC)
544     /* src_misal and dst_misal interrupts are triggered immediately on enable
545      * so return those errors here */
546     uint32_t status = Cy_AXIDMAC_Channel_GetInterruptStatus(base, obj->resource.channel_num);
547     if((status & CY_AXIDMAC_INTR_INVALID_DESCR_TYPE))
548     {
549         /* Clear all interrupts and return error */
550         Cy_AXIDMAC_Channel_ClearInterrupt(base, obj->resource.channel_num, CY_AXIDMAC_INTR_MASK);
551         return CYHAL_DMA_RSLT_ERR_INVALID_ALIGNMENT;
552     }
553 #elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
554     /* src_misal and dst_misal interrupts are triggered immediately on enable
555      * so return those errors here */
556     uint32_t status = Cy_DMAC_Channel_GetInterruptStatus(base, obj->resource.channel_num);
557     if((status & CY_DMAC_INTR_SRC_MISAL) ||
558        (status & CY_DMAC_INTR_DST_MISAL))
559     {
560         /* Clear all interrupts and return error */
561         Cy_DMAC_Channel_ClearInterrupt(base, obj->resource.channel_num, CY_DMAC_INTR_MASK);
562         return CYHAL_DMA_RSLT_ERR_INVALID_ALIGNMENT;
563     }
564 #endif
565 
566     /* Enable interrupt for this channel; preserve user priority if they enabled an interrupt */
567     _cyhal_system_irq_t irqn = _cyhal_dma_dmac_get_irqn(obj);
568     uint32_t priority = (CYHAL_DMA_NO_INTR == obj->irq_cause)
569         ? CYHAL_ISR_PRIORITY_DEFAULT
570         : _cyhal_irq_get_priority(irqn);
571 
572     if(CY_RSLT_SUCCESS != _cyhal_irq_register(irqn, priority, _cyhal_dma_dmac_irq_handler))
573         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
574     _cyhal_irq_enable(irqn);
575 
576     return CY_RSLT_SUCCESS;
577 }
578 
_cyhal_dma_dmac_init(cyhal_dma_t * obj,cyhal_source_t * src,cyhal_dest_t * dest,uint8_t priority)579 cy_rslt_t _cyhal_dma_dmac_init(cyhal_dma_t *obj, cyhal_source_t *src, cyhal_dest_t *dest, uint8_t priority)
580 {
581 
582 #if defined(CY_IP_MXSAXIDMAC)
583     if(!CY_AXIDMAC_IS_PRIORITY_VALID(priority))
584 #else
585     if(!CY_DMAC_IS_PRIORITY_VALID(priority))
586 #endif
587         return CYHAL_DMA_RSLT_ERR_INVALID_PRIORITY;
588 
589     if (_cyhal_dma_dmac_pm_transition_pending)
590     {
591         return CYHAL_SYSPM_RSLT_ERR_PM_PENDING;
592     }
593 
594     cy_rslt_t rslt = _cyhal_hwmgr_allocate_with_connection(
595         CYHAL_RSC_DMA, src, dest, _cyhal_dma_dmac_get_src, _cyhal_dma_dmac_get_dest, &obj->resource);
596     if(rslt != CY_RSLT_SUCCESS)
597         return rslt;
598 
599     obj->callback_data.callback = NULL;
600 
601     /* Setup descriptor and channel configs */
602     GET_RESOURCE_DATA(obj->descriptor_config) = _cyhal_dma_dmac_default_descriptor_config;
603     GET_RESOURCE_DATA(obj->channel_config) = _cyhal_dma_dmac_default_channel_config;
604 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
605     GET_RESOURCE_DATA(obj->channel_config).descriptor = GET_RESOURCE_DATA(&obj->descriptor);
606 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
607     obj->descriptor = obj->channel_config.descriptor;
608 #endif
609     GET_RESOURCE_DATA(obj->channel_config).priority = priority;
610 
611 #if CYHAL_DRIVER_AVAILABLE_SYSPM
612     if (!_cyhal_dma_dmac_has_enabled())
613     {
614         _cyhal_syspm_register_peripheral_callback(&_cyhal_dma_dmac_pm_callback_args);
615     }
616 #endif
617 
618     _cyhal_dma_dmac_set_obj(obj);
619 
620     return CY_RSLT_SUCCESS;
621 }
622 
_cyhal_dma_dmac_init_cfg(cyhal_dma_t * obj,const cyhal_dma_configurator_t * cfg)623 cy_rslt_t _cyhal_dma_dmac_init_cfg(cyhal_dma_t *obj, const cyhal_dma_configurator_t *cfg)
624 {
625     if (_cyhal_dma_dmac_pm_transition_pending)
626     {
627         return CYHAL_SYSPM_RSLT_ERR_PM_PENDING;
628     }
629 
630     obj->resource = *(cfg->resource);
631     obj->callback_data.callback = NULL;
632 
633     /* Setup descriptor and channel configs */
634 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
635     obj->descriptor_config.dmac = *(cfg->dmac_descriptor_config);
636     obj->channel_config.dmac = *(cfg->dmac_channel_config);
637     GET_RESOURCE_DATA(obj->channel_config).descriptor = GET_RESOURCE_DATA(&obj->descriptor);
638     #if defined(CY_IP_MXSAXIDMAC)
639         obj->expected_bursts = cfg->dmac_descriptor_config->xCount;
640     #else
641         obj->expected_bursts = cfg->dmac_descriptor_config->yCount;
642     #endif
643 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
644     obj->descriptor_config = *(cfg->descriptor_config);
645     obj->channel_config = *(cfg->channel_config);
646     obj->descriptor = obj->channel_config.descriptor;
647     obj->expected_bursts = 1;
648 #endif
649 
650 #if CYHAL_DRIVER_AVAILABLE_SYSPM
651     if (!_cyhal_dma_dmac_has_enabled())
652     {
653         _cyhal_syspm_register_peripheral_callback(&_cyhal_dma_dmac_pm_callback_args);
654     }
655 #endif
656 
657     _cyhal_dma_dmac_set_obj(obj);
658 
659     return _cyhal_dma_dmac_stage(obj);
660 }
661 
_cyhal_dma_dmac_free(cyhal_dma_t * obj)662 void _cyhal_dma_dmac_free(cyhal_dma_t *obj)
663 {
664     cyhal_dmac_hw_type* base = _cyhal_dma_dmac_get_base(obj->resource.block_num);
665 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
666     Cy_DMAC_Descriptor_DeInit(GET_RESOURCE_DATA(&obj->descriptor));
667     Cy_DMAC_Channel_DeInit(base, obj->resource.channel_num);
668 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
669     Cy_DMAC_Descriptor_DeInit(base, obj->resource.channel_num, obj->descriptor);
670     Cy_DMAC_Channel_DeInit(base, obj->resource.channel_num);
671 #elif defined(CY_IP_MXSAXIDMAC)
672     Cy_AXIDMAC_Descriptor_DeInit(GET_RESOURCE_DATA(&obj->descriptor));
673     Cy_AXIDMAC_Channel_DeInit(base, obj->resource.channel_num);
674 #endif
675 
676     _cyhal_irq_free(_cyhal_dma_dmac_get_irqn(obj));
677 
678     _cyhal_dma_dmac_free_obj(obj);
679 
680 #if CYHAL_DRIVER_AVAILABLE_SYSPM
681     if (!_cyhal_dma_dmac_has_enabled())
682     {
683         _cyhal_syspm_unregister_peripheral_callback(&_cyhal_dma_dmac_pm_callback_args);
684         _cyhal_dma_dmac_pm_transition_pending = false;
685     }
686 #endif
687 }
688 
689 /* Initialize descriptor, initialize channel, enable channel, enable channel
690  * interrupt, and enable DMAC controller */
_cyhal_dma_dmac_configure(cyhal_dma_t * obj,const cyhal_dma_cfg_t * cfg)691 cy_rslt_t _cyhal_dma_dmac_configure(cyhal_dma_t *obj, const cyhal_dma_cfg_t *cfg)
692 {
693     uint32_t total_length = cfg->length;
694 
695     /* Do not reconfigure if transfer is pending/active already */
696     if(_cyhal_dma_dmac_is_busy(obj))
697         return CYHAL_DMA_RSLT_ERR_CHANNEL_BUSY;
698 
699     // DMAC only supports <=65536 byte burst and <=65536 bytes per burst
700     if ((cfg->burst_size > 65536) ||
701         ((cfg->burst_size <= 1) && (cfg->length > 65536)) ||
702         ((cfg->burst_size > 0) && (cfg->length > (cfg->burst_size * 65536))))
703         return CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_SIZE;
704 
705 #if defined(CY_IP_M0S8CPUSSV3_DMAC)
706     // PSoC™ 4 devices do not support automatically disabling the channel on completion
707     if ((cfg->action == CYHAL_DMA_TRANSFER_BURST_DISABLE) ||
708         (cfg->action == CYHAL_DMA_TRANSFER_FULL_DISABLE))
709     {
710         return CYHAL_DMA_RSLT_FATAL_UNSUPPORTED_HARDWARE;
711     }
712 #endif
713 
714     #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
715     SCB_CleanDCache_by_Addr((void *)cfg->src_addr, cfg->length * (cfg->transfer_width / 8));
716     SCB_CleanDCache_by_Addr((void *)cfg->dst_addr, cfg->length * (cfg->transfer_width / 8));
717     #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
718     GET_RESOURCE_DATA(obj->descriptor_config).srcAddress = (void*)cfg->src_addr;
719     GET_RESOURCE_DATA(obj->descriptor_config).dstAddress = (void*)cfg->dst_addr;
720 
721     if ((cfg->transfer_width != 8) && (cfg->transfer_width != 16) && (cfg->transfer_width != 32))
722         return CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_WIDTH;
723 
724 #if !defined(CY_IP_MXSAXIDMAC)
725     total_length = cfg->length;
726 
727     if(cfg->transfer_width == 8)
728         GET_RESOURCE_DATA(obj->descriptor_config).dataSize = CY_DMAC_BYTE;
729     else if(cfg->transfer_width == 16)
730         GET_RESOURCE_DATA(obj->descriptor_config).dataSize = CY_DMAC_HALFWORD;
731     else if(cfg->transfer_width == 32)
732         GET_RESOURCE_DATA(obj->descriptor_config).dataSize = CY_DMAC_WORD;
733     else
734         return CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_WIDTH;
735 
736     /* By default, transfer what the user set for dataSize. However, if transfering between memory
737      * and a peripheral, make sure the peripheral access is using words. */
738     GET_RESOURCE_DATA(obj->descriptor_config).srcTransferSize =
739         GET_RESOURCE_DATA(obj->descriptor_config).dstTransferSize = CY_DMAC_TRANSFER_SIZE_DATA;
740     if (obj->direction == CYHAL_DMA_DIRECTION_PERIPH2MEM)
741         GET_RESOURCE_DATA(obj->descriptor_config).srcTransferSize = CY_DMAC_TRANSFER_SIZE_WORD;
742     else if (obj->direction == CYHAL_DMA_DIRECTION_MEM2PERIPH)
743         GET_RESOURCE_DATA(obj->descriptor_config).dstTransferSize = CY_DMAC_TRANSFER_SIZE_WORD;
744 #else
745     /* Need to convert number of elements to the total number of bytes for transfer */
746     total_length = cfg->length * (cfg->transfer_width / 8);
747     if (!CY_AXIDMAC_IS_LOOP_COUNT_VALID(total_length))
748     {
749         return CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_SIZE;
750     }
751 #endif
752 
753 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
754     GET_RESOURCE_DATA(obj->descriptor_config).nextDescriptor = GET_RESOURCE_DATA(&obj->descriptor);
755     if ((cfg->action == CYHAL_DMA_TRANSFER_BURST) || (cfg->action == CYHAL_DMA_TRANSFER_FULL))
756     {
757         GET_RESOURCE_DATA(obj->descriptor_config).channelState = _CYHAL_DMAC_CHANNEL_ENABLED;
758     }
759     else
760     {
761         GET_RESOURCE_DATA(obj->descriptor_config).channelState = _CYHAL_DMAC_CHANNEL_DISABLED;
762     }
763 
764     GET_RESOURCE_DATA(obj->descriptor_config).srcXincrement = cfg->src_increment;
765     GET_RESOURCE_DATA(obj->descriptor_config).dstXincrement = cfg->dst_increment;
766 
767     /* Setup 2D transfer if burst_size is being used otherwise set up 1D
768      * transfer */
769     if(cfg->burst_size != 0)
770     {
771         /* Length must be a multiple of burst_size */
772         if(total_length % cfg->burst_size != 0)
773             return CYHAL_DMA_RSLT_ERR_INVALID_BURST_SIZE;
774 
775     #if defined(CY_IP_MXSAXIDMAC)
776         GET_RESOURCE_DATA(obj->descriptor_config).descriptorType = CY_AXIDMAC_2D_MEMORY_COPY;
777         GET_RESOURCE_DATA(obj->descriptor_config).mCount = cfg->burst_size * (cfg->transfer_width / 8);
778         GET_RESOURCE_DATA(obj->descriptor_config).xCount = (cfg->length / cfg->burst_size);
779         GET_RESOURCE_DATA(obj->descriptor_config).srcXincrement = cfg->src_increment * cfg->burst_size * (cfg->transfer_width / 8);
780         GET_RESOURCE_DATA(obj->descriptor_config).dstXincrement = cfg->dst_increment * cfg->burst_size * (cfg->transfer_width / 8);
781     #else
782         GET_RESOURCE_DATA(obj->descriptor_config).descriptorType = CY_DMAC_2D_TRANSFER;
783         GET_RESOURCE_DATA(obj->descriptor_config).xCount = cfg->burst_size;
784         GET_RESOURCE_DATA(obj->descriptor_config).yCount = total_length / cfg->burst_size;
785         GET_RESOURCE_DATA(obj->descriptor_config).srcYincrement = cfg->src_increment * cfg->burst_size;
786         GET_RESOURCE_DATA(obj->descriptor_config).dstYincrement = cfg->dst_increment * cfg->burst_size;
787     #endif
788 
789     }
790     else
791     {
792     #if defined(CY_IP_MXSAXIDMAC)
793         GET_RESOURCE_DATA(obj->descriptor_config).descriptorType = CY_AXIDMAC_1D_MEMORY_COPY;
794         GET_RESOURCE_DATA(obj->descriptor_config).mCount = total_length;
795     #else
796         GET_RESOURCE_DATA(obj->descriptor_config).descriptorType = CY_DMAC_1D_TRANSFER;
797         GET_RESOURCE_DATA(obj->descriptor_config).xCount = total_length;
798     #endif
799     }
800 
801     /* If burst action, configure trigger and interrupt actions */
802     if (cfg->burst_size != 0 &&
803         (cfg->action == CYHAL_DMA_TRANSFER_BURST || cfg->action == CYHAL_DMA_TRANSFER_BURST_DISABLE))
804     {
805     #if defined(CY_IP_MXSAXIDMAC)
806         obj->expected_bursts = GET_RESOURCE_DATA(obj->descriptor_config).xCount;
807         GET_RESOURCE_DATA(obj->descriptor_config).interruptType = _CYHAL_DMAC_M_LOOP;
808         if (obj->source == _CYHAL_TRIGGER_CPUSS_ZERO) // If not overridden by connect_digital()
809             GET_RESOURCE_DATA(obj->descriptor_config).triggerInType = _CYHAL_DMAC_M_LOOP;
810     #else
811         obj->expected_bursts = GET_RESOURCE_DATA(obj->descriptor_config).yCount;
812         GET_RESOURCE_DATA(obj->descriptor_config).interruptType = _CYHAL_DMAC_X_LOOP;
813         if (obj->source == _CYHAL_TRIGGER_CPUSS_ZERO) // If not overridden by connect_digital()
814             GET_RESOURCE_DATA(obj->descriptor_config).triggerInType = _CYHAL_DMAC_X_LOOP;
815     #endif
816     }
817     else
818     {
819         obj->expected_bursts = 1;
820         GET_RESOURCE_DATA(obj->descriptor_config).interruptType = _CYHAL_DMAC_DESCR;
821         if (obj->source == _CYHAL_TRIGGER_CPUSS_ZERO) // If not overridden by connect_digital()
822             GET_RESOURCE_DATA(obj->descriptor_config).triggerInType = _CYHAL_DMAC_DESCR;
823      }
824 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
825     if(cfg->burst_size != 0)
826     {
827         return CYHAL_DMA_RSLT_ERR_INVALID_BURST_SIZE;
828     }
829     else
830     {
831         GET_RESOURCE_DATA(obj->descriptor_config).dataCount = total_length;
832         GET_RESOURCE_DATA(obj->descriptor_config).srcAddrIncrement = cfg->src_increment;
833         GET_RESOURCE_DATA(obj->descriptor_config).dstAddrIncrement = cfg->dst_increment;
834         obj->expected_bursts = 1;
835     }
836 #endif
837 
838     return _cyhal_dma_dmac_stage(obj);
839 }
840 
_cyhal_dma_dmac_enable(cyhal_dma_t * obj)841 cy_rslt_t _cyhal_dma_dmac_enable(cyhal_dma_t *obj)
842 {
843     cyhal_dmac_hw_type* base = _cyhal_dma_dmac_get_base(obj->resource.block_num);
844     _cyhal_dmac_channel_enable(base, obj->resource.channel_num);
845     return CY_RSLT_SUCCESS;
846 }
847 
_cyhal_dma_dmac_disable(cyhal_dma_t * obj)848 cy_rslt_t _cyhal_dma_dmac_disable(cyhal_dma_t *obj)
849 {
850     cyhal_dmac_hw_type* base = _cyhal_dma_dmac_get_base(obj->resource.block_num);
851     _cyhal_dmac_channel_disable(base, obj->resource.channel_num);
852     return CY_RSLT_SUCCESS;
853 }
854 
_cyhal_dma_dmac_start_transfer(cyhal_dma_t * obj)855 cy_rslt_t _cyhal_dma_dmac_start_transfer(cyhal_dma_t *obj)
856 {
857     /* Return warning if channel is busy */
858     if(_cyhal_dma_dmac_is_busy(obj))
859         return CYHAL_DMA_RSLT_WARN_TRANSFER_ALREADY_STARTED;
860 
861     if (_cyhal_dma_dmac_pm_transition_pending)
862         return CYHAL_SYSPM_RSLT_ERR_PM_PENDING;
863 
864     uint32_t trigline = _cyhal_dma_dmac_get_trigger_line(obj->resource.block_num, obj->resource.channel_num);
865     cy_en_trigmux_status_t trig_status = Cy_TrigMux_SwTrigger(trigline, CY_TRIGGER_TWO_CYCLES);
866 
867     /* Also return warning if SW trigger is already initiated but DMA hardware
868      * has not seen it yet */
869     if(trig_status == CY_TRIGMUX_INVALID_STATE)
870         return CYHAL_DMA_RSLT_WARN_TRANSFER_ALREADY_STARTED;
871     else
872         return CY_RSLT_SUCCESS;
873 }
874 
_cyhal_dma_dmac_enable_event(cyhal_dma_t * obj,cyhal_dma_event_t event,uint8_t intr_priority,bool enable)875 void _cyhal_dma_dmac_enable_event(cyhal_dma_t *obj, cyhal_dma_event_t event, uint8_t intr_priority, bool enable)
876 {
877 #if defined (CY_IP_M0S8CPUSSV3_DMAC)
878     DMAC_Type *base = _cyhal_dma_dmac_get_base(obj->resource.block_num);
879     uint32_t mask = Cy_DMAC_GetInterruptMask(base);
880 #endif
881     if(enable)
882     {
883 #if defined (CY_IP_M0S8CPUSSV3_DMAC)
884         Cy_DMAC_SetInterruptMask(base, mask | (1 << obj->resource.channel_num));
885 #endif
886         obj->irq_cause |= event;
887     }
888     else
889     {
890 #if defined (CY_IP_M0S8CPUSSV3_DMAC)
891         Cy_DMAC_SetInterruptMask(base, mask & ~(1 << obj->resource.channel_num));
892 #endif
893         obj->irq_cause &= ~event;
894     }
895 
896     _cyhal_irq_set_priority(_cyhal_dma_dmac_get_irqn(obj), intr_priority);
897 }
898 
_cyhal_dma_dmac_is_busy(cyhal_dma_t * obj)899 bool _cyhal_dma_dmac_is_busy(cyhal_dma_t *obj)
900 {
901     /* The value is a bit field of all pending or active channels */
902     return _cyhal_dmac_get_active_channel(_cyhal_dma_dmac_get_base(obj->resource.block_num)) & (1 << obj->resource.channel_num);
903 }
904 #if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXSAXIDMAC)
905 #if defined(CY_IP_MXSAXIDMAC)
_cyhal_convert_input_t(cyhal_dma_input_t input)906 static cy_en_axidmac_trigger_type_t _cyhal_convert_input_t(cyhal_dma_input_t input)
907 {
908     switch(input)
909     {
910         case CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT:
911             return CY_AXIDMAC_M_LOOP;
912         case CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST:
913             return CY_AXIDMAC_X_LOOP;
914         case CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS:
915             return CY_AXIDMAC_DESCR;
916         default:
917             // Should never reach here. Just silencing compiler warnings.
918             CY_ASSERT(false);
919             return CY_AXIDMAC_DESCR;
920     }
921 }
922 #elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
_cyhal_convert_input_t(cyhal_dma_input_t input)923 static cy_en_dmac_trigger_type_t _cyhal_convert_input_t(cyhal_dma_input_t input)
924 {
925     switch(input)
926     {
927         case CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT:
928             return CY_DMAC_1ELEMENT;
929         case CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST:
930             return CY_DMAC_X_LOOP;
931         case CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS:
932             return CY_DMAC_DESCR;
933         default:
934             // Should never reach here. Just silencing compiler warnings.
935             CY_ASSERT(false);
936             return CY_DMAC_DESCR;
937     }
938 }
939 #endif
940 
941 #if defined(CY_IP_MXSAXIDMAC)
_cyhal_convert_output_t(cyhal_dma_output_t output)942 static cy_en_axidmac_trigger_type_t _cyhal_convert_output_t(cyhal_dma_output_t output)
943 {
944     switch(output)
945     {
946         case CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT:
947             return CY_AXIDMAC_M_LOOP;
948         case CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST:
949             return CY_AXIDMAC_X_LOOP;
950         case CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS:
951             return CY_AXIDMAC_DESCR;
952         default:
953             // Should never reach here. Just silencing compiler warnings.
954             CY_ASSERT(false);
955             return CY_AXIDMAC_DESCR;
956     }
957 }
958 #else
_cyhal_convert_output_t(cyhal_dma_output_t output)959 static cy_en_dmac_trigger_type_t _cyhal_convert_output_t(cyhal_dma_output_t output)
960 {
961     switch(output)
962     {
963         case CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT:
964             return CY_DMAC_1ELEMENT;
965         case CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST:
966             return CY_DMAC_X_LOOP;
967         case CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS:
968             return CY_DMAC_DESCR;
969         default:
970             // Should never reach here. Just silencing compiler warnings.
971             CY_ASSERT(false);
972             return CY_DMAC_DESCR;
973     }
974 }
975 #endif
976 
_cyhal_dma_dmac_connect_digital(cyhal_dma_t * obj,cyhal_source_t source,cyhal_dma_input_t input)977 cy_rslt_t _cyhal_dma_dmac_connect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input)
978 {
979     if(input != CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT &&
980        input != CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST &&
981        input != CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS)
982         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
983 
984     obj->descriptor_config.dmac.triggerInType = _cyhal_convert_input_t(input);
985 
986     _cyhal_dmac_channel_disable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
987 
988     obj->descriptor.dmac.ctl &= ~_CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Msk;
989     obj->descriptor.dmac.ctl |= _VAL2FLD(_CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE, obj->descriptor_config.dmac.triggerInType);
990 
991     _cyhal_dmac_channel_enable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
992 
993     cyhal_dest_t dest = _cyhal_dma_dmac_get_dest(obj->resource.block_num, obj->resource.channel_num);
994 
995     return _cyhal_connect_signal(source, dest);
996 }
997 
_cyhal_dma_dmac_enable_output(cyhal_dma_t * obj,cyhal_dma_output_t output,cyhal_source_t * source)998 cy_rslt_t _cyhal_dma_dmac_enable_output(cyhal_dma_t *obj, cyhal_dma_output_t output, cyhal_source_t *source)
999 {
1000     if(output != CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT &&
1001        output != CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST &&
1002        output != CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS)
1003         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
1004 
1005     _cyhal_dmac_channel_disable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
1006 
1007     obj->descriptor.dmac.ctl &= ~_CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Msk;
1008     obj->descriptor.dmac.ctl |= _VAL2FLD(_CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE, _cyhal_convert_output_t(output));
1009 
1010     _cyhal_dmac_channel_enable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
1011     *source = _cyhal_dma_dmac_get_src(obj->resource.block_num, obj->resource.channel_num);
1012 
1013     return CY_RSLT_SUCCESS;
1014 }
1015 
_cyhal_dma_dmac_disconnect_digital(cyhal_dma_t * obj,cyhal_source_t source,cyhal_dma_input_t input)1016 cy_rslt_t _cyhal_dma_dmac_disconnect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input)
1017 {
1018     if(input != CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT &&
1019        input != CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST &&
1020        input != CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS)
1021         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
1022 
1023 
1024     // There is no option to totally disable. Just reset to default.
1025     // NOTE: Use .interruptType since it matches the desired .triggerInType from configure(), but
1026     // is not modified by connect/disconnect functions
1027     _cyhal_dmac_channel_disable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
1028 
1029     obj->descriptor.dmac.ctl &= ~_CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE_Msk;
1030     obj->descriptor.dmac.ctl |= _VAL2FLD(_CYHAL_DMAC_CH_DESCR_CTL_TR_IN_TYPE, _cyhal_dma_dmac_default_descriptor_config.interruptType);
1031 
1032     _cyhal_dmac_channel_enable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
1033 
1034     cyhal_dest_t dest = _cyhal_dma_dmac_get_dest(obj->resource.block_num, obj->resource.channel_num);
1035 
1036     return _cyhal_disconnect_signal(source, dest);
1037 }
1038 
_cyhal_dma_dmac_disable_output(cyhal_dma_t * obj,cyhal_dma_output_t output)1039 cy_rslt_t _cyhal_dma_dmac_disable_output(cyhal_dma_t *obj, cyhal_dma_output_t output)
1040 {
1041     if(output != CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT &&
1042        output != CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST &&
1043        output != CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS)
1044         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
1045 
1046     // There is no option to totally disable. Just reset to default.
1047     _cyhal_dmac_channel_disable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
1048 
1049     obj->descriptor.dmac.ctl &= ~_CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE_Msk;
1050     obj->descriptor.dmac.ctl |= _VAL2FLD(_CYHAL_DMAC_CH_DESCR_CTL_TR_OUT_TYPE, _cyhal_dma_dmac_default_descriptor_config.triggerOutType);
1051 
1052     _cyhal_dmac_channel_enable(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num);
1053 
1054     return CY_RSLT_SUCCESS;
1055 
1056 }
1057 #elif defined(CY_IP_M0S8CPUSSV3_DMAC)
1058 
_cyhal_dma_dmac_connect_digital(cyhal_dma_t * obj,cyhal_source_t source,cyhal_dma_input_t input)1059 cy_rslt_t _cyhal_dma_dmac_connect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input)
1060 {
1061     if((input != CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT) &&
1062        (input != CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS))
1063         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
1064 
1065     Cy_DMAC_Channel_SetCurrentDescriptor(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num, obj->descriptor);
1066 
1067     cyhal_dest_t dest = (cyhal_dest_t)(CYHAL_TRIGGER_CPUSS_DMAC0_TR_IN0 + obj->resource.channel_num);
1068 
1069 
1070     return _cyhal_connect_signal(source, dest);
1071 }
1072 
1073 // M0S8 output triggers are always active. This is a noop except to return the source.
_cyhal_dma_dmac_enable_output(cyhal_dma_t * obj,cyhal_dma_output_t output,cyhal_source_t * source)1074 cy_rslt_t _cyhal_dma_dmac_enable_output(cyhal_dma_t *obj, cyhal_dma_output_t output, cyhal_source_t *source)
1075 {
1076     if((output != CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT) &&
1077        (output != CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS))
1078         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
1079 
1080     *source = _cyhal_dma_dmac_get_src(obj->resource.block_num, obj->resource.channel_num);
1081 
1082     return CY_RSLT_SUCCESS;
1083 }
1084 
_cyhal_dma_dmac_disconnect_digital(cyhal_dma_t * obj,cyhal_source_t source,cyhal_dma_input_t input)1085 cy_rslt_t _cyhal_dma_dmac_disconnect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input)
1086 {
1087     if((input != CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT) &&
1088        (input != CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS))
1089         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
1090 
1091     // Reset to default
1092     Cy_DMAC_Channel_SetCurrentDescriptor(_cyhal_dma_dmac_get_base(obj->resource.block_num), obj->resource.channel_num, obj->descriptor);
1093 
1094     cyhal_dest_t dest = (cyhal_dest_t)(CYHAL_TRIGGER_CPUSS_DMAC0_TR_IN0 + obj->resource.channel_num);
1095 
1096     return _cyhal_disconnect_signal(source, dest);
1097 }
1098 
1099 // M0S8 output triggers are always active. This is a noop.
_cyhal_dma_dmac_disable_output(cyhal_dma_t * obj,cyhal_dma_output_t output)1100 cy_rslt_t _cyhal_dma_dmac_disable_output(cyhal_dma_t *obj, cyhal_dma_output_t output)
1101 {
1102     CY_UNUSED_PARAMETER(obj);
1103 
1104     if((output != CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT) &&
1105        (output != CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS))
1106         return CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER;
1107 
1108     return CY_RSLT_SUCCESS;
1109 }
1110 
1111 #endif /* defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC) */
1112 
1113 #endif /* (_CYHAL_DRIVER_AVAILABLE_DMA_DMAC) */
1114 
1115 #if defined(__cplusplus)
1116 }
1117 #endif
1118