| 
 | 1 | +/*  | 
 | 2 | + * Copyright (c) 2020 NXP  | 
 | 3 | + *  | 
 | 4 | + * SPDX-License-Identifier: Apache-2.0  | 
 | 5 | + */  | 
 | 6 | + | 
 | 7 | +/**  | 
 | 8 | + * @file  | 
 | 9 | + * @brief Verify zephyr dma link 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 tx -> rx  | 
 | 15 | + *   -# after a major/minor loop trigger another channel to transfer, rx -> rx2  | 
 | 16 | + * - Expected Results  | 
 | 17 | + *   -# Data is transferred correctly from src to dest  | 
 | 18 | + */  | 
 | 19 | + | 
 | 20 | +#include <zephyr.h>  | 
 | 21 | +#include <drivers/dma.h>  | 
 | 22 | +#include <ztest.h>  | 
 | 23 | + | 
 | 24 | +#define DMA_DEVICE_NAME CONFIG_DMA_0_NAME  | 
 | 25 | +#define TEST_DMA_CHANNEL_0 (0)  | 
 | 26 | +#define TEST_DMA_CHANNEL_1 (1)  | 
 | 27 | +#define RX_BUFF_SIZE (48)  | 
 | 28 | + | 
 | 29 | +#ifdef CONFIG_NOCACHE_MEMORY  | 
 | 30 | +static __aligned(32) char tx_data[RX_BUFF_SIZE] __used  | 
 | 31 | +	__attribute__((__section__(".nocache")));  | 
 | 32 | +static const char TX_DATA[] = "It is harder to be kind than to be wise........";  | 
 | 33 | +static __aligned(32) char rx_data[RX_BUFF_SIZE] __used  | 
 | 34 | +	__attribute__((__section__(".nocache.dma")));  | 
 | 35 | +static __aligned(32) char rx_data2[RX_BUFF_SIZE] __used  | 
 | 36 | +	__attribute__((__section__(".nocache.dma")));  | 
 | 37 | +#else  | 
 | 38 | +static const char tx_data[] = "It is harder to be kind than to be wise........";  | 
 | 39 | +static char rx_data[RX_BUFF_SIZE] = { 0 };  | 
 | 40 | +static char rx_data2[RX_BUFF_SIZE] = { 0 };  | 
 | 41 | +#endif  | 
 | 42 | + | 
 | 43 | +static void test_done(const struct device *dma_dev, void *arg, uint32_t id,  | 
 | 44 | +		      int error_code)  | 
 | 45 | +{  | 
 | 46 | +	if (error_code == 0) {  | 
 | 47 | +		TC_PRINT("DMA transfer done ch %d\n", id);  | 
 | 48 | +	} else {  | 
 | 49 | +		TC_PRINT("DMA transfer met an error\n");  | 
 | 50 | +	}  | 
 | 51 | +}  | 
 | 52 | + | 
 | 53 | +static int test_task(int minor, int major)  | 
 | 54 | +{  | 
 | 55 | +	struct dma_config dma_cfg = { 0 };  | 
 | 56 | +	struct dma_block_config dma_block_cfg = { 0 };  | 
 | 57 | +	const struct device *dma = device_get_binding(DMA_DEVICE_NAME);  | 
 | 58 | + | 
 | 59 | +	if (!dma) {  | 
 | 60 | +		TC_PRINT("Cannot get dma controller\n");  | 
 | 61 | +		return TC_FAIL;  | 
 | 62 | +	}  | 
 | 63 | + | 
 | 64 | +#ifdef CONFIG_NOCACHE_MEMORY  | 
 | 65 | +	memcpy(tx_data, TX_DATA, sizeof(TX_DATA));  | 
 | 66 | +#endif  | 
 | 67 | + | 
 | 68 | +	dma_cfg.channel_direction = MEMORY_TO_MEMORY;  | 
 | 69 | +	dma_cfg.source_data_size = 1U;  | 
 | 70 | +	dma_cfg.dest_data_size = 1U;  | 
 | 71 | +	dma_cfg.source_burst_length = 16;  | 
 | 72 | +	dma_cfg.dest_burst_length = 16;  | 
 | 73 | +	dma_cfg.dma_callback = test_done;  | 
 | 74 | +	dma_cfg.complete_callback_en = 0U;  | 
 | 75 | +	dma_cfg.error_callback_en = 1U;  | 
 | 76 | +	dma_cfg.block_count = 1U;  | 
 | 77 | +	dma_cfg.head_block = &dma_block_cfg;  | 
 | 78 | +#ifdef CONFIG_DMA_MCUX_TEST_SLOT_START  | 
 | 79 | +	dma_cfg.dma_slot = CONFIG_DMA_MCUX_TEST_SLOT_START;  | 
 | 80 | +#endif  | 
 | 81 | + | 
 | 82 | +	TC_PRINT("Preparing DMA Controller: Chan_ID=%u, BURST_LEN=%u\n",  | 
 | 83 | +		 TEST_DMA_CHANNEL_1, 8 >> 3);  | 
 | 84 | + | 
 | 85 | +	TC_PRINT("Starting the transfer\n");  | 
 | 86 | +	(void)memset(rx_data, 0, sizeof(rx_data));  | 
 | 87 | +	(void)memset(rx_data2, 0, sizeof(rx_data2));  | 
 | 88 | + | 
 | 89 | +	dma_block_cfg.block_size = sizeof(tx_data);  | 
 | 90 | +	dma_block_cfg.source_address = (uint32_t)tx_data;  | 
 | 91 | +	dma_block_cfg.dest_address = (uint32_t)rx_data2;  | 
 | 92 | + | 
 | 93 | +	if (dma_config(dma, TEST_DMA_CHANNEL_1, &dma_cfg)) {  | 
 | 94 | +		TC_PRINT("ERROR: transfer\n");  | 
 | 95 | +		return TC_FAIL;  | 
 | 96 | +	}  | 
 | 97 | + | 
 | 98 | +#ifdef CONFIG_DMA_MCUX_TEST_SLOT_START  | 
 | 99 | +	dma_cfg.dma_slot = CONFIG_DMA_MCUX_TEST_SLOT_START + 1;  | 
 | 100 | +#endif  | 
 | 101 | + | 
 | 102 | +	dma_cfg.source_chaining_en = minor;  | 
 | 103 | +	dma_cfg.dest_chaining_en = major;  | 
 | 104 | +	dma_cfg.linked_channel = TEST_DMA_CHANNEL_1;  | 
 | 105 | + | 
 | 106 | +	dma_block_cfg.block_size = sizeof(tx_data);  | 
 | 107 | +	dma_block_cfg.source_address = (uint32_t)tx_data;  | 
 | 108 | +	dma_block_cfg.dest_address = (uint32_t)rx_data;  | 
 | 109 | + | 
 | 110 | +	if (dma_config(dma, TEST_DMA_CHANNEL_0, &dma_cfg)) {  | 
 | 111 | +		TC_PRINT("ERROR: transfer\n");  | 
 | 112 | +		return TC_FAIL;  | 
 | 113 | +	}  | 
 | 114 | + | 
 | 115 | +	if (dma_start(dma, TEST_DMA_CHANNEL_0)) {  | 
 | 116 | +		TC_PRINT("ERROR: transfer\n");  | 
 | 117 | +		return TC_FAIL;  | 
 | 118 | +	}  | 
 | 119 | +	k_sleep(K_MSEC(2000));  | 
 | 120 | +	TC_PRINT("%s\n", rx_data);  | 
 | 121 | +	TC_PRINT("%s\n", rx_data2);  | 
 | 122 | +	if (minor == 0 && major == 1) {  | 
 | 123 | +		/* major link only trigger lined channel minor loop once */  | 
 | 124 | +		if (strncmp(tx_data, rx_data2,  | 
 | 125 | +				dma_cfg.source_burst_length) != 0)  | 
 | 126 | +			return TC_FAIL;  | 
 | 127 | +	} else if (minor == 1 && major == 0) {  | 
 | 128 | +		/* minor link trigger linked channel except the last one*/  | 
 | 129 | +		if (strncmp(tx_data, rx_data2,  | 
 | 130 | +				dma_block_cfg.block_size - dma_cfg.source_burst_length) != 0)  | 
 | 131 | +			return TC_FAIL;  | 
 | 132 | +	} else if (minor == 1 && major == 1) {  | 
 | 133 | +		if (strcmp(tx_data, rx_data2) != 0)  | 
 | 134 | +			return TC_FAIL;  | 
 | 135 | +	}  | 
 | 136 | + | 
 | 137 | +	return TC_PASS;  | 
 | 138 | +}  | 
 | 139 | + | 
 | 140 | +/* export test cases */  | 
 | 141 | +void test_dma_m2m_chan0_1_major_link(void)  | 
 | 142 | +{  | 
 | 143 | +	zassert_true((test_task(0, 1) == TC_PASS), NULL);  | 
 | 144 | +}  | 
 | 145 | + | 
 | 146 | +void test_dma_m2m_chan0_1_minor_link(void)  | 
 | 147 | +{  | 
 | 148 | +	zassert_true((test_task(1, 0) == TC_PASS), NULL);  | 
 | 149 | +}  | 
 | 150 | + | 
 | 151 | +void test_dma_m2m_chan0_1_minor_major_link(void)  | 
 | 152 | +{  | 
 | 153 | +	zassert_true((test_task(1, 1) == TC_PASS), NULL);  | 
 | 154 | +}  | 
0 commit comments