#include "FreeRTOS_IP_Private.h"\r
#include "FreeRTOS_Sockets.h"\r
#include "NetworkBufferManagement.h"\r
-\r
-/* Driver includes. */\r
-#include "lpc18xx_emac.h"\r
+#include "lpc18xx_43xx_EMAC_LPCOpen.h"\r
\r
/* Demo includes. */\r
#include "NetworkInterface.h"\r
\r
+/* Library includes. */\r
+#include "board.h"\r
+\r
#if configMAC_INTERRUPT_PRIORITY > configMAC_INTERRUPT_PRIORITY\r
#error configMAC_INTERRUPT_PRIORITY must be greater than or equal to configMAC_INTERRUPT_PRIORITY (higher numbers mean lower logical priority)\r
#endif\r
\r
/* The semaphore used to wake the deferred interrupt handler task when an Rx\r
interrupt is received. */\r
-static xSemaphoreHandle xEMACRxEventSemaphore = NULL;\r
+xSemaphoreHandle xEMACRxEventSemaphore = NULL;\r
\r
/*-----------------------------------------------------------*/\r
\r
portBASE_TYPE xNetworkInterfaceInitialise( void )\r
{\r
-EMAC_CFG_Type Emac_Config;\r
portBASE_TYPE xReturn;\r
extern uint8_t ucMACAddress[ 6 ];\r
\r
- Emac_Config.pbEMAC_Addr = ucMACAddress;\r
- xReturn = EMAC_Init( &Emac_Config );\r
+ xReturn = xEMACInit( ucMACAddress );\r
\r
if( xReturn == pdPASS )\r
{\r
- LPC_ETHERNET->DMA_INT_EN = DMA_INT_NOR_SUM | DMA_INT_RECEIVE;\r
-\r
/* Create the event semaphore if it has not already been created. */\r
if( xEMACRxEventSemaphore == NULL )\r
{\r
vTraceSetQueueName( xEMACRxEventSemaphore, "MAC_RX" );\r
}\r
#endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */\r
- }\r
\r
- configASSERT( xEMACRxEventSemaphore );\r
-\r
- /* The Rx deferred interrupt handler task is created at the highest\r
- possible priority to ensure the interrupt handler can return directly to\r
- it no matter which task was running when the interrupt occurred. */\r
- xTaskCreate( prvEMACDeferredInterruptHandlerTask, /* The function that implements the task. */\r
- ( const signed char * const ) "MACTsk",\r
- configMINIMAL_STACK_SIZE, /* Stack allocated to the task (defined in words, not bytes). */\r
- NULL, /* The task parameter is not used. */\r
- configMAX_PRIORITIES - 1, /* The priority assigned to the task. */\r
- NULL ); /* The handle is not required, so NULL is passed. */\r
-\r
- /* Enable the interrupt and set its priority as configured. THIS\r
- DRIVER REQUIRES configMAC_INTERRUPT_PRIORITY TO BE DEFINED, PREFERABLY\r
- IN FreeRTOSConfig.h. */\r
- NVIC_SetPriority( ETHERNET_IRQn, configMAC_INTERRUPT_PRIORITY );\r
- NVIC_EnableIRQ( ETHERNET_IRQn );\r
+ configASSERT( xEMACRxEventSemaphore );\r
+\r
+ /* The Rx deferred interrupt handler task is created at the highest\r
+ possible priority to ensure the interrupt handler can return directly to\r
+ it no matter which task was running when the interrupt occurred. */\r
+ xTaskCreate( prvEMACDeferredInterruptHandlerTask,/* The function that implements the task. */\r
+ ( const signed char * const ) "MACTsk",\r
+ configMINIMAL_STACK_SIZE, /* Stack allocated to the task (defined in words, not bytes). */\r
+ NULL, /* The task parameter is not used. */\r
+ configMAX_PRIORITIES - 1, /* The priority assigned to the task. */\r
+ NULL ); /* The handle is not required, so NULL is passed. */\r
+ }\r
}\r
\r
return xReturn;\r
/* Attempt to obtain access to a Tx descriptor. */\r
for( x = 0; x < niMAX_TX_ATTEMPTS; x++ )\r
{\r
- if( EMAC_CheckTransmitIndex() == TRUE )\r
+ if( xEMACIsTxDescriptorAvailable() == TRUE )\r
{\r
/* Assign the buffer being transmitted to the Tx descriptor. */\r
- EMAC_SetNextPacketToSend( pxNetworkBuffer->pucEthernetBuffer );\r
+ vEMACAssignBufferToDescriptor( pxNetworkBuffer->pucEthernetBuffer );\r
\r
/* The EMAC now owns the buffer and will free it when it has been\r
transmitted. Set pucBuffer to NULL to ensure the buffer is not\r
pxNetworkBuffer->pucEthernetBuffer = NULL;\r
\r
/* Initiate the Tx. */\r
- EMAC_StartTransmitNextBuffer( pxNetworkBuffer->xDataLength );\r
+ vEMACStartNextTransmission( pxNetworkBuffer->xDataLength );\r
iptraceNETWORK_INTERFACE_TRANSMIT();\r
\r
/* The Tx has been initiated. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void ETH_IRQHandler( void )\r
-{\r
-uint32_t ulInterruptCause;\r
-\r
- ulInterruptCause = LPC_ETHERNET->DMA_STAT ;\r
-\r
- /* Clear the interrupt. */\r
- LPC_ETHERNET->DMA_STAT |= ( DMA_INT_NOR_SUM | DMA_INT_RECEIVE );\r
-\r
- /* Clear fatal error conditions. NOTE: The driver does not clear all\r
- errors, only those actually experienced. For future reference, range\r
- errors are not actually errors so can be ignored. */\r
- if( ( ulInterruptCause & ( 1 << 13 ) ) != 0U )\r
- {\r
- LPC_ETHERNET->DMA_STAT |= ( 1 << 13 );\r
- }\r
-\r
- /* Unblock the deferred interrupt handler task if the event was an Rx. */\r
- if( ( ulInterruptCause & DMA_INT_RECEIVE ) != 0UL )\r
- {\r
- xSemaphoreGiveFromISR( xEMACRxEventSemaphore, NULL );\r
- }\r
-\r
- /* ulInterruptCause is used for convenience here. A context switch is\r
- wanted, but coding portEND_SWITCHING_ISR( 1 ) would likely result in a\r
- compiler warning. */\r
- portEND_SWITCHING_ISR( ulInterruptCause );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
static void prvEMACDeferredInterruptHandlerTask( void *pvParameters )\r
{\r
xNetworkBufferDescriptor_t *pxNetworkBuffer;\r
while( xSemaphoreTake( xEMACRxEventSemaphore, portMAX_DELAY ) == pdFALSE );\r
\r
/* At least one packet has been received. */\r
- while( EMAC_CheckReceiveIndex() != FALSE )\r
+ while( xEMACRxDataAvailable() != FALSE )\r
{\r
/* The buffer filled by the DMA is going to be passed into the IP\r
stack. Allocate another buffer for the DMA descriptor. */\r
the DMA. pxNetworkBuffer will then hold a reference to the\r
buffer that already contains the data without any data having\r
been copied between buffers. */\r
- EMAC_NextPacketToRead( pxNetworkBuffer );\r
+ vEMACSwapEmptyBufferForRxedData( pxNetworkBuffer );\r
\r
#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 1\r
{\r
}\r
\r
/* Release the descriptor. */\r
- EMAC_UpdateRxConsumeIndex();\r
+ vEMACReturnRxDescriptor();\r
}\r
}\r
}\r
--- /dev/null
+/*\r
+ * FreeRTOS+UDP V1.0.0 (C) 2013 Real Time Engineers ltd.\r
+ *\r
+ * This file is part of the FreeRTOS+UDP distribution. The FreeRTOS+UDP license\r
+ * terms are different to the FreeRTOS license terms.\r
+ *\r
+ * FreeRTOS+UDP uses a dual license model that allows the software to be used \r
+ * under a standard GPL open source license, or a commercial license. The \r
+ * standard GPL license (unlike the modified GPL license under which FreeRTOS \r
+ * itself is distributed) requires that all software statically linked with \r
+ * FreeRTOS+UDP is also distributed under the same GPL V2 license terms. \r
+ * Details of both license options follow:\r
+ *\r
+ * - Open source licensing -\r
+ * FreeRTOS+UDP is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the\r
+ * GNU General Public License (GPL) and does not remove the copyright notice or\r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ *\r
+ * - Commercial licensing -\r
+ * Businesses and individuals that for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+UDP into proprietary software for distribution in any \r
+ * form. Commercial licenses can be purchased from http://shop.freertos.org/udp \r
+ * and do not require any source files to be changed.\r
+ *\r
+ * FreeRTOS+UDP is distributed in the hope that it will be useful. You cannot\r
+ * use FreeRTOS+UDP unless you agree that you use the software 'as is'.\r
+ * FreeRTOS+UDP is provided WITHOUT ANY WARRANTY; without even the implied\r
+ * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR\r
+ * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they\r
+ * implied, expressed, or statutory.\r
+ *\r
+ * 1 tab == 4 spaces!\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/udp\r
+ *\r
+ */\r
+ \r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* FreeRTOS+UDP includes. */\r
+#include "FreeRTOS_UDP_IP.h"\r
+#include "FreeRTOS_IP_Private.h"\r
+#include "NetworkBufferManagement.h"\r
+\r
+/* Library includes. */\r
+#include "board.h"\r
+\r
+/* Descriptors that reference received buffers are expected to have both the\r
+first and last frame bits set because buffers are dimensioned to hold complete\r
+Ethernet frames. */\r
+#define emacEXPECTED_RX_STATUS_MASK ( RDES_LS | RDES_FS )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Set the Rx and Tx descriptors into their expected initial state.\r
+ */\r
+static void prvResetRxDescriptors( void );\r
+static void prvResetTxDescriptors( void );\r
+\r
+/*\r
+ * Returns the length of the data pointed to by the next Rx descriptor.\r
+ */\r
+static uint32_t prvReceivedDataLength( void );\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Rx and Tx descriptors and data array. */\r
+static volatile IP_ENET_001_ENHRXDESC_T xRXDescriptors[ configNUM_RX_ETHERNET_DMA_DESCRIPTORS ];\r
+static volatile IP_ENET_001_ENHTXDESC_T xTxDescriptors[ configNUM_TX_ETHERNET_DMA_DESCRIPTORS ];\r
+\r
+/* Indexes into the Rx and Tx descriptor arrays. */\r
+static unsigned int xRxDescriptorIndex = 0;\r
+static unsigned int xTxDescriptorIndex = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xEMACInit( uint8_t ucMACAddress[ 6 ] )\r
+{\r
+portBASE_TYPE xReturn;\r
+uint32_t ulPHYStatus;\r
+\r
+ /* Configure the hardware. */\r
+ Chip_ENET_Init( LPC_ETHERNET );\r
+\r
+ if( lpc_phy_init( pdTRUE, vTaskDelay ) == SUCCESS )\r
+ {\r
+ /* The MAC address is passed in as the function parameter. */\r
+ Chip_ENET_SetADDR( LPC_ETHERNET, ucMACAddress );\r
+\r
+ /* Wait for autonegotiation to complete. */\r
+ do\r
+ {\r
+ vTaskDelay( 100 );\r
+ ulPHYStatus = lpcPHYStsPoll();\r
+ } while( ( ulPHYStatus & PHY_LINK_CONNECTED ) == 0x00 );\r
+\r
+ /* Configure the hardware as per the negotiated link. */\r
+ if( ( ulPHYStatus & PHY_LINK_FULLDUPLX ) == PHY_LINK_FULLDUPLX )\r
+ {\r
+ IP_ENET_SetDuplex( LPC_ETHERNET, pdTRUE );\r
+ }\r
+ else\r
+ {\r
+ IP_ENET_SetDuplex( LPC_ETHERNET, pdFALSE );\r
+ }\r
+\r
+ if( ( ulPHYStatus & PHY_LINK_SPEED100 ) == PHY_LINK_SPEED100 )\r
+ {\r
+ IP_ENET_SetSpeed( LPC_ETHERNET, pdTRUE );\r
+ }\r
+ else\r
+ {\r
+ IP_ENET_SetSpeed( LPC_ETHERNET, pdFALSE );\r
+ }\r
+\r
+ /* Set descriptors to their initial state. */\r
+ prvResetRxDescriptors();\r
+ prvResetTxDescriptors();\r
+\r
+ /* Enable RX and TX. */\r
+ Chip_ENET_TXEnable( LPC_ETHERNET );\r
+ Chip_ENET_RXEnable( LPC_ETHERNET );\r
+\r
+ /* Enable the interrupt and set its priority as configured. THIS\r
+ DRIVER REQUIRES configMAC_INTERRUPT_PRIORITY TO BE DEFINED, PREFERABLY\r
+ IN FreeRTOSConfig.h. */\r
+ NVIC_SetPriority( ETHERNET_IRQn, configMAC_INTERRUPT_PRIORITY );\r
+ NVIC_EnableIRQ( ETHERNET_IRQn );\r
+\r
+ /* Enable interrupts. */\r
+ LPC_ETHERNET->DMA_INT_EN = DMA_IE_NIE | DMA_IE_RIE;\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xEMACIsTxDescriptorAvailable( void )\r
+{\r
+portBASE_TYPE xReturn;\r
+\r
+ if( ( xTxDescriptors[ xTxDescriptorIndex ].CTRLSTAT & RDES_OWN ) == 0 )\r
+ {\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vEMACAssignBufferToDescriptor( uint8_t * pucBuffer )\r
+{\r
+ /* The old packet is now finished with and can be freed. */\r
+ vEthernetBufferRelease( ( void * ) xTxDescriptors[ xTxDescriptorIndex ].B1ADD );\r
+\r
+ /* Assign the new packet to the descriptor. */\r
+ xTxDescriptors[ xTxDescriptorIndex ].B1ADD = ( uint32_t ) pucBuffer;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vEMACStartNextTransmission( uint32_t ulLength )\r
+{\r
+ xTxDescriptors[ xTxDescriptorIndex ].BSIZE = ulLength;\r
+ xTxDescriptors[ xTxDescriptorIndex ].CTRLSTAT |= RDES_OWN;\r
+\r
+ /* Wake Up the DMA if it's in Suspended Mode. */\r
+ LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1;\r
+ xTxDescriptorIndex++;\r
+\r
+ if( xTxDescriptorIndex == configNUM_TX_ETHERNET_DMA_DESCRIPTORS )\r
+ {\r
+ xTxDescriptorIndex = 0;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static uint32_t prvReceivedDataLength( void )\r
+{\r
+unsigned short RxLen = 0;\r
+\r
+ RxLen = ( xRXDescriptors[ xRxDescriptorIndex ].STATUS >> 16 ) & 0x03FFF;\r
+ return RxLen;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vEMACReturnRxDescriptor( void )\r
+{\r
+ xRXDescriptors[ xRxDescriptorIndex ].STATUS = RDES_OWN;\r
+ xRxDescriptorIndex++;\r
+\r
+ if( xRxDescriptorIndex == configNUM_RX_ETHERNET_DMA_DESCRIPTORS )\r
+ {\r
+ xRxDescriptorIndex = 0;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xEMACRxDataAvailable( void )\r
+{\r
+portBASE_TYPE xReturn;\r
+\r
+ if( ( xRXDescriptors[ xRxDescriptorIndex ].STATUS & RDES_OWN ) == 0 )\r
+ {\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vEMACSwapEmptyBufferForRxedData( xNetworkBufferDescriptor_t *pxNetworkBuffer )\r
+{\r
+uint8_t *pucTemp;\r
+\r
+ /* Swap the buffer in the network buffer with the buffer used by the DMA.\r
+ This allows the data to be passed out without having to perform any copies. */\r
+ pucTemp = ( uint8_t * ) xRXDescriptors[ xRxDescriptorIndex ].B1ADD;\r
+ xRXDescriptors[ xRxDescriptorIndex ].B1ADD = ( uint32_t ) pxNetworkBuffer->pucEthernetBuffer;\r
+ pxNetworkBuffer->pucEthernetBuffer = pucTemp;\r
+\r
+ /* Only supports frames coming in single buffers. If this frame is split\r
+ across multiple buffers then reject it (and if the frame is needed increase\r
+ the ipconfigNETWORK_MTU setting). */\r
+ if( ( xRXDescriptors[ xRxDescriptorIndex ].STATUS & emacEXPECTED_RX_STATUS_MASK ) != emacEXPECTED_RX_STATUS_MASK )\r
+ {\r
+ pxNetworkBuffer->xDataLength = 0;\r
+ }\r
+ else\r
+ {\r
+ pxNetworkBuffer->xDataLength = ( size_t ) prvReceivedDataLength() - ( ipETHERNET_CRC_BYTES - 1U );;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvResetRxDescriptors( void )\r
+{\r
+uint32_t x;\r
+size_t xBufferSize = ipTOTAL_ETHERNET_FRAME_SIZE;\r
+\r
+ for( x = 0; x < configNUM_RX_ETHERNET_DMA_DESCRIPTORS; x++ )\r
+ {\r
+ /* Obtain the buffer first, as the size of the buffer might be changed\r
+ within the pucEthernetBufferGet() call. */\r
+ xRXDescriptors[ x ].B1ADD = ( uint32_t ) pucEthernetBufferGet( &xBufferSize );\r
+ xRXDescriptors[ x ].STATUS = RDES_OWN;\r
+ xRXDescriptors[ x ].CTRL = xBufferSize;\r
+ xRXDescriptors[ x ].B2ADD = ( uint32_t ) &xRXDescriptors[ x + 1 ];\r
+ \r
+ configASSERT( ( ( ( uint32_t ) xRXDescriptors[x].B1ADD ) & 0x07 ) == 0 );\r
+ }\r
+\r
+ /* Last Descriptor */\r
+ xRXDescriptors[ configNUM_RX_ETHERNET_DMA_DESCRIPTORS - 1 ].CTRL |= RDES_ENH_RER;\r
+\r
+ xRxDescriptorIndex = 0;\r
+\r
+ /* Set Starting address of RX Descriptor list */\r
+ LPC_ETHERNET->DMA_REC_DES_ADDR = ( uint32_t ) xRXDescriptors;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvResetTxDescriptors( void )\r
+{\r
+/* Initialize Transmit Descriptor and Status array. */\r
+uint32_t x;\r
+\r
+ for( x = 0; x < configNUM_TX_ETHERNET_DMA_DESCRIPTORS; x++ )\r
+ {\r
+ xTxDescriptors[ x ].CTRLSTAT = TDES_ENH_FS | TDES_ENH_LS;\r
+ xTxDescriptors[ x ].BSIZE = 0;\r
+ xTxDescriptors[ x ].B2ADD = ( uint32_t ) &xTxDescriptors[ x + 1 ];\r
+\r
+ /* Packet is assigned when a Tx is initiated. */\r
+ xTxDescriptors[ x ].B1ADD = ( uint32_t )NULL;\r
+ }\r
+\r
+ /* Last Descriptor? */\r
+ xTxDescriptors[ configNUM_TX_ETHERNET_DMA_DESCRIPTORS-1 ].CTRLSTAT |= TDES_ENH_TER;\r
+\r
+ /* Set Starting address of TX Descriptor list */\r
+ LPC_ETHERNET->DMA_TRANS_DES_ADDR = ( uint32_t ) xTxDescriptors;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void ETH_IRQHandler( void )\r
+{\r
+uint32_t ulInterruptCause;\r
+extern xSemaphoreHandle xEMACRxEventSemaphore;\r
+\r
+ configASSERT( xEMACRxEventSemaphore );\r
+\r
+ ulInterruptCause = LPC_ETHERNET->DMA_STAT ;\r
+\r
+ /* Clear the interrupt. */\r
+ LPC_ETHERNET->DMA_STAT |= ( DMA_ST_NIS | DMA_ST_RI );\r
+\r
+ /* Clear fatal error conditions. NOTE: The driver does not clear all\r
+ errors, only those actually experienced. For future reference, range\r
+ errors are not actually errors so can be ignored. */\r
+ if( ( ulInterruptCause & DMA_ST_FBI ) != 0U )\r
+ {\r
+ LPC_ETHERNET->DMA_STAT |= DMA_ST_FBI;\r
+ }\r
+\r
+ /* Unblock the deferred interrupt handler task if the event was an Rx. */\r
+ if( ( ulInterruptCause & DMA_IE_RIE ) != 0UL )\r
+ {\r
+ xSemaphoreGiveFromISR( xEMACRxEventSemaphore, NULL );\r
+ }\r
+\r
+ /* ulInterruptCause is used for convenience here. A context switch is\r
+ wanted, but coding portEND_SWITCHING_ISR( 1 ) would likely result in a\r
+ compiler warning. */\r
+ portEND_SWITCHING_ISR( ulInterruptCause );\r
+}\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+UDP V1.0.0 (C) 2013 Real Time Engineers ltd.\r
+ *\r
+ * This file is part of the FreeRTOS+UDP distribution. The FreeRTOS+UDP license\r
+ * terms are different to the FreeRTOS license terms.\r
+ *\r
+ * FreeRTOS+UDP uses a dual license model that allows the software to be used\r
+ * under a standard GPL open source license, or a commercial license. The\r
+ * standard GPL license (unlike the modified GPL license under which FreeRTOS\r
+ * itself is distributed) requires that all software statically linked with\r
+ * FreeRTOS+UDP is also distributed under the same GPL V2 license terms.\r
+ * Details of both license options follow:\r
+ *\r
+ * - Open source licensing -\r
+ * FreeRTOS+UDP is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the\r
+ * GNU General Public License (GPL) and does not remove the copyright notice or\r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ *\r
+ * - Commercial licensing -\r
+ * Businesses and individuals that for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before\r
+ * incorporating FreeRTOS+UDP into proprietary software for distribution in any\r
+ * form. Commercial licenses can be purchased from http://shop.freertos.org/udp\r
+ * and do not require any source files to be changed.\r
+ *\r
+ * FreeRTOS+UDP is distributed in the hope that it will be useful. You cannot\r
+ * use FreeRTOS+UDP unless you agree that you use the software 'as is'.\r
+ * FreeRTOS+UDP is provided WITHOUT ANY WARRANTY; without even the implied\r
+ * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR\r
+ * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they\r
+ * implied, expressed, or statutory.\r
+ *\r
+ * 1 tab == 4 spaces!\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/udp\r
+ *\r
+ */\r
+\r
+#ifndef LPC18xx_43xx_EMAC_H\r
+#define LPC18xx_43xx_EMAC_H\r
+\r
+/*\r
+ * Initialise the MAC and PHY.\r
+ */\r
+portBASE_TYPE xEMACInit( uint8_t ucMACAddress[ 6 ] );\r
+\r
+/*\r
+ * Return pdTRUE if there is a FreeRTOS Tx descriptor. Return pdFALSE if all\r
+ * Tx descriptors are already in use.\r
+ */\r
+portBASE_TYPE xEMACIsTxDescriptorAvailable( void );\r
+\r
+/*\r
+ * Assign a buffer to a Tx descriptor so it is ready to be transmitted, but\r
+ * don't start the transmission yet.\r
+ */\r
+void vEMACAssignBufferToDescriptor( uint8_t * pucBuffer );\r
+\r
+/*\r
+ * Start transmitting the buffer pointed to by the next Tx descriptor. The\r
+ * buffer must have first been allocated to the Tx descriptor using a call to\r
+ * vEMACAssignBufferToDescriptor().\r
+ */\r
+void vEMACStartNextTransmission( uint32_t ulLength );\r
+\r
+/*\r
+ * The data pointed to by the Rx descriptor has been consumed, and the Rx\r
+ * descriptor can be returned to the control of the DMS.\r
+ */\r
+void vEMACReturnRxDescriptor( void );\r
+\r
+/*\r
+ * Returns pdTRUE if the next Rx descriptor contains received data. Returns\r
+ * pdFLASE fi the next Rx descriptor is still under the control of the DMA.\r
+ */\r
+portBASE_TYPE xEMACRxDataAvailable( void );\r
+void vEMACSwapEmptyBufferForRxedData( xNetworkBufferDescriptor_t *pxNetworkBuffer );\r
+\r
+#endif /* LPC18xx_43xx_EMAC_H */\r
+\r
+++ /dev/null
-/**********************************************************************\r
-* Copyright(C) 2011, NXP Semiconductor\r
-* All rights reserved.\r
-* Heavily modified by Real Time Engineers ltd.\r
-***********************************************************************\r
-* Software that is described herein is for illustrative purposes only\r
-* which provides customers with programming information regarding the\r
-* products. This software is supplied "AS IS" without any warranties.\r
-* NXP Semiconductors assumes no responsibility or liability for the\r
-* use of the software, conveys no license or title under any patent,\r
-* copyright, or mask work right to the product. NXP Semiconductors\r
-* reserves the right to make changes in the software without\r
-* notification. NXP Semiconductors also make no representation or\r
-* warranty that such application will be suitable for the specified\r
-* use without further testing or modification.\r
-**********************************************************************/\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-\r
-/* FreeRTOS+UDP includes. */\r
-#include "FreeRTOS_UDP_IP.h"\r
-#include "FreeRTOS_IP_Private.h"\r
-#include "NetworkBufferManagement.h"\r
-\r
-/* Library includes. */\r
-#include "lpc18xx_emac.h"\r
-#include "lpc18xx_rgu.h"\r
-#include "lpc18xx_scu.h"\r
-#include "lpc18xx_gpio.h"\r
-\r
-\r
-#define emacTIMEOUT_DELAY ( 2 )\r
-#define emacNEGOTIATE_DELAY ( 10 / portTICK_RATE_MS )\r
-\r
-#define emacEXPECTED_RX_STATUS_MASK ( RX_FIRST_SEGM | RX_LAST_SEGM )\r
-\r
-/* Rx descriptors and data array. */\r
-static volatile RX_Desc Rx_Desc[ configNUM_RX_ETHERNET_DMA_DESCRIPTORS ];\r
-static unsigned int RxDescIndex = 0;\r
-\r
-/** Rx Status data array - Must be 8-Byte aligned */\r
-#if defined ( __CC_ARM )\r
- static __align(8) RX_Stat Rx_Stat[ configNUM_RX_ETHERNET_DMA_DESCRIPTORS ];\r
-#elif defined ( __ICCARM__ )\r
- #pragma data_alignment=8\r
- static RX_Stat Rx_Stat[ configNUM_RX_ETHERNET_DMA_DESCRIPTORS ];\r
-#elif defined ( __GNUC__ )\r
- static volatile __attribute__ ((aligned (8))) RX_Stat Rx_Stat[ configNUM_RX_ETHERNET_DMA_DESCRIPTORS ];\r
-#endif\r
-\r
-/* Tx descriptors and status array. */\r
-static volatile TX_Desc Tx_Desc[ configNUM_TX_ETHERNET_DMA_DESCRIPTORS ];\r
-static volatile TX_Stat Tx_Stat[ configNUM_TX_ETHERNET_DMA_DESCRIPTORS ];\r
-static unsigned int TxDescIndex = 0;\r
-\r
-/* Private Functions ---------------------------------------------------------- */\r
-static void rx_descr_init( void );\r
-static void tx_descr_init( void );\r
-static int32_t write_PHY( uint32_t PhyReg, uint16_t Value );\r
-static int32_t read_PHY( uint32_t PhyReg );\r
-static void setEmacAddr( uint8_t abStationAddr[] );\r
-\r
-/*********************************************************************//**\r
- * @brief Initializes the EMAC peripheral according to the specified\r
- * parameters in the EMAC_ConfigStruct.\r
- * @param[in] EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure\r
- * that contains the configuration information for the\r
- * specified EMAC peripheral.\r
- * @return None\r
- *\r
- * Note: This function will initialize EMAC module according to procedure below:\r
- * - Remove the soft reset condition from the MAC\r
- * - Configure the PHY via the MIIM interface of the MAC\r
- * - Select RMII mode\r
- * - Configure the transmit and receive DMA engines, including the descriptor arrays\r
- * - Configure the host registers (MAC1,MAC2 etc.) in the MAC\r
- * - Enable the receive and transmit data paths\r
- * In default state after initializing, only Rx Done and Tx Done interrupt are enabled,\r
- * all remain interrupts are disabled\r
- * (Ref. from LPC17xx UM)\r
- **********************************************************************/\r
-portBASE_TYPE EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)\r
-{\r
-int32_t id1, id2, regv, phy = 0;\r
-int32_t phy_linkstatus_reg, phy_linkstatus_mask;\r
-uint32_t x;\r
-const uint32_t ulMaxAttempts = 250UL;\r
-portBASE_TYPE xReturn = pdPASS;\r
-\r
- /* Enable Ethernet Pins (NGX LPC1830 Xplorer. */\r
- scu_pinmux(0x2 ,0 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC7);\r
- scu_pinmux(0x1 ,17 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3);\r
- scu_pinmux(0x1 ,18 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3);\r
- scu_pinmux(0x1 ,20 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3);\r
- scu_pinmux(0x1 ,19 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC0);\r
- scu_pinmux(0x0 ,1 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC6);\r
- scu_pinmux(0x1 ,15 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3);\r
- scu_pinmux(0x0 ,0 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC2);\r
- scu_pinmux(0x1 ,16 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3);\r
- scu_pinmux(0xC ,9 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3);\r
- scu_pinmux(0x1 ,16 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC7);\r
-\r
- /* Ethernet RESET Pins */\r
- scu_pinmux(0x1 ,0 , MD_PUP, FUNC0);\r
- GPIO_SetDir(0,(1<<4), 1);\r
- GPIO_SetValue(0,(1<<4));\r
-\r
-\r
- #if MII /* Select MII interface */ // check MUXING for new Eagle...\r
- scu_pinmux(0xC ,6 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXD2: PC_6 -> FUNC3\r
- scu_pinmux(0xC ,7 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXD3: PC_7 -> FUNC3\r
- scu_pinmux(0xC ,0 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXLK: PC_0 -> FUNC3\r
- scu_pinmux(0xC ,2 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD2: PC_2 -> FUNC3\r
- scu_pinmux(0xC ,3 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD3: PC_3 -> FUNC3\r
- scu_pinmux(0xC ,5 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TX_ER: PC_5 -> FUNC3\r
- scu_pinmux(0x0 ,1 , (MD_PLN | MD_EZI | MD_ZI), FUNC2); // ENET_COL: P0_1 -> FUNC2\r
- #else /* Select RMII interface */\r
- LPC_CREG->CREG6 |= RMII_SELECT;\r
- #endif\r
-\r
-\r
- RGU_SoftReset( RGU_SIG_ETHERNET );\r
-\r
- /* Wait for reset. */\r
- while( !( LPC_RGU->RESET_ACTIVE_STATUS0 & ( 1 << ETHERNET_RST ) ) )\r
- {\r
- vTaskDelay( emacTIMEOUT_DELAY );\r
- }\r
-\r
- /* Reset all GMAC Subsystem internal registers and logic. */\r
- LPC_ETHERNET->DMA_BUS_MODE |= DMA_SOFT_RESET;\r
-\r
- /* Wait for software reset completion. */\r
- while( LPC_ETHERNET->DMA_BUS_MODE & DMA_SOFT_RESET )\r
- {\r
- vTaskDelay( emacTIMEOUT_DELAY );\r
- }\r
-\r
- /* Put the PHY in reset mode */\r
- write_PHY( PHY_REG_BMCR, PHY_BMCR_RESET );\r
-\r
- /* Wait for hardware reset to end. */\r
- for( x = 0; x < ulMaxAttempts; x++ )\r
- {\r
- regv = read_PHY (PHY_REG_BMCR);\r
- if( !( regv & PHY_BMCR_RESET ) )\r
- {\r
- /* Reset complete */\r
- break;\r
- }\r
- else\r
- {\r
- vTaskDelay( emacTIMEOUT_DELAY );\r
- }\r
- }\r
-\r
- if( x == ulMaxAttempts )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- /* Check if this is a DP83848C PHY. */\r
- id1 = read_PHY( PHY_REG_IDR1 );\r
- id2 = read_PHY( PHY_REG_IDR2 );\r
- if( ( ( id1 << 16 ) | ( id2 & 0xFFF0 ) ) == DP83848C_ID )\r
- {\r
- phy = DP83848C_ID;\r
- }\r
- else if( ( ( id1 << 16 ) | id2 ) == LAN8720_ID )\r
- {\r
- phy = LAN8720_ID;\r
- }\r
-\r
- if( phy != 0 )\r
- {\r
- /* Use autonegotiation about the link speed. */\r
- write_PHY( PHY_REG_BMCR, PHY_AUTO_NEG );\r
-\r
- /* Wait to complete Auto_Negotiation. */\r
- for( x = 0; x < ulMaxAttempts; x++ )\r
- {\r
- regv = read_PHY( PHY_REG_BMSR );\r
-\r
- if( ( regv & PHY_AUTO_NEG_DONE ) != 0 )\r
- {\r
- /* Auto negotiation Complete. */\r
- break;\r
- }\r
- else\r
- {\r
- vTaskDelay( emacNEGOTIATE_DELAY );\r
- }\r
- }\r
-\r
- if( x == ulMaxAttempts )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
-\r
- if( xReturn == pdPASS )\r
- {\r
- /* Default to DP83848C. */\r
- phy_linkstatus_reg = PHY_REG_STS;\r
- phy_linkstatus_mask = 0x0001;\r
-\r
- if( phy == LAN8720_ID )\r
- {\r
- phy_linkstatus_reg = PHY_REG_BMSR;\r
- phy_linkstatus_mask = 0x0004;\r
- }\r
-\r
- /* Check the link status. */\r
- for( x = 0; x < ulMaxAttempts; x++ )\r
- {\r
- regv = read_PHY( phy_linkstatus_reg );\r
-\r
- if( ( regv & phy_linkstatus_mask ) != 0 )\r
- {\r
- /* Link is on. */\r
- break;\r
- }\r
- else\r
- {\r
- vTaskDelay( emacNEGOTIATE_DELAY );\r
- }\r
- }\r
-\r
- if( x == ulMaxAttempts )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- regv = read_PHY( PHY_REG_SPCON );\r
- regv &= PHY_REG_HCDSPEED_MASK;\r
-\r
- /* Configure 100MBit/10MBit mode and Full/Half Duplex mode. */\r
- switch( regv )\r
- {\r
- case PHY_REG_HCDSPEED_10MB_FULLD:\r
- LPC_ETHERNET->MAC_CONFIG |= MAC_DUPMODE;\r
- break;\r
-\r
- case PHY_REG_HCDSPEED_100MB_HALFD:\r
- LPC_ETHERNET->MAC_CONFIG |= MAC_100MPS;\r
- break;\r
-\r
- case PHY_REG_HCDSPEED_100MB_FULLD:\r
- LPC_ETHERNET->MAC_CONFIG |= MAC_DUPMODE;\r
- LPC_ETHERNET->MAC_CONFIG |= MAC_100MPS;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- /* Set the Ethernet MAC Address registers */\r
- setEmacAddr( EMAC_ConfigStruct->pbEMAC_Addr );\r
-\r
- /* Initialize Descriptor Lists */\r
- rx_descr_init();\r
- tx_descr_init();\r
-\r
- /* Configure Filter\r
- LPC_ETHERNET->MAC_FRAME_FILTER is left at its default value.\r
- MAC_PROMISCUOUS and MAC_RECEIVEALL can be set if required. */\r
-\r
- /* Enable Receiver and Transmitter */\r
- LPC_ETHERNET->MAC_CONFIG |= (MAC_TX_ENABLE | MAC_RX_ENABLE);\r
-\r
- /* Enable interrupts */\r
- LPC_ETHERNET->DMA_INT_EN = DMA_INT_NOR_SUM | DMA_INT_RECEIVE ;\r
-\r
- /* Start Transmission & Receive processes */\r
- LPC_ETHERNET->DMA_OP_MODE |= (DMA_SS_TRANSMIT | DMA_SS_RECEIVE );\r
- }\r
-\r
- return xReturn;\r
-}\r
-\r
-/*********************************************************************//**\r
- **********************************************************************/\r
-portBASE_TYPE EMAC_CheckTransmitIndex( void )\r
-{\r
-portBASE_TYPE xReturn;\r
-\r
- if( ( Tx_Desc[ TxDescIndex ].Status & OWN_BIT ) == 0 )\r
- {\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- return xReturn;\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief EMAC_SetNextPacketToSend\r
- * @param[in] pucBuffer\r
- * @return None\r
- ***********************************************************************/\r
-void EMAC_SetNextPacketToSend( uint8_t * pucBuffer )\r
-{\r
- /* The old packet is now finished with and can be freed. */\r
- vEthernetBufferRelease( ( void * ) Tx_Desc[ TxDescIndex ].Packet );\r
-\r
- /* Assign the new packet to the descriptor. */\r
- Tx_Desc[ TxDescIndex ].Packet = ( uint32_t ) pucBuffer;\r
-}\r
-\r
-void EMAC_StartTransmitNextBuffer( uint32_t ulLength )\r
-{\r
- Tx_Desc[ TxDescIndex ].Ctrl = ulLength;\r
- Tx_Desc[ TxDescIndex ].Status |= OWN_BIT;\r
-\r
- /* Wake Up the DMA if it's in Suspended Mode. */\r
- LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1;\r
- TxDescIndex++;\r
-\r
- if( TxDescIndex == configNUM_TX_ETHERNET_DMA_DESCRIPTORS )\r
- {\r
- TxDescIndex = 0;\r
- }\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief Get size of current Received data in received buffer (due to\r
- * RxConsumeIndex)\r
- * @param[in] None\r
- * @return Size of received data\r
- **********************************************************************/\r
-uint32_t EMAC_GetReceiveDataSize(void)\r
-{\r
-unsigned short RxLen = 0;\r
-\r
- RxLen = ( Rx_Desc[ RxDescIndex ].Status >> 16 ) & 0x03FFF;\r
- return RxLen;\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief Increase the RxConsumeIndex (after reading the Receive buffer\r
- * to release the Receive buffer) and wrap-around the index if\r
- * it reaches the maximum Receive Number\r
- * @param[in] None\r
- * @return None\r
- **********************************************************************/\r
-void EMAC_UpdateRxConsumeIndex( void )\r
-{\r
- Rx_Desc[ RxDescIndex ].Status = OWN_BIT;\r
- RxDescIndex++;\r
-\r
- if( RxDescIndex == configNUM_RX_ETHERNET_DMA_DESCRIPTORS )\r
- {\r
- RxDescIndex = 0;\r
- }\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief Check whether if the current RxConsumeIndex is not equal to the\r
- * current RxProduceIndex.\r
- * @param[in] None\r
- * @return TRUE if they're not equal, otherwise return FALSE\r
- *\r
- * Note: In case the RxConsumeIndex is not equal to the RxProduceIndex,\r
- * it means there're available data has been received. They should be read\r
- * out and released the Receive Data Buffer by updating the RxConsumeIndex value.\r
- **********************************************************************/\r
-portBASE_TYPE EMAC_CheckReceiveIndex(void)\r
-{\r
-portBASE_TYPE xReturn;\r
-\r
- if( ( Rx_Desc[ RxDescIndex ].Status & OWN_BIT ) == 0 )\r
- {\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- return xReturn;\r
-}\r
-\r
-void EMAC_NextPacketToRead( xNetworkBufferDescriptor_t *pxNetworkBuffer )\r
-{\r
-uint8_t *pucTemp;\r
-\r
- /* Swap the buffer in the network buffer with the buffer used by the DMA.\r
- This allows the data to be passed out without having to perform any copies. */\r
- pucTemp = ( uint8_t * ) Rx_Desc[ RxDescIndex ].Packet;\r
- Rx_Desc[ RxDescIndex ].Packet = ( uint32_t ) pxNetworkBuffer->pucEthernetBuffer;\r
- pxNetworkBuffer->pucEthernetBuffer = pucTemp;\r
-\r
- /* Only supports frames coming in single buffers. If this frame is split\r
- across multiple buffers then reject it (and if the frame is needed increase\r
- the ipconfigNETWORK_MTU setting). */\r
- if( ( Rx_Desc[ RxDescIndex ].Status & emacEXPECTED_RX_STATUS_MASK ) != emacEXPECTED_RX_STATUS_MASK )\r
- {\r
- pxNetworkBuffer->xDataLength = 0;\r
- }\r
- else\r
- {\r
- pxNetworkBuffer->xDataLength = ( size_t ) EMAC_GetReceiveDataSize() - ( ipETHERNET_CRC_BYTES - 1U );;\r
- }\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief Initializes RX Descriptor\r
- * @param[in] None\r
- * @return None\r
- ***********************************************************************/\r
-static void rx_descr_init( void )\r
-{\r
-uint32_t x;\r
-size_t xBufferSize = ipTOTAL_ETHERNET_FRAME_SIZE;\r
-\r
- for( x = 0; x < configNUM_RX_ETHERNET_DMA_DESCRIPTORS; x++ )\r
- {\r
- /* Obtain the buffer first, as the size of the buffer might be changed\r
- within the pucEthernetBufferGet() call. */\r
- Rx_Desc[ x ].Packet = ( uint32_t ) pucEthernetBufferGet( &xBufferSize );\r
- Rx_Desc[ x ].Status = OWN_BIT;\r
- Rx_Desc[ x ].Ctrl = xBufferSize;\r
- Rx_Desc[ x ].NextDescripter = ( uint32_t ) &Rx_Desc[ x + 1 ];\r
- \r
- configASSERT( ( ( ( uint32_t ) Rx_Desc[x].Packet ) & 0x07 ) == 0 );\r
- }\r
-\r
- /* Last Descriptor */\r
- Rx_Desc[ configNUM_RX_ETHERNET_DMA_DESCRIPTORS - 1 ].Ctrl |= RX_END_RING;\r
-\r
- RxDescIndex = 0;\r
-\r
- /* Set Starting address of RX Descriptor list */\r
- LPC_ETHERNET->DMA_REC_DES_ADDR = ( uint32_t ) Rx_Desc;\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief Initializes TX Descriptor\r
- * @param[in] None\r
- * @return None\r
- ***********************************************************************/\r
-static void tx_descr_init( void )\r
-{\r
-/* Initialize Transmit Descriptor and Status array. */\r
-uint32_t x;\r
-\r
- for( x = 0; x < configNUM_TX_ETHERNET_DMA_DESCRIPTORS; x++ )\r
- {\r
- Tx_Desc[ x ].Status = TX_LAST_SEGM | TX_FIRST_SEGM;\r
- Tx_Desc[ x ].Ctrl = 0;\r
- Tx_Desc[ x ].NextDescripter = ( uint32_t ) &Tx_Desc[ x + 1 ];\r
-\r
- /* Packet is assigned when a Tx is initiated. */\r
- Tx_Desc[ x ].Packet = ( uint32_t )NULL;\r
- }\r
-\r
- /* Last Descriptor? */\r
- Tx_Desc[ configNUM_TX_ETHERNET_DMA_DESCRIPTORS-1 ].Status |= TX_END_RING;\r
-\r
- /* Set Starting address of TX Descriptor list */\r
- LPC_ETHERNET->DMA_TRANS_DES_ADDR = ( uint32_t ) Tx_Desc;\r
-}\r
-\r
-\r
-/*********************************************************************//**\r
- * @brief Write value to PHY device\r
- * @param[in] PhyReg: PHY Register address\r
- * @param[in] Value: Value to write\r
- * @return 0 - if success\r
- * 1 - if fail\r
- ***********************************************************************/\r
-static int32_t write_PHY (uint32_t PhyReg, uint16_t Value)\r
-{\r
-uint32_t x;\r
-const uint32_t ulMaxAttempts = 250UL;\r
-int32_t lReturn = pdPASS;\r
-\r
- /* Write a data 'Value' to PHY register 'PhyReg'. */\r
- x = 0;\r
- while( LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY )\r
- {\r
- x++;\r
-\r
- if( x >= ulMaxAttempts )\r
- {\r
- /* Time out. */\r
- lReturn = pdFAIL;\r
- break;\r
- }\r
- else\r
- {\r
- /* GMII is busy. */\r
- vTaskDelay( emacTIMEOUT_DELAY );\r
- }\r
- }\r
-\r
- if( lReturn == pdPASS )\r
- {\r
- LPC_ETHERNET->MAC_MII_ADDR = ( DP83848C_DEF_ADR << 11 ) | ( PhyReg << 6 ) | GMII_WRITE;\r
- LPC_ETHERNET->MAC_MII_DATA = Value;\r
-\r
- /* Start PHY Write Cycle. */\r
- LPC_ETHERNET->MAC_MII_ADDR |= GMII_BUSY;\r
-\r
- /* Wait untl operation completed. */\r
- for( x = 0; x < ulMaxAttempts; x++ )\r
- {\r
- if( ( LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY ) == 0 )\r
- {\r
- break;\r
- }\r
- else\r
- {\r
- vTaskDelay( emacTIMEOUT_DELAY );\r
- }\r
- }\r
-\r
- if( x == ulMaxAttempts )\r
- {\r
- /* Timeout. */\r
- lReturn = pdFAIL;\r
- }\r
- }\r
-\r
- return lReturn;\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief Read value from PHY device\r
- * @param[in] PhyReg: PHY Register address\r
- * @return 0 - if success\r
- * 1 - if fail\r
- ***********************************************************************/\r
-static int32_t read_PHY( uint32_t PhyReg )\r
-{\r
-int32_t lValue = 0;\r
-uint32_t x;\r
-const uint32_t ulMaxAttempts = 250UL;\r
-\r
- /* Write a data 'Value' to PHY register 'PhyReg'. */\r
- x = 0;\r
- while( LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY )\r
- {\r
- x++;\r
-\r
- if( x >= ulMaxAttempts )\r
- {\r
- /* Time out. */\r
- break;\r
- }\r
- else\r
- {\r
- /* GMII is busy. */\r
- vTaskDelay( emacTIMEOUT_DELAY );\r
- }\r
- }\r
-\r
- if( x < ulMaxAttempts )\r
- {\r
- /* Read a PHY register 'PhyReg'. */\r
- LPC_ETHERNET->MAC_MII_ADDR = ( DP83848C_DEF_ADR << 11 ) | ( PhyReg << 6 ) | GMII_READ;\r
-\r
- /* Start PHY Read Cycle. */\r
- LPC_ETHERNET->MAC_MII_ADDR |= GMII_BUSY;\r
-\r
- /* Wait until operation completed */\r
- for( x = 0; x < ulMaxAttempts; x++ )\r
- {\r
- if( ( LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY ) == 0 )\r
- {\r
- break;\r
- }\r
- else\r
- {\r
- vTaskDelay( emacTIMEOUT_DELAY );\r
- }\r
- }\r
-\r
- configASSERT( x != ulMaxAttempts );\r
- lValue = LPC_ETHERNET->MAC_MII_DATA;\r
- }\r
-\r
- return lValue;\r
-}\r
-\r
-/*********************************************************************//**\r
- * @brief Set Station MAC address for EMAC module\r
- * @param[in] abStationAddr Pointer to Station address that contains 6-bytes\r
- * of MAC address (should be in order from MAC Address 1 to MAC Address 6)\r
- * @return None\r
- **********************************************************************/\r
-static void setEmacAddr( uint8_t abStationAddr[] )\r
-{\r
- /* Set the Ethernet MAC Address registers */\r
- LPC_ETHERNET->MAC_ADDR0_HIGH = (( uint32_t ) abStationAddr[ 5 ] << 8 ) | ( uint32_t )abStationAddr[ 4 ];\r
- LPC_ETHERNET->MAC_ADDR0_LOW = (( uint32_t )abStationAddr[ 3 ] << 24) | (( uint32_t )abStationAddr[ 2 ] << 16) | (( uint32_t )abStationAddr[ 1 ] << 8 ) | ( uint32_t )abStationAddr[ 0 ];\r
-}\r
-\r
-\r
-\r
+++ /dev/null
-/***********************************************************************//**\r
- * @file lpc17xx_emac.h\r
- * @brief Contains all macro definitions and function prototypes\r
- * support for Ethernet MAC firmware library on LPC17xx\r
- * @version 2.0\r
- * @date 21. May. 2010\r
- * @author NXP MCU SW Application Team\r
- **************************************************************************\r
- * Software that is described herein is for illustrative purposes only\r
- * which provides customers with programming information regarding the\r
- * products. This software is supplied "AS IS" without any warranties.\r
- * NXP Semiconductors assumes no responsibility or liability for the\r
- * use of the software, conveys no license or title under any patent,\r
- * copyright, or mask work right to the product. NXP Semiconductors\r
- * reserves the right to make changes in the software without\r
- * notification. NXP Semiconductors also make no representation or\r
- * warranty that such application will be suitable for the specified\r
- * use without further testing or modification.\r
- **************************************************************************/\r
-\r
-/* Peripheral group ----------------------------------------------------------- */\r
-/** @defgroup EMAC EMAC\r
- * @ingroup LPC1700CMSIS_FwLib_Drivers\r
- * @{\r
- */\r
-\r
-#ifndef LPC18XX_EMAC_H_\r
-#define LPC18XX_EMAC_H_\r
-\r
-/* Includes ------------------------------------------------------------------- */\r
-#include "LPC18xx.h"\r
-\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C"\r
-{\r
-#endif\r
-\r
-#include "lpc_types.h"\r
-\r
-/* Configuration */\r
-\r
-/* Interface Selection */\r
-#define MII 0 // =0 RMII - =1 MII\r
-\r
-/* End of Configuration */\r
-\r
-/* Descriptors Fields bits */\r
-#define OWN_BIT (1U<<31) /* Own bit in RDES0 & TDES0 */\r
-#define RX_END_RING (1<<15) /* Receive End of Ring bit in RDES1 */\r
-#define RX_NXTDESC_FLAG (1<<14) /* Second Address Chained bit in RDES1 */\r
-#define TX_LAST_SEGM (1<<29) /* Last Segment bit in TDES0 */\r
-#define RX_LAST_SEGM (1<<9)\r
-#define TX_FIRST_SEGM (1<<28) /* First Segment bit in TDES0 */\r
-#define RX_FIRST_SEGM (1<<8) /* First Segment bit in TDES0 */\r
-#define TX_END_RING (1<<21) /* Transmit End of Ring bit in TDES0 */\r
-#define TX_NXTDESC_FLAG (1<<20) /* Second Address Chained bit in TDES0 */\r
-\r
-/* EMAC Memory Buffer configuration for 16K Ethernet RAM */\r
-#define EMAC_ETH_MAX_FLEN ipETHERNET_FRAME_SIZE_TO_USE\r
-\r
-/* NOTE: EMAC_NUM_RX_FRAG is not used by the example FreeRTOS drivers - use\r
-configNUM_RX_ETHERNET_DMA_DESCRIPTORS. */\r
-#define EMAC_NUM_RX_FRAG 6 /**< Num.of RX Fragments */\r
-\r
-/* NOTE: EMAC_NUM_TX_FRAG is not used by the example FreeRTOS drivers - use\r
-configNUM_TX_ETHERNET_DMA_DESCRIPTORS. */\r
-#define EMAC_NUM_TX_FRAG 2 /**< Num.of TX Fragments */\r
-\r
-/* EMAC Control and Status bits */\r
-#define MAC_RX_ENABLE (1<<2) /* Receiver Enable in MAC_CONFIG reg */\r
-#define MAC_TX_ENABLE (1<<3) /* Transmitter Enable in MAC_CONFIG reg */\r
-#define MAC_PADCRC_STRIP (1<<7) /* Automatic Pad-CRC Stripping in MAC_CONFIG reg */\r
-#define MAC_DUPMODE (1<<11) /* Duplex Mode in MAC_CONFIG reg */\r
-#define MAC_100MPS (1<<14) /* Speed is 100Mbps in MAC_CONFIG reg */\r
-#define MAC_PROMISCUOUS (1U<<0) /* Promiscuous Mode bit in MAC_FRAME_FILTER reg */\r
-#define MAC_DIS_BROAD (1U<<5) /* Disable Broadcast Frames bit in MAC_FRAME_FILTER reg */\r
-#define MAC_RECEIVEALL (1U<<31) /* Receive All bit in MAC_FRAME_FILTER reg */\r
-#define DMA_SOFT_RESET 0x01 /* Software Reset bit in DMA_BUS_MODE reg */\r
-#define DMA_SS_RECEIVE (1<<1) /* Start/Stop Receive bit in DMA_OP_MODE reg */\r
-#define DMA_SS_TRANSMIT (1<<13) /* Start/Stop Transmission bit in DMA_OP_MODE reg */\r
-#define DMA_INT_TRANSMIT (1<<0) /* Transmit Interrupt Enable bit in DMA_INT_EN reg */\r
-#define DMA_INT_OVERFLOW (1<<4) /* Overflow Interrupt Enable bit in DMA_INT_EN reg */\r
-#define DMA_INT_UNDERFLW (1<<5) /* Underflow Interrupt Enable bit in DMA_INT_EN reg */\r
-#define DMA_INT_RECEIVE (1<<6) /* Receive Interrupt Enable bit in DMA_INT_EN reg */\r
-#define DMA_INT_ABN_SUM (1<<15) /* Abnormal Interrupt Summary Enable bit in DMA_INT_EN reg */\r
-#define DMA_INT_NOR_SUM (1<<16) /* Normal Interrupt Summary Enable bit in DMA_INT_EN reg */\r
-\r
-/* MII Management Command Register */\r
-#define GMII_READ (0<<1) /* GMII Read PHY */\r
-#define GMII_WRITE (1<<1) /* GMII Write PHY */\r
-#define GMII_BUSY 0x00000001 /* GMII is Busy / Start Read/Write */\r
-#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */\r
-#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */\r
-\r
-/* MII Management Address Register */\r
-#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */\r
-\r
-/* LAN8720 PHY Registers */\r
-#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */\r
-#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */\r
-#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */\r
-#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */\r
-#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */\r
-#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */\r
-#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */\r
-#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */\r
-\r
-/* LAN8720 PHY Speed identify */\r
-#define PHY_REG_SPCON 0x1f /* Speed indication Register */\r
-#define PHY_REG_HCDSPEED_MASK 0x1c /* Speed indication Register mask*/\r
-#define PHY_REG_HCDSPEED_10MB_HALFD 0x04 /* Speed is 10Mbps HALF-duplex */\r
-#define PHY_REG_HCDSPEED_10MB_FULLD 0x14 /* Speed is 10Mbps FULL-duplex */\r
-#define PHY_REG_HCDSPEED_100MB_HALFD 0x08 /* Speed is 100Mbps HALF-duplex */\r
-#define PHY_REG_HCDSPEED_100MB_FULLD 0x18 /* Speed is 100Mbps FULL-duplex */\r
-\r
-\r
-/* PHY Extended Registers */\r
-#define PHY_REG_STS 0x10 /* Status Register */\r
-#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */\r
-#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */\r
-#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */\r
-#define PHY_REG_RECR 0x15 /* Receive Error Counter */\r
-#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */\r
-#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */\r
-#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */\r
-#define PHY_REG_PHYCR 0x19 /* PHY Control Register */\r
-#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */\r
-#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */\r
-#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */\r
-\r
-/* PHY Control and Status bits */\r
-#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */\r
-#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */\r
-#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */\r
-#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */\r
-#define PHY_AUTO_NEG 0x1000 /* Select Auto Negotiation */\r
-#define PHY_AUTO_NEG_DONE 0x0020 /* AutoNegotiation Complete in BMSR PHY reg */\r
-#define PHY_BMCR_RESET 0x8000 /* Reset bit at BMCR PHY reg */\r
-#define LINK_VALID_STS 0x0001 /* Link Valid Status at REG_STS PHY reg */\r
-#define FULL_DUP_STS 0x0004 /* Full Duplex Status at REG_STS PHY reg */\r
-#define SPEED_10M_STS 0x0002 /* 10Mbps Status at REG_STS PHY reg */\r
-\r
-#define DP83848C_DEF_ADR 0x01 /* Default PHY device address */\r
-#define DP83848C_ID 0x20005C90 /* PHY Identifier (without Rev. info */\r
-#define LAN8720_ID 0x0007C0F1 /* PHY Identifier for SMSC PHY */\r
-\r
-/* Misc */\r
-#define ETHERNET_RST 22 /* Reset Output for EMAC at RGU */\r
-#define RMII_SELECT 0x04 /* Select RMII in EMACCFG */\r
-\r
-\r
-/**\r
- * @brief EMAC configuration structure definition\r
- */\r
-typedef struct {\r
- uint32_t Mode; /**< Supported EMAC PHY device speed, should be one of the following:\r
- - EMAC_MODE_AUTO\r
- - EMAC_MODE_10M_FULL\r
- - EMAC_MODE_10M_HALF\r
- - EMAC_MODE_100M_FULL\r
- - EMAC_MODE_100M_HALF\r
- */\r
- uint8_t *pbEMAC_Addr; /**< Pointer to EMAC Station address that contains 6-bytes\r
- of MAC address, it must be sorted in order (bEMAC_Addr[0]..[5])\r
- */\r
-} EMAC_CFG_Type;\r
-\r
-/* Descriptor and status formats ---------------------------------------------- */\r
-/**\r
- * @brief RX Descriptor structure type definition\r
- */\r
-typedef struct {\r
- uint32_t Status; /**< Receive Status Descriptor */\r
- uint32_t Ctrl; /**< Receive Control Descriptor */\r
- uint32_t Packet; /**< Receive Packet Descriptor */\r
- uint32_t NextDescripter;/**< Receive Next Descriptor Address */\r
-} RX_Desc;\r
-\r
-/**\r
- * @brief RX Status structure type definition\r
- */\r
-typedef struct {\r
- uint32_t Info; /**< Receive Information Status */\r
- uint32_t HashCRC; /**< Receive Hash CRC Status */\r
-} RX_Stat;\r
-\r
-/**\r
- * @brief TX Descriptor structure type definition\r
- */\r
-typedef struct {\r
- uint32_t Status; /**< Transmit Status Descriptor */\r
- uint32_t Ctrl; /**< Transmit Control Descriptor */\r
- uint32_t Packet; /**< Transmit Packet Descriptor */\r
- uint32_t NextDescripter; /**< Transmit Next Descriptor Address */\r
-} TX_Desc;\r
-\r
-/**\r
- * @brief TX Status structure type definition\r
- */\r
-typedef struct {\r
- uint32_t Info; /**< Transmit Information Status */\r
-} TX_Stat;\r
-\r
-\r
-/**\r
- * @brief TX Data Buffer structure definition\r
- */\r
-typedef struct {\r
- uint32_t ulDataLen; /**< Data length */\r
- uint32_t *pbDataBuf; /**< A word-align data pointer to data buffer */\r
-} EMAC_PACKETBUF_Type;\r
-\r
-\r
-\r
-/* Prototypes */\r
-portBASE_TYPE EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct);\r
-int32_t EMAC_UpdatePHYStatus(void);\r
-uint32_t EMAC_GetReceiveDataSize(void);\r
-void EMAC_StartTransmitNextBuffer( uint32_t ulLength );\r
-void EMAC_SetNextPacketToSend( uint8_t * pucBuffer );\r
-void EMAC_NextPacketToRead( xNetworkBufferDescriptor_t *pxNetworkBuffer );\r
-void EMAC_UpdateRxConsumeIndex(void);\r
-portBASE_TYPE EMAC_CheckReceiveIndex(void);\r
-portBASE_TYPE EMAC_CheckTransmitIndex(void);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* LPC18XX_EMAC_H_ */\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/* --------------------------------- End Of File ------------------------------ */\r