1 /*
2 * Copyright (c) 2016 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Verify zephyr dma memory to memory transfer
10 * @details
11 * - Test Steps
12 * -# Set dma channel configuration including source/dest addr, burstlen
13 * -# Set direction memory-to-memory
14 * -# Start transfer
15 * - Expected Results
16 * -# Data is transferred correctly from src to dest
17 */
18
19 #include <zephyr/kernel.h>
20 #include <zephyr/drivers/dma.h>
21 #include <zephyr/ztest.h>
22
23 #include "test_buffers.h"
24
test_done(const struct device * dma_dev,void * arg,uint32_t id,int status)25 static void test_done(const struct device *dma_dev, void *arg,
26 uint32_t id, int status)
27 {
28 if (status >= 0) {
29 TC_PRINT("DMA transfer done\n");
30 } else {
31 TC_PRINT("DMA transfer met an error\n");
32 }
33 }
34
test_task(const struct device * dma,uint32_t chan_id,uint32_t blen)35 static int test_task(const struct device *dma, uint32_t chan_id, uint32_t blen)
36 {
37 struct dma_config dma_cfg = { 0 };
38 struct dma_block_config dma_block_cfg = { 0 };
39
40 if (!device_is_ready(dma)) {
41 TC_PRINT("dma controller device is not ready\n");
42 return TC_FAIL;
43 }
44
45 dma_cfg.channel_direction = MEMORY_TO_MEMORY;
46 dma_cfg.source_data_size = 1U;
47 dma_cfg.dest_data_size = 1U;
48 dma_cfg.source_burst_length = blen;
49 dma_cfg.dest_burst_length = blen;
50 dma_cfg.dma_callback = test_done;
51 dma_cfg.complete_callback_en = 0U;
52 dma_cfg.error_callback_dis = 0U;
53 dma_cfg.block_count = 1U;
54 dma_cfg.head_block = &dma_block_cfg;
55 #ifdef CONFIG_DMA_MCUX_TEST_SLOT_START
56 dma_cfg.dma_slot = CONFIG_DMA_MCUX_TEST_SLOT_START;
57 #endif
58
59 TC_PRINT("Preparing DMA Controller: Name=%s, Chan_ID=%u, BURST_LEN=%u\n",
60 dma->name, chan_id, blen >> 3);
61
62 TC_PRINT("Starting the transfer\n");
63 (void)memset(rx_data, 0, sizeof(rx_data));
64 dma_block_cfg.block_size = sizeof(tx_data);
65 #ifdef CONFIG_DMA_64BIT
66 dma_block_cfg.source_address = (uint64_t)tx_data;
67 dma_block_cfg.dest_address = (uint64_t)rx_data;
68 #else
69 dma_block_cfg.source_address = (uint32_t)tx_data;
70 dma_block_cfg.dest_address = (uint32_t)rx_data;
71 #endif
72
73 if (dma_config(dma, chan_id, &dma_cfg)) {
74 TC_PRINT("ERROR: transfer\n");
75 return TC_FAIL;
76 }
77
78 if (dma_start(dma, chan_id)) {
79 TC_PRINT("ERROR: transfer\n");
80 return TC_FAIL;
81 }
82 k_sleep(K_MSEC(2000));
83
84 TC_PRINT("%s\n", rx_data);
85 if (strcmp(tx_data, rx_data) != 0) {
86 return TC_FAIL;
87 }
88 return TC_PASS;
89 }
90
91 #define DMA_NAME(i, _) tst_dma##i
92 #define DMA_LIST LISTIFY(CONFIG_DMA_LOOP_TRANSFER_NUMBER_OF_DMAS, DMA_NAME, (,))
93
94 #if CONFIG_DMA_TRANSFER_BURST16
95 #define TEST_TASK(dma_name) \
96 ZTEST(dma_m2m, test_##dma_name##_m2m_chan0_burst8) \
97 { \
98 const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \
99 zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_0, 8) == TC_PASS)); \
100 } \
101 \
102 ZTEST(dma_m2m, test_##dma_name##_m2m_chan1_burst8) \
103 { \
104 const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \
105 zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_1, 8) == TC_PASS)); \
106 } \
107 \
108 ZTEST(dma_m2m, test_##dma_name##_m2m_chan0_burst16) \
109 { \
110 const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \
111 zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_0, 16) == TC_PASS)); \
112 } \
113 \
114 ZTEST(dma_m2m, test_##dma_name##_m2m_chan1_burst16) \
115 { \
116 const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \
117 zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_1, 16) == TC_PASS)); \
118 }
119 #else
120 #define TEST_TASK(dma_name) \
121 ZTEST(dma_m2m, test_##dma_name##_m2m_chan0_burst8) \
122 { \
123 const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \
124 zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_0, 8) == TC_PASS)); \
125 } \
126 \
127 ZTEST(dma_m2m, test_##dma_name##_m2m_chan1_burst8) \
128 { \
129 const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name)); \
130 zassert_true((test_task(dma, CONFIG_DMA_TRANSFER_CHANNEL_NR_1, 8) == TC_PASS)); \
131 }
132 #endif
133
134 FOR_EACH(TEST_TASK, (), DMA_LIST);
135