/* * Check for transfer completion. * * If the DMA engine has errors or any of the finished BDs has error bit set, * then the example should fail. * * @param InstancePtr is pointer to the XAxiCdma instance. * * @return Number of Bds that have been completed by hardware. * * @note None * ******************************************************************************/ static int CheckCompletion(XAxiCdma *InstancePtr) { int BdCount; XAxiCdma_Bd *BdPtr; XAxiCdma_Bd *BdCurPtr; int Status; int Index; /* Check whether the hardware has encountered any problems. * In some error cases, the DMA engine may not able to update the * BD that has caused the problem. */ if (XAxiCdma_GetError(InstancePtr) != 0x0) { xdbg_printf(XDBG_DEBUG_ERROR, "Transfer error %x\r\n", (unsigned int)XAxiCdma_GetError(InstancePtr)); Error = 1; return 0; } /* Get all processed BDs from hardware */ BdCount = XAxiCdma_BdRingFromHw(InstancePtr, XAXICDMA_ALL_BDS, &BdPtr); /* Check finished BDs then release them */ if(BdCount > 0) { BdCurPtr = BdPtr; for (Index = 0; Index < BdCount; Index++) { /* If the completed BD has error bit set, * then the example fails */ if (XAxiCdma_BdGetSts(BdCurPtr) & XAXICDMA_BD_STS_ALL_ERR_MASK) { Error = 1; return 0; } BdCurPtr = XAxiCdma_BdRingNext(InstancePtr, BdCurPtr); } /* Release the BDs so later submission can use them */ Status = XAxiCdma_BdRingFree(InstancePtr, BdCount, BdPtr); if(Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Error free BD %x\r\n", Status); Error = 1; return 0; } Done += BdCount; } return Done; }
int XAxiCdma_Transfer(XAxiCdma *InstancePtr, u32 SrcAddr, u32 DstAddr, int byte_Length, XAxiCdma_CallBackFn SimpleCallBack, void *CallbackRef) { int Status, CDMA_Status; Status = XAxiCdma_SimpleTransfer(InstancePtr, (u32) SrcAddr , (u32) DstAddr, byte_Length, NULL, NULL); if (Status != XST_SUCCESS) { CDMA_Status = XAxiCdma_GetError(InstancePtr); if (CDMA_Status != 0x0) { XAxiCdma_Reset(InstancePtr); //xil_xil_printf("Error Code = %x\r\r\n",CDMA_Status); } return XST_FAILURE; } while (XAxiCdma_IsBusy(InstancePtr)); // Wait CDMA_Status = XAxiCdma_GetError(InstancePtr); if (CDMA_Status != 0x0) { XAxiCdma_Reset(InstancePtr); //xil_xil_printf("Error Code = %x\r\r\n",CDMA_Status); return XST_FAILURE; } return XST_SUCCESS; }
/* * This function does a multi-BD scatter gather transfer * * @param InstancePtr points to the DMA engine instance * * @return * - XST_SUCCESS if transfer finishes successfully * - XST_FAILURE if transfer has errors * * @note None. * ******************************************************************************/ static int DoSgTransfer(XAxiCdma * InstancePtr) { int Status; u8 *SrcPtr; u8 *DstPtr; SrcPtr = (u8 *)TransmitBufferPtr; DstPtr = (u8 *)ReceiveBufferPtr; /* Setup the BD ring */ Status = SetupSgTransfer(InstancePtr); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Setup BD ring failed with %d\r\n", Status); return XST_FAILURE; } /* Submit BDs to the hardware */ Status = SubmitSgTransfer(InstancePtr); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Submit transfer failed with %d\r\n", Status); return XST_FAILURE; } /* Wait until the DMA transfer is done */ while ((Done < NUMBER_OF_BDS_TO_TRANSFER) && !Error) { /* Wait */ } if(Error) { xdbg_printf(XDBG_DEBUG_ERROR, "SG transfer has error %x\r\n", (unsigned int)XAxiCdma_GetError(InstancePtr)); return XST_FAILURE; } /* Transfer completes successfully, check data */ Status = CheckData(SrcPtr, DstPtr, MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Check data failed for sg " "transfer\r\n"); return XST_FAILURE; } /* Transfer finishes successfully */ return XST_SUCCESS; }
/* * * This function does one simple transfer * * @param InstancePtr is a pointer to the XAxiCdma instance * @param Length is the transfer length * @param Retries is how many times to retry on submission * * @return * - XST_SUCCESS if transfer is successful * - XST_FAILURE if either the transfer fails or the data has * error. * * @note None. * ******************************************************************************/ static int DoSimpleTransfer(XAxiCdma *InstancePtr, int Length, int Retries) { u32 Index; u8 *SrcPtr; u8 *DestPtr; int Status; Done = 0; Error = 0; /* Initialize the source buffer bytes with a pattern and the * the destination buffer bytes to zero */ SrcPtr = (u8 *)SrcBuffer; DestPtr = (u8 *)DestBuffer; for (Index = 0; Index < Length; Index++) { SrcPtr[Index] = Index & 0xFF; DestPtr[Index] = 0; } /* Flush the SrcBuffer before the DMA transfer, in case the Data Cache * is enabled */ Xil_DCacheFlushRange((u32)&SrcBuffer, Length); /* Try to start the DMA transfer */ while (Retries) { Retries -= 1; Status = XAxiCdma_SimpleTransfer(InstancePtr, (u32)SrcBuffer, (u32)DestBuffer, Length, Example_SimpleCallBack, InstancePtr); if (Status == XST_SUCCESS) { break; } } if (!Retries) { xdbg_printf(XDBG_DEBUG_ERROR, "Submit transfer failed\r\n"); return XST_FAILURE; } /* Wait until the DMA transfer is done */ while (!Done && !Error) { /* Wait */ } if (Error) { xdbg_printf(XDBG_DEBUG_ERROR, "Simple transfer has error %x\r\n", (unsigned int)XAxiCdma_GetError(InstancePtr)); return XST_FAILURE; } /* Transfer completes successfully, check data */ Status = CheckData(SrcPtr, DestPtr, Length); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Check data failed for simple " "transfer\r\n"); return XST_FAILURE; } return XST_SUCCESS; }
/** * This function transfers data from Source Address to Destination Address * using the AXI CDMA. * User has to specify the Source Address, Destination Address and Transfer * Length in AXICDMA_SRC_ADDR, AXICDMA_DEST_ADDR and AXICDMA_LENGTH defines * respectively. * * @param DeviceId is device ID of the XAxiCdma Device. * * @return - XST_SUCCESS if successful * - XST_FAILURE.if unsuccessful. * * @note If the hardware system is not built correctly, this function * may never return to the caller. * ******************************************************************************/ int DmaDataTransfer (u16 DeviceID) { int Status; volatile int Error; XAxiCdma_Config *ConfigPtr; Error = 0; /* * Make sure we have a valid addresses for Src and Dst. */ if (AXICDMA_SRC_ADDR == 0) { return XST_FAILURE; } if (AXICDMA_DEST_ADDR == 0) { return XST_FAILURE; } /* * Initialize the AXI CDMA IP. */ ConfigPtr = XAxiCdma_LookupConfig(DeviceID); if (ConfigPtr == NULL) { return XST_FAILURE; } Status = XAxiCdma_CfgInitialize(&CdmaInstance, ConfigPtr, ConfigPtr->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Reset the AXI CDMA device. */ XAxiCdma_Reset(&CdmaInstance); /* * Disable AXI CDMA Interrupts */ XAxiCdma_IntrDisable(&CdmaInstance, XAXICDMA_XR_IRQ_ALL_MASK); /* * Start Transferring Data from source to destination in polled mode */ XAxiCdma_SimpleTransfer (&CdmaInstance, AXICDMA_SRC_ADDR, AXICDMA_DEST_ADDR, AXICDMA_LENGTH, 0, 0); /* * Poll Status register waiting for either Completion or Error */ while (XAxiCdma_IsBusy(&CdmaInstance)); Error = XAxiCdma_GetError(&CdmaInstance); if (Error != 0x0) { xil_printf("AXI CDMA Transfer Error = %8.8x\r\n"); return XST_FAILURE; } xil_printf("AXI CDMA Transfer is Complete\r\n"); return XST_SUCCESS; }
/* 0 = no error */ Hint dma_geterror( XAxiCdma *dma ) { return (XAxiCdma_GetError(dma)); }
int XAxiCdma_SgIntrExample(XScuGic *IntcInstancePtr, XAxiCdma *InstancePtr, u16 DeviceId,u32 IntrId) #endif { XAxiCdma_Config *CfgPtr; int Status; u8 *SrcPtr; u8 *DstPtr; SrcPtr = (u8 *)TransmitBufferPtr; DstPtr = (u8 *)ReceiveBufferPtr; #ifdef __aarch64__ Xil_SetTlbAttributes(BD_SPACE_BASE, MARK_UNCACHEABLE); #endif /* Initialize the XAxiCdma device. */ CfgPtr = XAxiCdma_LookupConfig(DeviceId); if (!CfgPtr) { xdbg_printf(XDBG_DEBUG_ERROR, "Cannot find config structure for device %d\r\n", XPAR_AXICDMA_0_DEVICE_ID); return XST_FAILURE; } Status = XAxiCdma_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddress); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Initialization failed with %d\r\n", Status); return XST_FAILURE; } /* Setup the BD ring */ Status = SetupTransfer(InstancePtr); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Setup BD ring failed with %d\r\n", Status); return XST_FAILURE; } /* Setup the interrupt system */ Status = SetupIntrSystem(IntcInstancePtr, InstancePtr, IntrId); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Setup Intr system failed with %d\r\n", Status); return XST_FAILURE; } /* Enable completion and error interrupts */ XAxiCdma_IntrEnable(InstancePtr, XAXICDMA_XR_IRQ_ALL_MASK); /* Start the DMA transfer */ Status = DoTransfer(InstancePtr); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Do transfer failed with %d\r\n", Status); return XST_FAILURE; } /* Wait until the DMA transfer is done */ while ((Done < NUMBER_OF_BDS_TO_TRANSFER) && !Error) { /* Wait */ } if(Error) { xdbg_printf(XDBG_DEBUG_ERROR, "Transfer has error %x\r\n", (unsigned int)XAxiCdma_GetError(InstancePtr)); DisableIntrSystem(IntcInstancePtr, IntrId); return XST_FAILURE; } /* Transfer completes successfully, check data */ Status = CheckData(SrcPtr, DstPtr, MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Check data failed for sg " "transfer\r\n"); DisableIntrSystem(IntcInstancePtr, IntrId); return XST_FAILURE; } /* Test finishes successfully, clean up and return */ DisableIntrSystem(IntcInstancePtr, IntrId); return XST_SUCCESS; }
/* * This function does one simple transfer in polled mode * * @param InstancePtr is a pointer to the XAxiCdma instance * @param Length is the transfer length * @param Retries is how many times to retry on submission * * @return * - XST_SUCCESS if transfer is successful * - XST_FAILURE if either the transfer fails or the data has * error * * @note None * ******************************************************************************/ static int DoSimplePollTransfer(XAxiCdma *InstancePtr, int Length, int Retries) { int Index; u8 *SrcPtr; u8 *DestPtr; int Status; /* Initialize the source buffer bytes with a pattern and the * the destination buffer bytes to zero */ SrcPtr = (u8 *)SrcBuffer; DestPtr = (u8 *)DestBuffer; for (Index = 0; Index < BUFFER_BYTESIZE; Index++) { SrcPtr[Index] = Index & 0xFF; DestPtr[Index] = 0; } /* Flush the SrcBuffer before the DMA transfer, in case the Data Cache * is enabled */ Xil_DCacheFlushRange((u32)&SrcBuffer, Length); /* Try to start the DMA transfer */ while (Retries) { Retries -= 1; Status = XAxiCdma_SimpleTransfer(InstancePtr, (u32)SrcBuffer, (u32)DestBuffer, Length, NULL, NULL); if (Status == XST_SUCCESS) { break; } } /* Return failure if failed to submit the transfer */ if (!Retries) { return XST_FAILURE; } /* Wait until the DMA transfer is done */ while (XAxiCdma_IsBusy(InstancePtr)) { /* Wait */ } /* If the hardware has errors, this example fails * This is a poll example, no interrupt handler is involved. * Therefore, error conditions are not cleared by the driver. */ Error = XAxiCdma_GetError(InstancePtr); if (Error != 0x0) { int TimeOut = RESET_LOOP_COUNT; /* Need to reset the hardware to restore to the correct state */ XAxiCdma_Reset(InstancePtr); while (TimeOut) { if (XAxiCdma_ResetIsDone(InstancePtr)) { break; } TimeOut -= 1; } /* Reset has failed, print a message to notify the user */ return XST_FAILURE; } /* Transfer completes successfully, check data */ Status = CheckData(SrcPtr, DestPtr, Length); if (Status != XST_SUCCESS) { return XST_FAILURE; } return XST_SUCCESS; }