/** * @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++; }
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(); } } }
/** * Brief Receive Error Interrupt Callback function * 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 */ void RxError_UsrCBS(void) { if (EMAC_CheckReceiveDataStatus(EMAC_RINFO_RANGE_ERR) == RESET){ RXErrorCount++; _DBG_("Rx error: "); } }
int _EMAC_CheckReceiveDataStatus(uint8_t * args) { uint8_t * arg_ptr; uint32_t ulRxStatType; if ((arg_ptr = (uint8_t *) strtok(NULL, " ")) == NULL) return 1; ulRxStatType = (uint32_t) strtoul((char *) arg_ptr, NULL, 16); sprintf((char *) str, "%x\r\n", (unsigned int) EMAC_CheckReceiveDataStatus(ulRxStatType)); writeUSBOutString(str); return 0; }
void ENET_IRQHandler( void ) { uint32_t ulInterruptCause; extern volatile portBASE_TYPE xInsideISR; struct pbuf *p; struct eth_hdr *pxHeader; xInsideISR++; while( ( ulInterruptCause = LPC_EMAC->IntStatus ) != 0 ) { /* Clear the interrupt. */ LPC_EMAC->IntClear = ulInterruptCause; /* Clear fatal error conditions. */ if( ( ulInterruptCause & EMAC_INT_TX_UNDERRUN ) != 0U ) { LPC_EMAC->Command |= EMAC_CR_TX_RES; } if( ( ulInterruptCause & EMAC_INT_RX_DONE ) != 0UL ) { /* A packet has been received. */ if( EMAC_CheckReceiveIndex() != FALSE ) { if( EMAC_CheckReceiveDataStatus( EMAC_RINFO_LAST_FLAG ) == SET ) { /* move received packet into a new pbuf */ p = prvLowLevelInput(); /* no packet could be read, silently ignore this */ if( p != NULL ) { /* points to packet payload, which starts with an Ethernet header */ pxHeader = p->payload; switch( htons( pxHeader->type ) ) { /* IP or ARP packet? */ case ETHTYPE_IP: case ETHTYPE_ARP: /* Full packet send to tcpip_thread to process */ configASSERT( pxNetIfInUse ); if( pxNetIfInUse->input( p, pxNetIfInUse ) != ERR_OK ) { LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_input: IP input error\n" ) ); pbuf_free(p); p = NULL; } break; default: pbuf_free( p ); p = NULL; break; } } else { configASSERT( ( volatile void * ) NULL ); } } /* Release the frame. */ EMAC_UpdateRxConsumeIndex(); } } if( ( ulInterruptCause & EMAC_INT_TX_DONE ) != 0UL ) { /* Nothing to do here. */ } } xInsideISR--; }
/*********************************************************************//** * @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 } }