diff options
| author | GUI <[email protected]> | 2025-12-03 21:47:49 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-03 21:47:49 +0800 |
| commit | e5e0ad29bff1de391cff2ae516a55bd070c63520 (patch) | |
| tree | c604ee2fd9c587bcf7cd4144e53c0b33cb03346e /examples | |
| parent | 0ea9d8f3bedae05d6e882c096dc57a578b321507 (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.c | 146 |
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 */ |
