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(); } } }
/* 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); }
/** * @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++; }
/** * 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; }
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; }
// 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); }
/*********************************************************************//** * @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 } }