Update EMAC driver.
diff --git a/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzp b/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzp
index 284f782..644e120 100644
--- a/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzp
+++ b/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzp
@@ -25,13 +25,15 @@
         <file file_name="../Common/Minimal/PollQ.c"/>
       </folder>
       <file file_name="main.c"/>
-      <folder Name="WEB Server">
+      <folder Name="WEB Server" file_name="">
         <file file_name="../Common/ethernet/uIP/uip-1.0/uip/uip.c"/>
         <file file_name="../Common/ethernet/uIP/uip-1.0/uip/uip_arp.c"/>
         <file file_name="../Common/ethernet/uIP/uip-1.0/uip/psock.c"/>
         <file file_name="../Common/ethernet/uIP/uip-1.0/uip/timer.c"/>
         <file file_name="webserver/uIP_Task.c"/>
-        <file file_name="webserver/emac.c"/>
+        <file file_name="webserver/emac.c">
+          <configuration Name="THUMB Flash Debug" build_exclude_from_build="No"/>
+        </file>
         <file file_name="webserver/httpd.c"/>
         <file file_name="webserver/httpd-cgi.c"/>
         <file file_name="webserver/httpd-fs.c"/>
diff --git a/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzs b/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzs
index a7228d4..df6f6f4 100644
--- a/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzs
+++ b/Demo/CORTEX_LPC1768_GCC_Rowley/RTOSDemo.hzs
@@ -19,6 +19,9 @@
   <ProjectSessionItem path="RTOSDemo" name="unnamed" />
   <ProjectSessionItem path="RTOSDemo;RTOSDemo" name="unnamed" />
   <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files" name="unnamed" />
+  <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;Common Demo Tasks" name="unnamed" />
+  <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;FreeRTOS" name="unnamed" />
+  <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;WEB Server" name="unnamed" />
  </Project>
  <Register1>
   <RegisterWindow openNodes="CPU;CPU/xPSR;CPU/CFBP;CPU/CFBP/CONTROL[0];CPU/CFBP/CONTROL[1]" binaryNodes="" unsignedNodes="" visibleGroups="CPU" decimalNodes="" octalNodes="" asciiNodes="" />
@@ -49,7 +52,12 @@
   <Watches active="0" update="Never" />
  </Watch4>
  <Files>
-  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" y="172" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" left="0" selected="1" name="unnamed" top="150" />
+  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\emac.c" y="523" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\emac.c" left="0" selected="0" name="unnamed" top="489" />
+  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" y="172" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" left="0" selected="1" name="unnamed" top="355" />
+  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\uIP_Task.c" y="166" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\uIP_Task.c" left="0" selected="0" name="unnamed" top="138" />
+  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="8" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\EthDev_LPC17xx.h" y="277" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\EthDev_LPC17xx.h" left="0" selected="0" name="unnamed" top="13" />
+  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Source\queue.c" y="1049" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Source\queue.c" left="0" selected="0" name="unnamed" top="1027" />
+  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\Common\Minimal\integer.c" y="155" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\Common\Minimal\integer.c" left="0" selected="0" name="unnamed" top="133" />
  </Files>
- <ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="Amontec JTAGkey" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley" fileDialogDefaultFilter="*.*" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
+ <ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="Amontec JTAGkey" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver" fileDialogDefaultFilter="*.*" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
 </session>
diff --git a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev.h b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev.h
index 1e17438..b2a949c 100644
--- a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev.h
+++ b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev.h
@@ -103,7 +103,7 @@
 unsigned int   	Rdy4Tx(void);

 void           	DoSend_EMAC(unsigned short FrameSize);

 void 			vEMACWaitForInput( void );

-unsigned int 	uiGetEMACRxData( unsigned char *ucBuffer );

-

+unsigned long 	ulGetEMACRxData( void );

+void vSendEMACTxData( unsigned short usTxDataLen );

 

 #endif

diff --git a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev_LPC17xx.h b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev_LPC17xx.h
index 3af1e8f..9313443 100644
--- a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev_LPC17xx.h
+++ b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/EthDev_LPC17xx.h
@@ -25,8 +25,8 @@
 #include <stdint.h>

 

 /* EMAC Memory Buffer configuration for 16K Ethernet RAM. */

-#define NUM_RX_FRAG         4           /* Num.of RX Fragments 4*1536= 6.0kB */

-#define NUM_TX_FRAG         3           /* Num.of TX Fragments 3*1536= 4.6kB */

+#define NUM_RX_FRAG         3           /* Num.of RX Fragments. */

+#define NUM_TX_FRAG         2           /* Num.of TX Fragments. */

 #define ETH_FRAG_SIZE       1536        /* Packet Fragment size 1536 Bytes   */

 

 #define ETH_MAX_FLEN        1536        /* Max. Ethernet Frame Size          */

@@ -57,8 +57,7 @@
 #define RX_STAT_BASE        (RX_DESC_BASE + NUM_RX_FRAG*(2*4))     /* 2 * uint32_t, see RX_DESC_TypeDef */

 #define TX_DESC_BASE        (RX_STAT_BASE + NUM_RX_FRAG*(2*4))     /* 2 * uint32_t, see RX_STAT_TypeDef */

 #define TX_STAT_BASE        (TX_DESC_BASE + NUM_TX_FRAG*(2*4))     /* 2 * uint32_t, see TX_DESC_TypeDef */

-#define RX_BUF_BASE         (TX_STAT_BASE + NUM_TX_FRAG*(1*4))     /* 1 * uint32_t, see TX_STAT_TypeDef */

-#define TX_BUF_BASE         (RX_BUF_BASE  + NUM_RX_FRAG*ETH_FRAG_SIZE)

+#define ETH_BUF_BASE		(TX_STAT_BASE + NUM_TX_FRAG*(1*4))     /* 1 * uint32_t, see TX_STAT_TypeDef */

 

 /* RX and TX descriptor and status definitions. */

 #define RX_DESC_PACKET(i)   (*(unsigned int *)(RX_DESC_BASE   + 8*i))

@@ -68,9 +67,8 @@
 #define TX_DESC_PACKET(i)   (*(unsigned int *)(TX_DESC_BASE   + 8*i))

 #define TX_DESC_CTRL(i)     (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))

 #define TX_STAT_INFO(i)     (*(unsigned int *)(TX_STAT_BASE   + 4*i))

-#define RX_BUF(i)           (RX_BUF_BASE + ETH_FRAG_SIZE*i)

-#define TX_BUF(i)           (TX_BUF_BASE + ETH_FRAG_SIZE*i)

-

+#define ETH_BUF(i)          ( ETH_BUF_BASE + ETH_FRAG_SIZE*i )

+#define ETH_NUM_BUFFERS		( NUM_TX_FRAG + NUM_RX_FRAG + 1 ) /* There are in fact 2 more buffers than descriptors as the two Tx descriptors use the same buffer to speed up the uip Tx. */

 

 

 /* MAC Configuration Register 1 */

diff --git a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/emac.c b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/emac.c
index 5b5055a..5e350ed 100644
--- a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/emac.c
+++ b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/emac.c
@@ -30,8 +30,16 @@
 #define emacFULL_DUPLEX_ENABLED		( 0x0004 )

 #define emac10BASE_T_MODE			( 0x0002 )

 

+/* If no buffers are available, then wait this long before looking again.... */

+#define emacBUFFER_WAIT_DELAY	( 3 / portTICK_RATE_MS )

+

+/* ...and don't look more than this many times. */

+#define emacBUFFER_WAIT_ATTEMPTS	( 30 )

+

+#define emacTX_DESC_INDEX			( 0 )

+

 /* The semaphore used to wake the uIP task when data arives. */

-xSemaphoreHandle		xEMACSemaphore = NULL;

+extern xSemaphoreHandle xEMACSemaphore;

 

 static unsigned short	*rptr;

 static unsigned short	*tptr;

@@ -40,6 +48,21 @@
 static void prvSetupEMACHardware( void );

 static void prvConfigurePHY( void );

 static long prvSetupLinkStatus( void );

+static unsigned char *prvGetNextBuffer( void );

+static void prvReturnBuffer( unsigned char *pucBuffer );

+

+/* Each ucBufferInUse index corresponds to a position in the same index in the

+ucMACBuffers array.  If the index contains a 1 then the buffer within

+ucMACBuffers is in use, if it contains a 0 then the buffer is free. */

+static unsigned char ucBufferInUse[ ETH_NUM_BUFFERS ] = { pdFALSE };

+

+/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers

+allocated within this file. */

+unsigned char * uip_buf;

+

+/* Store the length of the data being sent so the data can be sent twice.  The

+value will be set back to 0 once the data has been sent twice. */

+static unsigned short usSendLen = 0;

 

 /*-----------------------------------------------------------*/

 

@@ -74,7 +97,7 @@
 }

 /*-----------------------------------------------------------*/

 

-unsigned short read_PHY( unsigned char ucPhyReg, portBASE_TYPE *pxStatus )

+unsigned short read_PHY( unsigned char ucPhyReg, long *plStatus )

 {

 long x;

 const long lMaxTime = 10;

@@ -97,23 +120,67 @@
 

 	if( x >= lMaxTime )

 	{

-		*pxStatus = pdFAIL;

+		*plStatus = pdFAIL;

 	}

 

 	return( MAC_MRDD );

 }

 /*-----------------------------------------------------------*/

 

-static void prvInitDescriptors( void )

+static unsigned char *prvGetNextBuffer( void )

 {

 long x;

+unsigned char *pucReturn = NULL;

+unsigned long ulAttempts = 0;

+

+	while( pucReturn == NULL )

+	{

+		/* Look through the buffers to find one that is not in use by

+		anything else. */

+		for( x = 0; x < ETH_NUM_BUFFERS; x++ )

+		{

+			if( ucBufferInUse[ x ] == pdFALSE )

+			{

+				ucBufferInUse[ x ] = pdTRUE;

+				pucReturn = ( unsigned char * ) ETH_BUF( x );

+				break;

+			}

+		}

+

+		/* Was a buffer found? */

+		if( pucReturn == NULL )

+		{

+			ulAttempts++;

+

+			if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )

+			{

+				break;

+			}

+

+			/* Wait then look again. */

+			vTaskDelay( emacBUFFER_WAIT_DELAY );

+		}

+	}

+

+	return pucReturn;

+}

+/*-----------------------------------------------------------*/

+

+static void prvInitDescriptors( void )

+{

+long x, lNextBuffer = 0;

 

 	for( x = 0; x < NUM_RX_FRAG; x++ )

 	{

-		RX_DESC_PACKET( x ) = RX_BUF( x );

+		/* Allocate the next Ethernet buffer to this descriptor. */

+		RX_DESC_PACKET( x ) = ETH_BUF( lNextBuffer );

 		RX_DESC_CTRL( x ) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );

 		RX_STAT_INFO( x ) = 0;

 		RX_STAT_HASHCRC( x ) = 0;

+

+		/* The Ethernet buffer is now in use. */

+		ucBufferInUse[ lNextBuffer ] = pdTRUE;

+		lNextBuffer++;

 	}

 

 	/* Set EMAC Receive Descriptor Registers. */

@@ -124,9 +191,11 @@
 	/* Rx Descriptors Point to 0 */

 	MAC_RXCONSUMEINDEX = 0;

 

+	/* A buffer is not allocated to the Tx descriptors until they are actually

+	used. */

 	for( x = 0; x < NUM_TX_FRAG; x++ )

 	{

-		TX_DESC_PACKET( x ) = TX_BUF( x );

+		TX_DESC_PACKET( x ) = NULL;

 		TX_DESC_CTRL( x ) = 0;

 		TX_STAT_INFO( x ) = 0;

 	}

@@ -144,7 +213,7 @@
 static void prvSetupEMACHardware( void )

 {

 unsigned short us;

-long x;

+long x, lDummy;

 

 	/* Enable P1 Ethernet Pins. */

 	PINSEL2 = emacPINSEL2_VALUE;

@@ -184,7 +253,7 @@
 	for( x = 0; x < 100; x++ )

 	{

 		vTaskDelay( emacSHORT_DELAY * 5 );

-		us = read_PHY( PHY_REG_BMCR, &us );

+		us = read_PHY( PHY_REG_BMCR, &lDummy );

 		if( !( us & MCFG_RES_MII ) )

 		{

 			/* Reset complete */

@@ -197,7 +266,7 @@
 static void prvConfigurePHY( void )

 {

 unsigned short us;

-long x;

+long x, lDummy;

 

 	/* Auto negotiate the configuration. */

 	if( write_PHY( PHY_REG_BMCR, PHY_AUTO_NEG ) )

@@ -206,7 +275,7 @@
 

 		for( x = 0; x < 10; x++ )

 		{

-			us = read_PHY( PHY_REG_BMSR, &us );

+			us = read_PHY( PHY_REG_BMSR, &lDummy );

 

 			if( us & PHY_AUTO_NEG_COMPLETE )

 			{

@@ -270,9 +339,9 @@
 }

 /*-----------------------------------------------------------*/

 

-portBASE_TYPE Init_EMAC( void )

+long Init_EMAC( void )

 {

-portBASE_TYPE xReturn = pdPASS;

+long lReturn = pdPASS;

 volatile unsigned long regv, tout;

 unsigned long ulID1, ulID2;

 

@@ -280,8 +349,8 @@
 	prvSetupEMACHardware();

 

 	/* Check if connected to a DP83848C PHY. */

-	ulID1 = read_PHY( PHY_REG_IDR1, &xReturn );

-	ulID2 = read_PHY( PHY_REG_IDR2, &xReturn );

+	ulID1 = read_PHY( PHY_REG_IDR1, &lReturn );

+	ulID2 = read_PHY( PHY_REG_IDR2, &lReturn );

 	if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) == DP83848C_ID )

 	{

 		/* Set the Ethernet MAC Address registers */

@@ -295,162 +364,169 @@
 		/* Receive Broadcast and Perfect Match Packets */

 		MAC_RXFILTERCTRL = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;

 

-		/* Create the semaphore used to wake the uIP task. */

-		vSemaphoreCreateBinary( xEMACSemaphore );

-

 		/* Setup the PHY. */

 		prvConfigurePHY();

 	}

 	else

 	{

-		xReturn = pdFAIL;

+		lReturn = pdFAIL;

 	}

 

 	/* Check the link status. */

-	if( xReturn == pdPASS )

+	if( lReturn == pdPASS )

 	{

-		xReturn = prvSetupLinkStatus();

+		lReturn = prvSetupLinkStatus();

 	}

 

-	if( xReturn == pdPASS )

+	if( lReturn == pdPASS )

 	{

+		/* Initialise uip_buf to ensure it points somewhere valid. */

+		uip_buf = prvGetNextBuffer();

+

 		/* Reset all interrupts */

-		MAC_INTCLEAR = 0xFFFF;

+		MAC_INTCLEAR = ( INT_RX_OVERRUN | INT_RX_ERR | INT_RX_FIN | INT_RX_DONE | INT_TX_UNDERRUN | INT_TX_ERR | INT_TX_FIN | INT_TX_DONE | INT_SOFT_INT | INT_WAKEUP );

 

 		/* Enable receive and transmit mode of MAC Ethernet core */

 		MAC_COMMAND |= ( CR_RX_EN | CR_TX_EN );

 		MAC_MAC1 |= MAC1_REC_EN;

 	}

 

-	return xReturn;

+	return lReturn;

 }

 /*-----------------------------------------------------------*/

 

-// reads a word in little-endian byte order from RX_BUFFER

-unsigned short ReadFrame_EMAC( void )

+static void prvReturnBuffer( unsigned char *pucBuffer )

 {

-	return( *rptr++ );

-}

+unsigned long ul;

 

-// copies bytes from frame port to MCU-memory

-// NOTES: * an odd number of byte may only be transfered

-//          if the frame is read to the end!

-//        * MCU-memory MUST start at word-boundary

-void CopyFromFrame_EMAC( void *Dest, unsigned short Size )

-{

-	unsigned short	*piDest;	// Keil: Pointer added to correct expression

-	piDest = Dest;				// Keil: Line added

-	while( Size > 1 )

+	/* Mark a buffer as free for use. */

+	for( ul = 0; ul < ETH_NUM_BUFFERS; ul++ )

 	{

-		*piDest++ = ReadFrame_EMAC();

-		Size -= 2;

+		if( ETH_BUF( ul ) == ( unsigned long ) pucBuffer )

+		{

+			ucBufferInUse[ ul ] = pdFALSE;

+			break;

+		}

 	}

-

-	if( Size )

-	{	// check for leftover byte...

-		*( unsigned char * ) piDest = ( char ) ReadFrame_EMAC();	// the LAN-Controller will return 0

-	}	// for the highbyte

 }

+/*-----------------------------------------------------------*/

 

-

-// Reads the length of the received ethernet frame and checks if the

-// destination address is a broadcast message or not

-// returns the frame length

-unsigned short StartReadFrame( void )

+unsigned long ulGetEMACRxData( void )

 {

-	unsigned short	RxLen;

-	unsigned int	idx;

-

-	idx = MAC_RXCONSUMEINDEX;

-	RxLen = ( RX_STAT_INFO(idx) & RINFO_SIZE ) - 3;

-	rptr = ( unsigned short * ) RX_DESC_PACKET( idx );

-	return( RxLen );

-}

-

-void EndReadFrame( void )

-{

-	unsigned int	idx;

-

-	/* DMA free packet. */

-	idx = MAC_RXCONSUMEINDEX;

-

-	if( ++idx == NUM_RX_FRAG )

-	{

-		idx = 0;

-	}

-

-	MAC_RXCONSUMEINDEX = idx;

-}

-

-unsigned int uiGetEMACRxData( unsigned char *ucBuffer )

-{

-	unsigned int	uiLen = 0;

+unsigned long ulLen = 0;

+long lIndex;

 

 	if( MAC_RXPRODUCEINDEX != MAC_RXCONSUMEINDEX )

 	{

-		uiLen = StartReadFrame();

-		CopyFromFrame_EMAC( ucBuffer, uiLen );

-		EndReadFrame();

+		/* Mark the current buffer as free as uip_buf is going to be set to

+		the buffer that contains the received data. */

+		prvReturnBuffer( uip_buf );

+

+		ulLen = ( RX_STAT_INFO( MAC_RXCONSUMEINDEX ) & RINFO_SIZE ) - 3;

+		uip_buf = ( unsigned char * ) RX_DESC_PACKET( MAC_RXCONSUMEINDEX );

+

+		/* Allocate a new buffer to the descriptor. */

+        RX_DESC_PACKET( MAC_RXCONSUMEINDEX ) = ( unsigned long ) prvGetNextBuffer();

+

+		/* Move the consume index onto the next position, ensuring it wraps to

+		the beginning at the appropriate place. */

+		lIndex = MAC_RXCONSUMEINDEX;

+

+		lIndex++;

+		if( lIndex >= NUM_RX_FRAG )

+		{

+			lIndex = 0;

+		}

+

+		MAC_RXCONSUMEINDEX = lIndex;

 	}

 

-	return uiLen;

+	return ulLen;

 }

+/*-----------------------------------------------------------*/

 

-// requests space in EMAC memory for storing an outgoing frame

-void RequestSend( void )

+void vSendEMACTxData( unsigned short usTxDataLen )

 {

-	unsigned int	idx;

+unsigned long ulAttempts = 0UL;

 

-	idx = MAC_TXPRODUCEINDEX;

-	tptr = ( unsigned short * ) TX_DESC_PACKET( idx );

-}

-

-// writes a word in little-endian byte order to TX_BUFFER

-void WriteFrame_EMAC( unsigned short Data )

-{

-	*tptr++ = Data;

-}

-

-// copies bytes from MCU-memory to frame port

-// NOTES: * an odd number of byte may only be transfered

-//          if the frame is written to the end!

-//        * MCU-memory MUST start at word-boundary

-void CopyToFrame_EMAC( void *Source, unsigned int Size )

-{

-	unsigned short	*piSource;

-

-	piSource = Source;

-	Size = ( Size + 1 ) & 0xFFFE;	// round Size up to next even number

-	while( Size > 0 )

+	/* Check to see if the Tx descriptor is free, indicated by its buffer being

+	NULL. */

+	while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != NULL )

 	{

-		WriteFrame_EMAC( *piSource++ );

-		Size -= 2;

-	}

-}

+		/* Wait for the Tx descriptor to become available. */

+		vTaskDelay( emacBUFFER_WAIT_DELAY );

 

-void DoSend_EMAC( unsigned short FrameSize )

-{

-	unsigned int	idx;

-

-	idx = MAC_TXPRODUCEINDEX;

-	TX_DESC_CTRL( idx ) = FrameSize | TCTRL_LAST;

-	if( ++idx == NUM_TX_FRAG )

-	{

-		idx = 0;

+		ulAttempts++;

+		if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS )

+		{

+			/* Something has gone wrong as the Tx descriptor is still in use.

+			Clear it down manually, the data it was sending will probably be

+			lost. */

+			prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );

+			break;

+		}

 	}

 

-	MAC_TXPRODUCEINDEX = idx;

+	/* Setup the Tx descriptor for transmission.  Remember the length of the

+	data being sent so the second descriptor can be used to send it again from

+	within the ISR. */

+	usSendLen = usTxDataLen;

+	TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf;

+	TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT );

+	MAC_TXPRODUCEINDEX = ( emacTX_DESC_INDEX + 1 );

+

+	/* uip_buf is being sent by the Tx descriptor.  Allocate a new buffer. */

+	uip_buf = prvGetNextBuffer();

 }

+/*-----------------------------------------------------------*/

+

+

+static char c[ 256 ] = { 0 };

+static int i = 0;

+

 

 void vEMAC_ISR( void )

 {

-	portBASE_TYPE	xHigherPriorityTaskWoken = pdFALSE;

+unsigned long ulStatus;

+portBASE_TYPE	xHigherPriorityTaskWoken = pdFALSE;

+

+	ulStatus = MAC_INTSTATUS;

 

 	/* Clear the interrupt. */

-	MAC_INTCLEAR = 0xffff;

+	MAC_INTCLEAR = ulStatus;

 

-	/* Ensure the uIP task is not blocked as data has arrived. */

-	xSemaphoreGiveFromISR( xEMACSemaphore, &xHigherPriorityTaskWoken );

+	if( ulStatus & INT_RX_DONE )

+	{

+		/* Ensure the uIP task is not blocked as data has arrived. */

+		xSemaphoreGiveFromISR( xEMACSemaphore, &xHigherPriorityTaskWoken );

+	}

+

+	if( ulStatus & INT_TX_DONE )

+	{

+		if( usSendLen > 0 )

+		{

+if( i < 255 )

+	c[ i++ ] = 1;

+			/* Send the data again, using the second descriptor.  As there are

+			only two descriptors the index is set back to 0. */

+			TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );

+			TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );

+			MAC_TXPRODUCEINDEX = ( emacTX_DESC_INDEX );

+

+			/* This is the second Tx so set usSendLen to 0 to indicate that the

+			Tx descriptors will be free again. */

+			usSendLen = 0UL;

+		}

+		else

+		{

+if( i < 255 )

+	c[ i++ ] = 1;

+

+			/* The Tx buffer is no longer required. */

+			prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );

+            TX_DESC_PACKET( emacTX_DESC_INDEX ) = NULL;

+		}

+	}

 

 	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

 }

diff --git a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uIP_Task.c b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uIP_Task.c
index a88e4ee..4d8f9cb 100644
--- a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uIP_Task.c
+++ b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uIP_Task.c
@@ -66,7 +66,8 @@
 

 /* Demo includes. */

 #include "EthDev_LPC17xx.h"

-#include "LED.h"

+#include "EthDev.h"

+#include "ParTest.h"

 

 #include "LPC17xx.h"

 #include "core_cm3.h"

@@ -84,11 +85,6 @@
 /*-----------------------------------------------------------*/

 

 /*

- * Send the uIP buffer to the MAC.

- */

-static void prvENET_Send(void);

-

-/*

  * Setup the MAC address in the MAC itself, and in the uIP stack.

  */

 static void prvSetMACAddress( void );

@@ -102,7 +98,7 @@
 /*-----------------------------------------------------------*/

 

 /* The semaphore used by the ISR to wake the uIP task. */

-extern xSemaphoreHandle xEMACSemaphore;

+xSemaphoreHandle xEMACSemaphore = NULL;

 

 /*-----------------------------------------------------------*/

 

@@ -127,9 +123,6 @@
 

 	( void ) pvParameters;

 

-	/* Create the semaphore used by the ISR to wake this task. */

-	vSemaphoreCreateBinary( xEMACSemaphore );

-

 	/* Initialise the uIP stack. */

 	timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );

 	timer_set( &arp_timer, configTICK_RATE_HZ * 10 );

@@ -140,6 +133,9 @@
 	uip_setnetmask( xIPAddr );

 	httpd_init();

 

+	/* Create the semaphore used to wake the uIP task. */

+	vSemaphoreCreateBinary( xEMACSemaphore );

+

 	/* Initialise the MAC. */

 	while( Init_EMAC() != pdPASS )

     {

@@ -148,7 +144,7 @@
 

 	portENTER_CRITICAL();

 	{

-		ETH_INTENABLE = INT_RX_DONE;

+		ETH_INTENABLE = ( INT_RX_DONE | INT_TX_DONE );

 		/* set the interrupt priority */

 		NVIC_SetPriority( ENET_IRQn, configMAX_SYSCALL_INTERRUPT_PRIORITY );

 		/* enable the interrupt */

@@ -161,9 +157,9 @@
 	for( ;; )

 	{

 		/* Is there received data ready to be processed? */

-		uip_len = uiGetEMACRxData( uip_buf );

+		uip_len = ulGetEMACRxData();

 

-		if( uip_len > 0 )

+		if( ( uip_len > 0 ) && ( uip_buf != NULL ) )

 		{

 			/* Standard uIP loop taken from the uIP manual. */

 			if( xHeader->type == htons( UIP_ETHTYPE_IP ) )

@@ -177,7 +173,7 @@
 				if( uip_len > 0 )

 				{

 					uip_arp_out();

-					prvENET_Send();

+					vSendEMACTxData( uip_len );

 				}

 			}

 			else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )

@@ -189,13 +185,13 @@
 				uip_len is set to a value > 0. */

 				if( uip_len > 0 )

 				{

-					prvENET_Send();

+					vSendEMACTxData( uip_len );

 				}

 			}

 		}

 		else

 		{

-			if( timer_expired( &periodic_timer ) )

+			if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) )

 			{

 				timer_reset( &periodic_timer );

 				for( i = 0; i < UIP_CONNS; i++ )

@@ -208,7 +204,7 @@
 					if( uip_len > 0 )

 					{

 						uip_arp_out();

-						prvENET_Send();

+						vSendEMACTxData( uip_len );

 					}

 				}

 

@@ -232,32 +228,6 @@
 }

 /*-----------------------------------------------------------*/

 

-static void prvENET_Send(void)

-{

-    RequestSend();

-

-    /* Copy the header into the Tx buffer. */

-    CopyToFrame_EMAC( uip_buf, uipTOTAL_FRAME_HEADER_SIZE );

-    if( uip_len > uipTOTAL_FRAME_HEADER_SIZE )

-    {

-        CopyToFrame_EMAC( uip_appdata, ( uip_len - uipTOTAL_FRAME_HEADER_SIZE ) );

-    }

-

-    DoSend_EMAC( uip_len );

-

-    RequestSend();

-

-    /* Copy the header into the Tx buffer. */

-    CopyToFrame_EMAC( uip_buf, uipTOTAL_FRAME_HEADER_SIZE );

-    if( uip_len > uipTOTAL_FRAME_HEADER_SIZE )

-    {

-        CopyToFrame_EMAC( uip_appdata, ( uip_len - uipTOTAL_FRAME_HEADER_SIZE ) );

-    }

-

-    DoSend_EMAC( uip_len );

-}

-/*-----------------------------------------------------------*/

-

 static void prvSetMACAddress( void )

 {

 struct uip_eth_addr xAddr;

diff --git a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uip-conf.h b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uip-conf.h
index 3e6f7f3..b52b23f 100644
--- a/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uip-conf.h
+++ b/Demo/CORTEX_LPC1768_GCC_Rowley/webserver/uip-conf.h
@@ -57,6 +57,8 @@
 

 #include <stdint.h>

 

+#define UIP_CONF_EXTERNAL_BUFFER

+

 /**

  * 8 bit datatype

  *