• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <string.h>
9 #include "hpm_dma_mgr.h"
10 #include "hpm_soc.h"
11 
12 /*****************************************************************************************************************
13  *
14  *  Definitions
15  *
16  *****************************************************************************************************************/
17 
18 typedef struct _dma_instance_info {
19     DMA_Type *base;
20     int32_t irq_num;
21 } dma_chn_info_t;
22 
23 /**
24  * @brief DMA Channel Context Structure
25  */
26 typedef struct _dma_channel_context {
27     bool is_allocated;                               /**< Whether DMA channel was allocated */
28     void *tc_cb_data_ptr;                            /**< User data required by transfer complete callback */
29     void *half_tc_cb_data_ptr;                       /**< User data required by half transfer complete callback */
30     void *error_cb_data_ptr;                         /**< User data required by error callback */
31     void *abort_cb_data_ptr;                         /**< User data required by abort callback */
32     dma_mgr_chn_cb_t tc_cb;                          /**< DMA channel transfer complete callback */
33     dma_mgr_chn_cb_t half_tc_cb;                     /**< DMA channel half transfer complete callback */
34     dma_mgr_chn_cb_t error_cb;                       /**< DMA channel error callback */
35     dma_mgr_chn_cb_t abort_cb;                       /**< DMA channel abort callback */
36 } dma_chn_context_t;
37 
38 /**
39  * @brief DMA Manager Context Structure
40  *
41  */
42 typedef struct _dma_mgr_context {
43     dma_chn_info_t dma_instance[DMA_SOC_MAX_COUNT];                                  /**< DMA instances */
44     dma_chn_context_t channels[DMA_SOC_MAX_COUNT][DMA_SOC_CHANNEL_NUM];              /**< Array of DMA channels */
45 } dma_mgr_context_t;
46 
47 
48 /*****************************************************************************************************************
49  *
50  *  Prototypes
51  *
52  *****************************************************************************************************************/
53 
54 /**
55  * @brief Search DMA channel context for specified DMA channel resource
56  *
57  * @param [in] resource DMA Channel resource
58  * @return The request DMA channel context if resource is valid or NULL if resource in invalid
59  */
60 static dma_chn_context_t *dma_mgr_search_chn_context(const dma_resource_t *resource);
61 
62 static uint32_t dma_mgr_enter_critical(void);
63 static void dma_mgr_exit_critical(uint32_t level);
64 
65 static void dma0_isr(void);
66 SDK_DECLARE_EXT_ISR_M(IRQn_HDMA, dma0_isr);
67 
68 #if defined(DMA_SOC_MAX_COUNT) && (DMA_SOC_MAX_COUNT > 1)
69 static void dma1_isr(void);
70 SDK_DECLARE_EXT_ISR_M(IRQn_XDMA, dma1_isr);
71 #endif
72 
73 /*****************************************************************************************************************
74  *
75  *  Variables
76  *
77  *****************************************************************************************************************/
78 static dma_mgr_context_t s_dma_mngr_ctx;
79 #define HPM_DMA_MGR (&s_dma_mngr_ctx)
80 
81 /*****************************************************************************************************************
82  *
83  *  Codes
84  *
85  *****************************************************************************************************************/
handle_dma_isr(DMA_Type * ptr,uint32_t instance)86 static inline void handle_dma_isr(DMA_Type *ptr, uint32_t instance)
87 {
88     uint32_t int_disable_mask;
89     uint32_t chn_int_stat;
90     dma_chn_context_t *chn_ctx;
91 
92     for (uint8_t channel = 0; channel < DMA_SOC_CHANNEL_NUM; channel++) {
93         int_disable_mask = dma_check_channel_interrupt_mask(ptr, channel);
94         chn_int_stat = dma_check_transfer_status(ptr, channel);
95         chn_ctx = &HPM_DMA_MGR->channels[instance][channel];
96 
97         if (((int_disable_mask & DMA_MGR_INTERRUPT_MASK_TC) == 0) && ((chn_int_stat & DMA_MGR_CHANNEL_STATUS_TC) != 0)) {
98             if (chn_ctx->tc_cb != NULL) {
99                 chn_ctx->tc_cb(ptr, channel, chn_ctx->tc_cb_data_ptr);
100             }
101         }
102         if (((int_disable_mask & DMA_MGR_INTERRUPT_MASK_HALF_TC) == 0) && ((chn_int_stat & DMA_MGR_CHANNEL_STATUS_HALF_TC) != 0)) {
103             if (chn_ctx->half_tc_cb != NULL) {
104                 chn_ctx->half_tc_cb(ptr, channel, chn_ctx->half_tc_cb_data_ptr);
105             }
106         }
107         if (((int_disable_mask & DMA_MGR_INTERRUPT_MASK_ERROR) == 0) && ((chn_int_stat & DMA_MGR_CHANNEL_STATUS_ERROR) != 0)) {
108             if (chn_ctx->error_cb != NULL) {
109                 chn_ctx->error_cb(ptr, channel, chn_ctx->error_cb_data_ptr);
110             }
111         }
112         if (((int_disable_mask & DMA_MGR_INTERRUPT_MASK_ABORT) == 0) && ((chn_int_stat & DMA_MGR_CHANNEL_STATUS_ABORT) != 0)) {
113             if (chn_ctx->abort_cb != NULL) {
114                 chn_ctx->abort_cb(ptr, channel, chn_ctx->abort_cb_data_ptr);
115             }
116         }
117     }
118 }
119 
dma0_isr(void)120 void dma0_isr(void)
121 {
122     handle_dma_isr(HPM_HDMA, 0);
123 }
124 
125 #if defined(DMA_SOC_MAX_COUNT) && (DMA_SOC_MAX_COUNT > 1)
dma1_isr(void)126 void dma1_isr(void)
127 {
128     handle_dma_isr(HPM_XDMA, 1);
129 }
130 #endif
131 
dma_mgr_enter_critical(void)132 static uint32_t dma_mgr_enter_critical(void)
133 {
134     return disable_global_irq(CSR_MSTATUS_MIE_MASK);
135 }
136 
dma_mgr_exit_critical(uint32_t level)137 static void dma_mgr_exit_critical(uint32_t level)
138 {
139     restore_global_irq(level);
140 }
141 
dma_mgr_init(void)142 void dma_mgr_init(void)
143 {
144     (void) memset(HPM_DMA_MGR, 0, sizeof(*HPM_DMA_MGR));
145     HPM_DMA_MGR->dma_instance[0].base = HPM_HDMA,
146     HPM_DMA_MGR->dma_instance[0].irq_num = IRQn_HDMA;
147  #if defined(DMA_SOC_MAX_COUNT) && (DMA_SOC_MAX_COUNT > 1)
148     HPM_DMA_MGR->dma_instance[1].base = HPM_XDMA;
149     HPM_DMA_MGR->dma_instance[1].irq_num = IRQn_XDMA;
150  #endif
151 }
152 
dma_mgr_request_resource(dma_resource_t * resource)153 hpm_stat_t dma_mgr_request_resource(dma_resource_t *resource)
154 {
155     hpm_stat_t status;
156 
157     if (resource == NULL) {
158         status = status_invalid_argument;
159     } else {
160         uint32_t instance;
161         uint32_t channel;
162         bool has_found = false;
163         uint32_t level = dma_mgr_enter_critical();
164         for (instance = 0; instance < DMA_SOC_MAX_COUNT; instance++) {
165             for (channel = 0; channel < DMA_SOC_CHANNEL_NUM; channel++) {
166                 if (!HPM_DMA_MGR->channels[instance][channel].is_allocated) {
167                     has_found = true;
168                     break;
169                 }
170             }
171             if (has_found) {
172                 break;
173             }
174         }
175 
176         if (has_found) {
177             HPM_DMA_MGR->channels[instance][channel].is_allocated = true;
178             resource->base = HPM_DMA_MGR->dma_instance[instance].base;
179             resource->channel = channel;
180             resource->irq_num = HPM_DMA_MGR->dma_instance[instance].irq_num;
181             status = status_success;
182         } else {
183             status = status_dma_mgr_no_resource;
184         }
185 
186         dma_mgr_exit_critical(level);
187     }
188 
189     return status;
190 }
191 
dma_mgr_search_chn_context(const dma_resource_t * resource)192 static dma_chn_context_t *dma_mgr_search_chn_context(const dma_resource_t *resource)
193 {
194     dma_chn_context_t *chn_ctx = NULL;
195 
196     if ((resource != NULL) && (resource->channel < DMA_SOC_CHANNEL_NUM)) {
197         uint32_t instance;
198         uint32_t channel;
199         bool has_found = false;
200         for (instance = 0; instance < DMA_SOC_MAX_COUNT; instance++) {
201             if (resource->base == HPM_DMA_MGR->dma_instance[instance].base) {
202                 has_found = true;
203                 break;
204             }
205         }
206 
207         channel = resource->channel;
208         if (has_found) {
209             if (HPM_DMA_MGR->channels[instance][channel].is_allocated) {
210                 chn_ctx = &HPM_DMA_MGR->channels[instance][channel];
211             }
212         }
213     }
214 
215     return chn_ctx;
216 }
217 
dma_mgr_release_resource(const dma_resource_t * resource)218 hpm_stat_t dma_mgr_release_resource(const dma_resource_t *resource)
219 {
220     hpm_stat_t status;
221 
222     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
223 
224     if (chn_ctx == NULL) {
225         status = status_invalid_argument;
226     } else {
227         uint32_t level = dma_mgr_enter_critical();
228         chn_ctx->is_allocated = false;
229         chn_ctx->tc_cb_data_ptr = NULL;
230         chn_ctx->half_tc_cb_data_ptr = NULL;
231         chn_ctx->error_cb_data_ptr = NULL;
232         chn_ctx->abort_cb_data_ptr = NULL;
233         chn_ctx->tc_cb = NULL;
234         chn_ctx->half_tc_cb = NULL;
235         chn_ctx->error_cb = NULL;
236         chn_ctx->abort_cb = NULL;
237         status = status_success;
238         dma_mgr_exit_critical(level);
239     }
240     return status;
241 }
242 
dma_mgr_enable_dma_irq_with_priority(const dma_resource_t * resource,uint32_t priority)243 hpm_stat_t dma_mgr_enable_dma_irq_with_priority(const dma_resource_t *resource, uint32_t priority)
244 {
245     hpm_stat_t status;
246 
247     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
248 
249     if (chn_ctx == NULL) {
250         status = status_invalid_argument;
251     } else {
252         intc_m_enable_irq_with_priority(resource->irq_num, priority);
253         status = status_success;
254     }
255     return status;
256 }
257 
dma_mgr_disable_dma_irq(const dma_resource_t * resource)258 hpm_stat_t dma_mgr_disable_dma_irq(const dma_resource_t *resource)
259 {
260     hpm_stat_t status;
261 
262     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
263 
264     if (chn_ctx == NULL) {
265         status = status_invalid_argument;
266     } else {
267         intc_m_disable_irq(resource->irq_num);
268         status = status_success;
269     }
270     return status;
271 }
272 
dma_mgr_install_chn_tc_callback(const dma_resource_t * resource,dma_mgr_chn_cb_t callback,void * user_data)273 hpm_stat_t dma_mgr_install_chn_tc_callback(const dma_resource_t *resource, dma_mgr_chn_cb_t callback, void *user_data)
274 {
275     hpm_stat_t status;
276 
277     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
278 
279     if (chn_ctx == NULL) {
280         status = status_invalid_argument;
281     } else {
282         chn_ctx->tc_cb_data_ptr = user_data;
283         chn_ctx->tc_cb = callback;
284         status = status_success;
285     }
286     return status;
287 }
288 
dma_mgr_install_chn_half_tc_callback(const dma_resource_t * resource,dma_mgr_chn_cb_t callback,void * user_data)289 hpm_stat_t dma_mgr_install_chn_half_tc_callback(const dma_resource_t *resource, dma_mgr_chn_cb_t callback, void *user_data)
290 {
291     hpm_stat_t status;
292 
293     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
294 
295     if (chn_ctx == NULL) {
296         status = status_invalid_argument;
297     } else {
298         chn_ctx->half_tc_cb_data_ptr = user_data;
299         chn_ctx->half_tc_cb = callback;
300         status = status_success;
301     }
302     return status;
303 }
304 
dma_mgr_install_chn_error_callback(const dma_resource_t * resource,dma_mgr_chn_cb_t callback,void * user_data)305 hpm_stat_t dma_mgr_install_chn_error_callback(const dma_resource_t *resource, dma_mgr_chn_cb_t callback, void *user_data)
306 {
307     hpm_stat_t status;
308 
309     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
310 
311     if (chn_ctx == NULL) {
312         status = status_invalid_argument;
313     } else {
314         chn_ctx->error_cb_data_ptr = user_data;
315         chn_ctx->error_cb = callback;
316         status = status_success;
317     }
318     return status;
319 }
320 
dma_mgr_install_chn_abort_callback(const dma_resource_t * resource,dma_mgr_chn_cb_t callback,void * user_data)321 hpm_stat_t dma_mgr_install_chn_abort_callback(const dma_resource_t *resource, dma_mgr_chn_cb_t callback, void *user_data)
322 {
323     hpm_stat_t status;
324 
325     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
326 
327     if (chn_ctx == NULL) {
328         status = status_invalid_argument;
329     } else {
330         chn_ctx->abort_cb_data_ptr = user_data;
331         chn_ctx->abort_cb = callback;
332         status = status_success;
333     }
334     return status;
335 }
336 
dma_mgr_get_default_chn_config(dma_mgr_chn_conf_t * config)337 void dma_mgr_get_default_chn_config(dma_mgr_chn_conf_t *config)
338 {
339     config->en_dmamux = false;
340     config->dmamux_src = 0;
341     config->priority = DMA_MGR_CHANNEL_PRIORITY_LOW;
342     config->src_burst_size = DMA_MGR_NUM_TRANSFER_PER_BURST_1T;
343     config->src_mode = DMA_MGR_HANDSHAKE_MODE_NORMAL;
344     config->dst_mode = DMA_MGR_HANDSHAKE_MODE_NORMAL;
345     config->src_width = DMA_MGR_TRANSFER_WIDTH_BYTE;
346     config->dst_width = DMA_MGR_TRANSFER_WIDTH_BYTE;
347     config->src_addr_ctrl = DMA_MGR_ADDRESS_CONTROL_INCREMENT;
348     config->dst_addr_ctrl = DMA_MGR_ADDRESS_CONTROL_INCREMENT;
349     config->src_addr = 0;
350     config->dst_addr = 0;
351     config->size_in_byte = 0;
352     config->linked_ptr = 0;
353     config->interrupt_mask = DMA_MGR_INTERRUPT_MASK_ALL;
354     config->en_infiniteloop = false;
355     config->handshake_opt = DMA_MGR_HANDSHAKE_OPT_ONE_BURST;
356     config->burst_opt = DMA_MGR_SRC_BURST_OPT_STANDAND_SIZE;
357 }
358 
dma_mgr_setup_channel(const dma_resource_t * resource,dma_mgr_chn_conf_t * config)359 hpm_stat_t dma_mgr_setup_channel(const dma_resource_t *resource, dma_mgr_chn_conf_t *config)
360 {
361     hpm_stat_t status;
362     uint32_t dmamux_ch;
363     dma_channel_config_t dma_config;
364 
365     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
366 
367     if (chn_ctx == NULL) {
368         status = status_invalid_argument;
369     } else {
370         dmamux_ch = DMA_SOC_CHN_TO_DMAMUX_CHN(resource->base, resource->channel);
371         dmamux_config(HPM_DMAMUX, dmamux_ch, config->dmamux_src, config->en_dmamux);
372         dma_config.priority = config->priority;
373         dma_config.src_burst_size = config->src_burst_size;
374         dma_config.src_mode = config->src_mode;
375         dma_config.dst_mode = config->dst_mode;
376         dma_config.src_width = config->src_width;
377         dma_config.dst_width = config->dst_width;
378         dma_config.src_addr_ctrl = config->src_addr_ctrl;
379         dma_config.dst_addr_ctrl = config->dst_addr_ctrl;
380         dma_config.src_addr = config->src_addr;
381         dma_config.dst_addr = config->dst_addr;
382         dma_config.size_in_byte = config->size_in_byte;
383         dma_config.linked_ptr = config->linked_ptr;
384         dma_config.interrupt_mask = config->interrupt_mask;
385 #ifdef DMA_MGR_HAS_INFINITE_LOOP
386         dma_config.en_infiniteloop = config->en_infiniteloop;
387 #endif
388 #ifdef DMA_MGR_HAS_HANDSHAKE_OPT
389         dma_config.handshake_opt = config->handshake_opt;
390 #endif
391 #ifdef DMA_MGR_HAS_BURST_OPT
392         dma_config.burst_opt = config->burst_opt;
393 #endif
394         status = dma_setup_channel(resource->base, resource->channel, &dma_config, false);
395     }
396     return status;
397 }
398 
dma_mgr_config_linked_descriptor(const dma_resource_t * resource,dma_mgr_chn_conf_t * config,dma_mgr_linked_descriptor_t * descriptor)399 hpm_stat_t dma_mgr_config_linked_descriptor(const dma_resource_t *resource, dma_mgr_chn_conf_t *config, dma_mgr_linked_descriptor_t *descriptor)
400 {
401     hpm_stat_t status;
402     dma_channel_config_t dma_config;
403 
404     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
405 
406     if (chn_ctx == NULL) {
407         status = status_invalid_argument;
408     } else {
409         dma_config.priority = config->priority;
410         dma_config.src_burst_size = config->src_burst_size;
411         dma_config.src_mode = config->src_mode;
412         dma_config.dst_mode = config->dst_mode;
413         dma_config.src_width = config->src_width;
414         dma_config.dst_width = config->dst_width;
415         dma_config.src_addr_ctrl = config->src_addr_ctrl;
416         dma_config.dst_addr_ctrl = config->dst_addr_ctrl;
417         dma_config.src_addr = config->src_addr;
418         dma_config.dst_addr = config->dst_addr;
419         dma_config.size_in_byte = config->size_in_byte;
420         dma_config.linked_ptr = config->linked_ptr;
421         dma_config.interrupt_mask = config->interrupt_mask;
422 #ifdef DMA_MGR_HAS_INFINITE_LOOP
423         dma_config.en_infiniteloop = config->en_infiniteloop;
424 #endif
425 #ifdef DMA_MGR_HAS_HANDSHAKE_OPT
426         dma_config.handshake_opt = config->handshake_opt;
427 #endif
428 #ifdef DMA_MGR_HAS_BURST_OPT
429         dma_config.burst_opt = config->burst_opt;
430 #endif
431         status = dma_config_linked_descriptor(resource->base, (dma_linked_descriptor_t *)descriptor, resource->channel, &dma_config);
432     }
433     return status;
434 }
435 
dma_mgr_enable_channel(const dma_resource_t * resource)436 hpm_stat_t dma_mgr_enable_channel(const dma_resource_t *resource)
437 {
438     hpm_stat_t status;
439 
440     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
441 
442     if (chn_ctx == NULL) {
443         status = status_invalid_argument;
444     } else {
445         status = dma_enable_channel(resource->base, resource->channel);
446     }
447     return status;
448 }
449 
dma_mgr_disable_channel(const dma_resource_t * resource)450 hpm_stat_t dma_mgr_disable_channel(const dma_resource_t *resource)
451 {
452     hpm_stat_t status;
453 
454     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
455 
456     if (chn_ctx == NULL) {
457         status = status_invalid_argument;
458     } else {
459         dma_disable_channel(resource->base, resource->channel);
460         status = status_success;
461     }
462     return status;
463 }
464 
dma_mgr_check_chn_enable(const dma_resource_t * resource,bool * enable)465 hpm_stat_t dma_mgr_check_chn_enable(const dma_resource_t *resource, bool *enable)
466 {
467     hpm_stat_t status;
468 
469     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
470 
471     if (chn_ctx == NULL) {
472         status = status_invalid_argument;
473     } else {
474         *enable = dma_channel_is_enable(resource->base, resource->channel);
475         status = status_success;
476     }
477     return status;
478 }
479 
dma_mgr_enable_chn_irq(const dma_resource_t * resource,uint32_t irq_mask)480 hpm_stat_t dma_mgr_enable_chn_irq(const dma_resource_t *resource, uint32_t irq_mask)
481 {
482     hpm_stat_t status;
483 
484     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
485 
486     if (chn_ctx == NULL) {
487         status = status_invalid_argument;
488     } else {
489         dma_enable_channel_interrupt(resource->base, resource->channel, irq_mask);
490         status = status_success;
491     }
492     return status;
493 }
494 
dma_mgr_disable_chn_irq(const dma_resource_t * resource,uint32_t irq_mask)495 hpm_stat_t dma_mgr_disable_chn_irq(const dma_resource_t *resource, uint32_t irq_mask)
496 {
497     hpm_stat_t status;
498 
499     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
500 
501     if (chn_ctx == NULL) {
502         status = status_invalid_argument;
503     } else {
504         dma_disable_channel_interrupt(resource->base, resource->channel, irq_mask);
505         status = status_success;
506     }
507     return status;
508 }
509 
dma_mgr_set_chn_priority(const dma_resource_t * resource,uint8_t priority)510 hpm_stat_t dma_mgr_set_chn_priority(const dma_resource_t *resource, uint8_t priority)
511 {
512     hpm_stat_t status;
513 
514     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
515 
516     if (chn_ctx == NULL) {
517         status = status_invalid_argument;
518     } else {
519         dma_set_priority(resource->base, resource->channel, priority);
520         status = status_success;
521     }
522     return status;
523 }
524 
dma_mgr_set_chn_src_work_mode(const dma_resource_t * resource,uint8_t mode)525 hpm_stat_t dma_mgr_set_chn_src_work_mode(const dma_resource_t *resource, uint8_t mode)
526 {
527     hpm_stat_t status;
528 
529     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
530 
531     if (chn_ctx == NULL) {
532         status = status_invalid_argument;
533     } else {
534         dma_set_source_work_mode(resource->base, resource->channel, mode);
535         status = status_success;
536     }
537     return status;
538 }
539 
dma_mgr_set_chn_dst_work_mode(const dma_resource_t * resource,uint8_t mode)540 hpm_stat_t dma_mgr_set_chn_dst_work_mode(const dma_resource_t *resource, uint8_t mode)
541 {
542     hpm_stat_t status;
543 
544     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
545 
546     if (chn_ctx == NULL) {
547         status = status_invalid_argument;
548     } else {
549         dma_set_destination_work_mode(resource->base, resource->channel, mode);
550         status = status_success;
551     }
552     return status;
553 }
554 
dma_mgr_set_chn_src_burst_size(const dma_resource_t * resource,uint8_t burstsize)555 hpm_stat_t dma_mgr_set_chn_src_burst_size(const dma_resource_t *resource, uint8_t burstsize)
556 {
557     hpm_stat_t status;
558 
559     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
560 
561     if (chn_ctx == NULL) {
562         status = status_invalid_argument;
563     } else {
564         dma_set_source_burst_size(resource->base, resource->channel, burstsize);
565         status = status_success;
566     }
567     return status;
568 }
569 
dma_mgr_get_chn_remaining_transize(const dma_resource_t * resource,uint32_t * size)570 hpm_stat_t dma_mgr_get_chn_remaining_transize(const dma_resource_t *resource, uint32_t *size)
571 {
572     hpm_stat_t status;
573 
574     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
575 
576     if (chn_ctx == NULL) {
577         status = status_invalid_argument;
578     } else {
579         *size = dma_get_remaining_transfer_size(resource->base, resource->channel);
580         status = status_success;
581     }
582     return status;
583 }
584 
dma_mgr_set_chn_transize(const dma_resource_t * resource,uint32_t size)585 hpm_stat_t dma_mgr_set_chn_transize(const dma_resource_t *resource, uint32_t size)
586 {
587     hpm_stat_t status;
588 
589     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
590 
591     if (chn_ctx == NULL) {
592         status = status_invalid_argument;
593     } else {
594         dma_set_transfer_size(resource->base, resource->channel, size);
595         status = status_success;
596     }
597     return status;
598 }
599 
dma_mgr_set_chn_src_width(const dma_resource_t * resource,uint8_t width)600 hpm_stat_t dma_mgr_set_chn_src_width(const dma_resource_t *resource, uint8_t width)
601 {
602     hpm_stat_t status;
603 
604     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
605 
606     if (chn_ctx == NULL) {
607         status = status_invalid_argument;
608     } else {
609         dma_set_source_width(resource->base, resource->channel, width);
610         status = status_success;
611     }
612     return status;
613 }
614 
dma_mgr_set_chn_dst_width(const dma_resource_t * resource,uint8_t width)615 hpm_stat_t dma_mgr_set_chn_dst_width(const dma_resource_t *resource, uint8_t width)
616 {
617     hpm_stat_t status;
618 
619     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
620 
621     if (chn_ctx == NULL) {
622         status = status_invalid_argument;
623     } else {
624         dma_set_destination_width(resource->base, resource->channel, width);
625         status = status_success;
626     }
627     return status;
628 }
629 
dma_mgr_set_chn_src_addr(const dma_resource_t * resource,uint32_t addr)630 hpm_stat_t dma_mgr_set_chn_src_addr(const dma_resource_t *resource, uint32_t addr)
631 {
632     hpm_stat_t status;
633 
634     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
635 
636     if (chn_ctx == NULL) {
637         status = status_invalid_argument;
638     } else {
639         dma_set_source_address(resource->base, resource->channel, addr);
640         status = status_success;
641     }
642     return status;
643 }
644 
dma_mgr_set_chn_dst_addr(const dma_resource_t * resource,uint32_t addr)645 hpm_stat_t dma_mgr_set_chn_dst_addr(const dma_resource_t *resource, uint32_t addr)
646 {
647     hpm_stat_t status;
648 
649     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
650 
651     if (chn_ctx == NULL) {
652         status = status_invalid_argument;
653     } else {
654         dma_set_destination_address(resource->base, resource->channel, addr);
655         status = status_success;
656     }
657     return status;
658 }
659 
dma_mgr_set_chn_src_addr_ctrl(const dma_resource_t * resource,uint8_t addr_ctrl)660 hpm_stat_t dma_mgr_set_chn_src_addr_ctrl(const dma_resource_t *resource, uint8_t addr_ctrl)
661 {
662     hpm_stat_t status;
663 
664     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
665 
666     if (chn_ctx == NULL) {
667         status = status_invalid_argument;
668     } else {
669         dma_set_source_address_ctrl(resource->base, resource->channel, addr_ctrl);
670         status = status_success;
671     }
672     return status;
673 }
674 
dma_mgr_set_chn_dst_addr_ctrl(const dma_resource_t * resource,uint8_t addr_ctrl)675 hpm_stat_t dma_mgr_set_chn_dst_addr_ctrl(const dma_resource_t *resource, uint8_t addr_ctrl)
676 {
677     hpm_stat_t status;
678 
679     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
680 
681     if (chn_ctx == NULL) {
682         status = status_invalid_argument;
683     } else {
684         dma_set_destination_address_ctrl(resource->base, resource->channel, addr_ctrl);
685         status = status_success;
686     }
687     return status;
688 }
689 
dma_mgr_set_chn_infinite_loop_mode(const dma_resource_t * resource,bool infinite_loop)690 hpm_stat_t dma_mgr_set_chn_infinite_loop_mode(const dma_resource_t *resource, bool infinite_loop)
691 {
692     hpm_stat_t status;
693 
694     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
695 
696     if (chn_ctx == NULL) {
697         status = status_invalid_argument;
698     } else {
699 #ifdef DMA_MGR_HAS_INFINITE_LOOP
700         dma_set_infinite_loop_mode(resource->base, resource->channel, infinite_loop);
701         status = status_success;
702 #else
703         (void)infinite_loop;
704         status = status_fail;
705 #endif
706     }
707     return status;
708 }
709 
dma_mgr_set_chn_src_busrt_option(const dma_resource_t * resource,uint8_t burst_opt)710 hpm_stat_t dma_mgr_set_chn_src_busrt_option(const dma_resource_t *resource, uint8_t burst_opt)
711 {
712     hpm_stat_t status;
713 
714     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
715 
716     if (chn_ctx == NULL) {
717         status = status_invalid_argument;
718     } else {
719 #ifdef DMA_MGR_HAS_BURST_OPT
720         dma_set_src_busrt_option(resource->base, resource->channel, burst_opt);
721         status = status_success;
722 #else
723         (void)burst_opt;
724         status = status_fail;
725 #endif
726     }
727     return status;
728 }
729 
dma_mgr_set_chn_handshake_option(const dma_resource_t * resource,uint8_t handshake_opt)730 hpm_stat_t dma_mgr_set_chn_handshake_option(const dma_resource_t *resource, uint8_t handshake_opt)
731 {
732     hpm_stat_t status;
733 
734     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
735 
736     if (chn_ctx == NULL) {
737         status = status_invalid_argument;
738     } else {
739 #ifdef DMA_MGR_HAS_HANDSHAKE_OPT
740         dma_set_handshake_option(resource->base, resource->channel, handshake_opt);
741         status = status_success;
742 #else
743         (void)handshake_opt;
744         status = status_fail;
745 #endif
746     }
747     return status;
748 }
749 
dma_mgr_abort_chn_transfer(const dma_resource_t * resource)750 hpm_stat_t dma_mgr_abort_chn_transfer(const dma_resource_t *resource)
751 {
752     hpm_stat_t status;
753 
754     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
755 
756     if (chn_ctx == NULL) {
757         status = status_invalid_argument;
758     } else {
759         dma_abort_channel(resource->base, 1u << resource->channel);
760         status = status_success;
761     }
762     return status;
763 }
764 
dma_mgr_check_chn_transfer_status(const dma_resource_t * resource,uint32_t * status)765 hpm_stat_t dma_mgr_check_chn_transfer_status(const dma_resource_t *resource, uint32_t *status)
766 {
767     hpm_stat_t stat;
768 
769     dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
770 
771     if (chn_ctx == NULL) {
772         stat = status_invalid_argument;
773     } else {
774         *status = dma_check_transfer_status(resource->base, resource->channel);
775         stat = status_success;
776     }
777     return stat;
778 }
779