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