@@ -205,6 +205,8 @@ void emacps_check_tx( xemacpsif_s * xemacpsif )
205205
206206void emacps_send_handler ( void * arg )
207207{
208+ /* This function is running in ISR mode,
209+ * called to handle a TX interrupt. */
208210 xemacpsif_s * xemacpsif ;
209211 BaseType_t xHigherPriorityTaskWoken = pdFALSE ;
210212 BaseType_t xEMACIndex ;
@@ -217,15 +219,9 @@ void emacps_send_handler( void * arg )
217219 * But it forgets to do a read-back. Do so now to avoid ever-returning ISR's. */
218220 ( void ) XEmacPs_ReadReg ( xemacpsif -> emacps .Config .BaseAddress , XEMACPS_TXSR_OFFSET );
219221
220- /* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
221- * "isr_events". The task in NetworkInterface will wake-up and do the necessary work.
222- */
223- xemacpsif -> isr_events |= EMAC_IF_TX_EVENT ;
224- xemacpsif -> txBusy = pdFALSE ;
225-
226222 if ( xEMACTaskHandles [ xEMACIndex ] != NULL )
227223 {
228- vTaskNotifyGiveFromISR ( xEMACTaskHandles [ xEMACIndex ], & xHigherPriorityTaskWoken );
224+ xTaskNotifyFromISR ( xEMACTaskHandles [ xEMACIndex ], EMAC_IF_TX_EVENT , eSetBits , & ( xHigherPriorityTaskWoken ) );
229225 }
230226
231227 portYIELD_FROM_ISR ( xHigherPriorityTaskWoken );
@@ -252,7 +248,6 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif,
252248 int iReleaseAfterSend )
253249{
254250 int txHead = xemacpsif -> txHead ;
255- int iHasSent = 0 ;
256251 uint32_t ulBaseAddress = xemacpsif -> emacps .Config .BaseAddress ;
257252 BaseType_t xEMACIndex = get_xEMACIndex ( & xemacpsif -> emacps );
258253 TickType_t xBlockTimeTicks = pdMS_TO_TICKS ( 5000U );
@@ -315,8 +310,6 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif,
315310 {
316311 }
317312
318- iHasSent = pdTRUE ;
319-
320313 txHead ++ ;
321314
322315 if ( txHead == ipconfigNIC_N_TX_DESC )
@@ -331,13 +324,12 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif,
331324 /* Data Synchronization Barrier */
332325 dsb ();
333326
334- if ( iHasSent == pdTRUE )
335327 {
336328 /* Make STARTTX high */
337329 uint32_t ulValue = XEmacPs_ReadReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET );
338- /* Start transmit */
339- xemacpsif -> txBusy = pdTRUE ;
340- XEmacPs_WriteReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET , ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
330+ /* Start transmit. */
331+ ulValue |= XEMACPS_NWCTRL_STARTTX_MASK ;
332+ XEmacPs_WriteReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET , ulValue );
341333 /* Read back the register to make sure the data is flushed. */
342334 ( void ) XEmacPs_ReadReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET );
343335 }
@@ -356,12 +348,13 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif,
356348
357349void emacps_recv_handler ( void * arg )
358350{
351+ /* This function is running in ISR mode,
352+ * called to handle an RX interrupt. */
359353 xemacpsif_s * xemacpsif ;
360354 BaseType_t xHigherPriorityTaskWoken = pdFALSE ;
361355 BaseType_t xEMACIndex ;
362356
363357 xemacpsif = ( xemacpsif_s * ) arg ;
364- xemacpsif -> isr_events |= EMAC_IF_RX_EVENT ;
365358 xEMACIndex = get_xEMACIndex ( & xemacpsif -> emacps );
366359
367360 /* The driver has already cleared the FRAMERX, BUFFNA and error bits
@@ -371,7 +364,7 @@ void emacps_recv_handler( void * arg )
371364
372365 if ( xEMACTaskHandles [ xEMACIndex ] != NULL )
373366 {
374- vTaskNotifyGiveFromISR ( xEMACTaskHandles [ xEMACIndex ], & xHigherPriorityTaskWoken );
367+ xTaskNotifyFromISR ( xEMACTaskHandles [ xEMACIndex ], EMAC_IF_RX_EVENT , eSetBits , & ( xHigherPriorityTaskWoken ) );
375368 }
376369
377370 portYIELD_FROM_ISR ( xHigherPriorityTaskWoken );
@@ -685,6 +678,19 @@ XStatus init_dma( xemacpsif_s * xemacpsif )
685678 configASSERT ( xTXDescriptorSemaphores [ xEMACIndex ] );
686679 }
687680
681+ if ( xemacpsif -> tx_mutex == NULL )
682+ {
683+ /* Both the IP- and the EMAC-task handle TX descriptors.
684+ * The IP-task sends packets, and the EMAC task clear
685+ * TX descriptors that are done.
686+ * A mutex is used so that either emacps_send_message() or
687+ * emacps_check_tx() can become active a a time.
688+ */
689+ xemacpsif -> tx_mutex = xSemaphoreCreateBinary ();
690+ configASSERT ( xemacpsif -> tx_mutex != NULL );
691+ xSemaphoreGive ( xemacpsif -> tx_mutex );
692+ }
693+
688694 /*
689695 * Allocate RX descriptors, 1 RxBD at a time.
690696 */
0 commit comments