Created
November 6, 2013 15:48
-
-
Save anonymous/7338398 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* FreeRTOS+UDP V1.0.1 (C) 2013 Real Time Engineers ltd. | |
* All rights reserved | |
* | |
* This file is part of the FreeRTOS+UDP distribution. The FreeRTOS+UDP license | |
* terms are different to the FreeRTOS license terms. | |
* | |
* FreeRTOS+UDP uses a dual license model that allows the software to be used | |
* under a standard GPL open source license, or a commercial license. The | |
* standard GPL license (unlike the modified GPL license under which FreeRTOS | |
* itself is distributed) requires that all software statically linked with | |
* FreeRTOS+UDP is also distributed under the same GPL V2 license terms. | |
* Details of both license options follow: | |
* | |
* - Open source licensing - | |
* FreeRTOS+UDP is a free download and may be used, modified, evaluated and | |
* distributed without charge provided the user adheres to version two of the | |
* GNU General Public License (GPL) and does not remove the copyright notice or | |
* this text. The GPL V2 text is available on the gnu.org web site, and on the | |
* following URL: http://www.FreeRTOS.org/gpl-2.0.txt. | |
* | |
* - Commercial licensing - | |
* Businesses and individuals that for commercial or other reasons cannot comply | |
* with the terms of the GPL V2 license must obtain a commercial license before | |
* incorporating FreeRTOS+UDP into proprietary software for distribution in any | |
* form. Commercial licenses can be purchased from http://shop.freertos.org/udp | |
* and do not require any source files to be changed. | |
* | |
* FreeRTOS+UDP is distributed in the hope that it will be useful. You cannot | |
* use FreeRTOS+UDP unless you agree that you use the software 'as is'. | |
* FreeRTOS+UDP is provided WITHOUT ANY WARRANTY; without even the implied | |
* warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
* PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they | |
* implied, expressed, or statutory. | |
* | |
* 1 tab == 4 spaces! | |
* | |
* http://www.FreeRTOS.org | |
* http://www.FreeRTOS.org/udp | |
* | |
*/ | |
/* Standard includes. */ | |
#include <stdint.h> | |
/* FreeRTOS includes. */ | |
#include "FreeRTOS.h" | |
#include "task.h" | |
#include "queue.h" | |
#include "semphr.h" | |
/* Hardware abstraction. */ | |
/* FreeRTOS+UDP includes. */ | |
#include "FreeRTOS_UDP_IP.h" | |
#include "FreeRTOS_Sockets.h" | |
#include "NetworkBufferManagement.h" | |
/* Driver includes */ | |
#include "xemaclite.h" | |
#include "xemaclite_example.h" | |
/* Demo includes. */ | |
#include "NetworkInterface.h" | |
#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1 | |
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer | |
#else | |
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) ) | |
#endif | |
/* When a packet is ready to be sent, if it cannot be sent immediately then the | |
task performing the transmit will block for niTX_BUFFER_FREE_WAIT | |
milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving | |
up. */ | |
#define niTX_BUFFER_FREE_WAIT ( ( portTickType ) 2UL / portTICK_RATE_MS ) | |
#define niMAX_TX_ATTEMPTS ( 5 ) | |
/* The length of the queue used to send interrupt status words from the | |
interrupt handler to the deferred handler task. */ | |
#define niINTERRUPT_QUEUE_LENGTH ( 10 ) | |
/*-----------------------------------------------------------*/ | |
/* | |
* A deferred interrupt handler task that processes | |
*/ | |
static void prvEMACHandlerTask( void *pvParameters ); | |
/*-----------------------------------------------------------*/ | |
/* The queue used to communicate Ethernet events with the IP task. */ | |
extern xQueueHandle xNetworkEventQueue; | |
/* The semaphore used to wake the deferred interrupt handler task when an Rx | |
interrupt is received. */ | |
static xSemaphoreHandle xEMACRxEventSemaphore = NULL; | |
/*-----------------------------------------------------------*/ | |
#define EMACLITE_TEST_FRAME_SIZE 1000 | |
/**************************** Type Definitions *******************************/ | |
/***************** Macros (Inline Functions) Definitions *********************/ | |
/************************** Function Prototypes ******************************/ | |
int EmacLitePolledExample(u16 DeviceId); | |
static int EmacLiteSendFrame(XEmacLite *InstancePtr, u32 PayloadSize); | |
static int EmacLiteRecvFrame(u32 PayloadSize); | |
/************************** Variable Definitions *****************************/ | |
/* | |
* Set up valid local and remote MAC addresses. This loop back test uses the | |
* LocalAddress both as a source and destination MAC address. | |
*/ | |
static u8 LocalAddress[XEL_MAC_ADDR_SIZE] = | |
{ | |
0x00, 0x0A, 0x35, 0x01, 0x02, 0x03 | |
}; | |
static u8 RemoteAddress[XEL_MAC_ADDR_SIZE] = | |
{ | |
0x00, 0x10, 0xa4, 0xb6, 0xfd, 0x09 | |
}; | |
portBASE_TYPE xNetworkInterfaceInitialise( void ) | |
{ | |
int Status; | |
XEmacLite *EmacLiteInstPtr = &EmacLiteInstance; | |
u32 PhyAddress = 0; | |
RecvFrameLength = 0; | |
XEmacLite_Config *ConfigPtr; | |
portBASE_TYPE xStatus; | |
/* | |
* Initialize the EmacLite device. | |
*/ | |
ConfigPtr = XEmacLite_LookupConfig(XPAR_ETHERNET_LITE_DEVICE_ID); | |
if (ConfigPtr == NULL) { | |
return XST_FAILURE; | |
} | |
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr, | |
ConfigPtr, | |
ConfigPtr->BaseAddress); | |
if (Status != XST_SUCCESS) { | |
return XST_FAILURE; | |
} | |
/* | |
* Set the MAC address. | |
*/ | |
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalAddress); | |
/* | |
* Empty any existing receive frames. | |
*/ | |
XEmacLite_FlushReceive(EmacLiteInstPtr); | |
/* | |
* Check if there is a TX buffer available, if there isn't it is an | |
* error. | |
*/ | |
if (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) { | |
return XST_FAILURE; | |
} | |
/* | |
* If the MDIO is configured in the device. | |
*/ | |
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) { | |
/* | |
* Detect the PHY device and enable the MAC Loop back | |
* in the PHY. | |
*/ | |
PhyAddress = EmacLitePhyDetect(EmacLiteInstPtr); | |
Status = EmacLiteEnablePhyLoopBack(EmacLiteInstPtr, | |
PhyAddress); | |
if (Status != XST_SUCCESS) { | |
return XST_FAILURE; | |
} | |
} | |
/* | |
* Reset the receive frame length to zero. | |
*/ | |
RecvFrameLength = 0; | |
Status = EmacLiteSendFrame(EmacLiteInstPtr, EMACLITE_TEST_FRAME_SIZE); | |
if (Status != XST_SUCCESS) { | |
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) { | |
/* | |
* Disable the MAC Loop back in the PHY. | |
*/ | |
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, | |
PhyAddress); | |
return XST_FAILURE; | |
} | |
} | |
/* | |
* If the MDIO is not configured in the core then return XST_SUCCESS | |
* as the frame has been transmitted. | |
*/ | |
if (!XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) { | |
return XST_SUCCESS; | |
} | |
/* | |
* Poll for receive packet. | |
*/ | |
while ((volatile u32)RecvFrameLength == 0) { | |
RecvFrameLength = XEmacLite_Recv(EmacLiteInstPtr, | |
(u8 *)RxFrame); | |
} | |
/* | |
* Check the received frame. | |
*/ | |
Status = EmacLiteRecvFrame(EMACLITE_TEST_FRAME_SIZE); | |
if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) { | |
/* | |
* Disable the MAC Loop back in the PHY. | |
*/ | |
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress); | |
return XST_FAILURE; | |
} | |
/* | |
* Disable the MAC Loop back in the PHY. | |
*/ | |
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress); | |
vSemaphoreCreateBinary( xEMACRxEventSemaphore ); | |
configASSERT( xEMACRxEventSemaphore ); | |
/* The handler task is created at the highest possible priority to | |
ensure the interrupt handler can return directly to it. */ | |
xTaskCreate( prvEMACHandlerTask, ( const signed char * const ) "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL ); | |
return xStatus; | |
} | |
portBASE_TYPE xNetworkInterfaceOutput( xNetworkBufferDescriptor_t * const pxNetworkBuffer ) | |
{ | |
u8 *FramePtr; | |
int Index; | |
FramePtr = (u8 *)TxFrame; | |
/* | |
* Set up the destination address as the local address for | |
* Phy Loopback. | |
*/ | |
if (XEmacLite_IsMdioConfigured(InstancePtr)) { | |
*FramePtr++ = LocalAddress[0]; | |
*FramePtr++ = LocalAddress[1]; | |
*FramePtr++ = LocalAddress[2]; | |
*FramePtr++ = LocalAddress[3]; | |
*FramePtr++ = LocalAddress[4]; | |
*FramePtr++ = LocalAddress[5]; | |
} else { | |
/* | |
* Fill in the valid Destination MAC address if | |
* the Loopback is not enabled. | |
*/ | |
*FramePtr++ = RemoteAddress[0]; | |
*FramePtr++ = RemoteAddress[1]; | |
*FramePtr++ = RemoteAddress[2]; | |
*FramePtr++ = RemoteAddress[3]; | |
*FramePtr++ = RemoteAddress[4]; | |
*FramePtr++ = RemoteAddress[5]; | |
} | |
/* | |
* Fill in the source MAC address. | |
*/ | |
*FramePtr++ = LocalAddress[0]; | |
*FramePtr++ = LocalAddress[1]; | |
*FramePtr++ = LocalAddress[2]; | |
*FramePtr++ = LocalAddress[3]; | |
*FramePtr++ = LocalAddress[4]; | |
*FramePtr++ = LocalAddress[5]; | |
/* | |
* Set up the type/length field - be sure its in network order. | |
*/ | |
*((u16 *)FramePtr) = Xil_Htons(PayloadSize); | |
FramePtr++; | |
FramePtr++; | |
/* | |
* Now fill in the data field with known values so we can verify them | |
* on receive. | |
*/ | |
for (Index = 0; Index < PayloadSize; Index++) { | |
*FramePtr++ = (u8)Index; | |
} | |
/* | |
* Now send the frame. | |
*/ | |
XEmacLite_Send(InstancePtr, (u8 *)TxFrame, PayloadSize + XEL_HEADER_SIZE); | |
return xReturn; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment