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