summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq')
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c180
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt12
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c89
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c194
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c12
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c75
7 files changed, 339 insertions, 225 deletions
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
index 1c11976cb..4a6af81f9 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
@@ -1,27 +1,27 @@
/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
+ * FreeRTOS V202002.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
/* Standard includes. */
#include <stdint.h>
@@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_ARP.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
@@ -50,10 +51,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Provided memory configured as uncached. */
#include "uncached_memory.h"
-#ifndef BMSR_LINK_STATUS
- #define BMSR_LINK_STATUS 0x0004UL
+#ifndef niEMAC_HANDLER_TASK_PRIORITY
+ /* Define the priority of the task prvEMACHandlerTask(). */
+ #define niEMAC_HANDLER_TASK_PRIORITY configMAX_PRIORITIES - 1
#endif
+#define niBMSR_LINK_STATUS 0x0004uL
+
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
receiving packets. */
@@ -83,6 +87,13 @@ FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
#endif
+#if( ipconfigZERO_COPY_RX_DRIVER == 0 || ipconfigZERO_COPY_TX_DRIVER == 0 )
+ #error Please define both 'ipconfigZERO_COPY_RX_DRIVER' and 'ipconfigZERO_COPY_TX_DRIVER' as 1
+#endif
+
+#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 || ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
+ #warning Please define both 'ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM' and 'ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM' as 1
+#endif
/*-----------------------------------------------------------*/
/*
@@ -96,6 +107,10 @@ static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
*/
static void prvEMACHandlerTask( void *pvParameters );
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources( void );
+#endif
+
/*-----------------------------------------------------------*/
/* EMAC data/descriptions. */
@@ -119,7 +134,7 @@ XEmacPs_Config mac_config =
extern int phy_detected;
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
+static uint32_t ulPHYLinkStatus = 0uL;
#if( ipconfigUSE_LLMNR == 1 )
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
@@ -188,7 +203,7 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
possible priority to ensure the interrupt handler can return directly
to it. The task's handle is stored in xEMACTaskHandle so interrupts can
notify the task when there is something to process. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle );
}
else
{
@@ -206,7 +221,24 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
{
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ ProtocolPacket_t *pxPacket;
+
+ /* If the peripheral must calculate the checksum, it wants
+ the protocol checksum to have a value of zero. */
+ pxPacket = ( ProtocolPacket_t * ) ( pxBuffer->pucEthernetBuffer );
+ if( ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_UDP ) &&
+ ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_TCP ) )
+ {
+ /* The EMAC will calculate the checksum of the IP-header.
+ It can only calculate protocol checksums of UDP and TCP,
+ so for ICMP and other protocols it must be done manually. */
+ usGenerateProtocolChecksum( (uint8_t*)&( pxPacket->xUDPPacket ), pxBuffer->xDataLength, pdTRUE );
+ }
+ }
+ #endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
{
iptraceNETWORK_INTERFACE_TRANSMIT();
emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
@@ -249,7 +281,7 @@ BaseType_t xReturn;
}
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
{
xReturn = pdTRUE;
break;
@@ -281,7 +313,7 @@ BaseType_t xGetPhyLinkStatus( void )
{
BaseType_t xReturn;
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )
{
xReturn = pdFALSE;
}
@@ -294,12 +326,58 @@ BaseType_t xReturn;
}
/*-----------------------------------------------------------*/
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources()
+ {
+ static UBaseType_t uxLastMinBufferCount = 0u;
+ static size_t uxMinLastSize = 0uL;
+ UBaseType_t uxCurrentBufferCount;
+ size_t uxMinSize;
+
+ uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
+
+ if( uxLastMinBufferCount != uxCurrentBufferCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentBufferCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(),
+ uxCurrentBufferCount ) );
+ }
+
+ uxMinSize = xPortGetMinimumEverFreeHeapSize();
+
+ if( uxMinLastSize != uxMinSize )
+ {
+ uxMinLastSize = uxMinSize;
+ FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
+ }
+
+ #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 0;
+ UBaseType_t uxCurrentCount = 0u;
+
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+ }
+#endif /* ( ipconfigHAS_PRINTF != 0 ) */
+/*-----------------------------------------------------------*/
+
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
BaseType_t xResult = 0;
uint32_t xStatus;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
@@ -316,30 +394,11 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
for( ;; )
{
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 0;
-
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
+ #if ( ipconfigHAS_PRINTF != 0 )
{
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ prvMonitorResources();
}
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+ #endif /* ipconfigHAS_PRINTF != 0 ) */
if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
{
@@ -372,19 +431,26 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
xResult = 0;
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )
+ {
+ /* Indicate that the Link Status is high, so that
+ xNetworkInterfaceOutput() can send packets. */
+ ulPHYLinkStatus |= niBMSR_LINK_STATUS;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume 1\n" ) );
+ }
}
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
{
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != ( xStatus & niBMSR_LINK_STATUS ) )
{
ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL ) );
}
vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
index f9e54bb2f..10a72b464 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
@@ -5,6 +5,7 @@ NetworkInterface for Xilinx' Zynq
Please include the following source files:
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/NetworkInterface.c
+ $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/uncached_memory.c
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
@@ -23,3 +24,14 @@ The following source files are NOT used for the FreeRTOS+TCP interface:
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_bdring.c
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_hw.c
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_sinit.c
+
+It is recommended to have these defined :
+
+#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
+#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
+#define ipconfigUSE_LINKED_RX_MESSAGES 1
+
+It is obligatory to define:
+
+#define ipconfigZERO_COPY_RX_DRIVER 1
+#define ipconfigZERO_COPY_TX_DRIVER 1
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
index b43e50ec2..bfbdc341b 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
@@ -1,10 +1,35 @@
/*
+ * FreeRTOS V202002.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/*
* uncached_memory.c
*
* This module will declare 1 MB of memory and switch off the caching for it.
*
* pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length
- * rounded up to a multiple of 4 KB
+ * rounded up to a multiple of 4 KB.
*
* ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT
* within the range of the 1 MB non-cached memory.
@@ -43,23 +68,35 @@
#include "uncached_memory.h"
-#define UNCACHED_MEMORY_SIZE 0x100000ul
+/* Reserve 1 MB of memory. */
+#define uncMEMORY_SIZE 0x100000uL
+
+/* Make sure that each pointer has an alignment of 4 KB. */
+#define uncALIGNMENT_SIZE 0x1000uL
#define DDR_MEMORY_END (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)
+#define uncMEMORY_ATTRIBUTE 0x1C02
+
static void vInitialiseUncachedMemory( void );
static uint8_t *pucHeadOfMemory;
static uint32_t ulMemorySize;
static uint8_t *pucStartOfMemory = NULL;
+/* The linker file defines some pseudo variables. '_end' is one of them.
+It is located at the first free byte in RAM. */
+extern u8 _end;
+
+/*-----------------------------------------------------------*/
+
uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )
{
uint8_t ucReturn;
if( ( pucStartOfMemory != NULL ) &&
( pucBuffer >= pucStartOfMemory ) &&
- ( pucBuffer < ( pucStartOfMemory + UNCACHED_MEMORY_SIZE ) ) )
+ ( pucBuffer < ( pucStartOfMemory + uncMEMORY_SIZE ) ) )
{
ucReturn = pdFALSE;
}
@@ -70,10 +107,12 @@ uint8_t ucReturn;
return ucReturn;
}
+/*-----------------------------------------------------------*/
uint8_t *pucGetUncachedMemory( uint32_t ulSize )
{
uint8_t *pucReturn;
+uint32_t ulSkipSize;
if( pucStartOfMemory == NULL )
{
@@ -85,48 +124,40 @@ uint8_t *pucReturn;
}
else
{
- uint32_t ulSkipSize;
-
pucReturn = pucHeadOfMemory;
- ulSkipSize = ( ulSize + 0x1000ul ) & ~0xffful;
+ /* Make sure that the next pointer return will have a good alignment. */
+ ulSkipSize = ( ulSize + uncALIGNMENT_SIZE ) & ~( uncALIGNMENT_SIZE - 1uL );
pucHeadOfMemory += ulSkipSize;
ulMemorySize -= ulSkipSize;
}
return pucReturn;
}
-
-extern u8 _end;
+/*-----------------------------------------------------------*/
static void vInitialiseUncachedMemory( )
{
/* At the end of program's space... */
- pucStartOfMemory = (uint8_t *) &_end;
- /*
- * Align the start address to 1 MB boundary.
- */
- pucStartOfMemory = (uint8_t *)( ( ( uint32_t )pucStartOfMemory + UNCACHED_MEMORY_SIZE ) & ( ~( UNCACHED_MEMORY_SIZE - 1 ) ) );
+ pucStartOfMemory = ( uint8_t * ) &( _end );
- if( ( ( u32 )pucStartOfMemory ) + UNCACHED_MEMORY_SIZE > DDR_MEMORY_END )
+ /* Align the start address to 1 MB boundary. */
+ pucStartOfMemory = ( uint8_t * )( ( ( uint32_t )pucStartOfMemory + uncMEMORY_SIZE ) & ( ~( uncMEMORY_SIZE - 1 ) ) );
+
+ if( ( ( u32 )pucStartOfMemory ) + uncMEMORY_SIZE > DDR_MEMORY_END )
{
-// vLoggingPrintf("vInitialiseUncachedMemory: Can not allocate uncached memory\n" );
+ FreeRTOS_printf( ( "vInitialiseUncachedMemory: Can not allocate uncached memory\n" ) );
}
else
{
- /*
- * Some objects want to be stored in uncached memory. Hence the 1 MB
- * address range that starts after "_end" is made uncached
- * by setting appropriate attributes in the translation table.
- */
- /* FIXME claudio rossi. Modified to prevent data abort exception (misaligned access)
- * when application is compiled with -O1 or more optimization flag.
- */
-/* Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0xc02 ); // addr, attr */
- Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0x1c02 ); // addr, attr
-
- /* For experiments in the SDIO driver, make the remaining uncached memory public */
+ /* Some objects want to be stored in uncached memory. Hence the 1 MB
+ address range that starts after "_end" is made uncached by setting
+ appropriate attributes in the translation table. */
+ Xil_SetTlbAttributes( ( uint32_t ) pucStartOfMemory, uncMEMORY_ATTRIBUTE );
+
+ /* For experiments in the SDIO driver, make the remaining uncached memory
+ public */
pucHeadOfMemory = pucStartOfMemory;
- ulMemorySize = UNCACHED_MEMORY_SIZE;
- memset( pucStartOfMemory, '\0', UNCACHED_MEMORY_SIZE );
+ ulMemorySize = uncMEMORY_SIZE;
+ memset( pucStartOfMemory, '\0', uncMEMORY_SIZE );
}
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
index 823dee0d3..bf0d174c0 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
@@ -26,7 +26,6 @@ extern "C" {
#include <stdint.h>
#include "xstatus.h"
-#include "sleep.h"
#include "xparameters.h"
#include "xparameters_ps.h" /* defines XPAR values */
#include "xil_types.h"
@@ -35,7 +34,6 @@ extern "C" {
#include "xil_exception.h"
#include "xpseudo_asm.h"
#include "xil_cache.h"
-#include "xil_printf.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xemacps.h" /* defines XEmacPs API */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
index fc09d2183..913b4b46c 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
@@ -1,36 +1,27 @@
/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-#include "Zynq/x_emacpsif.h"
-#include "Zynq/x_topology.h"
-#include "xstatus.h"
-
-#include "xparameters.h"
-#include "xparameters_ps.h"
-#include "xil_exception.h"
-#include "xil_mmu.h"
+ * FreeRTOS V202002.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
#include "FreeRTOS.h"
#include "task.h"
@@ -43,6 +34,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
+#include "Zynq/x_emacpsif.h"
+#include "Zynq/x_topology.h"
+#include "xstatus.h"
+
+#include "xparameters.h"
+#include "xparameters_ps.h"
+#include "xil_exception.h"
+#include "xil_mmu.h"
+
#include "uncached_memory.h"
/* Two defines used to set or clear the EMAC interrupt */
@@ -56,7 +56,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
-#define RX_BUFFER_ALIGNMENT 14
+#define dmaRX_TX_BUFFER_SIZE 1536
/* Defined in NetworkInterface.c */
extern TaskHandle_t xEMACTaskHandle;
@@ -120,8 +120,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
{
break;
}
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
-#warning ipconfigZERO_COPY_TX_DRIVER is defined
{
void *pvBuffer = pxDMA_tx_buffers[ tail ];
NetworkBufferDescriptor_t *pxBuffer;
@@ -140,7 +138,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
}
}
}
-#endif
/* Clear all but the "used" and "wrap" bits. */
if( tail < ipconfigNIC_N_TX_DESC - 1 )
{
@@ -170,6 +167,11 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xemacpsif = (xemacpsif_s *)(arg);
+ /* This function is called from an ISR. The Xilinx ISR-handler has already
+ cleared the TXCOMPL and TXSR_USEDREAD status bits in the XEMACPS_TXSR register.
+ But it forgets to do a read-back. Do so now to avoid ever-returning ISR's. */
+ ( void ) XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
+
/* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
"isr_events". The task in NetworkInterface will wake-up and do the necessary work.
*/
@@ -188,7 +190,7 @@ static BaseType_t xValidLength( BaseType_t xLength )
{
BaseType_t xReturn;
- if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
+ if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= dmaRX_TX_BUFFER_SIZE ) )
{
xReturn = pdTRUE;
}
@@ -207,12 +209,8 @@ int iHasSent = 0;
uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* This driver wants to own all network buffers which are to be transmitted. */
- configASSERT( iReleaseAfterSend != pdFALSE );
- }
- #endif
+ /* This driver wants to own all network buffers which are to be transmitted. */
+ configASSERT( iReleaseAfterSend != pdFALSE );
/* Open a do {} while ( 0 ) loop to be able to call break. */
do
@@ -235,7 +233,6 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
break;
}
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
/* Pass the pointer (and its ownership) directly to DMA. */
pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer;
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
@@ -244,15 +241,7 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
}
/* Buffer has been transferred, do not release it. */
iReleaseAfterSend = pdFALSE;
-#else
- if( pxDMA_tx_buffers[ head ] == NULL )
- {
- FreeRTOS_printf( ( "emacps_send_message: pxDMA_tx_buffers[ %d ] == NULL\n", head ) );
- break;
- }
- /* Copy the message to unbuffered space in RAM. */
- memcpy( pxDMA_tx_buffers[ head ], pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
-#endif
+
/* Packets will be sent one-by-one, so for each packet
the TXBUF_LAST bit will be set. */
ulFlags |= XEMACPS_TXBUF_LAST_MASK;
@@ -292,6 +281,8 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
/* Start transmit */
xemacpsif->txBusy = pdTRUE;
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
+ /* Read back the register to make sure the data is flushed. */
+ ( void ) XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET );
}
dsb();
@@ -306,6 +297,11 @@ void emacps_recv_handler(void *arg)
xemacpsif = (xemacpsif_s *)(arg);
xemacpsif->isr_events |= EMAC_IF_RX_EVENT;
+ /* The driver has already cleared the FRAMERX, BUFFNA and error bits
+ in the XEMACPS_RXSR register,
+ But it forgets to do a read-back. Do so now. */
+ ( void ) XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET);
+
if( xEMACTaskHandle != NULL )
{
vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
@@ -314,33 +310,35 @@ void emacps_recv_handler(void *arg)
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
-static NetworkBufferDescriptor_t *ethMsg = NULL;
-static NetworkBufferDescriptor_t *ethLast = NULL;
-
-static void passEthMessages( void )
+static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
{
IPStackEvent_t xRxEvent;
xRxEvent.eEventType = eNetworkRxEvent;
- xRxEvent.pvData = ( void * ) ethMsg;
+ xRxEvent.pvData = ( void * ) pxDescriptor;
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
{
/* The buffer could not be sent to the stack so must be released again.
This is a deferred handler taskr, not a real interrupt, so it is ok to
use the task level function here. */
- do
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
- vReleaseNetworkBufferAndDescriptor( ethMsg );
- ethMsg = xNext;
- } while( ethMsg != NULL );
-
+ do
+ {
+ NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ pxDescriptor = pxNext;
+ } while( pxDescriptor != NULL );
+ }
+ #else
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
+ FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
}
-
- ethMsg = ethLast = NULL;
}
int emacps_check_rx( xemacpsif_s *xemacpsif )
@@ -349,6 +347,10 @@ NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
int rx_bytes;
volatile int msgCount = 0;
int head = xemacpsif->rxHead;
+#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
+ NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
+#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
/* There seems to be an issue (SI# 692601), see comments below. */
resetrx_on_no_rxdata(xemacpsif);
@@ -364,12 +366,12 @@ int head = xemacpsif->rxHead;
break;
}
- pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ pxNewBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 );
if( pxNewBuffer == NULL )
{
/* A packet has been received, but there is no replacement for this Network Buffer.
The packet will be dropped, and it Network Buffer will stay in place. */
- FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Netwrok Buffer\n" ) );
+ FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Network Buffer\n" ) );
pxNewBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
}
else
@@ -394,26 +396,35 @@ int head = xemacpsif->rxHead;
/* store it in the receive queue, where it'll be processed by a
different handler. */
iptraceNETWORK_INTERFACE_RECEIVE();
- pxBuffer->pxNextBuffer = NULL;
-
- if( ethMsg == NULL )
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- // Becomes the first message
- ethMsg = pxBuffer;
+ pxBuffer->pxNextBuffer = NULL;
+
+ if( pxFirstDescriptor == NULL )
+ {
+ // Becomes the first message
+ pxFirstDescriptor = pxBuffer;
+ }
+ else if( pxLastDescriptor != NULL )
+ {
+ // Add to the tail
+ pxLastDescriptor->pxNextBuffer = pxBuffer;
+ }
+
+ pxLastDescriptor = pxBuffer;
}
- else if( ethLast != NULL )
+ #else
{
- // Add to the tail
- ethLast->pxNextBuffer = pxBuffer;
+ prvPassEthMessages( pxBuffer );
}
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
- ethLast = pxBuffer;
msgCount++;
}
{
if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )
{
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ Xil_DCacheInvalidateRange( ( ( uint32_t ) pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, ( uint32_t ) dmaRX_TX_BUFFER_SIZE );
}
{
uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
@@ -422,8 +433,10 @@ int head = xemacpsif->rxHead;
addr |= XEMACPS_RXBUF_WRAP_MASK;
}
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
- xemacpsif->rxSegments[ head ].address = addr;
xemacpsif->rxSegments[ head ].flags = 0;
+ xemacpsif->rxSegments[ head ].address = addr;
+ /* Make sure that the value has reached the peripheral by reading it back. */
+ ( void ) xemacpsif->rxSegments[ head ].address;
}
}
@@ -434,10 +447,14 @@ int head = xemacpsif->rxHead;
xemacpsif->rxHead = head;
}
- if( ethMsg != NULL )
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- passEthMessages( );
+ if( pxFirstDescriptor != NULL )
+ {
+ prvPassEthMessages( pxFirstDescriptor );
+ }
}
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
return msgCount;
}
@@ -455,11 +472,7 @@ unsigned char *ucTxBuffer;
{
xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;
xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- pxDMA_tx_buffers[ index ] = ( void* )NULL;
-#else
- pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
-#endif
+ pxDMA_tx_buffers[ index ] = ( unsigned char * )NULL;
ucTxBuffer += xemacpsif->uTxUnitSize;
}
xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
@@ -479,8 +492,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );
- /* Also round-up to 4KB */
- xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
+ xemacpsif->uTxUnitSize = dmaRX_TX_BUFFER_SIZE;
/*
* We allocate 65536 bytes for RX BDs which can accommodate a
* maximum of 8192 BDs which is much more than any application
@@ -507,7 +519,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
pxBuffer = pxDMA_rx_buffers[ iIndex ];
if( pxBuffer == NULL )
{
- pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ pxBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 );
if( pxBuffer == NULL )
{
FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
@@ -523,7 +535,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
{
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
- (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ (unsigned)dmaRX_TX_BUFFER_SIZE );
}
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
index e9443cda8..3d835d9a2 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
@@ -22,19 +22,19 @@
#include <stdio.h>
#include <stdlib.h>
-#include "Zynq/x_emacpsif.h"
-
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
-///* FreeRTOS+TCP includes. */
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "Zynq/x_emacpsif.h"
extern TaskHandle_t xEMACTaskHandle;
@@ -42,8 +42,6 @@ extern TaskHandle_t xEMACTaskHandle;
*** to run it on a PEEP board
***/
-unsigned int link_speed = 100;
-
void setup_isr( xemacpsif_s *xemacpsif )
{
/*
@@ -141,8 +139,6 @@ int xResult;
return xResult;
}
-BaseType_t xNetworkInterfaceInitialise( void );
-
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
{
xemacpsif_s *xemacpsif;
@@ -218,8 +214,6 @@ static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
}
}
-extern XEmacPs_Config mac_config;
-
void HandleTxErrors(xemacpsif_s *xemacpsif)
{
u32 netctrlreg;
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
index 12b8c60c8..62228d065 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
@@ -53,24 +53,23 @@
#include <stdio.h>
#include <stdlib.h>
-#include "Zynq/x_emacpsif.h"
-//#include "lwipopts.h"
-#include "xparameters_ps.h"
-#include "xparameters.h"
-
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
-///* FreeRTOS+TCP includes. */
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
+#include "Zynq/x_emacpsif.h"
+#include "xparameters_ps.h"
+#include "xparameters.h"
+
+
int phy_detected = 0;
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
@@ -99,6 +98,8 @@ int phy_detected = 0;
#define IEEE_CONTROL_REG_OFFSET 0
#define IEEE_STATUS_REG_OFFSET 1
+#define IEEE_PHYSID1_OFFSET 2
+#define IEEE_PHYSID2_OFFSET 3
#define IEEE_AUTONEGO_ADVERTISE_REG 4
#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
#define IEEE_1000_ADVERTISE_REG_OFFSET 9
@@ -135,9 +136,6 @@ int phy_detected = 0;
#define IEEE_PAUSE_MASK 0x0400
#define IEEE_AUTONEG_ERROR_MASK 0x8000
-#define PHY_DETECT_REG 1
-#define PHY_DETECT_MASK 0x1808
-
#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
@@ -161,21 +159,24 @@ int phy_detected = 0;
#define EMAC0_BASE_ADDRESS 0xE000B000
#define EMAC1_BASE_ADDRESS 0xE000C000
+#define PHY_ADDRESS_COUNT 32
+
+#define MINIMUM_SLEEP_TIME 2
+
+
static int detect_phy(XEmacPs *xemacpsp)
{
- u16 phy_reg;
- u32 phy_addr;
-
- for (phy_addr = 31; phy_addr > 0; phy_addr--) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
- &phy_reg);
-
- if ((phy_reg != 0xFFFF) &&
- ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
- /* Found a valid PHY address */
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
- phy_addr));
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
+ u16 id_lower, id_upper;
+ u32 phy_addr, id;
+
+ for (phy_addr = 0; phy_addr < PHY_ADDRESS_COUNT; phy_addr++) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PHYSID1_OFFSET, &id_lower);
+
+ if ((id_lower != ( u16 )0xFFFFu) && (id_lower != ( u16 )0x0u)) {
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PHYSID2_OFFSET, &id_upper);
+ id = ( ( ( uint32_t ) id_upper ) << 16 ) | ( id_lower & 0xFFF0 );
+ FreeRTOS_printf( ("XEmacPs detect_phy: %04lX at address %d.\n", id, phy_addr ) );
phy_detected = phy_addr;
return phy_addr;
}
@@ -238,8 +239,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
return 10;
- xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__);
+ FreeRTOS_printf( ( "%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
+ __FUNCTION__ ) );
return 10;
} else {
@@ -257,8 +258,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
case (IEEE_CTRL_LINKSPEED_10M):
return 10;
default:
- xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__, phylinkspeed);
+ FreeRTOS_printf( ( "%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
+ __FUNCTION__, phylinkspeed ) );
return 10;
}
@@ -282,7 +283,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
#else
u32 phy_addr = detect_phy(xemacpsp);
#endif
- xil_printf("Start PHY autonegotiation \r\n");
+ FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
@@ -338,24 +339,24 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
break;
}
#endif
- xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
+ FreeRTOS_printf( ( "Waiting for PHY to complete autonegotiation.\n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
&temp);
if (temp & IEEE_AUTONEG_ERROR_MASK) {
- xil_printf("Auto negotiation error \r\n");
+ FreeRTOS_printf( ( "Auto negotiation error \n" ) );
}
#endif
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
&status);
}
- xil_printf("autonegotiation complete \r\n");
+ FreeRTOS_printf( ( "autonegotiation complete \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
@@ -363,7 +364,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
#endif
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
+ FreeRTOS_printf( ( "Waiting for Link to be up; Polling for SGMII core Reg \n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
while(!(temp & 0x8000)) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
@@ -380,7 +381,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
return 10;
} else {
- xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
+ FreeRTOS_printf( ( "get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
return 10;
@@ -560,26 +561,26 @@ unsigned Phy_Setup (XEmacPs *xemacpsp)
link_speed = 1000;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#elif defined(ipconfigNIC_LINKSPEED100)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
link_speed = 100;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#elif defined(ipconfigNIC_LINKSPEED10)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
link_speed = 10;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#endif
if (conv_present) {
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
}
- xil_printf("link speed: %d\r\n", link_speed);
+ FreeRTOS_printf( ( "link speed: %d\n", link_speed ) );
return link_speed;
}