📄 net_nic.c
字号:
*
* 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) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit tx (see Note #1). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
EMAC_TxPkt(ppkt, size, perr); /* Hardware transmit routi */
if (*perr != NET_NIC_ERR_NONE) {
NetNIC_TxPktDiscard(perr);
return;
}
NET_CTR_STAT_INC(NetNIC_StatTxPktCtr);
}
/*
*********************************************************************************************************
* NetNIC_PhyRegRd()
*
* Description : (1) Read PHY register
*
* 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) : MRDD PHY register data.
*
* Caller(s) : EMAC_Init().
*
* Note(s) : none.
*********************************************************************************************************
*/
CPU_INT16U NetNIC_PhyRegRd (CPU_INT08U phy,
CPU_INT08U reg,
NET_ERR *perr)
{
CPU_INT08U retries;
retries = 0; /* Initialize retries to 0 */
MCMD = 0; /* Clear the Read COMMAND */
MADR = (phy << 8) | reg; /* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */
MCMD = MCMD_READ; /* Issue a Read COMMAND */
while ((MIND != 0) && (retries < PHY_RDWR_RETRIES)) { /* Read the Management Indicator register, MII busy if > 0 */
NetBSP_DlyMs(2); /* Delay while the read is in progress */
retries++;
}
if (retries >= PHY_RDWR_RETRIES) { /* If there are no retries remaining */
*perr = NET_PHY_ERR_REGRD_TIMEOUT; /* Return an error code if the PHY Read timed out */
} else {
*perr = NET_PHY_ERR_NONE;
}
return (MRDD); /* Return the content of the Management Read Data register */
}
/*
*********************************************************************************************************
* NetNIC_PhyRegWr()
*
* Description : (1) Write PHY register
*
* 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) : EMAC_Init().
*
* Note(s) : none.
*********************************************************************************************************
*/
void NetNIC_PhyRegWr (CPU_INT08U phy,
CPU_INT08U reg,
CPU_INT16U val,
NET_ERR *perr)
{
CPU_INT08U retries;
retries = 0; /* Initialize retries to 0 */
MCMD = MCMD_WRITE; /* Issue a Write COMMAND */
MADR = (phy << 8) | reg; /* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */
MWTD = val; /* Write the data to the Management Write Data register */
while ((MIND != 0) && (retries < PHY_RDWR_RETRIES)) { /* Read the Management Indicator register, MII busy if > 0 */
NetBSP_DlyMs(2); /* Delay while the read is in progress */
retries++;
}
if (retries >= PHY_RDWR_RETRIES) { /* If there are no retries remaining */
*perr = NET_PHY_ERR_REGWR_TIMEOUT; /* Return an error code if the PHY Read timed out */
} else {
*perr = NET_PHY_ERR_NONE;
}
}
/*
*********************************************************************************************************
*********************************************************************************************************
* LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 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;
}
/*
*********************************************************************************************************
* EMAC_Init()
*
* Description : (1) Initialize the LPC23XX/LPC24XX integrated EMAC
*
* (a) Initialize Registers
* (b) Initialize MAC Address
* (c) Initialize Auto Negotiation
* (d) Initialize Interrupts
* (e) Enable Receiver/Transmitter
*
* Argument(s) : perr a return error code indicating the result of initialization
* NET_NIC_ERR_NONE - success
* NET_NIC_ERR_NIC_OFF - link is down, or init failure occured
*
* Return(s) : none.
*
* Caller(s) : NetNIC_Init().
*
* Note(s) : (1) (a) Assumes MAC address to set has previously been initialized by
* (1) Application code for EMAC_MAC_ADDR_SEL_CFG
*
* (2) Interrupts MUST be enabled ONLY after ALL network initialization is complete (see also
* 'net.c Net_Init() Note #4d').
*
* (3) P1.6, ENET-TX_CLK, has to be set for EMAC to address a BUG in early revisions of the LPC2378.
* This pin must be set even if RMII is not used. The bug has been fixed on newer revisions of
* the chip and can be used for GPIO in some cicumstances. The Keil MCB2300 that this driver
* has been developed with contains the errata. RMII mode can be switched on and off from
* net_bsp.h by adjusting the EMAC_CFG_RMII macro accordingly.
*
* (4) The external PHY address is defined in net_phy.h as PHY_ADDR and should be set to
* the address of your external PHY on the MII bus. This value is shifted over to the
* left by 8 bits and written to the MAC_MADR register during PHY communications.
* Consult your PHY documentation for additional information on how to determine the
* address of your PHY.
*
* (5) The EMAC does not support the use of serial EEPROMS for automatically loading
* the MAC address after reset. Therefore, the macro EMAC_CFG_MAC_ADDR_SEL in
* net_bsp.h MUST be configured to EMAC_CFG_MAC_ADDR_SEL_CFG. This will allow
* the driver to load the Station Address registers with the data found in
* NetIF_MAC_Addr[], which is set by the user in app.c before calling Net_Init().
* If necessary, the user may take steps to read a serial EEPROM and then
* fill the content of NetIF_MAC_Addr[] accordingly.
*
* (6) Interrupts are enabled by uC/TCP-IP, Net_Init() calling NetNIC_IntEn().
*
* (7) Rx descriptors must be 32 bit aligned, Rx status descriptors must be 64 bit aligned.
*
* (8) The EMAC has 16KB of dedicated RAM located on the AHB2 bus at address 0x7FE00000,
* see net_bsp.h.
*********************************************************************************************************
*/
static void EMAC_Init (NET_ERR *perr)
{
CPU_INT16U i;
CPU_INT32U clk_freq;
NIC_RxNRdyCtr = 0; /* Initialize global Rx packet count to 0 */
NetNIC_LinkUp(); /* Set NetNIC_ConnStatus to TRUE by default (for uC/TCP-IP) */
/* ------- Reset and configure the EMAC registers --------- */
*perr = NET_NIC_ERR_NONE; /* Initialize the returned error code to NO Error */
PCONP |= (1 << 30); /* Enable the EMAC clock */
NetBSP_Phy_HW_Init(); /* Configure the I/O pins necessary for PHY communication */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -