📄 net_nic.c
字号:
CPU_CRITICAL_ENTER(); /* See 'DM9000 REGISTERS Note #5b'. */
NetNIC_WrReg_8(DM9000A_IMR, IMR_PAR);
NetNIC_WrReg_8(DM9000A_RCR, 0x00); /* RX disable */
CPU_CRITICAL_EXIT();
}
/*
*********************************************************************************************************
* NetNIC_ISR_Handler()
*
* Description : (1) Decode ISR & call appropriate ISR handler :
*
* (a) DM9000A Receive Buffer Not Available ISR NetNIC_RxPktDiscard().
* (b) DM9000A Receive ISR NetNIC_RxISR_Handler().
* (c) DM9000A Transmit ISR NetNIC_TxISR_Handler().
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : This is an ISR
*
* Note(s) : (2) DM9000A ISR MUST call NetNIC_ISR_Handler() & MUST be developer-implemented in
*
* \<Your Product Application>\net_isr*.*
*
* where
* <Your Product Application> directory path for Your Product's Application.
*
* (3) This function clears the interrupt source(s) on an external interrupt controller &, if
* ENABLED, 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)
{
CPU_INT08U int_status;
CPU_INT08U int_mask;
int_status = NetNIC_RdReg_8(DM9000A_ISR) & 0x3F; /* Read the interrupt status register */
int_mask = NetNIC_RdReg_8(DM9000A_IMR); /* Read the interrupt mask register */
if (int_status & ~int_mask) { /* Clear any interrupt not handled */
NetNIC_WrReg_8(DM9000A_ISR, int_status & ~int_mask);
}
int_status &= int_mask; /* AND status with mask to determine ints. to handle */
if ((int_status & ISR_PR) == ISR_PR) { /* Check for 'packet received' interrupt. */
NetNIC_RxISR_Handler();
NetNIC_WrReg_8(DM9000A_ISR, ISR_PR); /* Clear packet received interrupt. */
}
if ((int_status & ISR_PT) == ISR_PT) { /* Check for 'packet transmitted' interrupt. */
#if DM9000A_TX_QUEUE_MODE == DM9000A_TX_QUEUE_TWO_PACKETS
if (NetNIC_TxNQueued == 2) { /* If two packets are queued . . . */
NetNIC_WrReg_8(DM9000A_TXPLL, NetNIC_TxLenQueued & 0xFF); /* Write low byte of length into register */
NetNIC_WrReg_8(DM9000A_TXPLH, (NetNIC_TxLenQueued >> 8) & 0xFF); /* Write high byte of length into register */
NetNIC_WrReg_8(DM9000A_TCR, TCR_TXREQ); /* Set a TX request command */
NetNIC_TxLenQueued = 0; /* Length value is no longer valid. */
}
NetNIC_TxNQueued--; /* Decrement number of queued packets. */
#endif
NetNIC_TxISR_Handler();
NetNIC_WrReg_8(DM9000A_ISR, ISR_PT); /* Clear packet transmitted interrupt. */
}
if (int_status & (ISR_ROS | ISR_ROO)) { /* Clear all receiver errors. */
if (int_status & ISR_ROS) {
NetNIC_WrReg_8(DM9000A_ISR, ISR_ROS); /* Clear receive counter overflow interrupt. */
}
if (int_status & ISR_ROO) {
NetNIC_WrReg_8(DM9000A_ISR, ISR_ROO); /* Clear receive overflow interrupt. */
}
}
NetBSP_IntClr();
}
/*
*********************************************************************************************************
* NetNIC_RxISR_Handler()
*
* Description : Signal Network Interface Receive Task that a receive packet is available.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_ISR_Handler().
*
* Note(s) : (1) NetNIC_ISR_Handler() decodes DM9000A Receive ISR & calls NetNIC_RxISR_Handler().
*********************************************************************************************************
*/
static void NetNIC_RxISR_Handler (void)
{
NET_ERR err;
/* Interrupts are acknowledged when ISR read. */
/* ISR are previously read in NetNIC_ISR_Handler(). */
NetOS_IF_RxTaskSignal(&err);
}
/*
*********************************************************************************************************
* 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().
*********************************************************************************************************
*/
CPU_INT16U NetNIC_RxPktGetSize (void)
{
CPU_INT16U size;
size = DM9000A_EMAC_RxPktGetSize();
return (size);
}
/*
*********************************************************************************************************
* DM9000A_EMAC_RxPktGetSize()
*
* Description : (1) Get network packet size from NIC :
* (a) Read packet frame size.
*
* Argument(s) : none.
*
* Return(s) : Size, in octets, of NIC's next network packet.
*
* Caller(s) : NetNIC_RxPktGetSize().
*
* Note(s) : (1) See 'DM9000 EMAC RECEIVE BUFFER DESCRIPTOR' for packet frame format.
*
* (2) The first byte of the 16-bit status is checked:
* (a) if it is 0, the no packet has been received;
* (b) if it is 1, then a packet is in the SRAM;
* (c) if it is neither 0 nor 1, then an error has occurred and the NIC will be
* restarted.
*
* (3) The length is decreased by 4 to account for the 4-byte FCS. Though these bytes will
* not be written into a TCP/IP buffer, they must still be removed (i.e., read) from
* the DM9000A SRAM.
*********************************************************************************************************
*/
static CPU_INT16U DM9000A_EMAC_RxPktGetSize (void)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
CPU_INT16U size;
CPU_INT16U status;
NET_ERR err;
DM9000A_ENTER();
err = NET_NIC_ERR_NONE;
size = 0; /* Fall-through value */
status = NetNIC_RdReg_8(DM9000A_MRCMDX); /* Dummy read to determine if packet is ready (0xF0) */
status = NetNIC_RdData_8() & 0xFF; /* Read status byte (0xF0) */
if (status == 0x00) { /* If first byte of status is 0x00, packet is not in SRAM. */
size = 0;
/* If first byte of status is 0x01 */
} else if (status == 0x01) { /* then a packet has been received and is in SRAM */
#if DM9000A_IO_MODE == DM9000A_IO_8_BITS /* 8 bits of data is read per access */
NetNIC_WrReg_16(DM9000A_MRCMD); /* Prepare to read with auto-increment (0xF2) */
status = NetNIC_RdData_8(); /* Read lower byte of status word (0xF2) */
status |= (CPU_INT16U)NetNIC_RdData_8() << 8; /* Read upper byte of status word (0xF2) */
size = NetNIC_RdData_8(); /* Read lower byte of size word (0xF2) */
size |= (CPU_INT16U)NetNIC_RdData_8() << 8; /* Read upper byte of size word (0xF2) */
size -= 4; /* Decrease by 4 to account for FCS */
#elif DM9000A_IO_MODE == DM9000A_IO_16_BITS /* 16 bits of data are read per access */
NetNIC_WrIx_8(DM9000A_MRCMD); /* Prepare to read with auto-increment (0xF2) */
status = NetNIC_RdData_16(); /* Read status word (0xF2) */
size = NetNIC_RdData_16() - 4; /* Read size word and decrement by 4 (0xF2) */
#endif
status >>= 8; /* Upper byte of status is copy of RSR */
if (size > 1536) { /* If length is greater than longest expected packet . . . */
DM9000A_Restart(&err); /* . . .then reset DM9000A . . . . . . */
size = 0; /* . . .and return size of 0. */
} else if (status & RSR_ERRORS) { /* If there are receive errors . . . . . . */
size = 0; /* . . .return size of 0. */
} else {
;
}
/* If first byte of status is neither 0x00 or 0x01 */
} else { /* . . .then an error has occurred */
DM9000A_Restart(&err); /* . . .so reset DM9000A */
size = 0; /* . . .and return size of 0. */
}
DM9000A_EXIT();
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
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
DM9000A_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;
}
/*
*********************************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -