📄 net_nic.c
字号:
* Description : Enable NIC interrupts.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : Net_Init().
*
* Notes : 1) This funciton is only called once by Net_Init() only after
* the TCP-IP stack is fully initialized and ready to begin
* processing frames.
*********************************************************************************************************
*/
void NetNIC_IntEn (NET_ERR *perr)
{ /* Enable Rx and Tx interrupts */
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR | IMR_PTI | IMR_PRI | IMR_ROI);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* DM9000EP_EMAC_RxEn()
*
* Description : Enable DM9000EP EMAC Receiver.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : DM9000EP_EMAC_Init().
*
* Notes : 1) The DM9000EP will automatically pad short frames to the minimum length (64 bytes)
* and compute the FCS (CRC) for the frame automatically.
*********************************************************************************************************
*/
static void DM9000EP_EMAC_RxEn (void)
{
NetNIC_WrReg_8(DM9000EP_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
}
/*
*********************************************************************************************************
* DM9000EP_Enter()
*
* Description : This function disables interrupts and acquires a semaphore intended to provide exclusive
* access to the DM9000EP hardware.
*
* Arguments : none.
*
* Notes : none.
*********************************************************************************************************
*/
static void DM9000EP_Enter (void)
{
DM9000_Lock(); /* Acquire the DM9000 access semaphore */
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR); /* Disable interrupts */
}
/*
*********************************************************************************************************
* DM9000EP_Exit()
*
* Description : This function enables interrupts and releases a semaphore intended to provide exclusive
* access to the DM9000EP hardware.
*
* Arguments : none.
*
* Notes : none.
*********************************************************************************************************
*/
static void DM9000EP_Exit (void)
{
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR | IMR_PTI | IMR_PRI | IMR_ROI);/* Enable interrupts */
DM9000_Unlock(); /* Release the lock semaphore */
}
/*
*********************************************************************************************************
* NetNIC_ISR_Handler()
*
* Description : (1) Decode ISR and signal the Rx task as appropriate. If the interrupt is
* a Tx complete interrupt, then uC/TCP-IP transmit function is signaled
* to indicate that the transmitter is available for use.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : This is an ISR
*
* Note(s) : (1) rx_buf_wr_ix is the index of the next buffer to fill
* (2) rx_buf_rd_ix is the index of the next buffer to copy to
* a uC/TCP-IP buffer.
* (3) If the write index is 1 less than the rd index, then
* no additional buffers are available.
*********************************************************************************************************
*/
void NetNIC_ISR_Handler (void)
{
CPU_INT08U int_status;
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR); /* Disable interrupts */
int_status = NetNIC_RdReg_8(DM9000EP_ISR) & 0x0F; /* Read the interrupt status register */
while (int_status != 0) {
NetNIC_WrReg_8(DM9000EP_ISR, int_status);
if ((int_status & ISR_PR) > 0) { /* Check for Rx complete interrupt */
NetNIC_Rx_ISR_Handler();
}
if ((int_status & ISR_PT) > 0) { /* Transmit complete interrupt */
NetNIC_Tx_ISR_Handler();
}
int_status = NetNIC_RdReg_8(DM9000EP_ISR) & 0x0F; /* Read the interrupt status register */
}
NetBSP_IntClr(); /* Clear processor level (AIC) interrupts */
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR | IMR_PTI | IMR_PRI | IMR_ROI);/* Enable interrupts */
}
/*
*********************************************************************************************************
* NetNIC_Rx_ISR_Handler()
*
* Description : Read packets from the DM9000 Rx SRAM and buffer them until the Rx task
* is ready to process them.
*
* Argument(s) : none.
*
* Return(s) : non.
*
* Caller(s) : NetNIC_ISR_Handler().
*
* Note(s) : (1) This is an ISR
* (2) When no buffers are available, the (write index + 1) will be equal to the
* read index. Wrap around must be taken into account.
* (3) When the buffer list is empty, the write index will be equal to the
* read index.
* (4) The last buffer in the list is not usable when the list is 1 buffer from
* being full. The Rx task will have to process some packets. New packets
* that arrive when the list is full are discarded.
*********************************************************************************************************
*/
static void NetNIC_Rx_ISR_Handler (void)
{
CPU_INT16U *prxbuf;
CPU_INT08U rx_rdy;
CPU_INT16U rx_size;
CPU_INT16U rx_size_cpy;
CPU_INT16U next_buf_wr_ix;
CPU_INT16U i;
NET_ERR err;
CPU_INT16U rx_status;
while (DEF_TRUE) {
rx_rdy = NetNIC_RdReg_8(DM9000EP_MRCMDX); /* Dummy read to determine if packet is ready */
rx_rdy = NetNIC_RdData_8() & 0xFF; /* Dont increment the read pointer, get ready flag */
if (rx_rdy == 0) { /* No new packets in Rx SRAM to process */
return;
}
if (rx_rdy > 1) { /* If an error occured, reset and exit ISR */
DM9000EP_Reset();
return;
}
NetNIC_WrIx_8(DM9000EP_MRCMD); /* Prepare to read with auto-increment */
rx_status = NetNIC_RdData_16(); /* Read status word [rx_rdy][RSR Reg Format] */
rx_size = NetNIC_RdData_16(); /* Read size word */
rx_size_cpy = rx_size; /* Store a copy of the received packet size */
rx_size = (rx_size + 1) / 2; /* Determine number of 16 bit words to read from Rx SRAM */
if ((rx_status & 0xBF00) > 0) { /* If any receive errors occured */
for (i = 0; i < rx_size; i++) {
(void)NetNIC_RdData_16(); /* Read two bytes from NIC */
}
DM9000EP_Reset(); /* Software Reset */
return;
}
next_buf_wr_ix = (rx_buf_wr_ix + 1) % NUM_RX_BUF; /* Determine the index of the next Rx buffer to fill */
/* The next buffer is not the same as the CURRENT buffer Ix */
if (next_buf_wr_ix != rx_buf_rd_ix) { /* If a buffer is available (Wr ix hasnt lapped Rd index) */
prxbuf = (CPU_INT16U *)(&rx_buf[rx_buf_wr_ix]); /* Obtain a 16 bit pointer to the destination Rx buffer */
rx_buf_size[rx_buf_wr_ix] = rx_size_cpy - 4; /* Store the size of the current packet, subtract FCS */
for (i = 0; i < rx_size; i++) {
*prxbuf++ = NetNIC_RdData_16(); /* Store two bytes of data in the destination buffer */
} /* this includes the FCS since it must be read from Rx SRAM */
rx_buf_wr_ix = next_buf_wr_ix; /* Increment the rx buffer index, wrap to 0 if necessary */
NetOS_IF_RxTaskSignal(&err); /* Signal the Rx task to process the recieved packet */
} else { /* Out of buffers, discard the packet */
for (i = 0; i < rx_size; i++) {
(void)NetNIC_RdData_16(); /* Read two bytes from NIC */
}
}
}
}
/*
*********************************************************************************************************
* NetNIC_Tx_ISR_Handler()
*
* Description : Inform uC/TCP-IP that the transmitter is ready to receive another
* Tx packet
*
* Argument(s) : none.
*
* Return(s) : non.
*
* Caller(s) : NetNIC_ISR_Handler().
*
* Note(s) : (1) This is an ISR
*********************************************************************************************************
*/
static void NetNIC_Tx_ISR_Handler (void)
{
if (NetNIC_TxNQueued == 2) { /* If two packets are queued . . . */
NetNIC_WrReg_8(DM9000EP_TXPLH, (NetNIC_TxLenQueued >> 8) & 0xFF); /* Write high byte of length into register */
NetNIC_WrReg_8(DM9000EP_TXPLL, NetNIC_TxLenQueued & 0xFF); /* Write low byte of length into register */
NetNIC_WrReg_8(DM9000EP_TCR, TCR_TXREQ); /* Set a TX request command */
NetNIC_TxLenQueued = 0; /* Length value is no longer valid. */
}
NetNIC_TxNQueued--; /* Decrement number of queued packets. */
NetOS_NIC_TxRdySignal();
}
/*
*********************************************************************************************************
* NetNIC_RxPktGetSize()
*
* Description : Get network packet size from NIC.
*
* Argument(s) : none.
*
* Return(s) : Size, in octets, of NIC's next network packet.
*
* Caller(s) : NetIF_RxTaskHandler().
*
* Note(s) : (1) The size has been stored from the ISR context within
* rx_buf_size.
* (2) rx_buf_rd_ix is the index of the next buffer to copy
* to a uc/TCP-IP stack buffer
*********************************************************************************************************
*/
CPU_INT16U NetNIC_RxPktGetSize (void)
{
CPU_INT16U size;
size = rx_buf_size[rx_buf_rd_ix];
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -