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