dma_test.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-02-25 GuEe-GUI the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #if defined(RT_USING_DMA) && defined(RT_USING_FINSH)
  14. #include <stdlib.h>
  15. static void test_dma_callback(struct rt_dma_chan *chan, rt_size_t size)
  16. {
  17. rt_bool_t *done_ptr = chan->priv;
  18. *done_ptr = RT_TRUE;
  19. rt_hw_wmb();
  20. }
  21. static int dma_memcpy_test(int argc, char**argv)
  22. {
  23. rt_bool_t done;
  24. int dma_sz = 64;
  25. rt_ubase_t dma_addr;
  26. char *src_addr, *dst_addr;
  27. struct rt_device dev = {};
  28. struct rt_dma_slave_config config;
  29. struct rt_dma_slave_transfer transfer;
  30. struct rt_dma_chan *chn = rt_dma_chan_request(&dev, RT_NULL);
  31. if (rt_is_err_or_null(chn))
  32. {
  33. rt_kputs("Alloc DMA channel fail");
  34. return 0;
  35. }
  36. if (argc > 1)
  37. {
  38. dma_sz = atoi(argv[1]);
  39. }
  40. if (dma_sz % sizeof(rt_uint32_t))
  41. {
  42. dma_sz = RT_ALIGN_DOWN(dma_sz, sizeof(rt_uint32_t));
  43. rt_kprintf("DMA size align to %d\n", dma_sz);
  44. }
  45. if (!(src_addr = rt_dma_alloc_coherent(&dev, dma_sz, &dma_addr)))
  46. {
  47. rt_kprintf("Alloc DMA %s buffer(size = %d) fail\n", "SRC", dma_sz);
  48. goto _free_dma_chan;
  49. }
  50. config.src_addr = dma_addr;
  51. if (!(dst_addr = rt_dma_alloc_coherent(&dev, dma_sz, &dma_addr)))
  52. {
  53. rt_kprintf("Alloc DMA %s buffer(size = %d) fail\n", "DST", dma_sz);
  54. goto _free_src_addr;
  55. }
  56. config.dst_addr = dma_addr;
  57. config.direction = RT_DMA_MEM_TO_MEM;
  58. config.src_addr_width = sizeof(rt_uint32_t);
  59. config.src_maxburst = sizeof(rt_uint32_t);
  60. config.dst_addr_width = sizeof(rt_uint32_t);
  61. config.dst_maxburst = sizeof(rt_uint32_t);
  62. chn->callback = test_dma_callback;
  63. chn->priv = &done;
  64. if (rt_dma_chan_config(chn, &config))
  65. {
  66. rt_kprintf("DMA channel %s fail\n", "config");
  67. goto _free_dst_addr;
  68. }
  69. rt_memset(&transfer, 0, sizeof(transfer));
  70. transfer.src_addr = config.src_addr;
  71. transfer.dst_addr = config.dst_addr;
  72. transfer.buffer_len = dma_sz;
  73. if (rt_dma_prep_memcpy(chn, &transfer))
  74. {
  75. rt_kprintf("DMA channel %s fail\n", "prep");
  76. goto _free_dst_addr;
  77. }
  78. rt_memset(src_addr, 0xff, dma_sz);
  79. rt_memset(dst_addr, 0, dma_sz);
  80. rt_kprintf("%s %s:\n", "SRC", "start");
  81. for (int i = 0; i < dma_sz; ++i)
  82. {
  83. rt_kprintf("%02x ", src_addr[i]);
  84. }
  85. rt_kputs("\n");
  86. rt_kprintf("%s %s:\n", "DST", "start");
  87. for (int i = 0; i < dma_sz; ++i)
  88. {
  89. rt_kprintf("%02x ", dst_addr[i]);
  90. }
  91. rt_kputs("\n");
  92. done = RT_FALSE;
  93. if (rt_dma_chan_start(chn))
  94. {
  95. rt_kprintf("DMA channel %s fail\n", "start");
  96. goto _free_dst_addr;
  97. }
  98. while (!done)
  99. {
  100. rt_hw_cpu_relax();
  101. }
  102. rt_kprintf("%s %s:\n", "SRC", "end");
  103. for (int i = 0; i < dma_sz; ++i)
  104. {
  105. rt_kprintf("%02x ", src_addr[i]);
  106. }
  107. rt_kputs("\n");
  108. rt_kprintf("%s %s:\n", "DST", "end");
  109. for (int i = 0; i < dma_sz; ++i)
  110. {
  111. rt_kprintf("%02x ", dst_addr[i]);
  112. }
  113. rt_kputs("\n");
  114. _free_dst_addr:
  115. rt_dma_free_coherent(&dev, dma_sz, dst_addr, config.dst_addr);
  116. _free_src_addr:
  117. rt_dma_free_coherent(&dev, dma_sz, src_addr, config.src_addr);
  118. _free_dma_chan:
  119. rt_dma_chan_release(chn);
  120. return 0;
  121. }
  122. MSH_CMD_EXPORT(dma_memcpy_test, test dma memcpy e.g: dma_memcpy_test(64));
  123. #endif /* RT_USING_DMA && RT_USING_FINSH */