📄 net_nic.c
字号:
if (link_speed == NET_PHY_SPD_100) {
reg_val |= MACB_NCFGR_SPD; /* If 100mbps, set the 100mbps bit in reg_val */
}
if (link_duplex == NET_PHY_DUPLEX_FULL) {
reg_val |= MACB_NCFGR_FD; /* If Full Duplex, set the FD bit in reg_val */
}
/* Write the Link speed and duplex values to the */
MACB_NCFGR = reg_val; /* EMAC control network configuration register */
}
/*
*********************************************************************************************************
* NetNIC_ConnStatusGet()
*
* Description : Get NIC's network connection status.
*
* (1) Obtaining the NIC's network connection status is encapsulated in this function for the
* possibility that obtaining a NIC's connection status requires a non-trivial procedure.
*
*
* Argument(s) : none.
*
* Return(s) : NIC network connection status :
*
* DEF_OFF Network connection DOWN.
* DEF_ON Network connection UP.
*
* Caller(s) : NetIF_Pkt_Tx().
*********************************************************************************************************
*/
CPU_BOOLEAN NetNIC_ConnStatusGet (void)
{
return (NetNIC_ConnStatus);
}
/*
*********************************************************************************************************
* NetNIC_ISR_Handler()
*
* Description : (1) Decode ISR & call appropriate ISR handler :
*
* (a) MACB Receive Buffer Not Available ISR NetNIC_RxPktDiscard().
* (b) MACB Receive ISR NetNIC_RxISR_Handler().
* (c) MACB Transmit ISR NetNIC_TxISR_Handler().
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : This is an ISR
*
* Note(s) : (3) The functions NetNIC_IntEnter() and NetNIC_IntClr() inform the external interrupt
* controller that the ISR is being entered and clear the interrupt source(s) on the
* external interrupt controller, respectively. These MUST be developer-implemented in
*
* \<Your Product Application>\net_isr.c
*
* where
* <Your Product Application> directory path for Your Product's Application.
*********************************************************************************************************
*/
void NetNIC_ISR_Handler (void)
{
volatile CPU_INT32U isr_status;
CPU_INT32U rsr_status;
CPU_INT32U tsr_status;
NetNIC_IntEnter();
/* Read the interrupt status register */
isr_status = MACB_ISR; /* This read clears the bits in the ISR register */
/* Check for 'frame received' interrupt */
rsr_status = MACB_RSR; /* Read the Receive Status Register */
if ((rsr_status & MACB_RSR_REC) == MACB_RSR_REC) { /* Check if we have recieved a frame */
NetNIC_RxISR_Handler(); /* Call the Rx Handler */
MACB_RSR = MACB_RSR_REC; /* Clear the Receive Status Register REC bit */
}
/* Check for 'transmit complete' interrupt */
tsr_status = MACB_TSR; /* Read the Transmit Status Register */
if ((tsr_status & MACB_TSR_COMP) == MACB_TSR_COMP) { /* Check if we have completed transmitting a frame */
MACB_TSR = MACB_TSR_COMP; /* Clear the Transmit Status Register COMP bit */
NetNIC_TxISR_Handler(); /* Call the Tx Handler */
}
/* If a transmit buffer was read, clear the Used bit */
if ((tsr_status & MACB_TSR_UBR) == MACB_TSR_UBR) { /* Check if 'Used Bit Read' is set */
MACB_TSR = MACB_TSR_UBR; /* Clear 'Used Bit Read' */
}
if ((rsr_status & (MACB_RSR_BNA | MACB_RSR_OVR)) > 0) { /* Clear all receiver errors if they have occured */
MACB_RSR = (MACB_RSR_BNA | MACB_RSR_OVR);
NetNIC_RxISR_Handler(); /* If any error occured, we call NetNIC_RxISR_Handler() */
} /* to ensure that we havent missed any events */
NetNIC_IntClr(); /* Clr int ctrl'r int (see Note #3). */
}
/*
*********************************************************************************************************
* NetNIC_RxPktGetSize()
*
* Description : Get network packet size from NIC.
*
* Argument(s) : none.
*
* Return(s) : Size, in octets, of next frame to be read from the EMAC buffers
*
* Caller(s) : NetIF_RxTaskHandler()
*
* Notes : 1) On occassion, it is possible to have frame fragments in the descriptor list. As mentioned
* above in Note 1) of NIC_GetNRdy(), should 2 start of frame descriptors be found without
* corresponding EOF descriptors , then softwares must free the rogue descriptors. This
* function will free rogue descriptors if they are found while searching for the next
* frame and its corresponding size
*
* 2) This routine causes the TCP/IP stack to service received frames in a random order.
* In other words, frames that arrive before other frames are not guarrenteed to be
* serviced first. This is a result of always searching through the descriptor list from
* top to bottom, and not from an expected start point and wrapping around. The benefit to
* this approach however is that you dont have to keep state information about where the
* next expected SOF flag will be. Nor do you have check if the expected SOF pointer is
* correct and make changes should Note 1) effect the correctness of that pointer.
*
* 3) There MUST be at least 1 SOF / EOF combination in the descriptor list, otherwise
* interrupt generation would not have occured since interrupt generation takes place
* after the complete frame has been trasferred via DMA to RAM.
*********************************************************************************************************
*/
CPU_INT16U NetNIC_RxPktGetSize (void)
{ /* WARNING: No code should never be inserted between a */
CPU_INT16U size; /* ptr increment, and the following end of list check */
NIC_BUF_DESC *search_ptr; /* This function contains several pointer increments */
NIC_CurrentFrameStart = (NIC_BUF_DESC *)0; /* Initialize the Current Frame Start pointer to NULL */
NIC_CurrentFrameEnd = (NIC_BUF_DESC *)0; /* Initialize the Current Frame Start pointer to NULL */
search_ptr = NIC_ExpectedFrameStart; /* Begin searching from the expected SOF descriptor */
while (((search_ptr->status & EMAC_RXBUF_SOF_MASK) == 0) || /* While the expected SOF is NOT pointing to a software */
((search_ptr->addr & EMAC_RXBUF_SW_OWNED) == 0)) { /* owned SOF descriptor (precautionary code) */
search_ptr++; /* Move the next descriptor in the list */
if (search_ptr == NIC_RxBufDescPtrEnd) { /* If we are at the end of the list */
search_ptr = NIC_RxBufDescPtrStart; /* Wrap around to the beginning */
}
}
/* We now point to a SOF desc that software ownes */
NIC_CurrentFrameStart = search_ptr; /* Save the location of the SOF descriptor */
while (((search_ptr->status & EMAC_RXBUF_EOF_MASK) == 0) || /* Loop until we find the matching EOF descriptor */
((search_ptr->addr & EMAC_RXBUF_SW_OWNED) == 0)) { /* that is software owned */
search_ptr++;
if (search_ptr == NIC_RxBufDescPtrEnd) { /* If we are at the end of the list */
search_ptr = NIC_RxBufDescPtrStart; /* Wrap around to the beginning */
}
if (((search_ptr->status & EMAC_RXBUF_SOF_MASK) > 0) && /* If while searching for EOF we find another SW owned */
((search_ptr->addr & EMAC_RXBUF_SW_OWNED) > 0)) { /* SOF, then we must free the incomplete frame desc's */
while (NIC_CurrentFrameStart != search_ptr) { /* Loop from the last found SOF, to the newly found SOF */
NIC_CurrentFrameStart->addr &= ~EMAC_RXBUF_SW_OWNED; /* Free a descriptor belonging to the incomplete frame */
NIC_CurrentFrameStart++; /* Point to the next descriptor that needs to be freed */
if (NIC_CurrentFrameStart == NIC_RxBufDescPtrEnd) { /* If we are at the end of the descriptor list */
NIC_CurrentFrameStart = NIC_RxBufDescPtrStart; /* Wrap around to the beginning of the list */
}
}
/* Done freeing incomplete frame descriptors */
NIC_CurrentFrameStart = search_ptr; /* However, we must now save the new SOF location */
}
}
/* We now point to a SW owned EOF descriptor */
NIC_CurrentFrameEnd = search_ptr; /* Save the location of the EOF descriptor */
NIC_ExpectedFrameStart = (search_ptr + 1); /* The next expected SOF is in the next descriptor */
/* We store this information now to improve search */
/* performance on the next NetNIC_RxPktGetSize() */
if (NIC_ExpectedFrameStart == NIC_RxBufDescPtrEnd) { /* If the next expected frame points after the end of */
NIC_ExpectedFrameStart = NIC_RxBufDescPtrStart; /* the list, wrap back around to the beginning */
}
/* Retrieve the frame size for the frame to be read */
/* next from the buffers using the 'Current' pointers */
size = NIC_CurrentFrameEnd->status & EMAC_RXBUF_LEN_MASK;
return (size);
}
/*
*********************************************************************************************************
* NetNIC_RxPkt()
*
* Description : Read network packet from NIC into buffer.
*
* Argument(s) : ppkt Pointer to memory buffer to receive NIC packet.
*
* size Number of packet frame octets to read into buffer.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully read.
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
* NET_NIC_ERR_NULL_PTR Argument 'ppkt' passed a NULL pointer.
* NET_NIC_ERR_INVALID_SIZE Invalid size.
*
* Return(s) : none.
*
* Caller(s) : NetIF_RxTaskHandler().
*
* Note(s) : 1) NetNIC_RxPkt() blocked until network initialization completes; perform NO action.
*********************************************************************************************************
*/
void NetNIC_RxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -