Beispiel #1
0
void vCheckBuffersAndQueue( void )
{
static UBaseType_t uxLastMinBufferCount = 0;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
	static UBaseType_t uxLastMinQueueSpace;
#endif
static UBaseType_t uxCurrentCount;

	#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
	{
		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 */
	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 ) );
	}

}
Beispiel #2
0
	void FreeRTOS_PrintARPCache( void )
	{
	BaseType_t x, xCount = 0;

		/* Loop through each entry in the ARP cache. */
		for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
		{
			if( xARPCache[ x ].ulIPAddress != 0ul &&  xARPCache[ x ].ucAge > 0U )
			{
				/* See if the MAC-address also matches, and we're all happy */
				FreeRTOS_printf( ( "Arp %2ld: %3u - %16lxip : %02x:%02x:%02x : %02x:%02x:%02x\n",
					x,
					xARPCache[ x ].ucAge,
					xARPCache[ x ].ulIPAddress,
					xARPCache[ x ].xMACAddress.ucBytes[0],
					xARPCache[ x ].xMACAddress.ucBytes[1],
					xARPCache[ x ].xMACAddress.ucBytes[2],
					xARPCache[ x ].xMACAddress.ucBytes[3],
					xARPCache[ x ].xMACAddress.ucBytes[4],
					xARPCache[ x ].xMACAddress.ucBytes[5] ) );
				xCount++;
			}
		}

		FreeRTOS_printf( ( "Arp has %ld entries\n", xCount ) );
	}
Beispiel #3
0
void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority )
{
	/* The only public function in this module: start a task to contact
	some NTP server. */

	if( xNTPTaskhandle != NULL )
	{
		switch( xStatus )
		{
		case EStatusPause:
			xStatus = EStatusAsking;
			vSignalTask();
			break;
		case EStatusLookup:
			FreeRTOS_printf( ( "NTP looking up server\n" ) );
			break;
		case EStatusAsking:
			FreeRTOS_printf( ( "NTP still asking\n" ) );
			break;
		case EStatusFailed:
			FreeRTOS_printf( ( "NTP failed somehow\n" ) );
			ulIPAddressFound = 0ul;
			xStatus = EStatusLookup;
			vSignalTask();
			break;
		}
	}
	else
	{
		xUDPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
		if( xUDPSocket != NULL )
		{
		struct freertos_sockaddr xAddress;
		#if( ipconfigUSE_CALLBACKS != 0 )
			BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 0 );
		#else
			BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
		#endif

			xAddress.sin_addr = 0ul;
			xAddress.sin_port = FreeRTOS_htons( NTP_PORT );

			FreeRTOS_bind( xUDPSocket, &xAddress, sizeof( xAddress ) );
			FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
			xTaskCreate( 	prvNTPTask,						/* The function that implements the task. */
							( const char * ) "NTP client",	/* Just a text name for the task to aid debugging. */
							usTaskStackSize,				/* The stack size is defined in FreeRTOSIPConfig.h. */
							NULL,							/* The task parameter, not used in this case. */
							uxTaskPriority,					/* The priority assigned to the task is defined in FreeRTOSConfig.h. */
							&xNTPTaskhandle );				/* The task handle. */
		}
		else
		{
			FreeRTOS_printf( ( "Creating socket failed\n" ) );
		}
	}
}
static BaseType_t prvProcessCmd( xHTTPClient *pxClient, BaseType_t xIndex )
{
BaseType_t xResult = 0;

	/* A new command has been received. Process it */
	switch( xIndex )
	{
	case ECMD_GET:
		xResult = prvOpenUrl( pxClient );
		break;

	case ECMD_HEAD:
	case ECMD_POST:
	case ECMD_PUT:
	case ECMD_DELETE:
	case ECMD_TRACE:
	case ECMD_OPTIONS:
	case ECMD_CONNECT:
	case ECMD_PATCH:
	case ECMD_UNK:
		{
			FreeRTOS_printf( ( "prvProcessCmd: Not implemented: %s\n",
				xWebCommands[xIndex].pcCommandName ) );
		}
		break;
	}

	return xResult;
}
static void start_test(unsigned test)
{
    if (test < TEST_COUNT) {
        FreeRTOS_printf(("Creating a task for test %d\n", test));
        if (pdPASS != xTaskCreate(
            single_test_runner, 
            "single test", 
            SINGLE_TEST_STACK_DEPTH, 
            (void*)test, 
            SINGLE_TEST_PRIORITY, 
            &m_aTest[test].task
            )) {
            FreeRTOS_printf(("\n!! Failed to create a task for test %d!\n", test));
        }
    }
}
static void probePHY(ETH_HandleTypeDef * heth) {

	uint32_t ulRegValue = 0;

	/* Read the result of the auto-negotiation. */
	HAL_ETH_ReadPHYRegister(heth, PHY_SR, &ulRegValue);

	if (heth->Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE) {

		/* Read the result of the auto-negotiation. */
		HAL_ETH_ReadPHYRegister(heth, PHY_SR, &ulRegValue);
		if ((ulRegValue & PHY_LINK_STATUS) != 0) {
			ulPHYLinkStatus |= BMSR_LINK_STATUS;
		}
		else {
			ulPHYLinkStatus &= ~( BMSR_LINK_STATUS);
		}

		FreeRTOS_printf( ( ">> Autonego ready: %08x: %s duplex %u mbit %s status\n",
			(unsigned int)ulRegValue,
			(ulRegValue & PHY_DUPLEX_STATUS) ? "full" : "half",
			(ulRegValue & PHY_SPEED_STATUS) ? 10 : 100,
			(ulRegValue & PHY_LINK_STATUS) ? "high" : "low" ) );
	}

}
Beispiel #7
0
static void passEthMessages( void )
{
IPStackEvent_t xRxEvent;

	xRxEvent.eEventType = eNetworkRxEvent;
	xRxEvent.pvData = ( void * ) ethMsg;

	if( xSendEventStructToIPTask( &xRxEvent, ( portTickType ) 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
		{
			NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
			vReleaseNetworkBufferAndDescriptor( ethMsg );
			ethMsg = xNext;
		} while( ethMsg != NULL );

		iptraceETHERNET_RX_EVENT_LOST();
		FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
	}

	ethMsg = ethLast = NULL;
}
Beispiel #8
0
void emacps_check_tx( xemacpsif_s *xemacpsif )
{
int tail = xemacpsif->txTail;
int head = xemacpsif->txHead;

	if( head != tail )
	{
		for( ; ; )
		{
			if( ( xemacpsif->txSegments[ tail ].flags & XEMACPS_TXBUF_USED_MASK ) == 0 )
			{
				/* The driver is still waiting for the EMAC to sent this message.
				When done, "TXBUF_USED" will be set. */
				break;
			}
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
#warning ipconfigZERO_COPY_TX_DRIVER is defined
			{
			void *pvBuffer = pxDMA_tx_buffers[ tail ];
			NetworkBufferDescriptor_t *pxBuffer;

				if( pvBuffer != NULL )
				{
					pxDMA_tx_buffers[ tail ] = NULL;
					pxBuffer = pxPacketBuffer_to_NetworkBuffer( pvBuffer );
					if( pxBuffer != NULL )
					{
						vReleaseNetworkBufferAndDescriptor( pxBuffer );
					}
					else
					{
						FreeRTOS_printf( ( "emacps_check_tx: Can not find network bufffer" ) );
					}
				}
			}
#endif
			/* Clear all but the "used" and "wrap" bits. */
			if( tail < ipconfigNIC_N_TX_DESC - 1 )
			{
				xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK;
			}
			else
			{
				xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
			}

			if( ++tail == ipconfigNIC_N_TX_DESC )
			{
				tail = 0;
			}
			if( tail == head )
			{
				break;
			}
		}
		xemacpsif->txTail = tail;
	}
	return;
}
void StartPubnubTask(uint16_t usTaskStackSize, UBaseType_t uxTaskPriority)
{
    m_TestResultQueue = xQueueCreate(g_max_conc_tests + 2, sizeof(struct TestResultMessage));
    if (0 == m_TestResultQueue) {
        FreeRTOS_printf(("\n!! Failed to create the test result queue!\n"));
    }
    if (pdPASS != xTaskCreate(
        test_runner, 
        "test runner", 
        usTaskStackSize, 
        NULL,
        uxTaskPriority, 
        NULL
        )) {
        vQueueDelete(m_TestResultQueue);
        FreeRTOS_printf(("\n!! Failed to create the task runner!\n"));
    }
}
static void prvFileClose( xHTTPClient *pxClient )
{
	if( pxClient->pxFileHandle != NULL )
	{
		FreeRTOS_printf( ( "Closing file: %s\n", pxClient->pcCurrentFilename ) );
		ff_fclose( pxClient->pxFileHandle );
		pxClient->pxFileHandle = NULL;
	}
}
Beispiel #11
0
void test_runner(void *arg)
{
    PUBNUB_UNUSED(arg);

    for (;;) {
        unsigned next_test = 0;
        unsigned failed_count = 0;
        unsigned passed_count = 0;
        unsigned indete_count = 0;
        unsigned tests_in_progress = 0;

        FreeRTOS_printf(("Starting Run of %d tests\n", TEST_COUNT));

        while (failed_count + passed_count + indete_count < TEST_COUNT) {
            struct TestResultMessage msg;
            if ((tests_in_progress < g_max_conc_tests) && (next_test < TEST_COUNT)) {
                start_test(next_test++);
                ++tests_in_progress;
            }
            if (pdTRUE == xQueueReceive(m_TestResultQueue, &msg, pdMS_TO_TICKS(20))) {
                switch (msg.result) {
                case trFail:
                    FreeRTOS_printf(("\n !!!!!!! The %d. test ('%s') failed!\n\n", msg.test + 1, m_aTest[msg.test].name));
                    ++failed_count;
                    break;
                case trPass:
                    ++passed_count;
                    break;
                case trIndeterminate:
                    ++indete_count;
                    FreeRTOS_printf((" Indeterminate %d. test ('%s') of %d\t", msg.test+1, m_aTest[msg.test].name, TEST_COUNT));
                    /* Should restart the test... */
                    //FreeRTOS_printf((" ReStarting %d. test of %ld\t", msg.test + 1, TEST_COUNT));
                    break;
                }
#ifdef INCLUDE_vTaskDelete
                vTaskDelete(m_aTest[msg.test].task);
#endif
                --tests_in_progress;
            }
        }

        FreeRTOS_printf(("Test run over.\n"));
        if (passed_count == TEST_COUNT) {
            FreeRTOS_printf(("\n All %d tests passed\n", TEST_COUNT));
        }
        else {
            FreeRTOS_printf(("\n\n %d tests passed, %d tests failed, %d tests indeterminate\n", 
                    passed_count,
                    failed_count,
                    indete_count
                ));
        }

        vTaskDelay(pdMS_TO_TICKS(10 * 1000));
    }
}
Beispiel #12
0
BaseType_t xPhyCheckLinkStatus( EthernetPhy_t *pxPhyObject, BaseType_t xHadReception )
{
uint32_t ulStatus, ulBitMask = 1u;
BaseType_t xPhyIndex;
BaseType_t xNeedCheck = pdFALSE;

	if( xHadReception > 0 )
	{
		/* A packet was received. No need to check for the PHY status now,
		but set a timer to check it later on. */
		vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
		pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
	}
	else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
	{
		for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
		{
		BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];

			if( pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulStatus ) == 0 )
			{
				if( !!( pxPhyObject->ulLinkStatusMask & ulBitMask ) != !!( ulStatus & phyBMSR_LINK_STATUS ) )
				{
					if( ( ulStatus & phyBMSR_LINK_STATUS ) != 0 )
					{
						pxPhyObject->ulLinkStatusMask |= ulBitMask;
					}
					else
					{
						pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
					}
					FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
					eventLogAdd( "PHY LS now %02lX", pxPhyObject->ulLinkStatusMask );
					xNeedCheck = pdTRUE;
				}
			}
		}
		vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
		if( ( pxPhyObject->ulLinkStatusMask & phyBMSR_LINK_STATUS ) != 0 )
		{
			pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
		}
		else
		{
			pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_LOW_CHECK_TIME_MS );
		}
	}
	return xNeedCheck;
}
Beispiel #13
0
static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
{
TickType_t xStartTime = xTaskGetTickCount();
TickType_t xEndTime;
BaseType_t xReturn;
const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );

	for( ;; )
	{
		xEndTime = xTaskGetTickCount();

		if( ( xEndTime - xStartTime ) > xMaxTime )
		{
			/* Wated more than xMaxTime, return. */
			xReturn = pdFALSE;
			break;
		}

		/* Check the link status again. */
		ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );

		if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
		{
			/* Link is up - return. */
			xReturn = pdTRUE;
			break;
		}

		/* Link is down - wait in the Blocked state for a short while (to allow
		other tasks to execute) before checking again. */
		vTaskDelay( xShortTime );
	}

	FreeRTOS_printf( ( "xGMACWaitLS: %ld (PHY %d) freq %lu Mz\n",
		xReturn,
		ethernet_phy_addr,
		sysclk_get_cpu_hz() / HZ_PER_MHZ ) );

	return xReturn;
}
static BaseType_t prvOpenUrl( xHTTPClient *pxClient )
{
BaseType_t xRc;
char pcSlash[ 2 ];

	pxClient->bits.ulFlags = 0;

	if( pxClient->pcUrlData[ 0 ] != '/' )
	{
		/* Insert a slah before the file name */
		pcSlash[ 0 ] = '/';
		pcSlash[ 1 ] = '\0';
	}
	else
	{
		/* The browser provided a starting '/' already */
		pcSlash[ 0 ] = '\0';
	}
	snprintf( pxClient->pcCurrentFilename, sizeof pxClient->pcCurrentFilename, "%s%s%s",
		pxClient->pcRootDir,
		pcSlash,
		pxClient->pcUrlData);

	pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" );

	FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename,
		pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) );

	if( pxClient->pxFileHandle == NULL )
	{
		xRc = prvSendReply( pxClient, WEB_NOT_FOUND );	/* "404 File not found" */
	}
	else
	{
		pxClient->xBytesLeft = pxClient->pxFileHandle->ulFileSize;
		xRc = prvSendFile( pxClient );
	}

	return xRc;
}
Beispiel #15
0
/* Discover all PHY's connected by polling 32 indexes ( zero-based ) */
BaseType_t xPhyDiscover( EthernetPhy_t *pxPhyObject )
{
BaseType_t xPhyAddress;

	pxPhyObject->xPortCount = 0;

	for( xPhyAddress = phyMIN_PHY_ADDRESS; xPhyAddress <= phyMAX_PHY_ADDRESS; xPhyAddress++ )
	{
	uint32_t ulLowerID;

		pxPhyObject->fnPhyRead( xPhyAddress, phyREG_03_PHYSID2, &ulLowerID );
		/* A valid PHY id can not be all zeros or all ones. */
		if( ( ulLowerID != ( uint16_t )~0u )  && ( ulLowerID != ( uint16_t )0u ) )
		{
		uint32_t ulUpperID;
		uint32_t ulPhyID;

			pxPhyObject->fnPhyRead( xPhyAddress, phyREG_02_PHYSID1, &ulUpperID );
			ulPhyID = ( ( ( uint32_t ) ulUpperID ) << 16 ) | ( ulLowerID & 0xFFF0 );

			pxPhyObject->ucPhyIndexes[ pxPhyObject->xPortCount ] = xPhyAddress;
			pxPhyObject->ulPhyIDs[ pxPhyObject->xPortCount ] = ulPhyID;

			pxPhyObject->xPortCount++;

			/* See if there is more storage space. */
			if( pxPhyObject->xPortCount == ipconfigPHY_MAX_PORTS )
			{
				break;
			}
		}
	}
	if( pxPhyObject->xPortCount > 0 )
	{
		FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
		eventLogAdd( "PHY ID 0x%lX", pxPhyObject->ulPhyIDs[ 0 ] );
	}

	return pxPhyObject->xPortCount;
}
Beispiel #16
0
static void vDNS_callback( const char *pcName, void *pvSearchID, uint32_t ulIPAddress )
{
char pcBuf[16];

	/* The DNS lookup has a result, or it has reached the time-out. */
	FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
	FreeRTOS_printf( ( "IP address of %s found: %s\n", pcName, pcBuf ) );
	if( ulIPAddressFound == 0ul )
	{
		ulIPAddressFound = ulIPAddress;
	}
	/* For testing: in case DNS doen't respond, still try some NTP server
	with a known IP-address. */
	if( ulIPAddressFound == 0ul )
	{
		ulIPAddressFound = FreeRTOS_inet_addr_quick( 184, 105, 182, 7 );
/*		ulIPAddressFound = FreeRTOS_inet_addr_quick( 103, 242,  70, 4 );	*/
	}
	xStatus = EStatusAsking;

	vSignalTask();
}
Beispiel #17
0
static BaseType_t prvOpenURL( HTTPClient_t *pxClient )
{
BaseType_t xRc;
char pcSlash[ 2 ];

	pxClient->bits.ulFlags = 0;

	#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
	{
		if( strchr( pxClient->pcUrlData, ipconfigHTTP_REQUEST_CHARACTER ) != NULL )
		{
		size_t xResult;

			xResult = uxApplicationHTTPHandleRequestHook( pxClient->pcUrlData, pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ) );
			if( xResult > 0 )
			{
				strcpy( pxClient->pxParent->pcContentsType, "text/html" );
				snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
					"Content-Length: %d\r\n", ( int ) xResult );
				xRc = prvSendReply( pxClient, WEB_REPLY_OK );	/* "Requested file action OK" */
				if( xRc > 0 )
				{
					xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pcCurrentFilename, xResult, 0 );
				}
				/* Although against the coding standard of FreeRTOS, a return is
				done here  to simplify this conditional code. */
				return xRc;
			}
		}
	}
	#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */

	if( pxClient->pcUrlData[ 0 ] != '/' )
	{
		/* Insert a slash before the file name. */
		pcSlash[ 0 ] = '/';
		pcSlash[ 1 ] = '\0';
	}
	else
	{
		/* The browser provided a starting '/' already. */
		pcSlash[ 0 ] = '\0';
	}
	snprintf( pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ), "%s%s%s",
		pxClient->pcRootDir,
		pcSlash,
		pxClient->pcUrlData);

	pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" );

	FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename,
		pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) );

	if( pxClient->pxFileHandle == NULL )
	{
		/* "404 File not found". */
		xRc = prvSendReply( pxClient, WEB_NOT_FOUND );
	}
	else
	{
		pxClient->uxBytesLeft = ( size_t ) pxClient->pxFileHandle->ulFileSize;
		xRc = prvSendFile( pxClient );
	}

	return xRc;
}
Beispiel #18
0
/* Send a reset commando to a set of PHY-ports. */
static uint32_t xPhyReset( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
uint32_t ulDoneMask, ulConfig;
TickType_t xRemainingTime;
TimeOut_t xTimer;
BaseType_t xPhyIndex;

	/* A bit-mask ofPHY ports that are ready. */
	ulDoneMask = 0ul;

	/* Set the RESET bits high. */
	for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
	{
	BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];

		/* Read Control register. */
		pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
		pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig | phyBMCR_RESET );
	}

	xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 1000UL );
	vTaskSetTimeOutState( &xTimer );

	/* The reset should last less than a second. */
	for( ;; )
	{
		for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
		{
		BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];

			pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
			if( ( ulConfig & phyBMCR_RESET ) == 0 )
			{
				FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET %d ready\n", (int)xPhyIndex ) );
				ulDoneMask |= ( 1ul << xPhyIndex );
			}
		}
		if( ulDoneMask == ulPhyMask )
		{
			break;
		}
		if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
		{
			FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
			break;
		}
	}

	/* Clear the reset bits. */
	for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
	{
	BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];

		pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
		pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig & ~phyBMCR_RESET );
	}

	vTaskDelay( pdMS_TO_TICKS( 50ul ) );
	eventLogAdd( "PHY reset %d ports", (int)pxPhyObject->xPortCount );
	return ulDoneMask;
}
BaseType_t xHTTPClientWork( xTCPClient *pxTCPClient )
{
BaseType_t xRc;
xHTTPClient *pxClient = ( xHTTPClient * ) pxTCPClient;

	if( pxClient->pxFileHandle != NULL )
	{
		prvSendFile( pxClient );
	}

	xRc = FreeRTOS_recv( pxClient->xSocket, ( void * )pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 );

	if( xRc > 0 )
	{
	BaseType_t xIndex;
	const char *pcEndOfCmd;
	const struct xWEB_COMMAND *curCmd;
	char *pcBuffer = pcCOMMAND_BUFFER;

		if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) )
		{
			pcBuffer[ xRc ] = '\0';
		}
		while( xRc && ( pcBuffer[ xRc - 1 ] == 13 || pcBuffer[ xRc - 1 ] == 10 ) )
		{
			pcBuffer[ --xRc ] = '\0';
		}
		pcEndOfCmd = pcBuffer + xRc;

		curCmd = xWebCommands;
		pxClient->pcUrlData = pcBuffer;			/* Pointing to "/index.html HTTP/1.1" */
		pxClient->pcRestData = pcEmptyString;	/* Pointing to "HTTP/1.1" */

		// Last entry is "ECMD_UNK"
		for( xIndex = 0; xIndex < WEB_CMD_COUNT - 1; xIndex++, curCmd++ )
		{
		BaseType_t xLength;

			xLength = curCmd->xCommandLength;
			if( ( xRc >= xLength ) && ( memcmp( curCmd->pcCommandName, pcBuffer, xLength ) == 0 ) )
			{
			char *pcLastPtr;

				pxClient->pcUrlData += xLength + 1;
				for( pcLastPtr = (char *)pxClient->pcUrlData; pcLastPtr < pcEndOfCmd; pcLastPtr++ )
				{
					char ch = *pcLastPtr;
					if( ( ch == '\0' ) || ( strchr( "\n\r \t", ch ) != NULL ) )
					{
						*pcLastPtr = '\0';
						pxClient->pcRestData = pcLastPtr + 1;
						break;
					}
				}
				break;
			}
		}
		xRc = prvProcessCmd( pxClient, xIndex );
	}
	else if( xRc < 0 )
	{
		/* The connection will be closed and the client will be deleted */
		FreeRTOS_printf( ( "xHTTPClientWork: rc = %ld\n", xRc ) );
	}
	return xRc;
}
Beispiel #20
0
BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
uint32_t xPhyIndex, ulDoneMask, ulBitMask;
uint32_t ulPHYLinkStatus, ulRegValue;
TickType_t xRemainingTime;
TimeOut_t xTimer;

	if( ulPhyMask == ( uint32_t )0u )
	{
		return 0;
	}
	for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
	{
		if( ( ulPhyMask & ( 1lu << xPhyIndex ) ) != 0lu )
		{
		BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];

			/* Enable Auto-Negotiation. */
			pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, pxPhyObject->ulACRValue);
			pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
		}
	}
eventLogAdd( "AN start" );
	xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );
	vTaskSetTimeOutState( &xTimer );
	ulDoneMask = 0;
	/* Wait until the auto-negotiation will be completed */
	for( ;; )
	{
		ulBitMask = ( uint32_t )1u;
		for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
		{
			if( ( ulPhyMask & ulBitMask ) != 0lu )
			{
				if( ( ulDoneMask & ulBitMask ) == 0lu )
				{
				BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];

					pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue );
					if( ( ulRegValue & phyBMSR_AN_COMPLETE ) != 0 )
					{
						ulDoneMask |= ulBitMask;
					}
				}
			}
		}
		if( ulPhyMask == ulDoneMask )
		{
			break;
		}
		if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
		{
			FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
			eventLogAdd( "ANtimed out");
			break;
		}
	}
eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );

	if( ulDoneMask != ( uint32_t)0u )
	{
		ulBitMask = ( uint32_t )1u;
		pxPhyObject->ulLinkStatusMask &= ~( ulDoneMask );
		for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
		{
		BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
		uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];

			if( ( ulDoneMask & ulBitMask ) == ( uint32_t )0u )
			{
				continue;
			}

			/* Clear the 'phyBMCR_AN_RESTART'  bit. */
			pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue );

			pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue);
			if( ( ulRegValue & phyBMSR_LINK_STATUS ) != 0 )
			{
				ulPHYLinkStatus |= phyBMSR_LINK_STATUS;
				pxPhyObject->ulLinkStatusMask |= ulBitMask;
			}
			else
			{
				ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );
			}

			if( xHas_1F_PHYSPCS( ulPhyID ) )
			{
			/* 31 RW PHY Special Control Status */
			uint32_t ulControlStatus;

				pxPhyObject->fnPhyRead( xPhyAddress, phyREG_1F_PHYSPCS, &ulControlStatus);
				ulRegValue = 0;
				if( ( ulControlStatus & phyPHYSPCS_FULL_DUPLEX ) != 0 )
				{
					ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
				}
				if( ( ulControlStatus & phyPHYSPCS_SPEED_MASK ) == phyPHYSPCS_SPEED_10 )
				{
					ulRegValue |= phyPHYSTS_SPEED_STATUS;
				}

			}
			else
			{
				/* Read the result of the auto-negotiation. */
				pxPhyObject->fnPhyRead( xPhyAddress, PHYREG_10_PHYSTS, &ulRegValue);
			}

			FreeRTOS_printf( ( ">> Autonego ready: %08lx: %s duplex %u mbit %s status\n",
				ulRegValue,
				( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
				( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
				( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" ) );
			eventLogAdd( "%s duplex %u mbit %s st",
				( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
				( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
				( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" );
{
	uint32_t regs[4];
	int i,j;
	int address = 0x10;
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
		{
			pxPhyObject->fnPhyRead( xPhyAddress, address, regs + j );
			address++;
		}
		eventLogAdd("%04lX %04lX %04lX %04lX",
			regs[0], regs[1], regs[2], regs[3]);
	}
}
			if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t )0u )
			{
				pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
			}
			else
			{
				pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_HALF;
			}

			if( ( ulRegValue & phyPHYSTS_SPEED_STATUS ) != 0 )
			{
				pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_10;
			}
			else
			{
				pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_100;
			}
		}
	}	/* if( ulDoneMask != ( uint32_t)0u ) */

	return 0;
}
Beispiel #21
0
BaseType_t xPhyConfigure( EthernetPhy_t *pxPhyObject, const PhyProperties_t *pxPhyProperties )
{
uint32_t ulConfig, ulAdvertise;
BaseType_t xPhyIndex;

	if( pxPhyObject->xPortCount < 1 )
	{
		FreeRTOS_printf( ( "xPhyResetAll: No PHY's detected.\n" ) );
		return -1;
	}

	/* The expected ID for the 'LAN8742A'  is 0x0007c130. */
	/* The expected ID for the 'LAN8720'   is 0x0007c0f0. */
	/* The expected ID for the 'DP83848I'  is 0x20005C90. */

    /* Set advertise register. */
	if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) && ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )
	{
		ulAdvertise = phyADVERTISE_CSMA | phyADVERTISE_ALL;
		/* Reset auto-negotiation capability. */
	}
	else
	{
		ulAdvertise = phyADVERTISE_CSMA;

		if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO )
		{
			if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
			{
				ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_100FULL;
			}
			else
			{
				ulAdvertise |= phyADVERTISE_10HALF | phyADVERTISE_100HALF;
			}
		}
		else if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO )
		{
			if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_10 )
			{
				ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_10HALF;
			}
			else
			{
				ulAdvertise |= phyADVERTISE_100FULL | phyADVERTISE_100HALF;
			}
		}
		else if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )
		{
			if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
			{
				ulAdvertise |= phyADVERTISE_100FULL;
			}
			else
			{
				ulAdvertise |= phyADVERTISE_100HALF;
			}
		}
		else
		{
			if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
			{
				ulAdvertise |= phyADVERTISE_10FULL;
			}
			else
			{
				ulAdvertise |= phyADVERTISE_10HALF;
			}
		}
	}

	/* Send a reset commando to a set of PHY-ports. */
	xPhyReset( pxPhyObject, xPhyGetMask( pxPhyObject ) );

	for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
	{
	BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
	uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];

		/* Write advertise register. */
		pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, ulAdvertise );

		/*
				AN_EN        AN1         AN0       Forced Mode
				  0           0           0        10BASE-T, Half-Duplex
				  0           0           1        10BASE-T, Full-Duplex
				  0           1           0        100BASE-TX, Half-Duplex
				  0           1           1        100BASE-TX, Full-Duplex
				AN_EN        AN1         AN0       Advertised Mode
				  1           0           0        10BASE-T, Half/Full-Duplex
				  1           0           1        100BASE-TX, Half/Full-Duplex
				  1           1           0        10BASE-T Half-Duplex
												   100BASE-TX, Half-Duplex
				  1           1           1        10BASE-T, Half/Full-Duplex
												   100BASE-TX, Half/Full-Duplex
		*/

		/* Read Control register. */
		pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );

		ulConfig &= ~( phyBMCR_SPEED_100 | phyBMCR_FULL_DUPLEX );

		ulConfig |= phyBMCR_AN_ENABLE;

		if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )
		{
			ulConfig |= phyBMCR_SPEED_100;
		}
		else if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_10 )
		{
			ulConfig &= ~phyBMCR_SPEED_100;
		}

		if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
		{
			ulConfig |= phyBMCR_FULL_DUPLEX;
		}
		else if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_HALF )
		{
			ulConfig &= ~phyBMCR_FULL_DUPLEX;
		}

		if( xHas_19_PHYCR( ulPhyID ) )
		{
		uint32_t ulPhyControl;
			/* Read PHY Control register. */
			pxPhyObject->fnPhyRead( xPhyAddress, phyREG_19_PHYCR, &ulPhyControl );

			/* Clear bits which might get set: */
			ulPhyControl &= ~( PHYCR_MDIX_EN|PHYCR_MDIX_FORCE );

			if( pxPhyProperties->ucMDI_X == PHY_MDIX_AUTO )
			{
				ulPhyControl |= PHYCR_MDIX_EN;
			}
			else if( pxPhyProperties->ucMDI_X == PHY_MDIX_CROSSED )
			{
				/* Force direct link = Use crossed RJ45 cable. */
				ulPhyControl &= ~PHYCR_MDIX_FORCE;
			}
			else
			{
				/* Force crossed link = Use direct RJ45 cable. */
				ulPhyControl |= PHYCR_MDIX_FORCE;
			}
			/* update PHY Control Register. */
			pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_19_PHYCR, ulPhyControl );
		}

		FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
		eventLogAdd( "adv: %04lX config %04lX", ulAdvertise, ulConfig );
	}

	/* Keep these values for later use. */
	pxPhyObject->ulBCRValue = ulConfig;
	pxPhyObject->ulACRValue = ulAdvertise;

	return 0;
}
Beispiel #22
0
void emacps_set_rx_buffers( xemacpsif_s *xemacpsif, u32 ulCount )
{
	NetworkBufferDescriptor_t *pxBuffer;
	unsigned int FreeBds;
	int tail = xemacpsif->rxTail;
	int head = xemacpsif->rxHead;

	if( ulCount != 0 )
	{
		FreeBds = ulCount;
	}
	else
	{
		FreeBds = is_rx_packets_available( NULL );
	}

	while( FreeBds-- != 0 )
	{
		pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, ( TickType_t ) 0 );
		if( pxBuffer == NULL )
		{
			FreeRTOS_printf( ("unable to alloc pbuf in recv_handler\n" ) );
			dsb();
			return;
		}

		dsb();

		if( ( xemacpsif->rxSegments[ tail ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 )
		{
			FreeRTOS_printf( ("Buffer %d too far?\n", tail ) );
		}
		if( pxDMA_rx_buffers[ tail ] != NULL )
		{
			FreeRTOS_printf( ("Buffer %d not used?\n", tail ) );
		}
		pxDMA_rx_buffers[ tail ] = ( void * )pxBuffer;
		if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
		{
			Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE );
		}
		{
			uint32_t addr = ( ( uint32_t )pxBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
			if( tail == ( ipconfigNIC_N_RX_DESC - 1 ) )
			{
				addr |= XEMACPS_RXBUF_WRAP_MASK;
			}
			/* Clearing 'XEMACPS_RXBUF_NEW_MASK'       0x00000001 *< Used bit.. */
			xemacpsif->rxSegments[ tail ].address = addr;
			xemacpsif->rxSegments[ tail ].flags = 0;
		}
		if( ++tail == ipconfigNIC_N_RX_DESC )
		{
			tail = 0;
		}
		if( tail == head )
		{
			break;
		}
	}
	xemacpsif->rxTail = tail;
}
Beispiel #23
0
static uint32_t prvEMACRxPoll( void )
{
unsigned char *pucUseBuffer;
uint32_t ulReceiveCount, ulResult, ulReturnValue = 0;
static NetworkBufferDescriptor_t *pxNextNetworkBufferDescriptor = NULL;
const UBaseType_t xMinDescriptorsToLeave = 2UL;
const TickType_t xBlockTime = pdMS_TO_TICKS( 100UL );
static IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };

	for( ;; )
	{
		/* If pxNextNetworkBufferDescriptor was not left pointing at a valid
		descriptor then allocate one now. */
		if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
		{
			pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xBlockTime );
		}

		if( pxNextNetworkBufferDescriptor != NULL )
		{
			/* Point pucUseBuffer to the buffer pointed to by the descriptor. */
			pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
		}
		else
		{
			/* As long as pxNextNetworkBufferDescriptor is NULL, the incoming
			messages will be flushed and ignored. */
			pucUseBuffer = NULL;
		}

		/* Read the next packet from the hardware into pucUseBuffer. */
		ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, &ulReceiveCount );

		if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
		{
			/* No data from the hardware. */
			break;
		}

		if( pxNextNetworkBufferDescriptor == NULL )
		{
			/* Data was read from the hardware, but no descriptor was available
			for it, so it will be dropped. */
			iptraceETHERNET_RX_EVENT_LOST();
			continue;
		}

		iptraceNETWORK_INTERFACE_RECEIVE();
		pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
		xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;

		/* Send the descriptor to the IP task for processing. */
		if( xSendEventStructToIPTask( &xRxEvent, xBlockTime ) != pdTRUE )
		{
			/* The buffer could not be sent to the stack so must be released
			again. */
			vReleaseNetworkBufferAndDescriptor( pxNextNetworkBufferDescriptor );
			iptraceETHERNET_RX_EVENT_LOST();
			FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
		}

		/* Now the buffer has either been passed to the IP-task,
		or it has been released in the code above. */
		pxNextNetworkBufferDescriptor = NULL;
		ulReturnValue++;
	}

	return ulReturnValue;
}
Beispiel #24
0
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxCount;
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
	NetworkBufferDescriptor_t *pxBuffer;
#endif
uint8_t *pucBuffer;
BaseType_t xResult = 0;
uint32_t xStatus;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );

	/* Remove compiler warnings about unused parameters. */
	( void ) pvParameters;

	configASSERT( xEMACTaskHandle );

	vTaskSetTimeOutState( &xPhyTime );
	xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );

	for( ;; )
	{
		vCheckBuffersAndQueue();

		if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
		{
			/* No events to process now, wait for the next. */
			ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
		}

		if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
		{
			ulISREvents &= ~EMAC_IF_RX_EVENT;

			/* Wait for the EMAC interrupt to indicate that another packet has been
			received. */
			xResult = prvEMACRxPoll();
		}

		if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
		{
			/* Future extension: code to release TX buffers if zero-copy is used. */
			ulISREvents &= ~EMAC_IF_TX_EVENT;
			while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
			{
				#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
				{
					pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
					if( pxBuffer != NULL )
					{
						vReleaseNetworkBufferAndDescriptor( pxBuffer );
						tx_release_count[ 0 ]++;
					}
					else
					{
						tx_release_count[ 1 ]++;
					}
				}
				#else
				{
					tx_release_count[ 0 ]++;
				}
				#endif
				uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
				if( uxCount < GMAC_TX_BUFFERS )
				{
					/* Tell the counting semaphore that one more TX descriptor is available. */
					xSemaphoreGive( xTXDescriptorSemaphore );
				}
			}
		}

		if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
		{
			/* Future extension: logging about errors that occurred. */
			ulISREvents &= ~EMAC_IF_ERR_EVENT;
		}

		if( xResult > 0 )
		{
			/* A packet was received. No need to check for the PHY status now,
			but set a timer to check it later on. */
			vTaskSetTimeOutState( &xPhyTime );
			xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
			xResult = 0;
		}
		else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
		{
			/* Check the link status again. */
			xStatus = ulReadMDIO( PHY_REG_01_BMSR );

			if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
			{
				ulPHYLinkStatus = xStatus;
				FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
			}

			vTaskSetTimeOutState( &xPhyTime );
			if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
			{
				xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
			}
			else
			{
				xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
			}
		}
	}
}
Beispiel #25
0
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
{
	xemacpsif_s   *xemacpsif;
	struct xtopology_t *xtopologyp;
	XEmacPs *xemacps;

	xemacpsif = (xemacpsif_s *)(arg);

	xtopologyp = &xXTopology;

	xemacps = &xemacpsif->emacps;

	/* Do not appear to be used. */
	( void ) xemacps;
	( void ) xtopologyp;

	last_err_msg = NULL;

	if( ErrorWord != 0 )
	{
		switch (Direction) {
		case XEMACPS_RECV:
			if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
			{
				last_err_msg = "Receive DMA error";
				xNetworkInterfaceInitialise( );
			}
			if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
			{
				last_err_msg = "Receive over run";
				emacps_recv_handler(arg);
				emacps_set_rx_buffers( xemacpsif, 0 );
			}
			if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
			{
				last_err_msg = "Receive buffer not available";
				emacps_recv_handler(arg);
				emacps_set_rx_buffers( xemacpsif, 0 );
			}
			break;
		case XEMACPS_SEND:
			if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
			{
				last_err_msg = "Transmit DMA error";
				xNetworkInterfaceInitialise( );
			}
			if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
			{
				last_err_msg = "Transmit under run";
				HandleTxErrors( xemacpsif );
			}
			if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
			{
				last_err_msg = "Transmit buffer exhausted";
				HandleTxErrors( xemacpsif );
			}
			if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
			{
				last_err_msg = "Transmit retry excessed limits";
				HandleTxErrors( xemacpsif );
			}
			if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
			{
				last_err_msg = "Transmit collision";
				emacps_check_tx( xemacpsif );
			}
			break;
		}
	}
	// Break on this statement and inspect error_msg if you like
	if( last_err_msg != NULL )
	{
		error_msg_count++;
		FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
	}
}
Beispiel #26
0
XStatus init_dma(xemacpsif_s *xemacpsif)
{
	NetworkBufferDescriptor_t *pxBuffer;

	int iIndex;
	UBaseType_t xRxSize;
	UBaseType_t xTxSize;
	struct xtopology_t *xtopologyp = &xXTopology;

	xRxSize = ipconfigNIC_N_RX_DESC * sizeof( xemacpsif->rxSegments[ 0 ] );

	xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );

	/* Also round-up to 4KB */
	xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
	/*
	 * We allocate 65536 bytes for RX BDs which can accommodate a
	 * maximum of 8192 BDs which is much more than any application
	 * will ever need.
	 */
	xemacpsif->rxSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xRxSize )  );
	xemacpsif->txSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xTxSize ) );
	xemacpsif->tx_space   = ( unsigned char *   )( pucGetUncachedMemory ( ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize ) );

	/* These variables will be used in XEmacPs_Start (see src/xemacps.c). */
	xemacpsif->emacps.RxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->rxSegments;
	xemacpsif->emacps.TxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->txSegments;

	/*
	 * Allocate RX descriptors, 1 RxBD at a time.
	 */
	for( iIndex = 0; iIndex < ipconfigNIC_N_RX_DESC; iIndex++ )
	{
		pxBuffer = pxDMA_rx_buffers[ iIndex ];
		if( pxBuffer == NULL )
		{
			pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, ( TickType_t ) 0 );
			if( pxBuffer == NULL )
			{
				FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
				return -1;
			}
		}

		xemacpsif->rxSegments[ iIndex ].flags = 0;
		xemacpsif->rxSegments[ iIndex ].address = ( ( uint32_t )pxBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;

		pxDMA_rx_buffers[ iIndex ] = pxBuffer;
		/* Make sure this memory is not in cache for now. */
		if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
		{
			Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
				(unsigned)ipTOTAL_ETHERNET_FRAME_SIZE );
		}
	}

	xemacpsif->rxSegments[ ipconfigNIC_N_RX_DESC - 1 ].address |= XEMACPS_RXBUF_WRAP_MASK;

	memset( xemacpsif->tx_space, '\0', ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize );

	clean_dma_txdescs( xemacpsif );

	{
		uint32_t value;
		value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET );

		// 1xxxx: Attempt to use INCR16 AHB bursts
		value = ( value & ~( XEMACPS_DMACR_BLENGTH_MASK ) ) | XEMACPS_DMACR_INCR16_AHB_BURST;
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
		value |= XEMACPS_DMACR_TCPCKSUM_MASK;
#else
#warning Are you sure the EMAC should not calculate outgoing checksums?
		value &= ~XEMACPS_DMACR_TCPCKSUM_MASK;
#endif
		XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET, value );
	}
	{
		uint32_t value;
		value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET );

		/* Network buffers are 32-bit aligned + 2 bytes (because ipconfigPACKET_FILLER_SIZE = 2 ).
		Now tell the EMAC that received messages should be stored at "address + 2". */
		value = ( value & ~XEMACPS_NWCFG_RXOFFS_MASK ) | 0x8000;

#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM != 0 )
		value |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
#else
#warning Are you sure the EMAC should not calculate incoming checksums?
		value &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK;
#endif
		XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET, value );
	}

	/*
	 * Connect the device driver handler that will be called when an
	 * interrupt for the device occurs, the handler defined above performs
	 * the specific interrupt processing for the device.
	 */
	XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
		(Xil_ExceptionHandler)XEmacPs_IntrHandler,
		(void *)&xemacpsif->emacps);
	/*
	 * Enable the interrupt for emacps.
	 */
	EmacEnableIntr( );

	return 0;
}
Beispiel #27
0
static void prvNTPTask( void *pvParameters )
{
BaseType_t xServerIndex = 3;
struct freertos_sockaddr xAddress;
#if( ipconfigUSE_CALLBACKS != 0 )
	F_TCP_UDP_Handler_t xHandler;
#endif /* ipconfigUSE_CALLBACKS != 0 */

	xStatus = EStatusLookup;
	#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 )
	{
		xNTPWakeupSem = xSemaphoreCreateBinary();
	}
	#endif

	#if( ipconfigUSE_CALLBACKS != 0 )
	{
		memset( &xHandler, '\0', sizeof ( xHandler ) );
		xHandler.pOnUdpReceive = xOnUdpReceive;
		FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) );
	}
	#endif
	#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
	{
		FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) );
	}
	#endif
	for( ; ; )
	{
		switch( xStatus )
		{
		case EStatusLookup:
			if( ( ulIPAddressFound == 0ul ) || ( ulIPAddressFound == ~0ul ) )
			{
				if( ++xServerIndex == sizeof pcTimeServers / sizeof pcTimeServers[ 0 ] )
				{
					xServerIndex = 0;
				}
				FreeRTOS_printf( ( "Looking up server '%s'\n", pcTimeServers[ xServerIndex ] ) );
				FreeRTOS_gethostbyname_a( pcTimeServers[ xServerIndex ], vDNS_callback, (void *)NULL, 1200 );
			}
			else
			{
				xStatus = EStatusAsking;
			}
			break;

		case EStatusAsking:
			{
			char pcBuf[16];

				prvNTPPacketInit( );
				xAddress.sin_addr = ulIPAddressFound;
				xAddress.sin_port = FreeRTOS_htons( NTP_PORT );

				FreeRTOS_inet_ntoa( xAddress.sin_addr, pcBuf );
				FreeRTOS_printf( ( "Sending UDP message to %s:%u\n",
					pcBuf,
					FreeRTOS_ntohs( xAddress.sin_port ) ) );

				uxSendTime = xTaskGetTickCount( );
				FreeRTOS_sendto( xUDPSocket, ( void * )&xNTPPacket, sizeof( xNTPPacket ), 0, &xAddress, sizeof( xAddress ) );
			}
			break;

		case EStatusPause:
			break;

		case EStatusFailed:
			break;
		}

		#if( ipconfigUSE_CALLBACKS != 0 )
		{
			xSemaphoreTake( xNTPWakeupSem, 5000 );
		}
		#else
		{
		uint32_t xAddressSize;
		BaseType_t xReturned;
			xAddressSize = sizeof( xAddress );
			xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize );
			switch( xReturned )
			{
			case 0:
			case -pdFREERTOS_ERRNO_EAGAIN:
			case -pdFREERTOS_ERRNO_EINTR:
				break;
			default:
				if( xReturned < sizeof( xNTPPacket ) )
				{
					FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) );
				}
				else
				{
					prvReadTime( ( struct SNtpPacket *)cRecvBuffer );
					if( xStatus != EStatusPause )
					{
						xStatus = EStatusPause;
					}
				}
				break;
			}
		}
		#endif
	}
}
Beispiel #28
0
static void prvReadTime( struct SNtpPacket * pxPacket )
{
	FF_TimeStruct_t xTimeStruct;
	time_t uxPreviousSeconds;
	time_t uxPreviousMS;

	time_t uxCurrentSeconds;
	time_t uxCurrentMS;

	const char *pcTimeUnit;
	int32_t ilDiff;
	TickType_t uxTravelTime;

	uxTravelTime = xTaskGetTickCount() - uxSendTime;

	/* Transform the contents of the fields from big to native endian. */
	prvSwapFields( pxPacket );

	uxCurrentSeconds = pxPacket->receiveTimestamp.seconds - TIME1970;
	uxCurrentMS = pxPacket->receiveTimestamp.fraction / 4294967;
	uxCurrentSeconds += uxCurrentMS / 1000;
	uxCurrentMS = uxCurrentMS % 1000;

	// Get the last time recorded
	uxPreviousSeconds = FreeRTOS_get_secs_msec( &uxPreviousMS );

	// Set the new time with precision in msec. */
	FreeRTOS_set_secs_msec( &uxCurrentSeconds, &uxCurrentMS );

	if( uxCurrentSeconds >= uxPreviousSeconds )
	{
		ilDiff = ( int32_t ) ( uxCurrentSeconds - uxPreviousSeconds );
	}
	else
	{
		ilDiff = 0 - ( int32_t ) ( uxPreviousSeconds - uxCurrentSeconds );
	}

	if( ( ilDiff < -5 ) || ( ilDiff > 5 ) )
	{
		/* More than 5 seconds difference. */
		pcTimeUnit = "sec";
	}
	else
	{
		/* Less than or equal to 5 second difference. */
		
		uint32_t ulLowest = ( uxCurrentSeconds <= uxPreviousSeconds ) ? uxCurrentSeconds : uxPreviousSeconds;
		int32_t iCurMS = 1000 * ( uxCurrentSeconds - ulLowest ) + uxCurrentMS;
		int32_t iPrevMS = 1000 * ( uxPreviousSeconds - ulLowest ) + uxPreviousMS;
		ilDiff = iCurMS - iPrevMS;
		pcTimeUnit = "ms";
	}
	uxCurrentSeconds -= iTimeZone;

	FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct );

	/*
		378.067 [NTP client] NTP time: 9/11/2015 16:11:19.559 Diff -20 ms (289 ms)
		379.441 [NTP client] NTP time: 9/11/2015 16:11:20.933 Diff 0 ms (263 ms)
	*/

	FreeRTOS_printf( ("NTP time: %d/%d/%02d %2d:%02d:%02d.%03u Diff %d %s (%lu ms)\n",
		xTimeStruct.tm_mday,
		xTimeStruct.tm_mon + 1,
		xTimeStruct.tm_year + 1900,
		xTimeStruct.tm_hour,
		xTimeStruct.tm_min,
		xTimeStruct.tm_sec,
		( unsigned )uxCurrentMS,
		( unsigned )ilDiff,
		pcTimeUnit,
		uxTravelTime ) );

	/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
	( void ) pcTimeUnit;
	( void ) uxTravelTime;
}