Skip to content

Commit 52fa68c

Browse files
committed
Zynq: wait for transmission-ready before sending a new packet
1 parent d389e8b commit 52fa68c

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

source/portable/NetworkInterface/Zynq/x_emacpsif.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@
115115
volatile int rxHead, rxTail;
116116
volatile int txHead, txTail;
117117

118-
volatile int txBusy;
118+
/* txMutex is replacing the earlier int variable 'txBusy'. */
119+
SemaphoreHandle_t txMutex; /* Replacing the earlier variable 'volatile int txBusy'. */
119120

120121
volatile uint32_t isr_events;
121122

source/portable/NetworkInterface/Zynq/x_emacpsif_dma.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)