summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorGUI <[email protected]>2025-12-03 21:47:49 +0800
committerGitHub <[email protected]>2025-12-03 21:47:49 +0800
commite5e0ad29bff1de391cff2ae516a55bd070c63520 (patch)
treec604ee2fd9c587bcf7cd4144e53c0b33cb03346e /examples
parent0ea9d8f3bedae05d6e882c096dc57a578b321507 (diff)
[DM/DMA] Update DMA #10987
* Append WT attribute. * Change the API with pool size only. * Add address mask for DMA * Change DMA lock to mutex * Add pause callback for DMA engine driver * Add DMA Engine test * Add ARM PL330 DMA Engine driver
Diffstat (limited to 'examples')
-rw-r--r--examples/test/dma_test.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/examples/test/dma_test.c b/examples/test/dma_test.c
new file mode 100644
index 0000000000..4c41ecbdbb
--- /dev/null
+++ b/examples/test/dma_test.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-02-25 GuEe-GUI the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#if defined(RT_USING_DMA) && defined(RT_USING_FINSH)
+#include <stdlib.h>
+
+static void test_dma_callback(struct rt_dma_chan *chan, rt_size_t size)
+{
+ rt_bool_t *done_ptr = chan->priv;
+
+ *done_ptr = RT_TRUE;
+ rt_hw_wmb();
+}
+
+static int dma_memcpy_test(int argc, char**argv)
+{
+ rt_bool_t done;
+ int dma_sz = 64;
+ rt_ubase_t dma_addr;
+ char *src_addr, *dst_addr;
+ struct rt_device dev = {};
+ struct rt_dma_slave_config config;
+ struct rt_dma_slave_transfer transfer;
+ struct rt_dma_chan *chn = rt_dma_chan_request(&dev, RT_NULL);
+
+ if (rt_is_err_or_null(chn))
+ {
+ rt_kputs("Alloc DMA channel fail");
+ return 0;
+ }
+
+ if (argc > 1)
+ {
+ dma_sz = atoi(argv[1]);
+ }
+
+ if (dma_sz % sizeof(rt_uint32_t))
+ {
+ dma_sz = RT_ALIGN_DOWN(dma_sz, sizeof(rt_uint32_t));
+ rt_kprintf("DMA size align to %d\n", dma_sz);
+ }
+
+ if (!(src_addr = rt_dma_alloc_coherent(&dev, dma_sz, &dma_addr)))
+ {
+ rt_kprintf("Alloc DMA %s buffer(size = %d) fail\n", "SRC", dma_sz);
+ goto _free_dma_chan;
+ }
+ config.src_addr = dma_addr;
+
+ if (!(dst_addr = rt_dma_alloc_coherent(&dev, dma_sz, &dma_addr)))
+ {
+ rt_kprintf("Alloc DMA %s buffer(size = %d) fail\n", "DST", dma_sz);
+ goto _free_src_addr;
+ }
+ config.dst_addr = dma_addr;
+
+ config.direction = RT_DMA_MEM_TO_MEM;
+ config.src_addr_width = sizeof(rt_uint32_t);
+ config.src_maxburst = sizeof(rt_uint32_t);
+ config.dst_addr_width = sizeof(rt_uint32_t);
+ config.dst_maxburst = sizeof(rt_uint32_t);
+
+ chn->callback = test_dma_callback;
+ chn->priv = &done;
+ if (rt_dma_chan_config(chn, &config))
+ {
+ rt_kprintf("DMA channel %s fail\n", "config");
+ goto _free_dst_addr;
+ }
+
+ rt_memset(&transfer, 0, sizeof(transfer));
+ transfer.src_addr = config.src_addr;
+ transfer.dst_addr = config.dst_addr;
+ transfer.buffer_len = dma_sz;
+
+ if (rt_dma_prep_memcpy(chn, &transfer))
+ {
+ rt_kprintf("DMA channel %s fail\n", "prep");
+ goto _free_dst_addr;
+ }
+
+ rt_memset(src_addr, 0xff, dma_sz);
+ rt_memset(dst_addr, 0, dma_sz);
+
+ rt_kprintf("%s %s:\n", "SRC", "start");
+ for (int i = 0; i < dma_sz; ++i)
+ {
+ rt_kprintf("%02x ", src_addr[i]);
+ }
+ rt_kputs("\n");
+
+ rt_kprintf("%s %s:\n", "DST", "start");
+ for (int i = 0; i < dma_sz; ++i)
+ {
+ rt_kprintf("%02x ", dst_addr[i]);
+ }
+ rt_kputs("\n");
+
+ done = RT_FALSE;
+ if (rt_dma_chan_start(chn))
+ {
+ rt_kprintf("DMA channel %s fail\n", "start");
+ goto _free_dst_addr;
+ }
+
+ while (!done)
+ {
+ rt_hw_cpu_relax();
+ }
+
+ rt_kprintf("%s %s:\n", "SRC", "end");
+ for (int i = 0; i < dma_sz; ++i)
+ {
+ rt_kprintf("%02x ", src_addr[i]);
+ }
+ rt_kputs("\n");
+
+ rt_kprintf("%s %s:\n", "DST", "end");
+ for (int i = 0; i < dma_sz; ++i)
+ {
+ rt_kprintf("%02x ", dst_addr[i]);
+ }
+ rt_kputs("\n");
+
+_free_dst_addr:
+ rt_dma_free_coherent(&dev, dma_sz, dst_addr, config.dst_addr);
+_free_src_addr:
+ rt_dma_free_coherent(&dev, dma_sz, src_addr, config.src_addr);
+_free_dma_chan:
+ rt_dma_chan_release(chn);
+
+ return 0;
+}
+MSH_CMD_EXPORT(dma_memcpy_test, test dma memcpy e.g: dma_memcpy_test(64));
+#endif /* RT_USING_DMA && RT_USING_FINSH */