[DemoCode下载] M451的PDMA演示

[复制链接]
1697|9
 楼主| 幸福小强 发表于 2018-10-14 20:20 | 显示全部楼层 |阅读模式
DMA, pd, TE, ck
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url] smain.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
  4. * $Revision: 8 $
  5. * $Date: 15/09/02 10:04a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    Use PDMA channel 2 to transfer data from memory to memory.
  7. * @note
  8. * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
  9. *
  10. ******************************************************************************/
  11. #include <stdio.h>
  12. #include "M451Series.h"

  13. /*---------------------------------------------------------------------------------------------------------*/
  14. /* Macro, type and constant definitions                                                                    */
  15. /*---------------------------------------------------------------------------------------------------------*/
  16. #define PLL_CLOCK       72000000


  17. /*---------------------------------------------------------------------------------------------------------*/
  18. /* Global variables                                                                                        */
  19. /*---------------------------------------------------------------------------------------------------------*/
  20. uint32_t PDMA_TEST_LENGTH = 64;
  21. uint8_t SrcArray[256];
  22. uint8_t DestArray[256];
  23. uint32_t volatile u32IsTestOver = 0;

  24. /**
  25. * @brief       DMA IRQ
  26. *
  27. * @param       None
  28. *
  29. * [url=home.php?mod=space&uid=266161]@return[/url]      None
  30. *
  31. * [url=home.php?mod=space&uid=1543424]@Details[/url]     The DMA default IRQ, declared in startup_nuc400series.s.
  32. */
  33. void PDMA_IRQHandler(void)
  34. {
  35.     uint32_t status = PDMA_GET_INT_STATUS();

  36.     if(status & 0x1)    /* abort */
  37.     {
  38.         if(PDMA_GET_ABORT_STS() & 0x4)
  39.             u32IsTestOver = 2;
  40.         PDMA_CLR_ABORT_FLAG(PDMA_ABTSTS_ABTIFn_Msk);
  41.     }
  42.     else if(status & 0x2)      /* done */
  43.     {
  44.         if(PDMA_GET_TD_STS() & 0x4)
  45.             u32IsTestOver = 1;
  46.         PDMA_CLR_TD_FLAG(PDMA_TDSTS_TDIFn_Msk);
  47.     }
  48.     else
  49.         printf("unknown interrupt !!\n");
  50. }

  51. void SYS_Init(void)
  52. {
  53.     /*---------------------------------------------------------------------------------------------------------*/
  54.     /* Init System Clock                                                                                       */
  55.     /*---------------------------------------------------------------------------------------------------------*/

  56.     /* Enable HIRC clock (Internal RC 22.1184MHz) */
  57.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  58.     /* Waiting for HIRC clock ready */
  59.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

  60.     /* Select HCLK clock source as HIRC and and HCLK clock divider as 1 */
  61.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

  62.     /* Enable HXT clock (external XTAL 12MHz) */
  63.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

  64.     /* Waiting for HXT clock ready */
  65.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

  66.     /* Set core clock as PLL_CLOCK from PLL */
  67.     CLK_SetCoreClock(PLL_CLOCK);

  68.     /* Waiting for PLL clock ready */
  69.     CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);

  70.     /* Enable UART module clock */
  71.     CLK_EnableModuleClock(UART0_MODULE);

  72.     /* Select UART module clock source as HXT and UART module clock divider as 1 */
  73.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1));

  74.     /* Enable PDMA clock source */
  75.     CLK_EnableModuleClock(PDMA_MODULE);

  76.     /*---------------------------------------------------------------------------------------------------------*/
  77.     /* Init I/O Multi-function                                                                                 */
  78.     /*---------------------------------------------------------------------------------------------------------*/
  79.     /* Set PD multi-function pins for UART0 RXD and TXD */
  80.     SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD0MFP_Msk | SYS_GPD_MFPL_PD1MFP_Msk);
  81.     SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD0MFP_UART0_RXD | SYS_GPD_MFPL_PD1MFP_UART0_TXD);
  82. }

  83. void UART0_Init()
  84. {
  85.     /*---------------------------------------------------------------------------------------------------------*/
  86.     /* Init UART                                                                                               */
  87.     /*---------------------------------------------------------------------------------------------------------*/
  88.     /* Reset UART module */
  89.     SYS_ResetModule(UART0_RST);

  90.     /* Configure UART0 and set UART0 baud rate */
  91.     UART_Open(UART0, 115200);
  92. }


  93. /*---------------------------------------------------------------------------------------------------------*/
  94. /*  Main Function                                                                                          */
  95. /*---------------------------------------------------------------------------------------------------------*/
  96. int main(void)
  97. {
  98.     /* Unlock protected registers */
  99.     SYS_UnlockReg();

  100.     /* Init System, IP clock and multi-function I/O */
  101.     SYS_Init();

  102.     /* Lock protected registers */
  103.     /* If user want to write protected register, please issue SYS_UnlockReg() to unlock protected register. */
  104.     SYS_LockReg();

  105.     /* Init UART for printf */
  106.     UART0_Init();

  107.     printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

  108.     printf("+------------------------------------------------------+ \n");
  109.     printf("|    PDMA Memory to Memory Driver Sample Code          | \n");
  110.     printf("+------------------------------------------------------+ \n");

  111.     /* Reset PDMA module */
  112.     SYS_ResetModule(PDMA_RST);

  113.     /* Open Channel 2 */
  114.     PDMA_Open(0x4);
  115.     PDMA_SetTransferCnt(2, PDMA_WIDTH_32, PDMA_TEST_LENGTH);
  116.     /* transfer width is one word(32 bit) */
  117.     PDMA_SetTransferAddr(2, (uint32_t)SrcArray, PDMA_SAR_INC, (uint32_t)DestArray, PDMA_DAR_INC);

  118.     PDMA_SetTransferMode(2, PDMA_MEM, FALSE, 0);

  119.     //burst size is 4
  120.     PDMA_SetBurstType(2, PDMA_REQ_BURST, PDMA_BURST_4);

  121.     PDMA_EnableInt(2, PDMA_INT_TRANS_DONE);

  122.     NVIC_EnableIRQ(PDMA_IRQn);
  123.     u32IsTestOver = 0;

  124.     PDMA_Trigger(2);

  125.     while(u32IsTestOver == 0);

  126.     if(u32IsTestOver == 1)
  127.         printf("test done...\n");
  128.     else if(u32IsTestOver == 2)
  129.         printf("target abort...\n");

  130.     PDMA_Close();

  131.     while(1);
  132. }


 楼主| 幸福小强 发表于 2018-10-14 20:27 | 显示全部楼层
新唐的例子很不错,很全面的。
 楼主| 幸福小强 发表于 2018-10-14 20:28 | 显示全部楼层
Scatter_Gather
  1. /**************************************************************************//**
  2. * @file     main.c
  3. * @version  V1.00
  4. * $Date: 15/09/02 10:04a $
  5. * @brief
  6. *           Use PDMA channel 5 to transfer data from memory to memory by scatter-gather mode.
  7. *
  8. * @note
  9. * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
  10. *
  11. ******************************************************************************/
  12. #include <stdio.h>
  13. #include "M451Series.h"

  14. #define PLL_CLOCK           72000000

  15. uint32_t PDMA_TEST_LENGTH = 64;
  16. uint8_t SrcArray[256];
  17. uint8_t DestArray0[256];
  18. uint8_t DestArray1[256];

  19. typedef struct dma_desc_t
  20. {
  21.     uint32_t ctl;
  22.     uint32_t src;
  23.     uint32_t dest;
  24.     uint32_t offset;
  25. } DMA_DESC_T;

  26. DMA_DESC_T DMA_DESC[2];

  27. /**
  28. * @brief       DMA IRQ
  29. *
  30. * @param       None
  31. *
  32. * @return      None
  33. *
  34. * @details     The DMA default IRQ, declared in startup_M451series.s.
  35. */
  36. void PDMA_IRQHandler(void)
  37. {
  38. }

  39. void SYS_Init(void)
  40. {
  41.     /*---------------------------------------------------------------------------------------------------------*/
  42.     /* Init System Clock                                                                                       */
  43.     /*---------------------------------------------------------------------------------------------------------*/

  44.     /* Enable HIRC clock (Internal RC 22.1184MHz) */
  45.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  46.     /* Waiting for HIRC clock ready */
  47.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

  48.     /* Select HCLK clock source as HIRC and and HCLK clock divider as 1 */
  49.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

  50.     /* Enable HXT clock (external XTAL 12MHz) */
  51.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

  52.     /* Waiting for HXT clock ready */
  53.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

  54.     /* Set core clock as PLL_CLOCK from PLL */
  55.     CLK_SetCoreClock(PLL_CLOCK);

  56.     /* Waiting for PLL clock ready */
  57.     CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);

  58.     /* Switch HCLK clock source to PLL */
  59. //     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL,CLK_CLKDIV0_HCLK(1));

  60.     /* Enable IP clock */
  61.     CLK_EnableModuleClock(UART0_MODULE);
  62.     CLK_EnableModuleClock(PDMA_MODULE);

  63.     /* Select UART module clock source as HXT and UART module clock divider as 1 */
  64.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1));

  65.     /* Update System Core Clock */
  66.     /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
  67.     SystemCoreClockUpdate();

  68.     /*---------------------------------------------------------------------------------------------------------*/
  69.     /* Init I/O Multi-function                                                                                 */
  70.     /*---------------------------------------------------------------------------------------------------------*/
  71.     /* Set PD multi-function pins for UART0 RXD and TXD */
  72.     SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD0MFP_Msk | SYS_GPD_MFPL_PD1MFP_Msk);
  73.     SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD0MFP_UART0_RXD | SYS_GPD_MFPL_PD1MFP_UART0_TXD);
  74. }

  75. void UART0_Init(void)
  76. {
  77.     /*---------------------------------------------------------------------------------------------------------*/
  78.     /* Init UART                                                                                               */
  79.     /*---------------------------------------------------------------------------------------------------------*/
  80.     /* Reset UART module */
  81.     SYS_ResetModule(UART0_RST);

  82.     /* Configure UART0 and set UART0 baud rate */
  83.     UART_Open(UART0, 115200);
  84. }

  85. /*---------------------------------------------------------------------------------------------------------*/
  86. /* MAIN function                                                                                           */
  87. /*---------------------------------------------------------------------------------------------------------*/
  88. int main(void)
  89. {
  90.     uint32_t u32Src, u32Dst0, u32Dst1;

  91.     /* Unlock protected registers */
  92.     SYS_UnlockReg();

  93.     /* Init System, IP clock and multi-function I/O */
  94.     SYS_Init();

  95.     /* Lock protected registers */
  96.     /* If user want to write protected register, please issue SYS_UnlockReg() to unlock protected register. */
  97.     SYS_LockReg();

  98.     /* Init UART for printf */
  99.     UART0_Init();

  100.     printf("\n\nCPU @ %dHz\n", SystemCoreClock);

  101.     printf("+-----------------------------------------------------------------------+ \n");
  102.     printf("|    M451 PDMA Memory to Memory Driver Sample Code (Scatter-gather)     | \n");
  103.     printf("+-----------------------------------------------------------------------+ \n");

  104.     u32Src = (uint32_t)SrcArray;
  105.     u32Dst0 = (uint32_t)DestArray0;
  106.     u32Dst1 = (uint32_t)DestArray1;

  107.     DMA_DESC[0].ctl = ((PDMA_TEST_LENGTH - 1) << PDMA_DSCT_CTL_TXCNT_Pos) | PDMA_WIDTH_32 | PDMA_SAR_INC | PDMA_DAR_INC | PDMA_REQ_BURST | PDMA_OP_SCATTER;
  108.     DMA_DESC[0].src = u32Src;
  109.     DMA_DESC[0].dest = u32Dst0;
  110.     DMA_DESC[0].offset = (uint32_t)&DMA_DESC[1] - (PDMA->SCATBA);
  111.     DMA_DESC[1].ctl = ((PDMA_TEST_LENGTH - 1) << PDMA_DSCT_CTL_TXCNT_Pos) | PDMA_WIDTH_32 | PDMA_SAR_INC | PDMA_DAR_INC | PDMA_REQ_BURST | PDMA_OP_BASIC;
  112.     DMA_DESC[1].src = u32Dst0;
  113.     DMA_DESC[1].dest = u32Dst1;
  114.     DMA_DESC[1].offset = 0;

  115.     /* Open Channel 5 */
  116.     PDMA_Open(1 << 5);
  117.     PDMA_SetTransferMode(5, PDMA_MEM, 1, (uint32_t)&DMA_DESC[0]);
  118.     PDMA_Trigger(5);
  119.     while(PDMA_IS_CH_BUSY(5));

  120.     printf("test done...\n");

  121.     PDMA_Close();

  122.     while(1);
  123. }


捉虫天师 发表于 2018-10-14 22:48 | 显示全部楼层
PDMA不学好,没法搞带存储的
稳稳の幸福 发表于 2018-10-16 18:29 | 显示全部楼层
这个比较难。
稳稳の幸福 发表于 2018-10-16 19:35 | 显示全部楼层
确实比较难懂。
huangcunxiake 发表于 2018-10-16 21:57 | 显示全部楼层
PDMA操作不好容易出错,用好了很6
 楼主| 幸福小强 发表于 2018-10-17 15:48 | 显示全部楼层
需要弄清楚整个架构。
feng2046 发表于 2024-10-15 15:04 | 显示全部楼层
怎么传ADC
Jacquetry 发表于 2024-10-15 19:05 来自手机 | 显示全部楼层
PDMA该怎么学啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

143

主题

1727

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部