1 /*
2 * Copyright (c) 2022-2024 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 *****************************************************************************************************************/
dma_mgr_isr_handler(DMA_Type * ptr,uint32_t instance)86 void dma_mgr_isr_handler(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 dma_mgr_isr_handler(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 dma_mgr_isr_handler(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 config->en_src_burst_in_fixed_trans = false;
358 config->en_dst_burst_in_fixed_trans = false;
359 config->swap_mode = DMA_MGR_SWAP_MODE_TABLE;
360 config->swap_table = 0;
361 }
362
dma_mgr_setup_channel(const dma_resource_t * resource,dma_mgr_chn_conf_t * config)363 hpm_stat_t dma_mgr_setup_channel(const dma_resource_t *resource, dma_mgr_chn_conf_t *config)
364 {
365 hpm_stat_t status;
366 uint32_t dmamux_ch;
367 dma_channel_config_t dma_config;
368
369 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
370
371 if (chn_ctx == NULL) {
372 status = status_invalid_argument;
373 } else {
374 dmamux_ch = DMA_SOC_CHN_TO_DMAMUX_CHN(resource->base, resource->channel);
375 dmamux_config(HPM_DMAMUX, dmamux_ch, config->dmamux_src, config->en_dmamux);
376 dma_config.priority = config->priority;
377 dma_config.src_burst_size = config->src_burst_size;
378 dma_config.src_mode = config->src_mode;
379 dma_config.dst_mode = config->dst_mode;
380 dma_config.src_width = config->src_width;
381 dma_config.dst_width = config->dst_width;
382 dma_config.src_addr_ctrl = config->src_addr_ctrl;
383 dma_config.dst_addr_ctrl = config->dst_addr_ctrl;
384 dma_config.src_addr = config->src_addr;
385 dma_config.dst_addr = config->dst_addr;
386 dma_config.size_in_byte = config->size_in_byte;
387 dma_config.linked_ptr = config->linked_ptr;
388 dma_config.interrupt_mask = config->interrupt_mask;
389 #if defined(DMA_MGR_HAS_INFINITE_LOOP) && DMA_MGR_HAS_INFINITE_LOOP
390 dma_config.en_infiniteloop = config->en_infiniteloop;
391 #endif
392 #if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
393 dma_config.handshake_opt = config->handshake_opt;
394 #endif
395 #if defined(DMA_MGR_HAS_BURST_OPT) && DMA_MGR_HAS_BURST_OPT
396 dma_config.burst_opt = config->burst_opt;
397 #endif
398 #if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
399 dma_config.en_src_burst_in_fixed_trans = config->en_src_burst_in_fixed_trans;
400 dma_config.en_dst_burst_in_fixed_trans = config->en_dst_burst_in_fixed_trans;
401 #endif
402 #if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
403 dma_config.swap_mode = config->swap_mode;
404 dma_config.swap_table = config->swap_table;
405 #endif
406 status = dma_setup_channel(resource->base, resource->channel, &dma_config, false);
407 }
408 return status;
409 }
410
dma_mgr_config_linked_descriptor(const dma_resource_t * resource,dma_mgr_chn_conf_t * config,dma_mgr_linked_descriptor_t * descriptor)411 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)
412 {
413 hpm_stat_t status;
414 dma_channel_config_t dma_config;
415
416 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
417
418 if (chn_ctx == NULL) {
419 status = status_invalid_argument;
420 } else {
421 dma_config.priority = config->priority;
422 dma_config.src_burst_size = config->src_burst_size;
423 dma_config.src_mode = config->src_mode;
424 dma_config.dst_mode = config->dst_mode;
425 dma_config.src_width = config->src_width;
426 dma_config.dst_width = config->dst_width;
427 dma_config.src_addr_ctrl = config->src_addr_ctrl;
428 dma_config.dst_addr_ctrl = config->dst_addr_ctrl;
429 dma_config.src_addr = config->src_addr;
430 dma_config.dst_addr = config->dst_addr;
431 dma_config.size_in_byte = config->size_in_byte;
432 dma_config.linked_ptr = config->linked_ptr;
433 dma_config.interrupt_mask = config->interrupt_mask;
434 #if defined(DMA_MGR_HAS_INFINITE_LOOP) && DMA_MGR_HAS_INFINITE_LOOP
435 dma_config.en_infiniteloop = config->en_infiniteloop;
436 #endif
437 #if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
438 dma_config.handshake_opt = config->handshake_opt;
439 #endif
440 #if defined(DMA_MGR_HAS_BURST_OPT) && DMA_MGR_HAS_BURST_OPT
441 dma_config.burst_opt = config->burst_opt;
442 #endif
443 #if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
444 dma_config.en_src_burst_in_fixed_trans = config->en_src_burst_in_fixed_trans;
445 dma_config.en_dst_burst_in_fixed_trans = config->en_dst_burst_in_fixed_trans;
446 #endif
447 #if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
448 dma_config.swap_mode = config->swap_mode;
449 dma_config.swap_table = config->swap_table;
450 #endif
451 status = dma_config_linked_descriptor(resource->base, (dma_linked_descriptor_t *)descriptor, resource->channel, &dma_config);
452 }
453 return status;
454 }
455
dma_mgr_enable_channel(const dma_resource_t * resource)456 hpm_stat_t dma_mgr_enable_channel(const dma_resource_t *resource)
457 {
458 hpm_stat_t status;
459
460 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
461
462 if (chn_ctx == NULL) {
463 status = status_invalid_argument;
464 } else {
465 status = dma_enable_channel(resource->base, resource->channel);
466 }
467 return status;
468 }
469
dma_mgr_disable_channel(const dma_resource_t * resource)470 hpm_stat_t dma_mgr_disable_channel(const dma_resource_t *resource)
471 {
472 hpm_stat_t status;
473
474 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
475
476 if (chn_ctx == NULL) {
477 status = status_invalid_argument;
478 } else {
479 dma_disable_channel(resource->base, resource->channel);
480 status = status_success;
481 }
482 return status;
483 }
484
dma_mgr_check_chn_enable(const dma_resource_t * resource,bool * enable)485 hpm_stat_t dma_mgr_check_chn_enable(const dma_resource_t *resource, bool *enable)
486 {
487 hpm_stat_t status;
488
489 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
490
491 if (chn_ctx == NULL) {
492 status = status_invalid_argument;
493 } else {
494 *enable = dma_channel_is_enable(resource->base, resource->channel);
495 status = status_success;
496 }
497 return status;
498 }
499
dma_mgr_enable_chn_irq(const dma_resource_t * resource,uint32_t irq_mask)500 hpm_stat_t dma_mgr_enable_chn_irq(const dma_resource_t *resource, uint32_t irq_mask)
501 {
502 hpm_stat_t status;
503
504 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
505
506 if (chn_ctx == NULL) {
507 status = status_invalid_argument;
508 } else {
509 dma_enable_channel_interrupt(resource->base, resource->channel, irq_mask);
510 status = status_success;
511 }
512 return status;
513 }
514
dma_mgr_disable_chn_irq(const dma_resource_t * resource,uint32_t irq_mask)515 hpm_stat_t dma_mgr_disable_chn_irq(const dma_resource_t *resource, uint32_t irq_mask)
516 {
517 hpm_stat_t status;
518
519 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
520
521 if (chn_ctx == NULL) {
522 status = status_invalid_argument;
523 } else {
524 dma_disable_channel_interrupt(resource->base, resource->channel, irq_mask);
525 status = status_success;
526 }
527 return status;
528 }
529
dma_mgr_set_chn_priority(const dma_resource_t * resource,uint8_t priority)530 hpm_stat_t dma_mgr_set_chn_priority(const dma_resource_t *resource, uint8_t priority)
531 {
532 hpm_stat_t status;
533
534 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
535
536 if (chn_ctx == NULL) {
537 status = status_invalid_argument;
538 } else {
539 dma_set_priority(resource->base, resource->channel, priority);
540 status = status_success;
541 }
542 return status;
543 }
544
dma_mgr_set_chn_src_work_mode(const dma_resource_t * resource,uint8_t mode)545 hpm_stat_t dma_mgr_set_chn_src_work_mode(const dma_resource_t *resource, uint8_t mode)
546 {
547 hpm_stat_t status;
548
549 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
550
551 if (chn_ctx == NULL) {
552 status = status_invalid_argument;
553 } else {
554 dma_set_source_work_mode(resource->base, resource->channel, mode);
555 status = status_success;
556 }
557 return status;
558 }
559
dma_mgr_set_chn_dst_work_mode(const dma_resource_t * resource,uint8_t mode)560 hpm_stat_t dma_mgr_set_chn_dst_work_mode(const dma_resource_t *resource, uint8_t mode)
561 {
562 hpm_stat_t status;
563
564 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
565
566 if (chn_ctx == NULL) {
567 status = status_invalid_argument;
568 } else {
569 dma_set_destination_work_mode(resource->base, resource->channel, mode);
570 status = status_success;
571 }
572 return status;
573 }
574
dma_mgr_set_chn_src_burst_size(const dma_resource_t * resource,uint8_t burstsize)575 hpm_stat_t dma_mgr_set_chn_src_burst_size(const dma_resource_t *resource, uint8_t burstsize)
576 {
577 hpm_stat_t status;
578
579 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
580
581 if (chn_ctx == NULL) {
582 status = status_invalid_argument;
583 } else {
584 dma_set_source_burst_size(resource->base, resource->channel, burstsize);
585 status = status_success;
586 }
587 return status;
588 }
589
dma_mgr_get_chn_remaining_transize(const dma_resource_t * resource,uint32_t * size)590 hpm_stat_t dma_mgr_get_chn_remaining_transize(const dma_resource_t *resource, uint32_t *size)
591 {
592 hpm_stat_t status;
593
594 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
595
596 if (chn_ctx == NULL) {
597 status = status_invalid_argument;
598 } else {
599 *size = dma_get_remaining_transfer_size(resource->base, resource->channel);
600 status = status_success;
601 }
602 return status;
603 }
604
dma_mgr_set_chn_transize(const dma_resource_t * resource,uint32_t size)605 hpm_stat_t dma_mgr_set_chn_transize(const dma_resource_t *resource, uint32_t size)
606 {
607 hpm_stat_t status;
608
609 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
610
611 if (chn_ctx == NULL) {
612 status = status_invalid_argument;
613 } else {
614 dma_set_transfer_size(resource->base, resource->channel, size);
615 status = status_success;
616 }
617 return status;
618 }
619
dma_mgr_set_chn_src_width(const dma_resource_t * resource,uint8_t width)620 hpm_stat_t dma_mgr_set_chn_src_width(const dma_resource_t *resource, uint8_t width)
621 {
622 hpm_stat_t status;
623
624 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
625
626 if (chn_ctx == NULL) {
627 status = status_invalid_argument;
628 } else {
629 dma_set_source_width(resource->base, resource->channel, width);
630 status = status_success;
631 }
632 return status;
633 }
634
dma_mgr_set_chn_dst_width(const dma_resource_t * resource,uint8_t width)635 hpm_stat_t dma_mgr_set_chn_dst_width(const dma_resource_t *resource, uint8_t width)
636 {
637 hpm_stat_t status;
638
639 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
640
641 if (chn_ctx == NULL) {
642 status = status_invalid_argument;
643 } else {
644 dma_set_destination_width(resource->base, resource->channel, width);
645 status = status_success;
646 }
647 return status;
648 }
649
dma_mgr_set_chn_src_addr(const dma_resource_t * resource,uint32_t addr)650 hpm_stat_t dma_mgr_set_chn_src_addr(const dma_resource_t *resource, uint32_t addr)
651 {
652 hpm_stat_t status;
653
654 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
655
656 if (chn_ctx == NULL) {
657 status = status_invalid_argument;
658 } else {
659 dma_set_source_address(resource->base, resource->channel, addr);
660 status = status_success;
661 }
662 return status;
663 }
664
dma_mgr_set_chn_dst_addr(const dma_resource_t * resource,uint32_t addr)665 hpm_stat_t dma_mgr_set_chn_dst_addr(const dma_resource_t *resource, uint32_t addr)
666 {
667 hpm_stat_t status;
668
669 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
670
671 if (chn_ctx == NULL) {
672 status = status_invalid_argument;
673 } else {
674 dma_set_destination_address(resource->base, resource->channel, addr);
675 status = status_success;
676 }
677 return status;
678 }
679
dma_mgr_set_chn_src_addr_ctrl(const dma_resource_t * resource,uint8_t addr_ctrl)680 hpm_stat_t dma_mgr_set_chn_src_addr_ctrl(const dma_resource_t *resource, uint8_t addr_ctrl)
681 {
682 hpm_stat_t status;
683
684 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
685
686 if (chn_ctx == NULL) {
687 status = status_invalid_argument;
688 } else {
689 dma_set_source_address_ctrl(resource->base, resource->channel, addr_ctrl);
690 status = status_success;
691 }
692 return status;
693 }
694
dma_mgr_set_chn_dst_addr_ctrl(const dma_resource_t * resource,uint8_t addr_ctrl)695 hpm_stat_t dma_mgr_set_chn_dst_addr_ctrl(const dma_resource_t *resource, uint8_t addr_ctrl)
696 {
697 hpm_stat_t status;
698
699 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
700
701 if (chn_ctx == NULL) {
702 status = status_invalid_argument;
703 } else {
704 dma_set_destination_address_ctrl(resource->base, resource->channel, addr_ctrl);
705 status = status_success;
706 }
707 return status;
708 }
709
dma_mgr_set_chn_infinite_loop_mode(const dma_resource_t * resource,bool infinite_loop)710 hpm_stat_t dma_mgr_set_chn_infinite_loop_mode(const dma_resource_t *resource, bool infinite_loop)
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 #if defined(DMA_MGR_HAS_INFINITE_LOOP) && DMA_MGR_HAS_INFINITE_LOOP
720 dma_set_infinite_loop_mode(resource->base, resource->channel, infinite_loop);
721 status = status_success;
722 #else
723 (void)infinite_loop;
724 status = status_fail;
725 #endif
726 }
727 return status;
728 }
729
dma_mgr_set_chn_src_busrt_option(const dma_resource_t * resource,uint8_t burst_opt)730 hpm_stat_t dma_mgr_set_chn_src_busrt_option(const dma_resource_t *resource, uint8_t burst_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 #if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
740 dma_set_src_busrt_option(resource->base, resource->channel, burst_opt);
741 status = status_success;
742 #else
743 (void)burst_opt;
744 status = status_fail;
745 #endif
746 }
747 return status;
748 }
749
dma_mgr_set_chn_handshake_option(const dma_resource_t * resource,uint8_t handshake_opt)750 hpm_stat_t dma_mgr_set_chn_handshake_option(const dma_resource_t *resource, uint8_t handshake_opt)
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 #if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
760 dma_set_handshake_option(resource->base, resource->channel, handshake_opt);
761 status = status_success;
762 #else
763 (void)handshake_opt;
764 status = status_fail;
765 #endif
766 }
767 return status;
768 }
769
dma_mgr_abort_chn_transfer(const dma_resource_t * resource)770 hpm_stat_t dma_mgr_abort_chn_transfer(const dma_resource_t *resource)
771 {
772 hpm_stat_t status;
773
774 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
775
776 if (chn_ctx == NULL) {
777 status = status_invalid_argument;
778 } else {
779 dma_abort_channel(resource->base, 1u << resource->channel);
780 status = status_success;
781 }
782 return status;
783 }
784
dma_mgr_check_chn_transfer_status(const dma_resource_t * resource,uint32_t * status)785 hpm_stat_t dma_mgr_check_chn_transfer_status(const dma_resource_t *resource, uint32_t *status)
786 {
787 hpm_stat_t stat;
788
789 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
790
791 if (chn_ctx == NULL) {
792 stat = status_invalid_argument;
793 } else {
794 *status = dma_check_transfer_status(resource->base, resource->channel);
795 stat = status_success;
796 }
797 return stat;
798 }
799
dma_mgr_set_source_burst_in_fixed_transize_enable(const dma_resource_t * resource,bool enable)800 hpm_stat_t dma_mgr_set_source_burst_in_fixed_transize_enable(const dma_resource_t *resource, bool enable)
801 {
802 hpm_stat_t status;
803
804 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
805
806 if (chn_ctx == NULL) {
807 status = status_invalid_argument;
808 } else {
809 #if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
810 dma_set_source_burst_in_fixed_transize_enable(resource->base, resource->channel, enable);
811 status = status_success;
812 #else
813 (void)enable;
814 status = status_fail;
815 #endif
816 }
817 return status;
818 }
819
dma_mgr_set_destination_burst_in_fix_transize_enable(const dma_resource_t * resource,bool enable)820 hpm_stat_t dma_mgr_set_destination_burst_in_fix_transize_enable(const dma_resource_t *resource, bool enable)
821 {
822 hpm_stat_t status;
823
824 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
825
826 if (chn_ctx == NULL) {
827 status = status_invalid_argument;
828 } else {
829 #if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
830 dma_set_destination_burst_in_fixed_transize_enable(resource->base, resource->channel, enable);
831 status = status_success;
832 #else
833 (void)enable;
834 status = status_fail;
835 #endif
836 }
837 return status;
838 }
839
dma_mgr_set_swap_mode(const dma_resource_t * resource,uint8_t swap_mode)840 hpm_stat_t dma_mgr_set_swap_mode(const dma_resource_t *resource, uint8_t swap_mode)
841 {
842 hpm_stat_t status;
843
844 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
845
846 if (chn_ctx == NULL) {
847 status = status_invalid_argument;
848 } else {
849 #if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
850 dma_set_swap_mode(resource->base, resource->channel, swap_mode);
851 status = status_success;
852 #else
853 (void)swap_mode;
854 status = status_fail;
855 #endif
856 }
857 return status;
858 }
859
dma_mgr_set_swap_table(const dma_resource_t * resource,uint32_t swap_table)860 hpm_stat_t dma_mgr_set_swap_table(const dma_resource_t *resource, uint32_t swap_table)
861 {
862 hpm_stat_t status;
863
864 dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
865
866 if (chn_ctx == NULL) {
867 status = status_invalid_argument;
868 } else {
869 #if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
870 dma_set_swap_table(resource->base, resource->channel, swap_table);
871 status = status_success;
872 #else
873 (void)swap_table;
874 status = status_fail;
875 #endif
876 }
877 return status;
878 }
879