mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-04 05:13:51 -04:00
Sync FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP with the version in GitHub at (23665258cabe49d5d68ba23968b6845a7c80eb34).
Notes: - header has version 2.2.0. - This sync did not bring in ./test directory, though we should. - New NetworkInterfaces are introduced by this merge. - Keil compiler support. - FreeRTOS_IP.h new API xApplicationGetRandomNumber(). - FreeRTOS_IP_Private.h new eIPEvent_t eNetworkTxEvent. - FreeRTOS_Stream_Buffer.h removing static xStreamBufferIsEmpty() and xStreamBufferIsFull(). - FreeRTOSConfigDefaults.h provides default ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS. - other type changes.
This commit is contained in:
parent
0c1c85a9dd
commit
ec6f3d77c3
54 changed files with 5688 additions and 1701 deletions
|
@ -0,0 +1,629 @@
|
|||
/***********************************************************************************************************************
|
||||
* DISCLAIMER
|
||||
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
|
||||
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
|
||||
* applicable laws, including copyright laws.
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
|
||||
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
|
||||
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
|
||||
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
|
||||
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
|
||||
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
|
||||
* following link:
|
||||
* http://www.renesas.com/disclaimer
|
||||
*
|
||||
* Copyright (C) 2018 Renesas Electronics Corporation. All rights reserved.
|
||||
***********************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* File Name : NetworkInterface.c
|
||||
* Device(s) : RX
|
||||
* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
|
||||
***********************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* History : DD.MM.YYYY Version Description
|
||||
* : 07.03.2018 0.1 Development
|
||||
***********************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Includes <System Includes> , "Project Includes"
|
||||
***********************************************************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
/*#include "FreeRTOS_DNS.h" */
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
#include "r_ether_rx_if.h"
|
||||
#include "r_pinset.h"
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Macro definitions
|
||||
**********************************************************************************************************************/
|
||||
#define ETHER_BUFSIZE_MIN 60
|
||||
|
||||
#if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M )
|
||||
#if ETHER_CFG_MODE_SEL == 0
|
||||
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_MII()
|
||||
#elif ETHER_CFG_MODE_SEL == 1
|
||||
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_RMII()
|
||||
#endif
|
||||
#elif defined( BSP_MCU_RX63N )
|
||||
#if ETHER_CFG_MODE_SEL == 0
|
||||
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_MII()
|
||||
#elif ETHER_CFG_MODE_SEL == 1
|
||||
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_RMII()
|
||||
#endif
|
||||
#endif /* if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) */
|
||||
|
||||
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
|
||||
|
||||
/* Check if the LinkSStatus in the PHY is still high after 2 seconds of not
|
||||
* receiving packets. */
|
||||
#define PHY_LS_HIGH_CHECK_TIME_MS 2000
|
||||
#endif
|
||||
|
||||
#ifndef PHY_LS_LOW_CHECK_TIME_MS
|
||||
/* Check if the LinkSStatus in the PHY is still low every second. */
|
||||
#define PHY_LS_LOW_CHECK_TIME_MS 1000
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Private global variables and functions
|
||||
**********************************************************************************************************************/
|
||||
typedef enum
|
||||
{
|
||||
eMACInit, /* Must initialise MAC. */
|
||||
eMACPass, /* Initialisation was successful. */
|
||||
eMACFailed, /* Initialisation failed. */
|
||||
} eMAC_INIT_STATUS_TYPE;
|
||||
|
||||
static TaskHandle_t ether_receive_check_task_handle = 0;
|
||||
static TaskHandle_t ether_link_check_task_handle = 0;
|
||||
static TaskHandle_t xTaskToNotify = NULL;
|
||||
static BaseType_t xPHYLinkStatus;
|
||||
static BaseType_t xReportedStatus;
|
||||
static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
|
||||
|
||||
static int16_t SendData( uint8_t * pucBuffer,
|
||||
size_t length );
|
||||
static int InitializeNetwork( void );
|
||||
static void prvEMACDeferredInterruptHandlerTask( void * pvParameters );
|
||||
static void clear_all_ether_rx_discriptors( uint32_t event );
|
||||
|
||||
int32_t callback_ether_regist( void );
|
||||
void EINT_Trig_isr( void * );
|
||||
void get_random_number( uint8_t * data,
|
||||
uint32_t len );
|
||||
|
||||
void prvLinkStatusChange( BaseType_t xStatus );
|
||||
#if ( ipconfigHAS_PRINTF != 0 )
|
||||
static void prvMonitorResources( void );
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: xNetworkInterfaceInitialise ()
|
||||
* Description : Initialization of Ethernet driver.
|
||||
* Arguments : none
|
||||
* Return Value : pdPASS, pdFAIL
|
||||
**********************************************************************************************************************/
|
||||
BaseType_t xNetworkInterfaceInitialise( void )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
if( xMacInitStatus == eMACInit )
|
||||
{
|
||||
/*
|
||||
* Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
|
||||
* Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
|
||||
*
|
||||
* InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
|
||||
*/
|
||||
if( InitializeNetwork() == pdFALSE )
|
||||
{
|
||||
xMacInitStatus = eMACFailed;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Indicate that the MAC initialisation succeeded. */
|
||||
xMacInitStatus = eMACPass;
|
||||
}
|
||||
|
||||
FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
|
||||
}
|
||||
|
||||
if( xMacInitStatus == eMACPass )
|
||||
{
|
||||
xReturn = xPHYLinkStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
|
||||
FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
|
||||
|
||||
return xReturn;
|
||||
} /* End of function xNetworkInterfaceInitialise() */
|
||||
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: xNetworkInterfaceOutput ()
|
||||
* Description : Simple network output interface.
|
||||
* Arguments : pxDescriptor, xReleaseAfterSend
|
||||
* Return Value : pdTRUE, pdFALSE
|
||||
**********************************************************************************************************************/
|
||||
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
|
||||
BaseType_t xReleaseAfterSend )
|
||||
{
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
/* Simple network interfaces (as opposed to more efficient zero copy network
|
||||
* interfaces) just use Ethernet peripheral driver library functions to copy
|
||||
* data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.
|
||||
* This example assumes SendData() is a peripheral driver library function that
|
||||
* takes a pointer to the start of the data to be sent and the length of the
|
||||
* data to be sent as two separate parameters. The start of the data is located
|
||||
* by pxDescriptor->pucEthernetBuffer. The length of the data is located
|
||||
* by pxDescriptor->xDataLength. */
|
||||
if( xPHYLinkStatus != 0 )
|
||||
{
|
||||
if( SendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ) >= 0 )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
/* Call the standard trace macro to log the send event. */
|
||||
iptraceNETWORK_INTERFACE_TRANSMIT();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* As the PHY Link Status is low, it makes no sense trying to deliver a packet. */
|
||||
}
|
||||
|
||||
if( xReleaseAfterSend != pdFALSE )
|
||||
{
|
||||
/* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
|
||||
* buffer. The Ethernet buffer is therefore no longer needed, and must be
|
||||
* freed for re-use. */
|
||||
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
} /* End of function xNetworkInterfaceOutput() */
|
||||
|
||||
|
||||
#if ( ipconfigHAS_PRINTF != 0 )
|
||||
static void prvMonitorResources()
|
||||
{
|
||||
static UBaseType_t uxLastMinBufferCount = 0u;
|
||||
static UBaseType_t uxCurrentBufferCount = 0u;
|
||||
static size_t uxMinLastSize = 0uL;
|
||||
static size_t uxCurLastSize = 0uL;
|
||||
size_t uxMinSize;
|
||||
size_t uxCurSize;
|
||||
|
||||
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();
|
||||
uxCurSize = xPortGetFreeHeapSize();
|
||||
|
||||
if( uxMinLastSize != uxMinSize )
|
||||
{
|
||||
uxCurLastSize = uxCurSize;
|
||||
uxMinLastSize = uxMinSize;
|
||||
FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", uxCurSize, 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 ) */
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: prvEMACDeferredInterruptHandlerTask ()
|
||||
* Description : The deferred interrupt handler is a standard RTOS task.
|
||||
* Arguments : pvParameters
|
||||
* Return Value : none
|
||||
**********************************************************************************************************************/
|
||||
static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
|
||||
{
|
||||
NetworkBufferDescriptor_t * pxBufferDescriptor;
|
||||
int32_t xBytesReceived = 0;
|
||||
|
||||
/* Avoid compiler warning about unreferenced parameter. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Used to indicate that xSendEventStructToIPTask() is being called because
|
||||
* of an Ethernet receive event. */
|
||||
IPStackEvent_t xRxEvent;
|
||||
|
||||
uint8_t * buffer_pointer;
|
||||
|
||||
/* Some variables related to monitoring the PHY. */
|
||||
TimeOut_t xPhyTime;
|
||||
TickType_t xPhyRemTime;
|
||||
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
|
||||
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
|
||||
|
||||
FreeRTOS_printf( ( "Deferred Interrupt Handler Task started\n" ) );
|
||||
xTaskToNotify = ether_receive_check_task_handle;
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
#if ( ipconfigHAS_PRINTF != 0 )
|
||||
{
|
||||
prvMonitorResources();
|
||||
}
|
||||
#endif /* ipconfigHAS_PRINTF != 0 ) */
|
||||
|
||||
/* Wait for the Ethernet MAC interrupt to indicate that another packet
|
||||
* has been received. */
|
||||
if( xBytesReceived <= 0 )
|
||||
{
|
||||
ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
|
||||
}
|
||||
|
||||
/* See how much data was received. */
|
||||
xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
|
||||
|
||||
if( xBytesReceived < 0 )
|
||||
{
|
||||
/* This is an error. Logged. */
|
||||
if( xBytesReceived == ETHER_ERR_LINK )
|
||||
{
|
||||
/* Auto-negotiation is not completed, and transmission/
|
||||
reception is not enabled. Will be logged elsewhere. */
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d not %d\n", xBytesReceived, ETHER_ERR_LINK ) );
|
||||
}
|
||||
}
|
||||
else if( xBytesReceived > 0 )
|
||||
{
|
||||
/* Allocate a network buffer descriptor that points to a buffer
|
||||
* large enough to hold the received frame. As this is the simple
|
||||
* rather than efficient example the received data will just be copied
|
||||
* into this buffer. */
|
||||
pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( ( size_t ) xBytesReceived, 0 );
|
||||
|
||||
if( pxBufferDescriptor != NULL )
|
||||
{
|
||||
/* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet
|
||||
* buffer large enough to hold the received data. Copy the
|
||||
* received data into pcNetworkBuffer->pucEthernetBuffer. Here it
|
||||
* is assumed ReceiveData() is a peripheral driver function that
|
||||
* copies the received data into a buffer passed in as the function's
|
||||
* parameter. Remember! While is is a simple robust technique -
|
||||
* it is not efficient. An example that uses a zero copy technique
|
||||
* is provided further down this page. */
|
||||
memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer_pointer, ( size_t ) xBytesReceived );
|
||||
/*ReceiveData( pxBufferDescriptor->pucEthernetBuffer ); */
|
||||
|
||||
/* Set the actual packet length, in case a larger buffer was returned. */
|
||||
pxBufferDescriptor->xDataLength = ( size_t ) xBytesReceived;
|
||||
|
||||
R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
|
||||
|
||||
/* See if the data contained in the received Ethernet frame needs
|
||||
* to be processed. NOTE! It is preferable to do this in
|
||||
* the interrupt service routine itself, which would remove the need
|
||||
* to unblock this task for packets that don't need processing. */
|
||||
if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer ) == eProcessBuffer )
|
||||
{
|
||||
/* The event about to be sent to the TCP/IP is an Rx event. */
|
||||
xRxEvent.eEventType = eNetworkRxEvent;
|
||||
|
||||
/* pvData is used to point to the network buffer descriptor that
|
||||
* now references the received data. */
|
||||
xRxEvent.pvData = ( void * ) pxBufferDescriptor;
|
||||
|
||||
/* Send the data to the TCP/IP stack. */
|
||||
if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
|
||||
{
|
||||
/* The buffer could not be sent to the IP task so the buffer must be released. */
|
||||
vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
|
||||
|
||||
/* Make a call to the standard trace macro to log the occurrence. */
|
||||
iptraceETHERNET_RX_EVENT_LOST();
|
||||
clear_all_ether_rx_discriptors( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The message was successfully sent to the TCP/IP stack.
|
||||
* Call the standard trace macro to log the occurrence. */
|
||||
iptraceNETWORK_INTERFACE_RECEIVE();
|
||||
R_NOP();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The Ethernet frame can be dropped, but the Ethernet buffer must be released. */
|
||||
vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The event was lost because a network buffer was not available.
|
||||
* Call the standard trace macro to log the occurrence. */
|
||||
iptraceETHERNET_RX_EVENT_LOST();
|
||||
clear_all_ether_rx_discriptors( 1 );
|
||||
FreeRTOS_printf( ( "R_ETHER_Read_ZC2: Cleared descriptors\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( xBytesReceived > 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 );
|
||||
|
||||
/* Indicate that the Link Status is high, so that
|
||||
* xNetworkInterfaceOutput() can send packets. */
|
||||
if( xPHYLinkStatus == 0 )
|
||||
{
|
||||
xPHYLinkStatus = 1;
|
||||
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume %d\n", xPHYLinkStatus ) );
|
||||
}
|
||||
}
|
||||
else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
|
||||
{
|
||||
R_ETHER_LinkProcess( 0 );
|
||||
|
||||
if( xPHYLinkStatus != xReportedStatus )
|
||||
{
|
||||
xPHYLinkStatus = xReportedStatus;
|
||||
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", xPHYLinkStatus ) );
|
||||
}
|
||||
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
|
||||
if( xPHYLinkStatus != 0 )
|
||||
{
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
|
||||
}
|
||||
else
|
||||
{
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* End of function prvEMACDeferredInterruptHandlerTask() */
|
||||
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
|
||||
* Description : .
|
||||
* Arguments : pxNetworkBuffers
|
||||
* Return Value : none
|
||||
**********************************************************************************************************************/
|
||||
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
|
||||
{
|
||||
uint32_t ul;
|
||||
uint8_t * buffer_address;
|
||||
|
||||
R_EXTERN_SEC( B_ETHERNET_BUFFERS_1 )
|
||||
|
||||
buffer_address = R_SECTOP( B_ETHERNET_BUFFERS_1 );
|
||||
|
||||
for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
|
||||
{
|
||||
pxNetworkBuffers[ ul ].pucEthernetBuffer = ( buffer_address + ( ETHER_CFG_BUFSIZE * ul ) );
|
||||
}
|
||||
} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
|
||||
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: prvLinkStatusChange ()
|
||||
* Description : Function will be called when the Link Status of the phy has changed ( see ether_callback.c )
|
||||
* Arguments : xStatus : true when statyus has become high
|
||||
* Return Value : void
|
||||
**********************************************************************************************************************/
|
||||
void prvLinkStatusChange( BaseType_t xStatus )
|
||||
{
|
||||
if( xReportedStatus != xStatus )
|
||||
{
|
||||
xReportedStatus = xStatus;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: InitializeNetwork ()
|
||||
* Description :
|
||||
* Arguments : none
|
||||
* Return Value : pdTRUE, pdFALSE
|
||||
**********************************************************************************************************************/
|
||||
static int InitializeNetwork( void )
|
||||
{
|
||||
ether_return_t eth_ret;
|
||||
BaseType_t return_code = pdFALSE;
|
||||
ether_param_t param;
|
||||
uint8_t myethaddr[ 6 ] =
|
||||
{
|
||||
configMAC_ADDR0,
|
||||
configMAC_ADDR1,
|
||||
configMAC_ADDR2,
|
||||
configMAC_ADDR3,
|
||||
configMAC_ADDR4,
|
||||
configMAC_ADDR5
|
||||
}; /*XXX Fix me */
|
||||
|
||||
R_ETHER_PinSet_CHANNEL_0();
|
||||
R_ETHER_Initial();
|
||||
callback_ether_regist();
|
||||
|
||||
param.channel = ETHER_CHANNEL_0;
|
||||
eth_ret = R_ETHER_Control( CONTROL_POWER_ON, param ); /* PHY mode settings, module stop cancellation */
|
||||
|
||||
if( ETHER_SUCCESS != eth_ret )
|
||||
{
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
eth_ret = R_ETHER_Open_ZC2( ETHER_CHANNEL_0, myethaddr, ETHER_FLAG_OFF );
|
||||
|
||||
if( ETHER_SUCCESS != eth_ret )
|
||||
{
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
return_code = xTaskCreate( prvEMACDeferredInterruptHandlerTask,
|
||||
"ETHER_RECEIVE_CHECK_TASK",
|
||||
512u,
|
||||
0,
|
||||
configMAX_PRIORITIES - 1,
|
||||
ðer_receive_check_task_handle );
|
||||
|
||||
if( pdFALSE == return_code )
|
||||
{
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
return pdTRUE;
|
||||
} /* End of function InitializeNetwork() */
|
||||
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: SendData ()
|
||||
* Description :
|
||||
* Arguments : pucBuffer, length
|
||||
* Return Value : 0 success, negative fail
|
||||
**********************************************************************************************************************/
|
||||
static int16_t SendData( uint8_t * pucBuffer,
|
||||
size_t length ) /*TODO complete stub function */
|
||||
{
|
||||
ether_return_t ret;
|
||||
uint8_t * pwrite_buffer;
|
||||
uint16_t write_buf_size;
|
||||
|
||||
/* (1) Retrieve the transmit buffer location controlled by the descriptor. */
|
||||
ret = R_ETHER_Write_ZC2_GetBuf( ETHER_CHANNEL_0, ( void ** ) &pwrite_buffer, &write_buf_size );
|
||||
|
||||
if( ETHER_SUCCESS == ret )
|
||||
{
|
||||
if( write_buf_size >= length )
|
||||
{
|
||||
memcpy( pwrite_buffer, pucBuffer, length );
|
||||
}
|
||||
|
||||
if( length < ETHER_BUFSIZE_MIN ) /*under minimum*/
|
||||
{
|
||||
memset( ( pwrite_buffer + length ), 0, ( ETHER_BUFSIZE_MIN - length ) ); /*padding*/
|
||||
length = ETHER_BUFSIZE_MIN; /*resize*/
|
||||
}
|
||||
|
||||
ret = R_ETHER_Write_ZC2_SetBuf( ETHER_CHANNEL_0, ( uint16_t ) length );
|
||||
ret = R_ETHER_CheckWrite( ETHER_CHANNEL_0 );
|
||||
}
|
||||
|
||||
if( ETHER_SUCCESS != ret )
|
||||
{
|
||||
return -5; /* XXX return meaningful value */
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} /* End of function SendData() */
|
||||
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: EINT_Trig_isr
|
||||
* Description : Standard frame received interrupt handler
|
||||
* Arguments : ectrl - EDMAC and ETHERC control structure
|
||||
* Return Value : None
|
||||
* Note : This callback function is executed when EINT0 interrupt occurred.
|
||||
***********************************************************************************************************************/
|
||||
void EINT_Trig_isr( void * ectrl )
|
||||
{
|
||||
ether_cb_arg_t * pdecode;
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
pdecode = ( ether_cb_arg_t * ) ectrl;
|
||||
|
||||
if( pdecode->status_eesr & 0x00040000 ) /* EDMAC FR (Frame Receive Event) interrupt */
|
||||
{
|
||||
if( xTaskToNotify != NULL )
|
||||
{
|
||||
vTaskNotifyGiveFromISR( ether_receive_check_task_handle, &xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
|
||||
* should be performed to ensure the interrupt returns directly to the highest
|
||||
* priority task. The macro used for this purpose is dependent on the port in
|
||||
* use and may be called portEND_SWITCHING_ISR(). */
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
/*TODO complete interrupt handler for other events. */
|
||||
}
|
||||
} /* End of function EINT_Trig_isr() */
|
||||
|
||||
|
||||
static void clear_all_ether_rx_discriptors( uint32_t event )
|
||||
{
|
||||
int32_t xBytesReceived;
|
||||
uint8_t * buffer_pointer;
|
||||
|
||||
/* Avoid compiler warning about unreferenced parameter. */
|
||||
( void ) event;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
/* See how much data was received. */
|
||||
xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
|
||||
|
||||
if( 0 > xBytesReceived )
|
||||
{
|
||||
/* This is an error. Ignored. */
|
||||
}
|
||||
else if( 0 < xBytesReceived )
|
||||
{
|
||||
R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
|
||||
iptraceETHERNET_RX_EVENT_LOST();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* End of file "NetworkInterface.c"
|
||||
**********************************************************************************************************************/
|
|
@ -0,0 +1,177 @@
|
|||
/***********************************************************************************************************************
|
||||
* DISCLAIMER
|
||||
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
|
||||
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
|
||||
* applicable laws, including copyright laws.
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
|
||||
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
|
||||
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
|
||||
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
|
||||
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
|
||||
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
|
||||
* following link:
|
||||
* http://www.renesas.com/disclaimer
|
||||
*
|
||||
* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
|
||||
***********************************************************************************************************************/
|
||||
/***********************************************************************************************************************
|
||||
* File Name : ether_callback.c
|
||||
* Version : ----
|
||||
* Description : This module solves all the world's problems
|
||||
***********************************************************************************************************************/
|
||||
/**********************************************************************************************************************
|
||||
* History : DD.MM.YYYY Version Description
|
||||
* : 05.01.2015 ---- Clean up source code.
|
||||
***********************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************
|
||||
Includes <System Includes> , "Project Includes"
|
||||
***********************************************************************************************************************/
|
||||
#include "r_ether_rx_if.h"
|
||||
|
||||
/***********************************************************************************************************************
|
||||
Private global variables and functions
|
||||
***********************************************************************************************************************/
|
||||
int32_t callback_ether_regist(void);
|
||||
void callback_ether(void * pparam);
|
||||
static void callback_wakeon_lan(uint32_t channel);
|
||||
static void callback_link_on(uint32_t channel);
|
||||
static void callback_link_off(uint32_t channel);
|
||||
|
||||
volatile uint8_t pause_enable = ETHER_FLAG_OFF;
|
||||
volatile uint8_t magic_packet_detect[ETHER_CHANNEL_MAX];
|
||||
volatile uint8_t link_detect[ETHER_CHANNEL_MAX];
|
||||
|
||||
void EINT_Trig_isr(void *);
|
||||
|
||||
/*
|
||||
* When that Link Status changes, the following function will be called:
|
||||
*/
|
||||
void prvLinkStatusChange( BaseType_t xStatus );
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: callback_ether
|
||||
* Description : Regist of callback function
|
||||
* Arguments : -
|
||||
* Return Value : 0: success, -1:failed
|
||||
***********************************************************************************************************************/
|
||||
int32_t callback_ether_regist(void)
|
||||
{
|
||||
ether_param_t param;
|
||||
ether_cb_t cb_func;
|
||||
|
||||
int32_t ret;
|
||||
|
||||
/* Set the callback function (LAN cable connect/disconnect event) */
|
||||
cb_func.pcb_func = &callback_ether;
|
||||
param.ether_callback = cb_func;
|
||||
ret = R_ETHER_Control(CONTROL_SET_CALLBACK, param);
|
||||
if (ETHER_SUCCESS != ret)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the callback function (Ether interrupt event) */
|
||||
cb_func.pcb_int_hnd = &EINT_Trig_isr;
|
||||
param.ether_callback = cb_func;
|
||||
ret = R_ETHER_Control(CONTROL_SET_INT_HANDLER, param);
|
||||
if (ETHER_SUCCESS != ret)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} /* End of function callback_ether_regist() */
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: callback_ether
|
||||
* Description : Sample of the callback function
|
||||
* Arguments : pparam -
|
||||
*
|
||||
* Return Value : none
|
||||
***********************************************************************************************************************/
|
||||
void callback_ether(void * pparam)
|
||||
{
|
||||
ether_cb_arg_t * pdecode;
|
||||
uint32_t channel;
|
||||
|
||||
pdecode = (ether_cb_arg_t *)pparam;
|
||||
channel = pdecode->channel; /* Get Ethernet channel number */
|
||||
|
||||
switch (pdecode->event_id)
|
||||
{
|
||||
/* Callback function that notifies user to have detected magic packet. */
|
||||
case ETHER_CB_EVENT_ID_WAKEON_LAN:
|
||||
callback_wakeon_lan(channel);
|
||||
break;
|
||||
|
||||
/* Callback function that notifies user to have become Link up. */
|
||||
case ETHER_CB_EVENT_ID_LINK_ON:
|
||||
callback_link_on(channel);
|
||||
break;
|
||||
|
||||
/* Callback function that notifies user to have become Link down. */
|
||||
case ETHER_CB_EVENT_ID_LINK_OFF:
|
||||
callback_link_off(channel);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} /* End of function callback_ether() */
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: callback_wakeon_lan
|
||||
* Description :
|
||||
* Arguments : channel -
|
||||
* Ethernet channel number
|
||||
* Return Value : none
|
||||
***********************************************************************************************************************/
|
||||
static void callback_wakeon_lan(uint32_t channel)
|
||||
{
|
||||
if (ETHER_CHANNEL_MAX > channel)
|
||||
{
|
||||
magic_packet_detect[channel] = 1;
|
||||
|
||||
/* Please add necessary processing when magic packet is detected. */
|
||||
}
|
||||
} /* End of function callback_wakeon_lan() */
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: callback_link_on
|
||||
* Description :
|
||||
* Arguments : channel -
|
||||
* Ethernet channel number
|
||||
* Return Value : none
|
||||
***********************************************************************************************************************/
|
||||
static void callback_link_on(uint32_t channel)
|
||||
{
|
||||
if (ETHER_CHANNEL_MAX > channel)
|
||||
{
|
||||
link_detect[channel] = ETHER_FLAG_ON_LINK_ON;
|
||||
|
||||
/* Please add necessary processing when becoming Link up. */
|
||||
prvLinkStatusChange( 1 );
|
||||
}
|
||||
} /* End of function callback_link_on() */
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: callback_link_off
|
||||
* Description :
|
||||
* Arguments : channel -
|
||||
* Ethernet channel number
|
||||
* Return Value : none
|
||||
***********************************************************************************************************************/
|
||||
static void callback_link_off(uint32_t channel)
|
||||
{
|
||||
if (ETHER_CHANNEL_MAX > channel)
|
||||
{
|
||||
link_detect[channel] = ETHER_FLAG_ON_LINK_OFF;
|
||||
|
||||
/* Please add necessary processing when becoming Link down. */
|
||||
prvLinkStatusChange( 0 );
|
||||
}
|
||||
} /* End of function ether_cb_link_off() */
|
||||
|
||||
/* End of File */
|
Loading…
Add table
Add a link
Reference in a new issue