📄 net_nic.c
字号:
{
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
#endif
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit rx (see Note #2). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* --------------------- VALIDATE PTR --------------------- */
if (ppkt == (void *)0) {
*perr = NET_NIC_ERR_NULL_PTR;
return;
}
/* --------------------- VALIDATE SIZE -------------------- */
if (size < NET_IF_FRAME_MIN_SIZE) {
*perr = NET_NIC_ERR_INVALID_SIZE;
return;
}
#endif
DM9000EP_EMAC_RxPkt(ppkt, size, perr); /* Rd Rx pkt from NIC. */
if (*perr != NET_NIC_ERR_NONE) {
return;
}
NET_CTR_STAT_INC(NetNIC_StatRxPktCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* DM9000EP_EMAC_RxPkt()
*
* Description : (1) Read network packet from NIC into buffer :
* (a) Read the Status Word and Length Word
* (b) Copy the packet data to the provided buffer
* (c) Discard the 4 byte FCS
* (d) Check for another recieved frame in SRAM, if present signal the Rx task
* (e) If no additional frames present, re-enable interrupts
* (f) Release the DM9000 Lock
*
* Argument(s) : ppkt Pointer to memory buffer to receive NIC packet.
* ---- Argument checked in NetNIC_RxPkt().
*
* size Number of packet frame octets to read into buffer.
* ---- Argument checked in NetNIC_RxPkt().
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully transmitted.
* DM9000_EMAC_ERR_RX_BUSY Receiver not ready.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_RxPkt().
*
* Note(s) : (1) rx_buf_rd_ix is the index of the next buffer to copy
* to a uc/TCP-IP stack buffer.
* (2) A local buffer is discarded when rx_buf_rd_ix is
* incremented by 1.
*********************************************************************************************************
*/
static void DM9000EP_EMAC_RxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
/* Copy the buffer to a uC/TCP-IP stack buffer */
Mem_Copy(ppkt, (void *)(&rx_buf[rx_buf_rd_ix]), rx_buf_size[rx_buf_rd_ix]);
CPU_CRITICAL_ENTER();
rx_buf_rd_ix = (rx_buf_rd_ix + 1) % NUM_RX_BUF; /* Discard the local buffer */
CPU_CRITICAL_EXIT();
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* NetNIC_RxPktDiscard()
*
* Description : Discard network packet from NIC to free NIC packet frames for new receive packets.
*
* Argument(s) : size Number of packet frame octets.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully discarded.
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
*
* Return(s) : none.
*
* Caller(s) : NetIF_RxTaskHandler().
*
* Note(s) : (1) NetNIC_RxPktDiscard() blocked until network initialization completes; perform NO action.
*
* (2) #### 'perr' may NOT be necessary (remove before product release if unnecessary).
*
* (3) Access to the DM9000 has been locked by the Rx task within the call to
* NetNIC_RxPktGetSize(). If an error occured during packet processing,
* this function may be called in place of NetNIC_RxPkt(). Either NetNIC_RxPkt()
* or this function are responsible for unlocking access to the DM9000 when complete.
*
* (4) A size equal to 0 unlocks the DM9000 and does not discard any internal frame data.
* This situation may occur if a reception error is detected within NetNIC_RxPktGetSize()
* and a DM9000 MAC reset must be performed. In this case, the internal SRAM pointers
* are reset and it is not necessary to discard any data in SRAM. There will not
* be any additional frames present in Rx SRAM, so a check does not need to be performed.
*********************************************************************************************************
*/
void NetNIC_RxPktDiscard (CPU_INT16U size,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit discard (see Note #1). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
if (size > 0) {
DM9000EP_EMAC_RxPktDiscard(size);
}
NET_CTR_ERR_INC(NetNIC_ErrRxPktDiscardedCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* DM9000EP_EMAC_RxPktDiscard()
*
* Description : Discard network packet from NIC to free NIC packet frames for new receive packets.
*
* Argument(s) : size The number of bytes to remove from the DM9000 Rx SRAM
*
* Returns : None
*
* Caller(s) : NetNIC_RxPktDiscard()
*
* Note(s) : (1) This functionality has been implemented within the ISR.
*********************************************************************************************************
*/
static void DM9000EP_EMAC_RxPktDiscard (CPU_INT16U size)
{
}
/*
*********************************************************************************************************
* NetNIC_TxPkt()
*
* Description : Transmit data packets from network driver layer to network interface card.
*
* Argument(s) : ppkt Pointer to memory buffer to transmit NIC packet.
*
* size Number of packet frame octets to write to frame.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully transmitted.
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
*
* - RETURNED BY NetNIC_TxPktDiscard() : -
* NET_ERR_TX Transmit error; packet discarded.
*
* Return(s) : none.
*
* Caller(s) : NetIF_Pkt_Tx().
*
* Note(s) : (1) NetNIC_TxPkt() blocked until network initialization completes; perform NO action.
*********************************************************************************************************
*/
void NetNIC_TxPkt (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
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit tx (see Note #1). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* --------------------- VALIDATE PTR --------------------- */
if (ppkt == (void *)0) {
NetNIC_TxPktDiscard(perr);
return;
}
#endif
DM9000EP_EMAC_TxPkt(ppkt, size, perr); /* Tx pkt to DM9000. */
if (*perr != NET_NIC_ERR_NONE) {
NetNIC_TxPktDiscard(perr);
return;
}
NET_CTR_STAT_INC(NetNIC_StatTxPktCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* DM9000EP_EMAC_TxPkt()
*
* Description : (1) Instruct DM9000 EMAC to send network packet :
* (a) Acquire the DM9000 lock
* (b) Disable DM9000 interrupts to prevent an ISR from accessing the bus
* and corrupting the transmit process.
* (c) Copy the frame data to the DM9000 Tx SRAM
* (d) Write the frame length, and issue a Tx command.
* This starts actual transmission of the packet.
* (e) Enable DM9000 interrupts
* (f) Unlock the DM9000 for access by other tasks
*
* Argument(s) : ppkt Pointer to memory buffer to transmit NIC packet.
* ---- Argument checked in NetNIC_TxPkt().
*
* size Number of packet frame octets to write to frame.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully transmitted.
* Return(s) : none.
*
* Caller(s) : NetNIC_TxPkt().
*
* Note(s) : None.
*********************************************************************************************************
*/
static void DM9000EP_EMAC_TxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
CPU_INT16U *p16;
CPU_INT16U sizetmp;
CPU_INT16U i;
*perr = NET_NIC_ERR_NONE; /* Assume no error */
p16 = (CPU_INT16U *)ppkt;
CPU_CRITICAL_ENTER();
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR); /* Disable interrupts */
CPU_CRITICAL_EXIT();
NetNIC_WrIx_8(DM9000EP_MWCMD); /* Prepare to write memory with auto-increment */
sizetmp = size;
size = (size + 1) / 2; /* Determine the number of 16 bit words to send */
for (i = 0; i < size; i++) {
NetNIC_WrData_16(*p16); /* Write word of data to register */
p16++; /* Increment packet pointer */
}
if (NetNIC_TxNQueued == 0) { /* If no packets are queued . . . */
NetNIC_WrReg_8(DM9000EP_TXPLH, (sizetmp >> 8) & 0xFF); /* . . .write high byte of length into register (0xFDh) */
NetNIC_WrReg_8(DM9000EP_TXPLL, sizetmp & 0xFF); /* . . .write low byte of length into register (0xFCh) */
NetNIC_WrReg_8(DM9000EP_TCR, TCR_TXREQ); /* . . .set a TX request command (0x02[0]) */
NetOS_NIC_TxRdySignal(); /* . . .and indicate that another packet can be tx'ed. */
} else if (NetNIC_TxNQueued == 1) { /* If one packet is queued . . . */
NetNIC_TxLenQueued = sizetmp; /* . . .then store length of packet. */
}
NetNIC_TxNQueued++; /* Increment number of queued packets */
CPU_CRITICAL_ENTER();
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR | IMR_PTI | IMR_PRI | IMR_ROI);/* Enable interrupts */
CPU_CRITICAL_EXIT();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -