📄 net_nic.c
字号:
* being transmitted (or waiting to be transmitted). Instead, the data is written
* to the buffer and the data length stored. This second buffer's data will be
* transmitted from NetNIC_ISR_Handler() when a transmit completed interrupt is
* received.
*********************************************************************************************************
*/
static void DM9000A_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_INT08U *p8;
CPU_INT16U *p16;
CPU_INT16U sizetmp;
DM9000A_ENTER();
p8 = (CPU_INT08U *)ppkt;
p16 = (CPU_INT16U *)ppkt;
sizetmp = size;
NetNIC_WrIx_8(DM9000A_MWCMD); /* Prepare to write memory with auto-increment */
#if DM9000A_IO_MODE == DM9000A_IO_8_BITS
(void)p16;
while (size > 0) {
NetNIC_WrData_8(*p8); /* Write byte of data to register */
p8++; /* Increment packet pointer */
size--;
}
#elif DM9000A_IO_MODE == DM9000A_IO_16_BITS
(void)p8;
while (size >= 2) {
NetNIC_WrData_16(*p16); /* Write word of data to register */
p16++; /* Increment packet pointer */
size -= 2;
}
if (size == 1) { /* If an odd number of packets need be transmitted */
NetNIC_WrData_16((CPU_INT16U)(*(CPU_INT08U *)p16) & 0x00FF);/* Write data to register */
}
#endif
#if DM9000A_TX_QUEUE_MODE == DM9000A_TX_QUEUE_TWO_PACKETS
if (NetNIC_TxNQueued == 0) { /* If no packets are queued . . . */
NetNIC_WrReg_8(DM9000A_TXPLL, sizetmp & 0xFF); /* . . .write low byte of length into register (0xFCh) */
NetNIC_WrReg_8(DM9000A_TXPLH, (sizetmp >> 8) & 0xFF); /* . . .write high byte of length into register (0xFDh) */
NetNIC_WrReg_8(DM9000A_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 */
#else
NetNIC_WrReg_8(DM9000A_TXPLL, sizetmp & 0xFF); /* Write low byte of length into register (0xFCh) */
NetNIC_WrReg_8(DM9000A_TXPLH, (sizetmp >> 8) & 0xFF); /* Write high byte of length into register (0xFDh) */
NetNIC_WrReg_8(DM9000A_TCR, TCR_TXREQ); /* Set a TX request command (0x02[0]) */
#endif
DM9000A_EXIT();
*perr = NET_NIC_ERR_NONE; /* Return no error to the stack */
}
/*
*********************************************************************************************************
* NetNIC_TxPktDiscard()
*
* Description : On any Transmit errors, set error.
*
* Argument(s) : pbuf Pointer to network buffer.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_ERR_TX Transmit error; packet discarded.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_TxPkt().
*********************************************************************************************************
*/
static void NetNIC_TxPktDiscard (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
NET_CTR_ERR_INC(NetNIC_ErrTxPktDiscardedCtr);
*perr = NET_ERR_TX;
}
/*
*********************************************************************************************************
* NetNIC_TxISR_Handler()
*
* Description : (1) Clear transmit interrupt &/or transmit errors :
*
* (a) Acknowledge transmit interrupt.
* (b) Post transmit FIFO empty signal.
*
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_ISR_Handler().
*
* Note(s) : (2) NetNIC_ISR_Handler() decodes DM9000 Transmit ISR & calls NetNIC_TxISR_Handler().
*********************************************************************************************************
*/
static void NetNIC_TxISR_Handler (void)
{
/* Interrupts are acknowledged when ISR read. */
/* ISR are previously read in NetNIC_ISR_Handler(). */
/* --------------- POST TX COMPLETE SIGNAL ---------------- */
NetOS_NIC_TxRdySignal();
}
/*
*********************************************************************************************************
* NetNIC_TxPktPrepare()
*
* Description : Prepare to 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_TxPktPrepare() blocked until network initialization completes; perform NO action.
*********************************************************************************************************
*/
void NetNIC_TxPktPrepare (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
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
DM9000A_EMAC_TxPktPrepare(ppkt, size, perr); /* Prepare to tx pkt to DM9000A. */
if (*perr != NET_NIC_ERR_NONE) {
NetNIC_TxPktDiscard(perr);
return;
}
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* DM9000A_EMAC_TxPktPrepare()
*
* Description : (1) Copy packet into local NIC TX buffer prior to the end of the transmission of the last
packet.
*
* 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_TxPktPrepare().
*********************************************************************************************************
*/
static void DM9000A_EMAC_TxPktPrepare (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* NetNIC_PhyRegRd()
*
* Description : Read PHY data value.
*
* Argument(s) : phy PHY address, normally 0.
* reg PHY register.
* perr Pointer to variable that will hold the return error code from this function
*
* Return(s) : Data read from PHY register.
*
* Caller(s) : DM9000A_EMAC_Init()
*
* Note(s) : Register ALWAYS reads 16-bit data values.
*********************************************************************************************************
*/
CPU_INT16U NetNIC_PhyRegRd (CPU_INT08U phy,
CPU_INT08U reg,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
CPU_INT16U reg_val;
CPU_CRITICAL_ENTER();
NetNIC_WrReg_8(DM9000A_EPAR, phy | reg); /* Write PHY register offset into register (0x0C) */
NetNIC_WrReg_8(DM9000A_EPCR, EPCR_ERPRR | EPCR_EPOS); /* Write PHY + READ command into register (0x0B) */
CPU_CRITICAL_EXIT();
NetBSP_DlyU(100);
CPU_CRITICAL_ENTER();
NetNIC_WrReg_8(DM9000A_EPCR, EPCR_EPOS); /* Write PHY command into register (0x0B) */
reg_val = NetNIC_RdReg_8(DM9000A_EPDRL); /* Read low byte from register (0x0D) */
reg_val |= NetNIC_RdReg_8(DM9000A_EPDRH) << 8; /* Read high byte from register (0x0E) */
CPU_CRITICAL_EXIT();
*perr = NET_ERR_NONE;
return (reg_val);
}
/*
*********************************************************************************************************
* NetNIC_PhyRegWr()
*
* Description : Write PHY data value.
*
* Argument(s) : phy PHY address, normally 0.
* reg PHY register.
* val Data to write to PHY register.
* perr Pointer to variable that will hold the return error code from this function :
*
* Return(s) : None.
*
* Caller(s) : None.
*
* Note(s) : Register ALWAYS writes 16-bit data values.
*********************************************************************************************************
*/
void NetNIC_PhyRegWr (CPU_INT08U phy,
CPU_INT08U reg,
CPU_INT16U val,
NET_ERR *perr)
{
CPU_INT08U val_high;
CPU_INT08U val_low;
val_high = (CPU_INT08U)(val >> 8);
val_low = (CPU_INT08U)(val & 0x0F);
NetNIC_WrReg_8(DM9000A_EPAR, phy | reg); /* Write PHY regis
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -