XilinxProcessorIPLib/drivers/emacps/examples/xemacps_example_intr_dma.c
LONG EmacPsDmaSingleFrameIntrExample(XEmacPs *EmacPsInstancePtr)
{
	LONG Status;
	u32 PayloadSize = 1000;
	u32 NumRxBuf = 0;
	u32 RxFrLen;
	XEmacPs_Bd *Bd1Ptr;
	XEmacPs_Bd *BdRxPtr;

	/*
	 * Clear variables shared with callbacks
	 */
	FramesRx = 0;
	FramesTx = 0;
	DeviceErrors = 0;

	if (GemVersion > 2) {
		PayloadSize = (JUMBO_FRAME_SIZE - FRAME_HDR_SIZE);
	}
	/*
	 * Calculate the frame length (not including FCS)
	 */
	TxFrameLength = XEMACPS_HDR_SIZE + PayloadSize;

	/*
	 * Setup packet to be transmitted
	 */
	EmacPsUtilFrameHdrFormatMAC(&TxFrame, EmacPsMAC);
	EmacPsUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	EmacPsUtilFrameSetPayloadData(&TxFrame, PayloadSize);

	if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
		Xil_DCacheFlushRange((UINTPTR)&TxFrame, sizeof(EthernetFrame));
	}

	/*
	 * Clear out receive packet memory area
	 */
	EmacPsUtilFrameMemClear(&RxFrame);

	if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
		Xil_DCacheFlushRange((UINTPTR)&RxFrame, sizeof(EthernetFrame));
	}

	/*
	 * Allocate RxBDs since we do not know how many BDs will be used
	 * in advance, use RXBD_CNT here.
	 */
	Status = XEmacPs_BdRingAlloc(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				      1, &BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error allocating RxBD");
		return XST_FAILURE;
	}


	/*
	 * Setup the BD. The XEmacPs_BdRingClone() call will mark the
	 * "wrap" field for last RxBD. Setup buffer address to associated
	 * BD.
	 */

	XEmacPs_BdSetAddressRx(BdRxPtr, (UINTPTR)&RxFrame);

	/*
	 * Enqueue to HW
	 */
	Status = XEmacPs_BdRingToHw(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				    1, BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error committing RxBD to HW");
		return XST_FAILURE;
	}
	/*
	 * Though the max BD size is 16 bytes for extended desc mode, performing
	 * cache flush for 64 bytes. which is equal to the cache line size.
	 */
	if (GemVersion > 2)
	{
		if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
			Xil_DCacheFlushRange((UINTPTR)BdRxPtr, 64);
		}
	}
	/*
	 * Allocate, setup, and enqueue 1 TxBDs. The first BD will
	 * describe the first 32 bytes of TxFrame and the rest of BDs
	 * will describe the rest of the frame.
	 *
	 * The function below will allocate 1 adjacent BDs with Bd1Ptr
	 * being set as the lead BD.
	 */
	Status = XEmacPs_BdRingAlloc(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				      1, &Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error allocating TxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup first TxBD
	 */
	XEmacPs_BdSetAddressTx(Bd1Ptr, (UINTPTR)&TxFrame);
	XEmacPs_BdSetLength(Bd1Ptr, TxFrameLength);
	XEmacPs_BdClearTxUsed(Bd1Ptr);
	XEmacPs_BdSetLast(Bd1Ptr);

	/*
	 * Enqueue to HW
	 */
	Status = XEmacPs_BdRingToHw(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				     1, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error committing TxBD to HW");
		return XST_FAILURE;
	}
	if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
		Xil_DCacheFlushRange((UINTPTR)Bd1Ptr, 64);
	}
	/*
	 * Set the Queue pointers
	 */
	XEmacPs_SetQueuePtr(EmacPsInstancePtr, EmacPsInstancePtr->RxBdRing.BaseBdAddr, 0, XEMACPS_RECV);
	if (GemVersion > 2) {
	XEmacPs_SetQueuePtr(EmacPsInstancePtr, EmacPsInstancePtr->TxBdRing.BaseBdAddr, 1, XEMACPS_SEND);
	}else {
		XEmacPs_SetQueuePtr(EmacPsInstancePtr, EmacPsInstancePtr->TxBdRing.BaseBdAddr, 0, XEMACPS_SEND);
	}

	/*
	 * Start the device
	 */
	XEmacPs_Start(EmacPsInstancePtr);

	/* Start transmit */
	XEmacPs_Transmit(EmacPsInstancePtr);

	/*
	 * Wait for transmission to complete
	 */
	while (!FramesTx);

	/*
	 * Now that the frame has been sent, post process our TxBDs.
	 * Since we have only submitted 1 to hardware, then there should
	 * be only 1 ready for post processing.
	 */
	if (XEmacPs_BdRingFromHwTx(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				    1, &Bd1Ptr) == 0) {
		EmacPsUtilErrorTrap
			("TxBDs were not ready for post processing");
		return XST_FAILURE;
	}

	/*
	 * Examine the TxBDs.
	 *
	 * There isn't much to do. The only thing to check would be DMA
	 * exception bits. But this would also be caught in the error
	 * handler. So we just return these BDs to the free list.
	 */


	Status = XEmacPs_BdRingFree(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				     1, Bd1Ptr);

	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}

	/*
	 * Wait for Rx indication
	 */
	while (!FramesRx);

	/*
	 * Now that the frame has been received, post process our RxBD.
	 * Since we have submitted to hardware, then there should be only 1
	 * ready for post processing.
	 */
	NumRxBuf = XEmacPs_BdRingFromHwRx(&(XEmacPs_GetRxRing
					  (EmacPsInstancePtr)), 1,
					 &BdRxPtr);
	if (0 == NumRxBuf) {
		EmacPsUtilErrorTrap("RxBD was not ready for post processing");
		return XST_FAILURE;
	}

	/*
	 * There is no device status to check. If there was a DMA error,
	 * it should have been reported to the error handler. Check the
	 * receive lengthi against the transmitted length, then verify
	 * the data.
	 */
	if (GemVersion > 2) {
		/* API to get correct RX frame size - jumbo or otherwise */
		RxFrLen = XEmacPs_GetRxFrameSize(EmacPsInstancePtr, BdRxPtr);
	} else {
		RxFrLen = XEmacPs_BdGetLength(BdRxPtr);
	}
	if (RxFrLen != TxFrameLength) {
		EmacPsUtilErrorTrap("Length mismatch");
		return XST_FAILURE;
	}

	if (EmacPsUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
		EmacPsUtilErrorTrap("Data mismatch");
		return XST_FAILURE;
	}

	/*
	 * Return the RxBD back to the channel for later allocation. Free
	 * the exact number we just post processed.
	 */
	Status = XEmacPs_BdRingFree(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				     NumRxBuf, BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error freeing up RxBDs");
		return XST_FAILURE;
	}

	/*
	 * Finished this example. If everything worked correctly, all TxBDs
	 * and RxBDs should be free for allocation. Stop the device.
	 */
	XEmacPs_Stop(EmacPsInstancePtr);

	return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* This function demonstrates the usage of the EMACPS by sending and
* receiving a single frame in DMA interrupt mode.
* The source packet will be described by two descriptors. It will be
* received into a buffer described by a single descriptor.
*
* @param	EmacPsInstancePtr is a pointer to the instance of the EmacPs
*		driver.
*
* @return	XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note		None.
*
*****************************************************************************/
This function demonstrates the usage of the EMACPS by sending and
receiving a single frame in DMA interrupt mode.
The source packet will be described by two descriptors. It will be
received into a buffer described by a single descriptor.
This function demonstrates the usage of the EMACPS by sending and receiving a single frame in DMA interrupt mode . The source packet will be described by two descriptors . It will be received into a buffer described by a single descriptor .
LONG EmacPsDmaSingleFrameIntrExample(XEmacPs *EmacPsInstancePtr)
{
	LONG Status;
	u32 PayloadSize = 1000;
	u32 NumRxBuf = 0;
	u32 RxFrLen;
	XEmacPs_Bd *Bd1Ptr;
	XEmacPs_Bd *BdRxPtr;
	FramesRx = 0;
	FramesTx = 0;
	DeviceErrors = 0;
	if (GemVersion > 2) {
		PayloadSize = (JUMBO_FRAME_SIZE - FRAME_HDR_SIZE);
	}
	TxFrameLength = XEMACPS_HDR_SIZE + PayloadSize;
	EmacPsUtilFrameHdrFormatMAC(&TxFrame, EmacPsMAC);
	EmacPsUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	EmacPsUtilFrameSetPayloadData(&TxFrame, PayloadSize);
	if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
		Xil_DCacheFlushRange((UINTPTR)&TxFrame, sizeof(EthernetFrame));
	}
	EmacPsUtilFrameMemClear(&RxFrame);
	if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
		Xil_DCacheFlushRange((UINTPTR)&RxFrame, sizeof(EthernetFrame));
	}
	Status = XEmacPs_BdRingAlloc(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				      1, &BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error allocating RxBD");
		return XST_FAILURE;
	}
	XEmacPs_BdSetAddressRx(BdRxPtr, (UINTPTR)&RxFrame);
	Status = XEmacPs_BdRingToHw(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				    1, BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error committing RxBD to HW");
		return XST_FAILURE;
	}
	if (GemVersion > 2)
	{
		if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
			Xil_DCacheFlushRange((UINTPTR)BdRxPtr, 64);
		}
	}
	Status = XEmacPs_BdRingAlloc(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				      1, &Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error allocating TxBD");
		return XST_FAILURE;
	}
	XEmacPs_BdSetAddressTx(Bd1Ptr, (UINTPTR)&TxFrame);
	XEmacPs_BdSetLength(Bd1Ptr, TxFrameLength);
	XEmacPs_BdClearTxUsed(Bd1Ptr);
	XEmacPs_BdSetLast(Bd1Ptr);
	Status = XEmacPs_BdRingToHw(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				     1, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error committing TxBD to HW");
		return XST_FAILURE;
	}
	if (EmacPsInstancePtr->Config.IsCacheCoherent == 0) {
		Xil_DCacheFlushRange((UINTPTR)Bd1Ptr, 64);
	}
	XEmacPs_SetQueuePtr(EmacPsInstancePtr, EmacPsInstancePtr->RxBdRing.BaseBdAddr, 0, XEMACPS_RECV);
	if (GemVersion > 2) {
	XEmacPs_SetQueuePtr(EmacPsInstancePtr, EmacPsInstancePtr->TxBdRing.BaseBdAddr, 1, XEMACPS_SEND);
	}else {
		XEmacPs_SetQueuePtr(EmacPsInstancePtr, EmacPsInstancePtr->TxBdRing.BaseBdAddr, 0, XEMACPS_SEND);
	}
	XEmacPs_Start(EmacPsInstancePtr);
	XEmacPs_Transmit(EmacPsInstancePtr);
	while (!FramesTx);
	if (XEmacPs_BdRingFromHwTx(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				    1, &Bd1Ptr) == 0) {
		EmacPsUtilErrorTrap
			("TxBDs were not ready for post processing");
		return XST_FAILURE;
	}
	Status = XEmacPs_BdRingFree(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				     1, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}
	while (!FramesRx);
	NumRxBuf = XEmacPs_BdRingFromHwRx(&(XEmacPs_GetRxRing
					  (EmacPsInstancePtr)), 1,
					 &BdRxPtr);
	if (0 == NumRxBuf) {
		EmacPsUtilErrorTrap("RxBD was not ready for post processing");
		return XST_FAILURE;
	}
	if (GemVersion > 2) {
		RxFrLen = XEmacPs_GetRxFrameSize(EmacPsInstancePtr, BdRxPtr);
	} else {
		RxFrLen = XEmacPs_BdGetLength(BdRxPtr);
	}
	if (RxFrLen != TxFrameLength) {
		EmacPsUtilErrorTrap("Length mismatch");
		return XST_FAILURE;
	}
	if (EmacPsUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
		EmacPsUtilErrorTrap("Data mismatch");
		return XST_FAILURE;
	}
	Status = XEmacPs_BdRingFree(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				     NumRxBuf, BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error freeing up RxBDs");
		return XST_FAILURE;
	}
	XEmacPs_Stop(EmacPsInstancePtr);
	return XST_SUCCESS;
}
LONG EmacPsDmaSingleFrameIntrExample ( XEmacPs * EmacPsInstancePtr ) { LONG Status ; u32 PayloadSize = 1000 ; u32 NumRxBuf = 0 ; u32 RxFrLen ; XEmacPs_Bd * Bd1Ptr ; XEmacPs_Bd * BdRxPtr ; FramesRx = 0 ; FramesTx = 0 ; DeviceErrors = 0 ; if ( GemVersion > 2 ) { PayloadSize = ( JUMBO_FRAME_SIZE - FRAME_HDR_SIZE ) ; } TxFrameLength = XEMACPS_HDR_SIZE + PayloadSize ; EmacPsUtilFrameHdrFormatMAC ( & TxFrame , EmacPsMAC ) ; EmacPsUtilFrameHdrFormatType ( & TxFrame , PayloadSize ) ; EmacPsUtilFrameSetPayloadData ( & TxFrame , PayloadSize ) ; if ( EmacPsInstancePtr -> Config . IsCacheCoherent == 0 ) { Xil_DCacheFlushRange ( ( UINTPTR ) & TxFrame , sizeof ( EthernetFrame ) ) ; } EmacPsUtilFrameMemClear ( & RxFrame ) ; if ( EmacPsInstancePtr -> Config . IsCacheCoherent == 0 ) { Xil_DCacheFlushRange ( ( UINTPTR ) & RxFrame , sizeof ( EthernetFrame ) ) ; } Status = XEmacPs_BdRingAlloc ( & ( XEmacPs_GetRxRing ( EmacPsInstancePtr ) ) , 1 , & BdRxPtr ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XEmacPs_BdSetAddressRx ( BdRxPtr , ( UINTPTR ) & RxFrame ) ; Status = XEmacPs_BdRingToHw ( & ( XEmacPs_GetRxRing ( EmacPsInstancePtr ) ) , 1 , BdRxPtr ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } if ( GemVersion > 2 ) { if ( EmacPsInstancePtr -> Config . IsCacheCoherent == 0 ) { Xil_DCacheFlushRange ( ( UINTPTR ) BdRxPtr , 64 ) ; } } Status = XEmacPs_BdRingAlloc ( & ( XEmacPs_GetTxRing ( EmacPsInstancePtr ) ) , 1 , & Bd1Ptr ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XEmacPs_BdSetAddressTx ( Bd1Ptr , ( UINTPTR ) & TxFrame ) ; XEmacPs_BdSetLength ( Bd1Ptr , TxFrameLength ) ; XEmacPs_BdClearTxUsed ( Bd1Ptr ) ; XEmacPs_BdSetLast ( Bd1Ptr ) ; Status = XEmacPs_BdRingToHw ( & ( XEmacPs_GetTxRing ( EmacPsInstancePtr ) ) , 1 , Bd1Ptr ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } if ( EmacPsInstancePtr -> Config . IsCacheCoherent == 0 ) { Xil_DCacheFlushRange ( ( UINTPTR ) Bd1Ptr , 64 ) ; } XEmacPs_SetQueuePtr ( EmacPsInstancePtr , EmacPsInstancePtr -> RxBdRing . BaseBdAddr , 0 , XEMACPS_RECV ) ; if ( GemVersion > 2 ) { XEmacPs_SetQueuePtr ( EmacPsInstancePtr , EmacPsInstancePtr -> TxBdRing . BaseBdAddr , 1 , XEMACPS_SEND ) ; } else { XEmacPs_SetQueuePtr ( EmacPsInstancePtr , EmacPsInstancePtr -> TxBdRing . BaseBdAddr , 0 , XEMACPS_SEND ) ; } XEmacPs_Start ( EmacPsInstancePtr ) ; XEmacPs_Transmit ( EmacPsInstancePtr ) ; while ( ! FramesTx ) ; if ( XEmacPs_BdRingFromHwTx ( & ( XEmacPs_GetTxRing ( EmacPsInstancePtr ) ) , 1 , & Bd1Ptr ) == 0 ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XEmacPs_BdRingFree ( & ( XEmacPs_GetTxRing ( EmacPsInstancePtr ) ) , 1 , Bd1Ptr ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } while ( ! FramesRx ) ; NumRxBuf = XEmacPs_BdRingFromHwRx ( & ( XEmacPs_GetRxRing ( EmacPsInstancePtr ) ) , 1 , & BdRxPtr ) ; if ( 0 == NumRxBuf ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } if ( GemVersion > 2 ) { RxFrLen = XEmacPs_GetRxFrameSize ( EmacPsInstancePtr , BdRxPtr ) ; } else { RxFrLen = XEmacPs_BdGetLength ( BdRxPtr ) ; } if ( RxFrLen != TxFrameLength ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } if ( EmacPsUtilFrameVerify ( & TxFrame , & RxFrame ) != 0 ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XEmacPs_BdRingFree ( & ( XEmacPs_GetRxRing ( EmacPsInstancePtr ) ) , NumRxBuf , BdRxPtr ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XEmacPs_Stop ( EmacPsInstancePtr ) ; return XST_SUCCESS ; }
This function demonstrates the usage of the EMACPS by sending and
receiving a single frame in DMA interrupt mode.
This function demonstrates the usage of the EMACPS by sending and receiving a single frame in DMA interrupt mode .
/*
	 * Clear variables shared with callbacks
	 */ /*
	 * Calculate the frame length (not including FCS)
	 */ /*
	 * Setup packet to be transmitted
	 */ /*
	 * Clear out receive packet memory area
	 */ /*
	 * Allocate RxBDs since we do not know how many BDs will be used
	 * in advance, use RXBD_CNT here.
	 */ /*
	 * Setup the BD. The XEmacPs_BdRingClone() call will mark the
	 * "wrap" field for last RxBD. Setup buffer address to associated
	 * BD.
	 */ /*
	 * Enqueue to HW
	 */ /*
	 * Though the max BD size is 16 bytes for extended desc mode, performing
	 * cache flush for 64 bytes. which is equal to the cache line size.
	 */ /*
	 * Allocate, setup, and enqueue 1 TxBDs. The first BD will
	 * describe the first 32 bytes of TxFrame and the rest of BDs
	 * will describe the rest of the frame.
	 *
	 * The function below will allocate 1 adjacent BDs with Bd1Ptr
	 * being set as the lead BD.
	 */ /*
	 * Setup first TxBD
	 */ /*
	 * Enqueue to HW
	 */ /*
	 * Set the Queue pointers
	 */ /*
	 * Start the device
	 */ /* Start transmit */ /*
	 * Wait for transmission to complete
	 */ /*
	 * Now that the frame has been sent, post process our TxBDs.
	 * Since we have only submitted 1 to hardware, then there should
	 * be only 1 ready for post processing.
	 */ /*
	 * Examine the TxBDs.
	 *
	 * There isn't much to do. The only thing to check would be DMA
	 * exception bits. But this would also be caught in the error
	 * handler. So we just return these BDs to the free list.
	 */ /*
	 * Wait for Rx indication
	 */ /*
	 * Now that the frame has been received, post process our RxBD.
	 * Since we have submitted to hardware, then there should be only 1
	 * ready for post processing.
	 */ /*
	 * There is no device status to check. If there was a DMA error,
	 * it should have been reported to the error handler. Check the
	 * receive lengthi against the transmitted length, then verify
	 * the data.
	 */ /* API to get correct RX frame size - jumbo or otherwise */ /*
	 * Return the RxBD back to the channel for later allocation. Free
	 * the exact number we just post processed.
	 */ /*
	 * Finished this example. If everything worked correctly, all TxBDs
	 * and RxBDs should be free for allocation. Stop the device.
	 */