发 帖  
原厂入驻New
申请华秋企业认证 多层板首单免费打样!
30s提交资料,10分钟通过审核(免费赔付+顺丰包邮)>>立即报名

[经验] 【MYD-CZU3EG开发板试用体验】04-DMA中断方式传输(官方xcsudma_intr_examples例程讲解与扩展)

2019-10-29 10:06:58  293 DMA 开发板
分享
1
       之前在第三篇中使用的DMA中断是将ZYNQ7000中的代码移植过来使用的,然而可能这并不是官方对于UltraScale系列的官方例程,而对于DMA的中断传输方式,官方也有其例程。
       本实验中使用的软件版本:Vivado2019.1;SDK版本:Release Version: 2019.1
       使用的为官方的例程xcsudma_intr_examples,而有这个例子可以扩展出我们想要实现的工程。但首先我们要弄清楚官方的这个例程的含义,才能进一步得到我们想要的功能。
       首先,我们依旧先看一下硬件图,这次我找到一个旧的下载器,用作调试使用,硬件实物图如下所示:
0401.jpg

        接着就是.bd文件(即Block Design),其设计和第三篇中的相似如下图所示:
040102.PNG

040103.PNG
       接着打开SDK界面,我们找到官方的例程并打开之,如下所示的那样:
040104.PNG
       我们可以看到,这个例程还是比较简单的,仅仅只有一个.c文件,所以代码并不很多,我在这里只保留了主要代码,便于大家理解:
  1. /**
  2. * [url=home.php?mod=space&uid=1455510]@file[/url] xcsudma_intr_example.c
  3. * This file contains a design example using the XCsuDma driver in interrupt
  4. * mode. It sends data and expects to receive the same data through the device
  5. * using the local loop back mode.
  6. *
  7. * @note
  8. * The example contains an infinite loop such that IF interrupts are not
  9. * working it may hang.
  10. *
  11. ******************************************************************************/

  12. #include "xcsudma.h"
  13. #include "xparameters.h"
  14. #include "xil_exception.h"
  15. #ifdef XPAR_INTC_0_DEVICE_ID
  16. #include "xintc.h"
  17. /*
  18. * The following constants map to the XPAR parameters created in the
  19. * xparameters.h file. They are defined here such that a user can easily
  20. * change all the needed parameters in one place.
  21. */
  22. #define CSUDMA_DEVICE_ID  XPAR_XCSUDMA_0_DEVICE_ID /* CSU DMA device Id */
  23. #ifdef XPAR_INTC_0_DEVICE_ID
  24. #define INTC                XIntc
  25. #define INTG_INTC_DEVICE_ID        XPAR_INTC_0_DEVICE_ID
  26. #define INTG_CSUDMA_INTR_DEVICE_ID XPAR_INTC_0_CSUDMA_0_VEC_ID /**< ZDMA Interrupt Id */
  27. #else
  28. #define INTC                XScuGic
  29. #define INTG_INTC_DEVICE_ID                XPAR_SCUGIC_SINGLE_DEVICE_ID
  30. #if defined (versal)
  31. #define INTG_CSUDMA_INTR_DEVICE_ID        XPAR_PSU_PMCDMA_0_INTR /**< Interrupt device ID
  32.                                                  *  of PMC DMA 0 device ID */
  33. #else
  34. #define INTG_CSUDMA_INTR_DEVICE_ID         XPAR_XCSUDMA_INTR /**< Interrupt device ID
  35.                                                  *  of CSU DMA device ID */
  36. #endif
  37. #endif

  38. #define CSU_SSS_CONFIG_OFFSET        0x008                /**< CSU SSS_CFG Offset */
  39. #define CSUDMA_LOOPBACK_CFG        0x00000050        /**< LOOP BACK configuration
  40.                                                   *  macro */
  41. #define PMC_SSS_CONFIG_OFFSET        0x500                /**< CSU SSS_CFG Offset */
  42. #define PMCDMA0_LOOPBACK_CFG        0x0000000D        /**< LOOP BACK configuration
  43.                                                   *  macro for PMCDMA0*/
  44. #define PMCDMA1_LOOPBACK_CFG        0x00000090        /**< LOOP BACK configuration
  45.                                                   *  macro for PMCDMA1*/
  46. #define SIZE                0x100                /**< Size of the data to be
  47.                                           *  transfered */
  48. u32 DstBuf[SIZE] __attribute__ ((aligned (64)));        /**< Destination buffer */
  49. u32 SrcBuf[SIZE] __attribute__ ((aligned (64)));        /**< Source buffer */

  50. int XCsuDma_IntrExample(INTC *IntcInstancePtr, XCsuDma *CsuDmaInstance,
  51.                         u16 DeviceId, u16 IntrId);
  52. static int SetupInterruptSystem(INTC *IntcInstancePtr,
  53.                                 XCsuDma *CsuDmaInstance,
  54.                                 u16 CsuDmaIntrId);
  55. void IntrHandler(void *CallBackRef);

  56. static void SrcHandler(void *CallBackRef, u32 Event);
  57. static void DstHandler(void *CallBackRef, u32 Event);

  58. XCsuDma CsuDma;                /**<Instance of the Csu_Dma Device */
  59. static INTC Intc;        /* Instance of the Interrupt Controller */
  60. u32 DstDone = 0;

  61. int main(void)
  62. {
  63.         int Status;
  64.         /* Run the selftest example */
  65.         Status = XCsuDma_IntrExample(&Intc, &CsuDma, (u16)CSUDMA_DEVICE_ID,
  66.                                      INTG_CSUDMA_INTR_DEVICE_ID);
  67.         if (Status != XST_SUCCESS) {
  68.                 xil_printf("CSU_DMA Interrupt Example FaiLED\r\n");
  69.                 return XST_FAILURE;
  70.         }
  71.         xil_printf("Successfully ran CSU_DMA Interrupt Example\r\n");
  72.         return XST_SUCCESS;
  73. }

  74. /*****************************************************************************/
  75. /**
  76. *
  77. * This function peRForms data transfer in loop back mode in interrupt mode
  78. * and verify the data.
  79. *
  80. * @param        DeviceId is the XPAR_<CSUDMA Instance>_DEVICE_ID value from
  81. *                xparameters.h.
  82. *
  83. * @return
  84. *                - XST_SUCCESS if successful.
  85. *                - XST_FAILURE if failed.
  86. *
  87. * @note                None.
  88. *
  89. ******************************************************************************/
  90. int XCsuDma_IntrExample(INTC *IntcInstancePtr, XCsuDma *CsuDmaInstance,
  91.                         u16 DeviceId, u16 IntrId)
  92. {
  93.         int Status;
  94.         XCsuDma_Config *Config;
  95.         u32 Index = 0;
  96.         u32 *SrcPtr = SrcBuf;
  97.         u32 *DstPtr = DstBuf;
  98.         u32 Test_Data = 0xABCD1234;
  99.         u32 *Ptr = SrcBuf;
  100.         u32 EnLast = 0;
  101.         /*
  102.          * Initialize the CsuDma driver so that it's ready to use
  103.          * look up the configuration in the config table,
  104.          * then initialize it.
  105.          */
  106.         Config = XCsuDma_LookupConfig(DeviceId);
  107.         if (NULL == Config) {
  108.                 return XST_FAILURE;
  109.         }

  110.         Status = XCsuDma_CfgInitialize(CsuDmaInstance, Config, Config->BaseAddress);
  111.         if (Status != XST_SUCCESS) {
  112.                 return XST_FAILURE;
  113.         }

  114. #if defined (versal)
  115.         if (Config->DmaType != XCSUDMA_DMATYPEIS_CSUDMA)
  116.                 XCsuDma_PmcReset(Config->DmaType);
  117. #endif

  118.         /*
  119.          * Performs the self-test to check hardware build.
  120.          */
  121.         Status = XCsuDma_SelfTest(CsuDmaInstance);
  122.         if (Status != XST_SUCCESS) {
  123.                 return XST_FAILURE;
  124.         }

  125.         /*
  126.          * Connect to the interrupt controller.
  127.          */
  128.         Status = SetupInterruptSystem(IntcInstancePtr, CsuDmaInstance,
  129.                                       IntrId);
  130.         if (Status != XST_SUCCESS) {
  131.                 return XST_FAILURE;
  132.         }
  133.         /* Enable interrupts */
  134.         XCsuDma_EnableIntr(CsuDmaInstance, XCSUDMA_DST_CHANNEL,
  135.                                 XCSUDMA_IXR_DONE_MASK);
  136.         /*
  137.          * Setting CSU_DMA in loop back mode.
  138.          */

  139.         if (Config->DmaType == XCSUDMA_DMATYPEIS_CSUDMA) {
  140.                 Xil_Out32(XCSU_BASEADDRESS + CSU_SSS_CONFIG_OFFSET,
  141.                         ((Xil_In32(XCSU_BASEADDRESS + CSU_SSS_CONFIG_OFFSET) & 0xF0000) |
  142.                                                 CSUDMA_LOOPBACK_CFG));
  143. #if defined (versal)
  144.         } else if(Config->DmaType == XCSUDMA_DMATYPEIS_PMCDMA0) {
  145.                 Xil_Out32(XPS_PMC_GLOBAL_BASEADDRESS + PMC_SSS_CONFIG_OFFSET,
  146.                         ((Xil_In32(XPS_PMC_GLOBAL_BASEADDRESS + PMC_SSS_CONFIG_OFFSET) & 0xFF000000) |
  147.                                                 PMCDMA0_LOOPBACK_CFG));
  148.         } else {
  149.                 Xil_Out32(XPS_PMC_GLOBAL_BASEADDRESS + PMC_SSS_CONFIG_OFFSET,
  150.                         ((Xil_In32(XPS_PMC_GLOBAL_BASEADDRESS + PMC_SSS_CONFIG_OFFSET) & 0xFF000000) |
  151.                                                 PMCDMA1_LOOPBACK_CFG));
  152. #endif
  153.         }

  154.         /* Data writing at source address location */

  155.         for(Index = 0; Index < SIZE; Index++)
  156.         {
  157.                 *Ptr = Test_Data;
  158.                 Test_Data += 0x1;
  159.                 Ptr++;
  160.         }

  161.         /* Data transfer in loop back mode */
  162.         XCsuDma_Transfer(CsuDmaInstance, XCSUDMA_DST_CHANNEL, (UINTPTR)DstBuf, SIZE, EnLast);
  163.         XCsuDma_Transfer(CsuDmaInstance, XCSUDMA_SRC_CHANNEL, (UINTPTR)SrcBuf, SIZE, EnLast);

  164.         /* Wait for generation of destination work is done */
  165.         while(DstDone == 0);
  166.         /* Disable interrupts */
  167.         XCsuDma_DisableIntr(CsuDmaInstance, XCSUDMA_DST_CHANNEL,
  168.                                 XCSUDMA_IXR_DONE_MASK);
  169.         /* To acknowledge the transfer has completed */
  170.         XCsuDma_IntrClear(CsuDmaInstance, XCSUDMA_SRC_CHANNEL, XCSUDMA_IXR_DONE_MASK);
  171.         XCsuDma_IntrClear(CsuDmaInstance, XCSUDMA_DST_CHANNEL, XCSUDMA_IXR_DONE_MASK);

  172.         /*
  173.          * Verifying data of transfered by comparing data at
  174.          * source and address locations.
  175.          */

  176.         for (Index = 0; Index < SIZE; Index++) {
  177.                 if (*SrcPtr != *DstPtr) {
  178.                         return XST_FAILURE;
  179.                 }
  180.                 else {
  181.                         SrcPtr++;
  182.                         DstPtr++;
  183.                 }
  184.         }

  185.         return XST_SUCCESS;
  186. }

  187. /*****************************************************************************/
  188. /**
  189. * This function sets up the interrupt system so interrupts can occur for the
  190. * CSU DMA. This function is application-specific. The user should modify this
  191. * function to fit the application.
  192. *
  193. * @param        IntcInstancePtr is a pointer to the instance of the INTC.
  194. * @param        InstancePtr contains a pointer to the instance of the CSU DMA
  195. *                driver which is going to be connected to the interrupt
  196. *                controller.
  197. * @param        IntrId is the interrupt Id and is typically
  198. *                XPAR_<CSUDMA_instance>_INTR value from xparameters.h.
  199. *
  200. * @return
  201. *                - XST_SUCCESS if successful
  202. *                - XST_FAILURE if failed
  203. *
  204. * @note                None.
  205. ****************************************************************************/
  206. static int SetupInterruptSystem(INTC *IntcInstancePtr,
  207.                                 XCsuDma *InstancePtr,
  208.                                 u16 IntrId)
  209. {
  210.         int Status;

  211. #ifdef XPAR_INTC_0_DEVICE_ID
  212. #ifndef TESTAPP_GEN
  213.         /* Initialize the interrupt controller and connect the ISRs */
  214.         Status = XIntc_Initialize(IntcInstancePtr, INTG_INTC_DEVICE_ID);
  215.         if (Status != XST_SUCCESS)
  216.         {

  217.                 xil_printf("Failed init intc\r\n");
  218.                 return XST_FAILURE;
  219.         }
  220. #endif
  221.         /*
  222.          * Connect the driver interrupt handler
  223.          */
  224.         Status = XIntc_Connect(IntcInstancePtr, IntrId,
  225.                                 (XInterruptHandler)IntrHandler, InstancePtr);
  226.         if (Status != XST_SUCCESS)
  227.         {

  228.                 xil_printf("Failed connect intc\r\n");
  229.                 return XST_FAILURE;
  230.         }
  231. #ifndef TESTAPP_GEN
  232.         /*
  233.          * Start the interrupt controller such that interrupts are enabled for
  234.          * all devices that cause interrupts.
  235.          */
  236.         Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
  237.         if (Status != XST_SUCCESS)
  238.         {
  239.                 return XST_FAILURE;
  240.         }
  241. #endif

  242.         /*
  243.          * Enable the interrupt for the CSUDMA device.
  244.          */
  245.         XIntc_Enable(IntcInstancePtr, IntrId);
  246. #ifndef TESTAPP_GEN
  247.         Xil_ExceptionInit();
  248.         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
  249.                                 (Xil_ExceptionHandler)XIntc_InterruptHandler,
  250.                                 (void *)IntcInstancePtr);
  251. #endif
  252. #else
  253. #ifndef TESTAPP_GEN
  254.         XScuGic_Config *IntcConfig; /* Config for interrupt controller */
  255.         /*
  256.          * Initialize the interrupt controller driver
  257.          */
  258.         IntcConfig = XScuGic_LookupConfig(INTG_INTC_DEVICE_ID);
  259.         if (NULL == IntcConfig) {
  260.                 return XST_FAILURE;
  261.         }
  262.         Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
  263.                                         IntcConfig->CpuBaseAddress);
  264.         if (Status != XST_SUCCESS) {
  265.                 return XST_FAILURE;
  266.         }
  267.         /*
  268.          * Connect the interrupt controller interrupt handler to the
  269.          * hardware interrupt handling logic in the processor.
  270.          */
  271.         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
  272.                         (Xil_ExceptionHandler) XScuGic_InterruptHandler,
  273.                                 IntcInstancePtr);
  274. #endif
  275.         /*
  276.          * Connect a device driver handler that will be called when an
  277.          * interrupt for the device occurs, the device driver handler
  278.          * performs the specific interrupt processing for the device
  279.          */
  280.         Status = XScuGic_Connect(IntcInstancePtr, IntrId,
  281.                         (Xil_ExceptionHandler) IntrHandler,
  282.                                   (void *) InstancePtr);
  283.         if (Status != XST_SUCCESS) {
  284.                 return XST_FAILURE;
  285.         }
  286.         /*
  287.          * Enable the interrupt for the device
  288.          */
  289.         XScuGic_Enable(IntcInstancePtr, IntrId);
  290. #endif
  291. #ifndef TESTAPP_GEN
  292.         /*
  293.          * Enable interrupts
  294.          */
  295.         Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
  296. #endif
  297.         return XST_SUCCESS;
  298. }

  299. /*****************************************************************************/
  300. /**
  301. *
  302. * This function is the interrupt handler for the CSU_DMA driver.
  303. *
  304. * This handler reads the interrupt status from the Status register, determines
  305. * the source of the interrupts, calls according callbacks, and finally clears
  306. * the interrupts.
  307. *
  308. * @param        CallBackRef is the callback reference passed from the interrupt
  309. *                handler, which in our case is a pointer to the driver instance.
  310. *
  311. * @return        None.
  312. *
  313. * @note                None.
  314. *
  315. ******************************************************************************/
  316. void IntrHandler(void *CallBackRef)
  317. {
  318.         u32 SrcPending;
  319.         u32 DstPending;
  320.         XCsuDma *XCsuDmaPtr = NULL;
  321.         XCsuDmaPtr = (XCsuDma *)((void *)CallBackRef);

  322.         /* Handling interrupt */

  323.         /* Getting pending interrupts of source */
  324.         SrcPending = XCsuDma_IntrGetStatus(XCsuDmaPtr, XCSUDMA_SRC_CHANNEL);
  325.         XCsuDma_IntrClear(XCsuDmaPtr, XCSUDMA_SRC_CHANNEL, SrcPending);
  326.         SrcPending &= (~XCsuDma_GetIntrMask(XCsuDmaPtr, XCSUDMA_SRC_CHANNEL));

  327.         /* Getting pending interrupts of destination */
  328.         DstPending = XCsuDma_IntrGetStatus(XCsuDmaPtr, XCSUDMA_DST_CHANNEL);
  329.         XCsuDma_IntrClear(XCsuDmaPtr, XCSUDMA_DST_CHANNEL, DstPending);
  330.         DstPending &= (~XCsuDma_GetIntrMask(XCsuDmaPtr, XCSUDMA_DST_CHANNEL));

  331.         if (SrcPending != 0x00) {
  332.                 SrcHandler(XCsuDmaPtr, SrcPending);
  333.         }
  334.         if (DstPending != 0x00) {
  335.                 DstHandler(XCsuDmaPtr, DstPending);
  336.         }
  337. }

  338. /*****************************************************************************/
  339. /**
  340. * This is static function which handlers source channel interrupts.
  341. *
  342. * @param        CallBackRef is the callback reference passed from the interrupt
  343. *                handler, which in our case is a pointer to the driver instance.
  344. * @param        Event specifies which interrupts were occured.
  345. *
  346. * @return        None.
  347. * @note                None.
  348. *
  349. ******************************************************************************/
  350. static void SrcHandler(void *CallBackRef, u32 Event)
  351. {
  352.     //该中断函数在本例中没有用到,在这里就是空函数,
  353.     //如果需要,我会在附上该段代码
  354. }

  355. /*****************************************************************************/
  356. /**
  357. * This static function handles destination channel interrupts.
  358. *
  359. * @param        CallBackRef is the callback reference passed from the interrupt
  360. *                handler, which in our case is a pointer to the driver instance.
  361. * @param        Event specifies which interrupts were occured.
  362. *
  363. * @return        None.
  364. * @note                None.
  365. *
  366. ******************************************************************************/
  367. static void DstHandler(void *CallBackRef, u32 Event){
  368.     //由于代码太多,省略一些条件判断。
  369.    //只保留了本实验中需要的代码

  370.     if (Event & XCSUDMA_IXR_DONE_MASK) {
  371.         DstDone = 1;
  372.     }
  373. }
复制代码
      其中,传输的核心函数即为:XCsuDma_Transfer( ),这个函数负责向DMA发送或接收DMA传来的数据,这个函数的代码为:
  1. /*****************************************************************************/
  2. /**
  3. *
  4. * This function sets the starting address and amount(size) of the data to be
  5. * transfered from/to the memory through the AXI interface.
  6. *
  7. * @param        InstancePtr is a pointer to XCsuDma instance to be worked on.
  8. * @param        Channel represents the type of channel either it is Source or
  9. *                 Destination.
  10. *                Source channel      - XCSUDMA_SRC_CHANNEL
  11. *                Destination Channel - XCSUDMA_DST_CHANNEL
  12. * @param        Addr is a 64 bit variable which holds the starting address of
  13. *                 data which needs to write into the memory(DST) (or read        from
  14. *                 the memory(SRC)).
  15. * @param        Size is a 32 bit variable which represents the number of 4 byte
  16. *                 words needs to be transfered from starting address.
  17. * @param        EnDataLast is to trigger an end of message. It will enable or
  18. *                 disable data_inp_last signal to stream interface when current
  19. *                 command is completed. It is applicable only to source channel
  20. *                 and neglected for destination channel.
  21. *                 -        1 - Asserts data_inp_last signal.
  22. *                 -        0 - data_inp_last will not be asserted.
  23. *
  24. * @return        None.
  25. *
  26. * @note                Data_inp_last signal is asserted simultaneously with the
  27. *                 data_inp_valid signal associated with the final 32-bit word
  28. *                transfer.
  29. *
  30. ******************************************************************************/
  31. void XCsuDma_Transfer(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
  32.                                         UINTPTR Addr, u32 Size, u8 EnDataLast)
  33. {
  34.         /* Verify arguments */
  35.         Xil_AssertVoid(InstancePtr != NULL);
  36.         Xil_AssertVoid(((Addr) & (u64)(XCSUDMA_ADDR_LSB_MASK)) == (u64)0x00);
  37.         Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
  38.                                         (Channel == (XCSUDMA_DST_CHANNEL)));
  39.         Xil_AssertVoid(Size <= (u32)(XCSUDMA_SIZE_MAX));
  40.         Xil_AssertVoid(InstancePtr->IsReady == (u32)(XIL_COMPONENT_IS_READY));

  41. #if !defined(PSU_PMU)
  42.         /* Flushing cache memory */
  43.         if (Channel == (XCSUDMA_SRC_CHANNEL)) {
  44.                 Xil_DCacheFlushRange(Addr, Size << (u32)(XCSUDMA_SIZE_SHIFT));
  45.         }
  46.         /* Invalidating cache memory */
  47.         else {
  48. #if defined(__aarch64__)
  49.                 Xil_DCacheInvalidateRange(Addr, Size <<
  50.                                         (u32)(XCSUDMA_SIZE_SHIFT));
  51. #else
  52.                 Xil_DCacheFlushRange(Addr, Size << (u32)(XCSUDMA_SIZE_SHIFT));
  53. #endif
  54.         }
  55. #endif

  56.         XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
  57.                 ((u32)(XCSUDMA_ADDR_OFFSET) +
  58.                 ((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
  59.                                 ((u32)(Addr) & (u32)(XCSUDMA_ADDR_MASK)));

  60.         XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
  61.                 ((u32)(XCSUDMA_ADDR_MSB_OFFSET) +
  62.                         ((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
  63.                         ((u32)((Addr & ULONG64_HI_MASK) >> XCSUDMA_MSB_ADDR_SHIFT) &
  64.                                         (u32)(XCSUDMA_MSB_ADDR_MASK)));

  65.         if (EnDataLast == (u8)(XCSUDMA_LAST_WORD_MASK)) {
  66.                 XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
  67.                         ((u32)(XCSUDMA_SIZE_OFFSET) +
  68.                                 ((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
  69.                         ((Size << (u32)(XCSUDMA_SIZE_SHIFT)) |
  70.                                         (u32)(XCSUDMA_LAST_WORD_MASK)));
  71.         }
  72.         else {
  73.                 XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
  74.                         ((u32)(XCSUDMA_SIZE_OFFSET) +
  75.                                 ((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
  76.                                 (Size << (u32)(XCSUDMA_SIZE_SHIFT)));
  77.         }
  78. }
复制代码
      这个函数主要对两个寄存器进行操作,即为:
0406.PNG
0407.PNG

       而接收完成或是发送完成则由中断通知CPU,这个中断函数即为:IntrHandler(void *CallBackRef),而这个中断函数又分为接收和发送完成两部分,其代码为:

  1. void IntrHandler(void *CallBackRef)
  2. {
  3.         u32 SrcPending;
  4.         u32 DstPending;
  5.         XCsuDma *XCsuDmaPtr = NULL;
  6.         XCsuDmaPtr = (XCsuDma *)((void *)CallBackRef);

  7.         /* Handling interrupt */

  8.         /* Getting pending interrupts of source */
  9.         SrcPending = XCsuDma_IntrGetStatus(XCsuDmaPtr, XCSUDMA_SRC_CHANNEL);
  10.         XCsuDma_IntrClear(XCsuDmaPtr, XCSUDMA_SRC_CHANNEL, SrcPending);
  11.         SrcPending &= (~XCsuDma_GetIntrMask(XCsuDmaPtr, XCSUDMA_SRC_CHANNEL));

  12.         /* Getting pending interrupts of destination */
  13.         DstPending = XCsuDma_IntrGetStatus(XCsuDmaPtr, XCSUDMA_DST_CHANNEL);
  14.         XCsuDma_IntrClear(XCsuDmaPtr, XCSUDMA_DST_CHANNEL, DstPending);
  15.         DstPending &= (~XCsuDma_GetIntrMask(XCsuDmaPtr, XCSUDMA_DST_CHANNEL));


  16.         if (SrcPending != 0x00) {
  17.                 SrcHandler(XCsuDmaPtr, SrcPending);
  18.         }

  19.         if (DstPending != 0x00) {
  20.                 DstHandler(XCsuDmaPtr, DstPending);
  21.         }
  22. }
复制代码
      即在XCsuDma_Transfer( )接收到设定数量的数据完成后,会进入到中断函数中去,从而执行DstHandler(XCsuDmaPtr, DstPending);
       调试过程也是如此的,在debug模式下,可以设置断点观察,如下所示:
0402.PNG
0403.PNG
0404.PNG
       可以看到,执行过程中DstDone置位,主函数可以继续执行下去。
       最终的结果:
0405.PNG
       这就是这个例程,大家可以在这个例程的基础上进行就该就可以了。

相关经验

这个有意思哈,感谢分享
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

发经验
关闭

站长推荐 上一条 /10 下一条

快速回复 返回顶部 返回列表