bool vMACBWaitForInput(unsigned long ulTimeOut) { #ifdef FREERTOS_USED // Just wait until we are signaled from an ISR that data is available, or // we simply time out. xSemaphoreTake( xSemaphore, ulTimeOut ); return true; #else unsigned long i; volatile unsigned long ulEventStatus; i = ulTimeOut * 1000; // wait for an interrupt to occurs do { if ( DataToRead != 0 ) { // IT occurs, reset interrupt flag portENTER_CRITICAL(); DataToRead--; portEXIT_CRITICAL(); return true; } i--; }while(i != 0); // If the BNA bit is set, check if there is at least one available frame in // the rx buffers. ulEventStatus = AVR32_MACB.rsr; if( ulEventStatus & AVR32_MACB_BNA_MASK ) { AVR32_MACB.rsr = AVR32_MACB_BNA_MASK; // Clear AVR32_MACB.rsr; // Read to force the previous write if(ulMACBInputLength()) return true; } return false; #endif }
static struct pbuf * low_level_input(struct netif *netif) { struct pbuf *p = NULL; struct pbuf *q; u16_t len = 0; static xSemaphoreHandle xRxSemaphore = NULL; /* Parameter not used. */ ( void ) netif; if( xRxSemaphore == NULL ) { vSemaphoreCreateBinary( xRxSemaphore ); } /* Access to the emac is guarded using a semaphore. */ if( xSemaphoreTake( xRxSemaphore, netifGUARD_BLOCK_TIME ) ) { /* Obtain the size of the packet. */ len = ulMACBInputLength(); if( len ) { #if ETH_PAD_SIZE len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif /* We allocate a pbuf chain of pbufs from the pool. */ p = pbuf_alloc( PBUF_RAW, len, PBUF_POOL ); if( p != NULL ) { #if ETH_PAD_SIZE pbuf_header( p, -ETH_PAD_SIZE ); /* drop the padding word */ #endif /* Let the driver know we are going to read a new packet. */ vMACBRead( NULL, 0, len ); /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */ for( q = p; q != NULL; q = q->next ) { /* Read enough bytes to fill this pbuf in the chain. The available data in the pbuf is given by the q->len variable. */ vMACBRead( q->payload, q->len, len ); } #if ETH_PAD_SIZE pbuf_header( p, ETH_PAD_SIZE ); /* reclaim the padding word */ #endif #if LINK_STATS lwip_stats.link.recv++; #endif /* LINK_STATS */ } else { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif /* LINK_STATS */ } } xSemaphoreGive( xRxSemaphore ); } return p; }