Пример #1
0
Файл: emac.c Проект: wugsh/wgs
unsigned long ulGetEMACRxData( void )
{
unsigned long ulLen = 0;
long lIndex;

	if( EMAC->RxProduceIndex != EMAC->RxConsumeIndex )
	{
		/* Mark the current buffer as free as uip_buf is going to be set to
		the buffer that contains the received data. */
		prvReturnBuffer( uip_buf );

		ulLen = ( RX_STAT_INFO( EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3;
		uip_buf = ( unsigned char * ) RX_DESC_PACKET( EMAC->RxConsumeIndex );

		/* Allocate a new buffer to the descriptor. */
        RX_DESC_PACKET( EMAC->RxConsumeIndex ) = ( unsigned long ) prvGetNextBuffer();

		/* Move the consume index onto the next position, ensuring it wraps to
		the beginning at the appropriate place. */
		lIndex = EMAC->RxConsumeIndex;

		lIndex++;
		if( lIndex >= NUM_RX_FRAG )
		{
			lIndex = 0;
		}

		EMAC->RxConsumeIndex = lIndex;
	}

	return ulLen;
}
Пример #2
0
Файл: emac.c Проект: wugsh/wgs
void vSendEMACTxData( unsigned short usTxDataLen )
{
unsigned long ulAttempts = 0UL;

	/* Check to see if the Tx descriptor is free, indicated by its buffer being
	NULL. */
	while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL )
	{
		/* Wait for the Tx descriptor to become available. */
		vTaskDelay( emacBUFFER_WAIT_DELAY );

		ulAttempts++;
		if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS )
		{
			/* Something has gone wrong as the Tx descriptor is still in use.
			Clear it down manually, the data it was sending will probably be
			lost. */
			prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
			break;
		}
	}

	/* Setup the Tx descriptor for transmission.  Remember the length of the
	data being sent so the second descriptor can be used to send it again from
	within the ISR. */
	usSendLen = usTxDataLen;
	TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf;
	TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT );
	EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 );

	/* uip_buf is being sent by the Tx descriptor.  Allocate a new buffer. */
	uip_buf = prvGetNextBuffer();
}
Пример #3
0
void vEMAC_ISR_Handler( void )
{
    unsigned long ul = EDMAC.EESR.LONG;
    long lHigherPriorityTaskWoken = pdFALSE;
    extern xSemaphoreHandle xEMACSemaphore;
    static long ulTxEndInts = 0;

    /* Has a Tx end occurred? */
    if( ul & emacTX_END_INTERRUPT )
    {
        ++ulTxEndInts;
        if( ulTxEndInts >= 2 )
        {
            /* Only return the buffer to the pool once both Txes have completed. */
            prvReturnBuffer( ( void * ) xTxDescriptors[ 0 ].buf_p );
            ulTxEndInts = 0;
        }
        EDMAC.EESR.LONG = emacTX_END_INTERRUPT;
    }

    /* Has an Rx end occurred? */
    if( ul & emacRX_END_INTERRUPT )
    {
        /* Make sure the Ethernet task is not blocked waiting for a packet. */
        xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( lHigherPriorityTaskWoken );
        EDMAC.EESR.LONG = emacRX_END_INTERRUPT;
    }
}
Пример #4
0
unsigned long ulEMACRead( void )
{
unsigned long ulBytesReceived;

	ulBytesReceived = prvCheckRxFifoStatus();

	if( ulBytesReceived > 0 )
	{
		/* Mark the pxDescriptor buffer as free as uip_buf is going to be set to
		the buffer that contains the received data. */
		prvReturnBuffer( uip_buf );

		/* Point uip_buf to the data about ot be processed. */
		uip_buf = ( void * ) pxCurrentRxDesc->buf_p;
		
		/* Allocate a new buffer to the descriptor, as uip_buf is now using it's
		old descriptor. */
		pxCurrentRxDesc->buf_p = prvGetNextBuffer();

		/* Prepare the descriptor to go again. */
		pxCurrentRxDesc->status &= ~( FP1 | FP0 );
		pxCurrentRxDesc->status |= ACT;

		/* Move onto the next buffer in the ring. */
		pxCurrentRxDesc = pxCurrentRxDesc->next;
		
		if( EDMAC.EDRRR.LONG == 0x00000000L )
		{
			/* Restart Ethernet if it has stopped */
			EDMAC.EDRRR.LONG = 0x00000001L;
		}
	}

	return ulBytesReceived;
}
Пример #5
0
unsigned long ulEMACRead( void )
{
    unsigned long ulBytesReceived;

    ulBytesReceived = prvCheckRxFifoStatus();

    if( ulBytesReceived > 0 )
    {
        xCurrentRxDesc->status &= ~( FP1 | FP0 );
        xCurrentRxDesc->status |= ACT;

        if( EDMAC.EDRRR.LONG == 0x00000000L )
        {
            /* Restart Ethernet if it has stopped */
            EDMAC.EDRRR.LONG = 0x00000001L;
        }

        /* Mark the pxDescriptor buffer as free as uip_buf is going to be set to
        the buffer that contains the received data. */
        prvReturnBuffer( uip_buf );

        uip_buf = ( void * ) xCurrentRxDesc->buf_p;

        /* Move onto the next buffer in the ring. */
        xCurrentRxDesc = xCurrentRxDesc->next;
    }

    return ulBytesReceived;
}
Пример #6
0
__interrupt void vEMAC_ISR_Handler( void )
{
unsigned long ul = EDMAC.EESR.LONG;
long lHigherPriorityTaskWoken = pdFALSE;
extern xQueueHandle xEMACEventQueue;
const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;

	__enable_interrupt();

	/* Has a Tx end occurred? */
	if( ul & emacTX_END_INTERRUPT )
	{
		/* Only return the buffer to the pool once both Txes have completed. */
		prvReturnBuffer( ( void * ) xTxDescriptors[ 0 ].buf_p );
		EDMAC.EESR.LONG = emacTX_END_INTERRUPT;
	}

	/* Has an Rx end occurred? */
	if( ul & emacRX_END_INTERRUPT )
	{
		/* Make sure the Ethernet task is not blocked waiting for a packet. */
		xQueueSendFromISR( xEMACEventQueue, &ulRxEvent, &lHigherPriorityTaskWoken );
		portYIELD_FROM_ISR( lHigherPriorityTaskWoken );
		EDMAC.EESR.LONG = emacRX_END_INTERRUPT;
	}
}
Пример #7
0
void vEMAC_ISR( void )
{
    unsigned long ulStatus;
    long lHigherPriorityTaskWoken = pdFALSE;

    ulStatus = EMAC->IntStatus;

    /* Clear the interrupt. */
    EMAC->IntClear = ulStatus;

    if( ulStatus & INT_RX_DONE ) {
        /* Ensure the uIP task is not blocked as data has arrived. */
        xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );
    }

    if( ulStatus & INT_TX_DONE ) {
        if( usSendLen > 0 ) {
            /* Send the data again, using the second descriptor.  As there are
            only two descriptors the index is set back to 0. */
            TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );
            TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );
            EMAC->TxProduceIndex = ( emacTX_DESC_INDEX );

            /* This is the second Tx so set usSendLen to 0 to indicate that the
            Tx descriptors will be free again. */
            usSendLen = 0UL;
        } else {
            /* The Tx buffer is no longer required. */
            prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
            TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;
        }
    }

    portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
Пример #8
0
void vEMAC_TxISRHandler( void )
{
	/* Clear the interrupt. */
	ENET_EIR = ENET_EIR_TXF_MASK;

	/* Check the buffers have not already been freed in the first of the
	two Tx interrupts - which could potentially happen if the second Tx completed
	during the interrupt for the first Tx. */
	if( xTxDescriptors[ 0 ].data != NULL )
	{
		if( ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) && ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) )
		{
			configASSERT( xTxDescriptors[ 0 ].data == xTxDescriptors[ 1 ].data );
			
			xTxDescriptors[ 0 ].data = ( uint8_t* ) __REV( ( unsigned long ) xTxDescriptors[ 0 ].data );
			prvReturnBuffer( xTxDescriptors[ 0 ].data );
			
			/* Just to mark the fact that the buffer has already been released. */
			xTxDescriptors[ 0 ].data = NULL;
		}
	}
}
Пример #9
0
unsigned short usEMACRead( void )
{
unsigned short usBytesReceived;

	usBytesReceived = prvCheckRxStatus();
	usBytesReceived = __REVSH( usBytesReceived );

	if( usBytesReceived > 0 )
	{
		/* Mark the pxDescriptor buffer as free as uip_buf is going to be set to
		the buffer that contains the received data. */
		prvReturnBuffer( uip_buf );

		/* Point uip_buf to the data about to be processed. */
		uip_buf = ( void * ) pxCurrentRxDesc->data;
		uip_buf = ( void * ) __REV( ( unsigned long ) uip_buf );
		
		/* Allocate a new buffer to the descriptor, as uip_buf is now using it's
		old descriptor. */
		pxCurrentRxDesc->data = ( uint8_t * ) prvGetNextBuffer();
		pxCurrentRxDesc->data = ( uint8_t* ) __REV( ( unsigned long ) pxCurrentRxDesc->data );

		/* Prepare the descriptor to go again. */
		pxCurrentRxDesc->status |= RX_BD_E;

		/* Move onto the next buffer in the ring. */
		ulRxDescriptorIndex++;
		if( ulRxDescriptorIndex >= emacNUM_RX_DESCRIPTORS )
		{
			ulRxDescriptorIndex = 0UL;
		}
		pxCurrentRxDesc = &( xRxDescriptors[ ulRxDescriptorIndex ] );
		
		/* Restart Ethernet if it has stopped */
		ENET_RDAR = ENET_RDAR_RDAR_MASK;
	}

	return usBytesReceived;
}