@@ -120,6 +120,8 @@ static __ALIGNED(4) uint8_t eth_tx_buf[configNUM_TX_DESCRIPTORS][XMC_ETH_MAC_BUF
120
120
#endif
121
121
#endif
122
122
123
+ #define TX_BUFFER_FREE_WAIT ( pdMS_TO_TICKS( 5UL ) )
124
+ #define MAX_TX_ATTEMPTS ( 10 )
123
125
124
126
/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
125
127
driver will filter incoming packets and only pass the stack those packets it
@@ -148,30 +150,27 @@ void ETH0_0_IRQHandler(void)
148
150
ulStatusRegister = XMC_ETH_MAC_GetEventStatus (& eth_mac );
149
151
XMC_ETH_MAC_ClearEventStatus (& eth_mac , ulStatusRegister );
150
152
151
- if (netif_task_handler != 0 )
152
- {
153
- /* xHigherPriorityTaskWoken must be initialised to pdFALSE. If calling
154
- xTaskNotifyFromISR() unblocks the handling task, and the priority of
155
- the handling task is higher than the priority of the currently running task,
156
- then xHigherPriorityTaskWoken will automatically get set to pdTRUE. */
157
- xHigherPriorityTaskWoken = pdFALSE ;
158
-
159
- /* Unblock the handling task so the task can perform any processing necessitated
160
- by the interrupt. xHandlingTask is the task's handle, which was obtained
161
- when the task was created. The handling task's notification value
162
- is bitwise ORed with the interrupt status - ensuring bits that are already
163
- set are not overwritten. */
164
- xTaskNotifyFromISR (netif_task_handler , ulStatusRegister , eSetBits , & xHigherPriorityTaskWoken );
165
-
166
- /* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
167
- The macro used to do this is dependent on the port and may be called
168
- portEND_SWITCHING_ISR. */
169
- portYIELD_FROM_ISR (xHigherPriorityTaskWoken );
170
- }
153
+ /* xHigherPriorityTaskWoken must be initialised to pdFALSE. If calling
154
+ xTaskNotifyFromISR() unblocks the handling task, and the priority of
155
+ the handling task is higher than the priority of the currently running task,
156
+ then xHigherPriorityTaskWoken will automatically get set to pdTRUE. */
157
+ xHigherPriorityTaskWoken = pdFALSE ;
158
+
159
+ /* Unblock the handling task so the task can perform any processing necessitated
160
+ by the interrupt. xHandlingTask is the task's handle, which was obtained
161
+ when the task was created. The handling task's notification value
162
+ is bitwise ORed with the interrupt status - ensuring bits that are already
163
+ set are not overwritten. */
164
+ xTaskNotifyFromISR (netif_task_handler , ulStatusRegister , eSetBits , & xHigherPriorityTaskWoken );
165
+
166
+ /* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
167
+ The macro used to do this is dependent on the port and may be called
168
+ portEND_SWITCHING_ISR. */
169
+ portYIELD_FROM_ISR (xHigherPriorityTaskWoken );
171
170
}
172
171
173
172
#if (ipconfigZERO_COPY_RX_DRIVER == 0 )
174
- static void prvNetworkInterfaceInput (void )
173
+ static BaseType_t prvNetworkInterfaceInput (void )
175
174
{
176
175
uint32_t xReceivedLength ;
177
176
uint8_t * pucBuffer ;
@@ -213,63 +212,79 @@ static void prvNetworkInterfaceInput(void)
213
212
XMC_ETH_MAC_ReturnRxDescriptor (& eth_mac );
214
213
XMC_ETH_MAC_ResumeRx (& eth_mac );
215
214
215
+ return ( xReceivedLength > 0 );
216
+
216
217
}
217
218
#else
218
- static void prvNetworkInterfaceInput (void )
219
+ static BaseType_t prvNetworkInterfaceInput (void )
219
220
{
220
221
uint32_t xReceivedLength ;
221
222
uint8_t * pucBuffer ;
222
- NetworkBufferDescriptor_t * pxDescriptor ;
223
- const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS ( 250 );
223
+ NetworkBufferDescriptor_t * pxCurDescriptor ;
224
+ NetworkBufferDescriptor_t * pxNewDescriptor = NULL ;
225
+
224
226
xIPStackEvent_t xRxEvent = { eNetworkRxEvent , NULL };
225
227
226
228
xReceivedLength = XMC_ETH_MAC_GetRxFrameSize (& eth_mac );
227
- if (( xReceivedLength > 0 ) && ( xReceivedLength <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
229
+ if (xReceivedLength > 0 )
228
230
{
229
- pucBuffer = XMC_ETH_MAC_GetRxBuffer (& eth_mac );
230
-
231
- if (ipCONSIDER_FRAME_FOR_PROCESSING (pucBuffer ))
231
+ /* Check if it is a valid frame */
232
+ if (xReceivedLength <= ipTOTAL_ETHERNET_FRAME_SIZE )
232
233
{
233
- /* Allocate a new network buffer descriptor that references an Ethernet
234
- frame large enough to hold the maximum network packet size (as defined
235
- in the FreeRTOSIPConfig.h header file). */
236
- pxDescriptor = pxGetNetworkBufferWithDescriptor (ipTOTAL_ETHERNET_FRAME_SIZE , xDescriptorWaitTime );
237
- if (pxDescriptor != NULL )
238
- {
239
- XMC_ETH_MAC_SetRxBuffer (& eth_mac , pxDescriptor -> pucEthernetBuffer );
240
-
241
- pxDescriptor -> pucEthernetBuffer = pucBuffer ;
242
- pxDescriptor -> xDataLength = xReceivedLength ;
243
-
244
- * ( ( NetworkBufferDescriptor_t * * )
245
- ( pxDescriptor -> pucEthernetBuffer - ipBUFFER_PADDING ) ) = pxDescriptor ;
246
-
247
- /*
248
- * The network buffer descriptor now points to the Ethernet buffer that
249
- * contains the received data, and the Ethernet DMA descriptor now points
250
- * to a newly allocated (and empty) Ethernet buffer ready to receive more
251
- * data. No data was copied. Only pointers to data were swapped.
252
- */
234
+ pucBuffer = XMC_ETH_MAC_GetRxBuffer (& eth_mac );
253
235
254
- xRxEvent .pvData = ( void * )pxDescriptor ;
255
-
256
- /* Pass the data to the TCP/IP task for processing. */
257
- if (xSendEventStructToIPTask ( & xRxEvent , xDescriptorWaitTime ) == pdFALSE )
236
+ if (ipCONSIDER_FRAME_FOR_PROCESSING (pucBuffer ))
237
+ {
238
+ /* Allocate a new network buffer descriptor that references an Ethernet
239
+ frame large enough to hold the maximum network packet size (as defined
240
+ in the FreeRTOSIPConfig.h header file). */
241
+ pxNewDescriptor = pxGetNetworkBufferWithDescriptor (ipTOTAL_ETHERNET_FRAME_SIZE , 0 );
242
+ if (pxNewDescriptor != NULL )
258
243
{
259
- /* Could not send the descriptor into the TCP/IP stack, it must be released. */
260
- vReleaseNetworkBufferAndDescriptor (pxDescriptor );
261
- iptraceETHERNET_RX_EVENT_LOST ();
244
+ XMC_ETH_MAC_SetRxBuffer (& eth_mac , pxNewDescriptor -> pucEthernetBuffer );
245
+
246
+ pxCurDescriptor = pxPacketBuffer_to_NetworkBuffer ( pucBuffer );
247
+ configASSERT ( pxCurDescriptor != NULL );
248
+
249
+ pxCurDescriptor -> xDataLength = xReceivedLength ;
250
+
251
+ /*
252
+ * The network buffer descriptor now points to the Ethernet buffer that
253
+ * contains the received data, and the Ethernet DMA descriptor now points
254
+ * to a newly allocated (and empty) Ethernet buffer ready to receive more
255
+ * data. No data was copied. Only pointers to data were swapped.
256
+ */
257
+
258
+ xRxEvent .pvData = ( void * )pxCurDescriptor ;
259
+
260
+ /* Pass the data to the TCP/IP task for processing. */
261
+ if (xSendEventStructToIPTask ( & xRxEvent , 0 ) == pdFALSE )
262
+ {
263
+ /* Could not send the descriptor into the TCP/IP stack, it must be released. */
264
+ vReleaseNetworkBufferAndDescriptor (pxCurDescriptor );
265
+ iptraceETHERNET_RX_EVENT_LOST ();
266
+ }
267
+ else
268
+ {
269
+ iptraceNETWORK_INTERFACE_RECEIVE ();
270
+ }
262
271
}
263
272
else
264
273
{
265
- iptraceNETWORK_INTERFACE_RECEIVE ();
274
+ /* The event was lost because a network buffer was not available.
275
+ Call the standard trace macro to log the occurrence. */
276
+ iptraceETHERNET_RX_EVENT_LOST ();
266
277
}
267
278
}
268
279
}
280
+
281
+ XMC_ETH_MAC_ReturnRxDescriptor (& eth_mac );
269
282
}
270
283
271
- XMC_ETH_MAC_ReturnRxDescriptor (& eth_mac );
272
284
XMC_ETH_MAC_ResumeRx (& eth_mac );
285
+
286
+ return ( xReceivedLength > 0 );
287
+
273
288
}
274
289
#endif
275
290
@@ -290,7 +305,7 @@ static void vClearTXBuffers()
290
305
NetworkBufferDescriptor_t * pxDescriptor = pxPacketBuffer_to_NetworkBuffer (ucPayLoad );
291
306
if (pxDescriptor != NULL )
292
307
{
293
- vReleaseNetworkBufferAndDescriptor (pxDescriptor );
308
+ vReleaseNetworkBufferAndDescriptor (pxDescriptor );
294
309
}
295
310
XMC_ETH_MAC_SetTxBufferEx (& eth_mac , ulTxDescriptorToClear , 0 );
296
311
}
@@ -320,7 +335,7 @@ static void set_link_up(void)
320
335
XMC_ETH_MAC_SetLink (& eth_mac , speed , duplex );
321
336
322
337
/* Enable ethernet interrupts */
323
- XMC_ETH_MAC_EnableEvent (& eth_mac , (uint32_t )(XMC_ETH_MAC_EVENT_RECEIVE | XMC_ETH_MAC_EVENT_TRANSMIT ));
338
+ XMC_ETH_MAC_EnableEvent (& eth_mac , (uint32_t )(XMC_ETH_MAC_EVENT_RECEIVE | XMC_ETH_MAC_EVENT_RECEIVE_BUFFER_UNAVAILABLE | XMC_ETH_MAC_EVENT_TRANSMIT ));
324
339
325
340
NVIC_SetPriority (ETH0_0_IRQn , NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 62U , 0U ));
326
341
NVIC_ClearPendingIRQ (ETH0_0_IRQn );
@@ -334,7 +349,7 @@ static void set_link_up(void)
334
349
335
350
static void set_link_down (void )
336
351
{
337
- XMC_ETH_MAC_DisableEvent (& eth_mac , (uint32_t )(XMC_ETH_MAC_EVENT_RECEIVE | XMC_ETH_MAC_EVENT_TRANSMIT ));
352
+ XMC_ETH_MAC_DisableEvent (& eth_mac , (uint32_t )(XMC_ETH_MAC_EVENT_RECEIVE | XMC_ETH_MAC_EVENT_RECEIVE_BUFFER_UNAVAILABLE | XMC_ETH_MAC_EVENT_TRANSMIT ));
338
353
NVIC_DisableIRQ (ETH0_0_IRQn );
339
354
340
355
XMC_ETH_MAC_DisableTx (& eth_mac );
@@ -360,13 +375,9 @@ static void netif_task(void *arg)
360
375
& ulInterruptStatus , /* Receives the notification value. */
361
376
portMAX_DELAY ); /* Block indefinitely. */
362
377
363
- if ((ulInterruptStatus & XMC_ETH_MAC_EVENT_RECEIVE ) != 0 )
378
+ if ((ulInterruptStatus & ( XMC_ETH_MAC_EVENT_RECEIVE | XMC_ETH_MAC_EVENT_RECEIVE_BUFFER_UNAVAILABLE ) ) != 0 )
364
379
{
365
- /* Go through the application owned descriptors */
366
- while (XMC_ETH_MAC_IsRxDescriptorOwnedByDma (& eth_mac ) == pdFALSE )
367
- {
368
- prvNetworkInterfaceInput ();
369
- }
380
+ while (prvNetworkInterfaceInput ());
370
381
}
371
382
372
383
if ((ulInterruptStatus & XMC_ETH_MAC_EVENT_TRANSMIT ) != 0 )
@@ -516,8 +527,8 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkB
516
527
BaseType_t xNetworkInterfaceOutput ( NetworkBufferDescriptor_t * const pxDescriptor , BaseType_t xReleaseAfterSend )
517
528
{
518
529
(void )xReleaseAfterSend ;
519
- const TickType_t xBlockTimeTicks = pdMS_TO_TICKS (50u );
520
530
BaseType_t xReturn = pdFAIL ;
531
+ int32_t x ;
521
532
522
533
do
523
534
{
@@ -526,9 +537,18 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescript
526
537
break ;
527
538
}
528
539
529
- if (xSemaphoreTake (xTXDescriptorSemaphore , xBlockTimeTicks ) != pdPASS )
540
+ for (x = 0 ; x < MAX_TX_ATTEMPTS ; ++ x )
541
+ {
542
+ if (xSemaphoreTake (xTXDescriptorSemaphore , 0 ) == pdPASS )
543
+ {
544
+ break ;
545
+ }
546
+ iptraceWAITING_FOR_TX_DMA_DESCRIPTOR ();
547
+ vTaskDelay (TX_BUFFER_FREE_WAIT );
548
+ }
549
+
550
+ if (x == MAX_TX_ATTEMPTS )
530
551
{
531
- /* Time-out waiting for a free TX descriptor. */
532
552
break ;
533
553
}
534
554
@@ -586,6 +606,9 @@ void vNetworkInterfaceAllocateRAMToBuffers(
586
606
/* pucEthernetBuffer is set to point ipBUFFER_PADDING bytes in from the
587
607
beginning of the allocated buffer. */
588
608
pxDescriptor [ x ].pucEthernetBuffer = & ( ucBuffers [ x ][ ipBUFFER_PADDING ] );
609
+ pxDescriptor [ x ].xDataLength = 0 ;
610
+ pxDescriptor [ x ].usPort = 0 ;
611
+ pxDescriptor [ x ].usBoundPort = 0 ;
589
612
590
613
/* The following line is also required, but will not be required in
591
614
future versions. */
0 commit comments