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