@@ -221,7 +221,9 @@ void emacps_send_handler( void * arg )
221221 * "isr_events". The task in NetworkInterface will wake-up and do the necessary work.
222222 */
223223 xemacpsif -> isr_events |= EMAC_IF_TX_EVENT ;
224- xemacpsif -> txBusy = pdFALSE ;
224+
225+ /* Take the mutex without blocking. */
226+ xSemaphoreGiveFromISR ( xemacpsif -> txMutex , & xHigherPriorityTaskWoken );
225227
226228 if ( xEMACTaskHandles [ xEMACIndex ] != NULL )
227229 {
@@ -252,7 +254,6 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif,
252254 int iReleaseAfterSend )
253255{
254256 int txHead = xemacpsif -> txHead ;
255- int iHasSent = 0 ;
256257 uint32_t ulBaseAddress = xemacpsif -> emacps .Config .BaseAddress ;
257258 BaseType_t xEMACIndex = get_xEMACIndex ( & xemacpsif -> emacps );
258259 TickType_t xBlockTimeTicks = pdMS_TO_TICKS ( 5000U );
@@ -315,8 +316,6 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif,
315316 {
316317 }
317318
318- iHasSent = pdTRUE ;
319-
320319 txHead ++ ;
321320
322321 if ( txHead == ipconfigNIC_N_TX_DESC )
@@ -328,18 +327,24 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif,
328327 * accessed as little as possible. */
329328 xemacpsif -> txHead = txHead ;
330329
330+ if ( xSemaphoreTake ( xemacpsif -> txMutex , 200U ) == pdFALSE )
331+ {
332+ FreeRTOS_printf ( ( "emacps_send_message: mutex can not be taken, something is really wrong.\n" ) );
333+ /* There is no risk in continuing here. */
334+ }
335+
331336 /* Data Synchronization Barrier */
332337 dsb ();
333338
334- if ( iHasSent == pdTRUE )
335339 {
336- /* Make STARTTX high */
337- 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 ) );
341- /* Read back the register to make sure the data is flushed. */
342- ( void ) XEmacPs_ReadReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET );
340+ /* Make STARTTX high */
341+ uint32_t ulValue = XEmacPs_ReadReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET );
342+ /* Set the Start transmit bit. */
343+ ulValue |= XEMACPS_NWCTRL_STARTTX_MASK ;
344+ XEmacPs_WriteReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET , ulValue );
345+ /* Read back the register to make sure the data is flushed. */
346+ ( void ) XEmacPs_ReadReg ( ulBaseAddress , XEMACPS_NWCTRL_OFFSET );
347+ /* The mutex will be given later on in emacps_send_handler(). */
343348 }
344349
345350 dsb ();
@@ -685,6 +690,15 @@ XStatus init_dma( xemacpsif_s * xemacpsif )
685690 configASSERT ( xTXDescriptorSemaphores [ xEMACIndex ] );
686691 }
687692
693+ if ( xemacpsif -> txMutex == NULL )
694+ {
695+ /* txMutex can always be taken, except between sending a packet
696+ * and receiving the TX RX interrupt. */
697+ xemacpsif -> txMutex = xSemaphoreCreateBinary ();
698+ xSemaphoreGive ( xemacpsif -> txMutex );
699+ configASSERT ( xemacpsif -> txMutex != NULL );
700+ }
701+
688702 /*
689703 * Allocate RX descriptors, 1 RxBD at a time.
690704 */
0 commit comments