📄 net_nic.c
字号:
/*
*********************************************************************************************************
* uC/TCP-IP
* The Embedded TCP/IP Suite
*
* (c) Copyright 2003-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/TCP-IP is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/TCP-IP in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to help
* you experience uC/TCP-IP. The fact that the source code is provided does
* NOT mean that you can use it without paying a licensing fee.
*
* Network Interface Card (NIC) port files provided, as is, for FREE and do
* NOT require any additional licensing or licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* NETWORK INTERFACE CARD
*
* Davicom DM9000EP
*
* Filename : net_nic.h
* Version : V1.90
* Programmer(s) : EHS
*********************************************************************************************************
* Note(s) : (1) Supports the Davicom DM9000EP Ethernet Controller
*
* Davicom: (http://www.davicom.com.tw)
*
* (2) REQUIREs Ethernet Network Interface Layer located in the following network directory :
*
* \<Network Protocol Suite>\IF\Ether\
*
* where
* <Network Protocol Suite> directory path for network protocol suite.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define NET_NIC_MODULE
#include <net.h>
#include <bsp.h>
/*
*********************************************************************************************************
* CONSTANTS
*********************************************************************************************************
*/
#define NUM_RX_BUF (NET_BUF_CFG_NBR_SMALL + NET_BUF_CFG_NBR_LARGE)
#define RX_BUF_SIZE 1536
/*
*********************************************************************************************************
* GLOBALS
*********************************************************************************************************
*/
CPU_INT16U rx_buf_rd_ix; /* Index of buffer next to be copied to uC/TCP-IP buffer */
CPU_INT16U rx_buf_wr_ix; /* Index of buffer next to be filled from ISR */
CPU_INT08U rx_buf[NUM_RX_BUF][RX_BUF_SIZE];
CPU_INT16U rx_buf_size[NUM_RX_BUF];
static CPU_INT08U NetNIC_TxNQueued; /* Indicates how many packets are queued . . . */
/* . . .in the DM9000E's buffers (up to 2): . . . */
/* . . .a value of 1 = one packet tx'ed; and */
/* . . .a value of 2 = one packet tx'ed, one waiting to tx. */
static CPU_INT16U NetNIC_TxLenQueued; /* Holds the length of the queued packet waiting for tx. */
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void NetNIC_TxPktDiscard (NET_ERR *perr);
/* ---------------- DM9000EP EMAC FNCTS ------------------- */
static void DM9000EP_Init (NET_ERR *perr);
static void DM9000EP_Reset (void);
/* ---------------- DM9000EP EMAC RX FNCTS ---------------- */
static void DM9000EP_EMAC_RxEn (void);
static void DM9000EP_Enter (void);
static void DM9000EP_Exit (void);
static void DM9000EP_EMAC_RxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr);
static void DM9000EP_EMAC_RxPktDiscard (CPU_INT16U size);
/* ---------------- DM9000EP EMAC TX FNCTS ---------------- */
static void DM9000EP_EMAC_TxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr);
static CPU_INT32U DM9000EP_Info (void);
static void NetNIC_Tx_ISR_Handler (void);
static void NetNIC_Rx_ISR_Handler (void);
/*
*********************************************************************************************************
* NetNIC_Init()
*
* Description : (1) Initialize Network Interface Card :
* (a) Perform NIC Layer OS initialization
* (b) Initialize NIC status
* (c) Initialize NIC statistics & error counters
* (d) Initialize DM9000EP
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : Net_Init().
*********************************************************************************************************
*/
void NetNIC_Init (NET_ERR *perr)
{
/* ----------------- PERFORM NIC/OS INIT ------------------ */
NetOS_NIC_Init(perr); /* Create NIC objs. */
if (*perr != NET_OS_ERR_NONE) {
return;
}
/* ------------------- INIT NIC STATUS -------------------- */
NetNIC_ConnStatus = DEF_OFF;
/* --------------- INIT NIC STAT & ERR CTRS --------------- */
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
NetNIC_StatRxPktCtr = 0;
NetNIC_StatTxPktCtr = 0;
#endif
#if (NET_CTR_CFG_ERR_EN == DEF_ENABLED)
NetNIC_ErrRxPktDiscardedCtr = 0;
NetNIC_ErrTxPktDiscardedCtr = 0;
#endif
/* ---------------------- INIT DM9000 --------------------- */
DM9000EP_Init(perr);
}
/*
*********************************************************************************************************
* DM9000EP_Init()
*
* Description : Initialize & start DM9000 :
* (1) Initialize additional OS resources
* (2) Initialize host processor BUS interface for the DM9000EP
* (3) Initialize PHY.
* (4) Initiate auto-negotiation.
* (5) Initialize MAC
* (6) Initialize host processor interrupt controller
* (7) Enable receiver.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_Init()
*
* Note(s) : (1) (a) Assumes MAC address to set has previously been initialized by
*
* (1) DM9000EP's EEPROM for DM9000_EMAC_MAC_ADDR_SEL_EEPROM
* (2) Application code for DM9000_EMAC_MAC_ADDR_SEL_CFG
*
* (2) Transmitter is always enabled
*
* (3) Interrupts MUST be enabled ONLY after ALL network initialization is complete (see also
* 'net.c Net_Init() Note #4c').
*********************************************************************************************************
*/
static void DM9000EP_Init (NET_ERR *perr)
{
CPU_INT16U i;
CPU_INT16U reg_val;
CPU_INT32U info;
CPU_INT08U retries;
rx_buf_wr_ix = 0; /* Initialize global write buffer index to 0 */
rx_buf_rd_ix = 0; /* Initialize global read buffer index to 0 */
for (i = 0; i < NUM_RX_BUF; i++) {
rx_buf_size[i] = 0; /* Initialize the buffer size array to 0 for debugging */
}
/* --------------- Initialize OS interface ---------------- */
NetBSP_OS_X_Init(); /* Initialize the DM9000 exclusive access semaphore */
/* ----- Configure processor / DM9000EP HW interface ------ */
NetBSP_NIC_HW_Init(); /* Initialize the processor I/O */
/* ------------ Reset the DM9000EP MAC and PHY ------------ */
NetNIC_WrReg_8(DM9000EP_GPR, GPR_PHYPD); /* Power down the PHY */
NetNIC_WrReg_8(DM9000EP_GPR, GPR_PHYPU); /* Power up the PHY */
/* --- Reset twice as suggested by the DM9000 datasheet --- */
NetNIC_WrReg_8(DM9000EP_NCR, NCR_RST | NCR_LBK_MAC); /* Perform a reset, loopback enabled to internal MAC */
NetBSP_DlyU(50); /* Delay for a short while (20uS required) */
NetNIC_WrReg_8(DM9000EP_NCR, NCR_RST | NCR_LBK_MAC); /* Perform a reset, loopback enabled to internal MAC */
NetBSP_DlyU(50); /* Delay for a short while (20uS required) */
NetNIC_WrReg_8(DM9000EP_NCR, NCR_LBK_NORMAL); /* Put the NIC into Normal Operation Mode (no loopback) */
retries = 100; /* Reset the PHY (not the same powering down and then up) */
NetNIC_PhyRegWr(DM9000EP_PHY, DM9000EP_PHY_BMCR, PHY_BMCR_RESET, perr);
do { /* Loop until reset completes or retries expired */
retries--;
reg_val = NetNIC_PhyRegRd(DM9000EP_PHY, DM9000EP_PHY_BMCR, perr);
NetBSP_DlyM(2); /* Delay 2ms */
} while (((reg_val & PHY_BMCR_RESET) > 0) && (retries > 0));
/* ------------ Test DM9000EP communication --------------- */
info = DM9000EP_Info(); /* Probe DM9000EP indentifier registers */
if (info != 0x90000A46) { /* If value is not as expected, */
*perr = NET_NIC_ERR_NIC_OFF; /* then assign NET_NIC_ERR_NIC_OFF error */
return; /* and return */
}
/* ------------ Start Auto-Negotiation process ------------ */
i = 100; /* 100 Retries to see if Auto Negotiation is complete */
NetNIC_PhyRegWr(DM9000EP_PHY, DM9000EP_PHY_ANAR, 0x05E1, perr); /* Advertise flow control support */
NetNIC_PhyRegWr(DM9000EP_PHY, DM9000EP_PHY_BMCR, 0x1200, perr); /* Enable and Restart auto-negotiation */
do { /* Wait until auto-negotiation completes or retries expired */
i--;
reg_val = NetNIC_PhyRegRd(DM9000EP_PHY, DM9000EP_PHY_BMSR, perr);
NetBSP_DlyM(50);
} while (((reg_val & PHY_BMSR_AN_COMP) == 0) && (i > 0));
/* ------------ Configure Operating Parameters ------------ */
NetNIC_WrReg_8(DM9000EP_TCR, 0); /* Clear TX control register */
NetNIC_WrReg_8(DM9000EP_BPTR, BPTR_BPHW(3) | BPTR_JPT_200u); /* Configure flow control overflow threshold */
NetNIC_WrReg_8(DM9000EP_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* Configure flow control low / high thresholds */
NetNIC_WrReg_8(DM9000EP_FCR, FCR_TXPEN | FCR_FLCE | FCR_BKPM); /* Enable flow control, backpressure = off */
NetNIC_WrReg_8(DM9000EP_SMCR, 0); /* Ensure Special Mode register is cleared */
NetNIC_WrReg_8(DM9000EP_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* Clear the Wakeup and Tx Status bits */
/* ------------ Initialize device MAC address ------------- */
#if (EMAC_CFG_MAC_ADDR_SEL == EMAC_MAC_ADDR_SEL_EEPROM) /* Fetch MAC from EEPROM */
for (i = 0; i < 6; i++) {
NetIF_MAC_Addr[i] = NetNIC_RdReg_8(DM9000EP_PAR0 + i);
}
#else /* MAC address is application-configured. */
for (i = 0; i < 6; i++) {
NetNIC_WrReg_8(DM9000EP_PAR0 + i, NetIF_MAC_Addr[i]);
}
#endif
NetIF_MAC_AddrValid = DEF_YES; /* Assume MAC address is valid. */
for (i = 0; i < 7; i++) { /* Default the multicast address registers */
NetNIC_WrReg_8(DM9000EP_MAR0 + i, 0);
}
NetNIC_WrReg_8(DM9000EP_MAR0 + 7, 0x80); /* Default the multicast address registers */
/* ------------ Enable host interrupt controller ---------- */
NetBSP_IntInit(); /* Configure and enable AIC, not DM9000 interrupts */
/* EMAC int's are enabled by NetInit -> NetNIC_IntEn */
NetNIC_WrReg_8(DM9000EP_ISR, ISR_ALL); /* Clear all DM9000 interrupt sources */
NetNIC_WrReg_8(DM9000EP_IMR, IMR_PAR); /* Disable all interrupts (Enabled later by uC/TCP-IP) */
/* SRAM read write pointers wrap automatically */
NetNIC_ConnStatus = DEF_ON; /* Report link status as up, regardless of actual state */
DM9000EP_EMAC_RxEn(); /* Enable the EMAC receiver */
*perr = NET_NIC_ERR_NONE; /* No fatal errors occured during initialization */
}
/*
*********************************************************************************************************
* NetNIC_IntEn()
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -