Пример #1
0
void ENET_IRQHandler (void)
{
    uint32_t int_stat;

    EMAC_PACKETBUF_Type RxDatbuf = {
        .pbDataBuf = uip_buf,
    };

    // Get EMAC interrupt status
    while ((int_stat = (LPC_EMAC->IntStatus & LPC_EMAC->IntEnable)) != 0) {
            LPC_EMAC->IntClear = int_stat; /*clear interrupt*/
           
            if ((int_stat & EMAC_INT_RX_DONE))
            {
                if (EMAC_CheckReceiveDataStatus(EMAC_RINFO_ERR_MASK)) {
                    /*error*/
                    goto rel;
                }
                /*copy frame to uip buffer*/
                uip_len = RxDatbuf.ulDataLen = EMAC_GetReceiveDataSize() - 3;
                EMAC_ReadPacketBuffer(&RxDatbuf);
                packet_received = 1;
            rel:
                /*release frame from EMAC buffer*/
                EMAC_UpdateRxConsumeIndex();
            }
    }
}
Пример #2
0
/* receive an Ethernet frame from MAC/DMA controller */
UNS_32 tapdev_read(void * pPacket)
{
	UNS_32 Size = EMAC_MAX_PACKET_SIZE;
	UNS_32 in_size;
	EMAC_PACKETBUF_Type RxPack;

	// Check Receive status
	if (EMAC_CheckReceiveIndex() == FALSE){
		return (0);
	}

	// Get size of receive data
	in_size = EMAC_GetReceiveDataSize() + 1;

	Size = MIN(Size,in_size);

	// Setup Rx packet
	RxPack.pbDataBuf = (uint32_t *)pPacket;
	RxPack.ulDataLen = Size;
	EMAC_ReadPacketBuffer(&RxPack);

	// update receive status
	EMAC_UpdateRxConsumeIndex();
	return(Size);
}
Пример #3
0
/**
 * @brief Receive Data Packet Done Callback function.
 * Called by EMAC Standard Interrupt handler in EMAC driver
 *
 * Note: All packets are greater than (TX_PACKET_SIZE + 4)
 * will be ignore!
 */
void RxDone_UsrCBS(void)
{
	EMAC_PACKETBUF_Type RxDatbuf;
	uint32_t RxLen;

	/* Packet received, check if packet is valid. */
	if (EMAC_CheckReceiveIndex()){
		if (!EMAC_CheckReceiveDataStatus(EMAC_RINFO_LAST_FLAG)){
			goto rel;
		}
		// Get data size, trip out 4-bytes CRC field, note that length in (-1) style format
		RxLen = EMAC_GetReceiveDataSize() - 3;
		// Note that packet added 4-bytes CRC created by yourself
		if ((RxLen > (TX_PACKET_SIZE + 4)) || (EMAC_CheckReceiveDataStatus(EMAC_RINFO_ERR_MASK))) {
			/* Invalid frame, ignore it and free buffer */
			goto rel;
		}
		ReceiveLength = RxLen;
		// Valid Frame, just copy it
		RxDatbuf.pbDataBuf = (uint32_t *)gRxBuf;
		RxDatbuf.ulDataLen = RxLen;
		EMAC_ReadPacketBuffer(&RxDatbuf);
		PacketReceived = TRUE;

rel:
		/* Release frame from EMAC buffer */
		EMAC_UpdateRxConsumeIndex();
	}
	_DBG_("Rx done");
	RxDoneCount++;
}
Пример #4
0
/**
 * Should allocate a pbuf and transfer the bytes of the incoming
 * packet from the interface into the pbuf.
 *
 * @param netif the lwip network interface structure for this lpc17xx_if
 * @return a pbuf filled with the received packet (including MAC header)
 *         NULL on memory error
 */
static struct pbuf *
low_level_input(struct netif *netif)
{
  struct pbuf *p, *q;
  u16_t len;

  if (EMAC_CheckReceiveIndex() == FALSE)
    return NULL;

  /* Obtain the size of the packet and put it into the "len"
     variable. */
  len = EMAC_GetReceiveDataSize() + 1;

#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

    /* 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.
       * This does not necessarily have to be a memcpy, you can also preallocate
       * pbufs for a DMA-enabled MAC and after receiving truncate it to the
       * actually received size. In this case, ensure the tot_len member of the
       * pbuf is the sum of the chained pbuf len members.
       */
      EMAC_PACKETBUF_Type RxPack;
      RxPack.pbDataBuf = q->payload;
      RxPack.ulDataLen = q->len;
      EMAC_ReadPacketBuffer(&RxPack);
    }

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif

    LINK_STATS_INC(link.recv);
  } else {
    LINK_STATS_INC(link.memerr);
    LINK_STATS_INC(link.drop);
  }
  EMAC_UpdateRxConsumeIndex();

  return p;  
}
Пример #5
0
int _EMAC_ReadPacketBuffer(uint8_t * args)
{
	uint8_t * arg_ptr;
	EMAC_PACKETBUF_Type* pDataStruct;

	if ((arg_ptr = (uint8_t *) strtok(NULL, " ")) == NULL) return 1;
	pDataStruct = (EMAC_PACKETBUF_Type*) strtoul((char *) arg_ptr, NULL, 16);

	EMAC_ReadPacketBuffer(pDataStruct);
	return 0;
}
Пример #6
0
// Reads the length of the received ethernet frame and checks if the
// destination address is a broadcast message or not
// returns the frame length
unsigned short StartReadFrame(void) {
	unsigned short RxLen;
	EMAC_PACKETBUF_Type RxPack;

	RxLen = EMAC_GetReceiveDataSize() - 3;
	// Copy packet to data buffer
	RxPack.pbDataBuf = (uint32_t *)pgBuf;
	RxPack.ulDataLen = RxLen;
	EMAC_ReadPacketBuffer(&RxPack);
	// Point to the data buffer
	rptr = (unsigned short *)pgBuf;
	return(RxLen);
}
Пример #7
0
/*********************************************************************//**
 * @brief		Ethernet service routine handler
 * @param[in]	none
 * @return 		none
 **********************************************************************/
void ENET_IRQHandler (void)
{
	EMAC_PACKETBUF_Type RxDatbuf;
	uint32_t RxLen;

	/* EMAC Ethernet Controller Interrupt function. */
	uint32_t int_stat;
	// Get EMAC interrupt status
	while ((int_stat = (LPC_EMAC->IntStatus & LPC_EMAC->IntEnable)) != 0) {
		// Clear interrupt status
		LPC_EMAC->IntClear = int_stat;
		/* scan interrupt status source */

		/* ---------- receive overrun ------------*/
		if((int_stat & EMAC_INT_RX_OVERRUN))
		{
			RXOverrunCount++;
			_DBG_("Rx overrun");
		}

		/*-----------  receive error -------------*/
		/* Note:
		 * The EMAC doesn't distinguish the frame type and frame length,
		 * so, e.g. when the IP(0x8000) or ARP(0x0806) packets are received,
		 * it compares the frame type with the max length and gives the
		 * "Range" error. In fact, this bit is not an error indication,
		 * but simply a statement by the chip regarding the status of
		 * the received frame
		 */
		if ((int_stat & EMAC_INT_RX_ERR))
		{
			if (EMAC_CheckReceiveDataStatus(EMAC_RINFO_RANGE_ERR) == RESET){
				RXErrorCount++;
				_DBG_("Rx error: ");
			}
		}

		/* ---------- RX Finished Process Descriptors ----------*/
		if ((int_stat & EMAC_INT_RX_FIN))
		{
			RxFinishedCount++;
			_DBG_("Rx finish");
		}

		/* ---------- Receive Done -----------------------------*/
		/* Note: All packets are greater than (TX_PACKET_SIZE + 4)
		 * will be ignore!
		 */
		if ((int_stat & EMAC_INT_RX_DONE))
		{
			/* Packet received, check if packet is valid. */
			if (EMAC_CheckReceiveIndex()){
				if (!EMAC_CheckReceiveDataStatus(EMAC_RINFO_LAST_FLAG)){
					goto rel;
				}
				// Get data size, trip out 4-bytes CRC field, note that length in (-1) style format
				RxLen = EMAC_GetReceiveDataSize() - 3;
				// Note that packet added 4-bytes CRC created by yourself
				if ((RxLen > (TX_PACKET_SIZE + 4)) || (EMAC_CheckReceiveDataStatus(EMAC_RINFO_ERR_MASK))) {
					/* Invalid frame, ignore it and free buffer */
					goto rel;
				}
				ReceiveLength = RxLen;
				// Valid Frame, just copy it
				RxDatbuf.pbDataBuf = (uint32_t *)gRxBuf;
				RxDatbuf.ulDataLen = RxLen;
				EMAC_ReadPacketBuffer(&RxDatbuf);
				PacketReceived = TRUE;

		rel:
				/* Release frame from EMAC buffer */
				EMAC_UpdateRxConsumeIndex();
			}
			_DBG_("Rx done");
			RxDoneCount++;
		}

		/*------------------- Transmit Underrun -----------------------*/
		if ((int_stat & EMAC_INT_TX_UNDERRUN))
		{
			TXUnderrunCount++;
			_DBG_("Tx under-run");
		}

		/*------------------- Transmit Error --------------------------*/
		if ((int_stat & EMAC_INT_TX_ERR))
		{
			TXErrorCount++;
			_DBG_("Tx error");
		}

		/* ----------------- TX Finished Process Descriptors ----------*/
		if ((int_stat & EMAC_INT_TX_FIN))
		{
			TxFinishedCount++;
			_DBG_("Tx finish");
		}

		/* ----------------- Transmit Done ----------------------------*/
		if ((int_stat & EMAC_INT_TX_DONE))
		{
			TxDoneCount++;
			_DBG_("Tx done");
		}
#if ENABLE_WOL
		/* ------------------ Wakeup Event Interrupt ------------------*/
		/* Never gone here since interrupt in this
		 * functionality has been disable, even if in wake-up mode
		 */
		if ((int_stat & EMAC_INT_WAKEUP))
		{
			WOLCount++;
		}
#endif
	}
}