]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
139979cce5a5e64f610be7af6f81d5bb9180e00e
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / RX / NetworkInterface.c
1 /***********************************************************************************************************************
2 * DISCLAIMER
3 * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
4 * other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
5 * applicable laws, including copyright laws.
6 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
7 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
8 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
9 * EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
10 * SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
11 * SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
12 * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
13 * this software. By using this software, you agree to the additional terms and conditions found by accessing the
14 * following link:
15 * http://www.renesas.com/disclaimer
16 *
17 * Copyright (C) 2018 Renesas Electronics Corporation. All rights reserved.
18 ***********************************************************************************************************************/
19
20 /***********************************************************************************************************************
21 * File Name    : NetworkInterface.c
22 * Device(s)    : RX
23 * Description  : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
24 ***********************************************************************************************************************/
25
26 /***********************************************************************************************************************
27 * History : DD.MM.YYYY Version  Description
28 *         : 07.03.2018 0.1     Development
29 ***********************************************************************************************************************/
30
31 /***********************************************************************************************************************
32 *  Includes   <System Includes> , "Project Includes"
33 ***********************************************************************************************************************/
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 /* FreeRTOS includes. */
40 #include "FreeRTOS.h"
41 #include "task.h"
42 #include "FreeRTOS_IP.h"
43 #include "FreeRTOS_IP_Private.h"
44 /*#include "FreeRTOS_DNS.h" */
45 #include "NetworkBufferManagement.h"
46 #include "NetworkInterface.h"
47
48 #include "r_ether_rx_if.h"
49 #include "r_pinset.h"
50
51 /***********************************************************************************************************************
52  * Macro definitions
53  **********************************************************************************************************************/
54 #define ETHER_BUFSIZE_MIN    60
55
56 #if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M )
57     #if ETHER_CFG_MODE_SEL == 0
58         #define R_ETHER_PinSet_CHANNEL_0()    R_ETHER_PinSet_ETHERC0_MII()
59     #elif ETHER_CFG_MODE_SEL == 1
60         #define R_ETHER_PinSet_CHANNEL_0()    R_ETHER_PinSet_ETHERC0_RMII()
61     #endif
62 #elif defined( BSP_MCU_RX63N )
63     #if ETHER_CFG_MODE_SEL == 0
64         #define R_ETHER_PinSet_CHANNEL_0()    R_ETHER_PinSet_ETHERC_MII()
65     #elif ETHER_CFG_MODE_SEL == 1
66         #define R_ETHER_PinSet_CHANNEL_0()    R_ETHER_PinSet_ETHERC_RMII()
67     #endif
68 #endif /* if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) */
69
70 #ifndef PHY_LS_HIGH_CHECK_TIME_MS
71
72 /* Check if the LinkSStatus in the PHY is still high after 2 seconds of not
73  * receiving packets. */
74     #define PHY_LS_HIGH_CHECK_TIME_MS    2000
75 #endif
76
77 #ifndef PHY_LS_LOW_CHECK_TIME_MS
78     /* Check if the LinkSStatus in the PHY is still low every second. */
79     #define PHY_LS_LOW_CHECK_TIME_MS    1000
80 #endif
81
82 /***********************************************************************************************************************
83  * Private global variables and functions
84  **********************************************************************************************************************/
85 typedef enum
86 {
87     eMACInit,   /* Must initialise MAC. */
88     eMACPass,   /* Initialisation was successful. */
89     eMACFailed, /* Initialisation failed. */
90 } eMAC_INIT_STATUS_TYPE;
91
92 static TaskHandle_t ether_receive_check_task_handle = 0;
93 static TaskHandle_t ether_link_check_task_handle = 0;
94 static TaskHandle_t xTaskToNotify = NULL;
95 static BaseType_t xPHYLinkStatus;
96 static BaseType_t xReportedStatus;
97 static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
98
99 static int16_t SendData( uint8_t * pucBuffer,
100                          size_t length );
101 static int InitializeNetwork( void );
102 static void prvEMACDeferredInterruptHandlerTask( void * pvParameters );
103 static void clear_all_ether_rx_discriptors( uint32_t event );
104
105 int32_t callback_ether_regist( void );
106 void EINT_Trig_isr( void * );
107 void get_random_number( uint8_t * data,
108                         uint32_t len );
109
110 void prvLinkStatusChange( BaseType_t xStatus );
111 #if ( ipconfigHAS_PRINTF != 0 )
112     static void prvMonitorResources( void );
113 #endif
114
115 /***********************************************************************************************************************
116  * Function Name: xNetworkInterfaceInitialise ()
117  * Description  : Initialization of Ethernet driver.
118  * Arguments    : none
119  * Return Value : pdPASS, pdFAIL
120  **********************************************************************************************************************/
121 BaseType_t xNetworkInterfaceInitialise( void )
122 {
123     BaseType_t xReturn;
124
125     if( xMacInitStatus == eMACInit )
126     {
127         /*
128          * Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
129          * Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
130          *
131          * InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
132          */
133         if( InitializeNetwork() == pdFALSE )
134         {
135             xMacInitStatus = eMACFailed;
136         }
137         else
138         {
139             /* Indicate that the MAC initialisation succeeded. */
140             xMacInitStatus = eMACPass;
141         }
142
143         FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
144     }
145
146     if( xMacInitStatus == eMACPass )
147     {
148         xReturn = xPHYLinkStatus;
149     }
150     else
151     {
152         xReturn = pdFAIL;
153     }
154
155     FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
156
157     return xReturn;
158 } /* End of function xNetworkInterfaceInitialise() */
159
160
161 /***********************************************************************************************************************
162  * Function Name: xNetworkInterfaceOutput ()
163  * Description  : Simple network output interface.
164  * Arguments    : pxDescriptor, xReleaseAfterSend
165  * Return Value : pdTRUE, pdFALSE
166  **********************************************************************************************************************/
167 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
168                                     BaseType_t xReleaseAfterSend )
169 {
170     BaseType_t xReturn = pdFALSE;
171
172     /* Simple network interfaces (as opposed to more efficient zero copy network
173      * interfaces) just use Ethernet peripheral driver library functions to copy
174      * data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.
175      * This example assumes SendData() is a peripheral driver library function that
176      * takes a pointer to the start of the data to be sent and the length of the
177      * data to be sent as two separate parameters.  The start of the data is located
178      * by pxDescriptor->pucEthernetBuffer.  The length of the data is located
179      * by pxDescriptor->xDataLength. */
180     if( xPHYLinkStatus != 0 )
181     {
182         if( SendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ) >= 0 )
183         {
184             xReturn = pdTRUE;
185             /* Call the standard trace macro to log the send event. */
186             iptraceNETWORK_INTERFACE_TRANSMIT();
187         }
188     }
189     else
190     {
191         /* As the PHY Link Status is low, it makes no sense trying to deliver a packet. */
192     }
193
194     if( xReleaseAfterSend != pdFALSE )
195     {
196         /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
197          * buffer.  The Ethernet buffer is therefore no longer needed, and must be
198          * freed for re-use. */
199         vReleaseNetworkBufferAndDescriptor( pxDescriptor );
200     }
201
202     return xReturn;
203 } /* End of function xNetworkInterfaceOutput() */
204
205
206 #if ( ipconfigHAS_PRINTF != 0 )
207     static void prvMonitorResources()
208     {
209         static UBaseType_t uxLastMinBufferCount = 0u;
210         static UBaseType_t uxCurrentBufferCount = 0u;
211         static size_t uxMinLastSize = 0uL;
212         static size_t uxCurLastSize = 0uL;
213         size_t uxMinSize;
214         size_t uxCurSize;
215
216         uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
217
218         if( uxLastMinBufferCount != uxCurrentBufferCount )
219         {
220             /* The logging produced below may be helpful
221              * while tuning +TCP: see how many buffers are in use. */
222             uxLastMinBufferCount = uxCurrentBufferCount;
223             FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
224                                uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
225         }
226
227         uxMinSize = xPortGetMinimumEverFreeHeapSize();
228         uxCurSize = xPortGetFreeHeapSize();
229
230         if( uxMinLastSize != uxMinSize )
231         {
232             uxCurLastSize = uxCurSize;
233             uxMinLastSize = uxMinSize;
234             FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", uxCurSize, uxMinSize ) );
235         }
236
237         #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
238             {
239                 static UBaseType_t uxLastMinQueueSpace = 0;
240                 UBaseType_t uxCurrentCount = 0u;
241
242                 uxCurrentCount = uxGetMinimumIPQueueSpace();
243
244                 if( uxLastMinQueueSpace != uxCurrentCount )
245                 {
246                     /* The logging produced below may be helpful
247                      * while tuning +TCP: see how many buffers are in use. */
248                     uxLastMinQueueSpace = uxCurrentCount;
249                     FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
250                 }
251             }
252         #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
253     }
254 #endif /* ( ipconfigHAS_PRINTF != 0 ) */
255
256 /***********************************************************************************************************************
257  * Function Name: prvEMACDeferredInterruptHandlerTask ()
258  * Description  : The deferred interrupt handler is a standard RTOS task.
259  * Arguments    : pvParameters
260  * Return Value : none
261  **********************************************************************************************************************/
262 static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
263 {
264     NetworkBufferDescriptor_t * pxBufferDescriptor;
265     int32_t xBytesReceived = 0;
266
267     /* Avoid compiler warning about unreferenced parameter. */
268     ( void ) pvParameters;
269
270     /* Used to indicate that xSendEventStructToIPTask() is being called because
271      * of an Ethernet receive event. */
272     IPStackEvent_t xRxEvent;
273
274     uint8_t * buffer_pointer;
275
276     /* Some variables related to monitoring the PHY. */
277     TimeOut_t xPhyTime;
278     TickType_t xPhyRemTime;
279     const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
280
281     vTaskSetTimeOutState( &xPhyTime );
282     xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
283
284     FreeRTOS_printf( ( "Deferred Interrupt Handler Task started\n" ) );
285     xTaskToNotify = ether_receive_check_task_handle;
286
287     for( ; ; )
288     {
289         #if ( ipconfigHAS_PRINTF != 0 )
290             {
291                 prvMonitorResources();
292             }
293         #endif /* ipconfigHAS_PRINTF != 0 ) */
294
295         /* Wait for the Ethernet MAC interrupt to indicate that another packet
296          * has been received.  */
297         if( xBytesReceived <= 0 )
298         {
299             ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
300         }
301
302         /* See how much data was received.  */
303         xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
304
305         if( xBytesReceived < 0 )
306         {
307             /* This is an error. Logged. */
308             FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d\n", xBytesReceived ) );
309         }
310         else if( xBytesReceived > 0 )
311         {
312             /* Allocate a network buffer descriptor that points to a buffer
313              * large enough to hold the received frame.  As this is the simple
314              * rather than efficient example the received data will just be copied
315              * into this buffer. */
316             pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( ( size_t ) xBytesReceived, 0 );
317
318             if( pxBufferDescriptor != NULL )
319             {
320                 /* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet
321                  * buffer large enough to hold the received data.  Copy the
322                  * received data into pcNetworkBuffer->pucEthernetBuffer.  Here it
323                  * is assumed ReceiveData() is a peripheral driver function that
324                  * copies the received data into a buffer passed in as the function's
325                  * parameter.  Remember! While is is a simple robust technique -
326                  * it is not efficient.  An example that uses a zero copy technique
327                  * is provided further down this page. */
328                 memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer_pointer, ( size_t ) xBytesReceived );
329                 /*ReceiveData( pxBufferDescriptor->pucEthernetBuffer ); */
330
331                 /* Set the actual packet length, in case a larger buffer was returned. */
332                 pxBufferDescriptor->xDataLength = ( size_t ) xBytesReceived;
333
334                 R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
335
336                 /* See if the data contained in the received Ethernet frame needs
337                 * to be processed.  NOTE! It is preferable to do this in
338                 * the interrupt service routine itself, which would remove the need
339                 * to unblock this task for packets that don't need processing. */
340                 if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer ) == eProcessBuffer )
341                 {
342                     /* The event about to be sent to the TCP/IP is an Rx event. */
343                     xRxEvent.eEventType = eNetworkRxEvent;
344
345                     /* pvData is used to point to the network buffer descriptor that
346                      * now references the received data. */
347                     xRxEvent.pvData = ( void * ) pxBufferDescriptor;
348
349                     /* Send the data to the TCP/IP stack. */
350                     if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
351                     {
352                         /* The buffer could not be sent to the IP task so the buffer must be released. */
353                         vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
354
355                         /* Make a call to the standard trace macro to log the occurrence. */
356                         iptraceETHERNET_RX_EVENT_LOST();
357                         clear_all_ether_rx_discriptors( 0 );
358                     }
359                     else
360                     {
361                         /* The message was successfully sent to the TCP/IP stack.
362                         * Call the standard trace macro to log the occurrence. */
363                         iptraceNETWORK_INTERFACE_RECEIVE();
364                         R_NOP();
365                     }
366                 }
367                 else
368                 {
369                     /* The Ethernet frame can be dropped, but the Ethernet buffer must be released. */
370                     vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
371                 }
372             }
373             else
374             {
375                 /* The event was lost because a network buffer was not available.
376                  * Call the standard trace macro to log the occurrence. */
377                 iptraceETHERNET_RX_EVENT_LOST();
378                 clear_all_ether_rx_discriptors( 1 );
379                 FreeRTOS_printf( ( "R_ETHER_Read_ZC2: Cleared descriptors\n" ) );
380             }
381         }
382
383         if( xBytesReceived > 0 )
384         {
385             /* A packet was received. No need to check for the PHY status now,
386              * but set a timer to check it later on. */
387             vTaskSetTimeOutState( &xPhyTime );
388             xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
389
390             /* Indicate that the Link Status is high, so that
391              * xNetworkInterfaceOutput() can send packets. */
392             if( xPHYLinkStatus == 0 )
393             {
394                 xPHYLinkStatus = 1;
395                 FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume %d\n", xPHYLinkStatus ) );
396             }
397         }
398         else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
399         {
400             R_ETHER_LinkProcess( 0 );
401
402             if( xPHYLinkStatus != xReportedStatus )
403             {
404                 xPHYLinkStatus = xReportedStatus;
405                 FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", xPHYLinkStatus ) );
406             }
407
408             vTaskSetTimeOutState( &xPhyTime );
409
410             if( xPHYLinkStatus != 0 )
411             {
412                 xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
413             }
414             else
415             {
416                 xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
417             }
418         }
419     }
420 } /* End of function prvEMACDeferredInterruptHandlerTask() */
421
422
423 /***********************************************************************************************************************
424  * Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
425  * Description  : .
426  * Arguments    : pxNetworkBuffers
427  * Return Value : none
428  **********************************************************************************************************************/
429 void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
430 {
431     uint32_t ul;
432     uint8_t * buffer_address;
433
434     R_EXTERN_SEC( B_ETHERNET_BUFFERS_1 )
435
436     buffer_address = R_SECTOP( B_ETHERNET_BUFFERS_1 );
437
438     for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
439     {
440         pxNetworkBuffers[ ul ].pucEthernetBuffer = ( buffer_address + ( ETHER_CFG_BUFSIZE * ul ) );
441     }
442 } /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
443
444
445 /***********************************************************************************************************************
446  * Function Name: prvLinkStatusChange ()
447  * Description  : Function will be called when the Link Status of the phy has changed ( see ether_callback.c )
448  * Arguments    : xStatus : true when statyus has become high
449  * Return Value : void
450  **********************************************************************************************************************/
451 void prvLinkStatusChange( BaseType_t xStatus )
452 {
453     if( xReportedStatus != xStatus )
454     {
455         FreeRTOS_printf( ( "prvLinkStatusChange( %d )\n", xStatus ) );
456         xReportedStatus = xStatus;
457     }
458 }
459
460 /***********************************************************************************************************************
461  * Function Name: InitializeNetwork ()
462  * Description  :
463  * Arguments    : none
464  * Return Value : pdTRUE, pdFALSE
465  **********************************************************************************************************************/
466 static int InitializeNetwork( void )
467 {
468     ether_return_t eth_ret;
469     BaseType_t return_code = pdFALSE;
470     ether_param_t param;
471     uint8_t myethaddr[ 6 ] =
472     {
473         configMAC_ADDR0,
474         configMAC_ADDR1,
475         configMAC_ADDR2,
476         configMAC_ADDR3,
477         configMAC_ADDR4,
478         configMAC_ADDR5
479     }; /*XXX Fix me */
480
481     R_ETHER_PinSet_CHANNEL_0();
482     R_ETHER_Initial();
483     callback_ether_regist();
484
485     param.channel = ETHER_CHANNEL_0;
486     eth_ret = R_ETHER_Control( CONTROL_POWER_ON, param ); /* PHY mode settings, module stop cancellation */
487
488     if( ETHER_SUCCESS != eth_ret )
489     {
490         return pdFALSE;
491     }
492
493     eth_ret = R_ETHER_Open_ZC2( ETHER_CHANNEL_0, myethaddr, ETHER_FLAG_OFF );
494
495     if( ETHER_SUCCESS != eth_ret )
496     {
497         return pdFALSE;
498     }
499
500     return_code = xTaskCreate( prvEMACDeferredInterruptHandlerTask,
501                                "ETHER_RECEIVE_CHECK_TASK",
502                                512u,
503                                0,
504                                configMAX_PRIORITIES - 1,
505                                &ether_receive_check_task_handle );
506
507     if( pdFALSE == return_code )
508     {
509         return pdFALSE;
510     }
511
512     return pdTRUE;
513 } /* End of function InitializeNetwork() */
514
515
516 /***********************************************************************************************************************
517  * Function Name: SendData ()
518  * Description  :
519  * Arguments    : pucBuffer, length
520  * Return Value : 0 success, negative fail
521  **********************************************************************************************************************/
522 static int16_t SendData( uint8_t * pucBuffer,
523                          size_t length ) /*TODO complete stub function */
524 {
525     ether_return_t ret;
526     uint8_t * pwrite_buffer;
527     uint16_t write_buf_size;
528
529     /* (1) Retrieve the transmit buffer location controlled by the  descriptor. */
530     ret = R_ETHER_Write_ZC2_GetBuf( ETHER_CHANNEL_0, ( void ** ) &pwrite_buffer, &write_buf_size );
531
532     if( ETHER_SUCCESS == ret )
533     {
534         if( write_buf_size >= length )
535         {
536             memcpy( pwrite_buffer, pucBuffer, length );
537         }
538
539         if( length < ETHER_BUFSIZE_MIN )                                             /*under minimum*/
540         {
541             memset( ( pwrite_buffer + length ), 0, ( ETHER_BUFSIZE_MIN - length ) ); /*padding*/
542             length = ETHER_BUFSIZE_MIN;                                              /*resize*/
543         }
544
545         ret = R_ETHER_Write_ZC2_SetBuf( ETHER_CHANNEL_0, ( uint16_t ) length );
546         ret = R_ETHER_CheckWrite( ETHER_CHANNEL_0 );
547     }
548
549     if( ETHER_SUCCESS != ret )
550     {
551         return -5; /* XXX return meaningful value */
552     }
553     else
554     {
555         return 0;
556     }
557 } /* End of function SendData() */
558
559
560 /***********************************************************************************************************************
561 * Function Name: EINT_Trig_isr
562 * Description  : Standard frame received interrupt handler
563 * Arguments    : ectrl - EDMAC and ETHERC control structure
564 * Return Value : None
565 * Note         : This callback function is executed when EINT0 interrupt occurred.
566 ***********************************************************************************************************************/
567 void EINT_Trig_isr( void * ectrl )
568 {
569     ether_cb_arg_t * pdecode;
570     BaseType_t xHigherPriorityTaskWoken = pdFALSE;
571
572     pdecode = ( ether_cb_arg_t * ) ectrl;
573
574     if( pdecode->status_eesr & 0x00040000 ) /* EDMAC FR (Frame Receive Event) interrupt */
575     {
576         if( xTaskToNotify != NULL )
577         {
578             vTaskNotifyGiveFromISR( ether_receive_check_task_handle, &xHigherPriorityTaskWoken );
579         }
580
581         /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
582          * should be performed to ensure the interrupt returns directly to the highest
583          * priority task.  The macro used for this purpose is dependent on the port in
584          * use and may be called portEND_SWITCHING_ISR(). */
585         portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
586         /*TODO complete interrupt handler for other events. */
587     }
588 } /* End of function EINT_Trig_isr() */
589
590
591 static void clear_all_ether_rx_discriptors( uint32_t event )
592 {
593     int32_t xBytesReceived;
594     uint8_t * buffer_pointer;
595
596     /* Avoid compiler warning about unreferenced parameter. */
597     ( void ) event;
598
599     while( 1 )
600     {
601         /* See how much data was received.  */
602         xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
603
604         if( 0 > xBytesReceived )
605         {
606             /* This is an error. Ignored. */
607         }
608         else if( 0 < xBytesReceived )
609         {
610             R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
611             iptraceETHERNET_RX_EVENT_LOST();
612         }
613         else
614         {
615             break;
616         }
617     }
618 }
619
620 /***********************************************************************************************************************
621  * End of file "NetworkInterface.c"
622  **********************************************************************************************************************/