📄 net_nic.c
字号:
/*
*********************************************************************************************************
* uC/TCP-IP
* The Embedded TCP/IP Stack
*
* (c) Copyright 2003-2005; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
* Knowledge of the source code may not be used to write a similar
* product. This file may only be used in accordance with a license
* and should not be redistributed in any way.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* NETWORK INTERFACE CARD
* Davicom DM9000A
*
* Filename : net_nic.c
* Programmer(s) : EHS
* : BAN
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define NET_NIC_MODULE
#include <net.h>
#include <bsp.h>
/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* GLOBALS
*********************************************************************************************************
*/
#if DM9000A_TX_QUEUE_MODE == DM9000A_TX_QUEUE_TWO_PACKETS
static CPU_INT08U NetNIC_TxNQueued; /* Indicates how many packets are queued . . . */
/* . . .in the DM9000A'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. */
#endif
/*
*********************************************************************************************************
* CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MACROS
*
* Note(s) : (1) DM9000A_ENTER() and DM9000A_EXIT() should be used to "protect" the DM9000A against
* access by the ISR handler during the reading or transmitting of a packet. Because
* these functions use CPU_CRITICAL_ENTER() and CPU_CRITICAL_EXIT() to protect the
* necessary DM9000A register writes, the declaration
*
* #if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
* CPU_SR cpu_sr;
* #endif
*
* should be included in each function in which these are used.
*
*********************************************************************************************************
*/
#define DM9000A_ENTER() { \
CPU_CRITICAL_ENTER(); \
NetNIC_WrReg_8(DM9000A_IMR, IMR_PAR); \
CPU_CRITICAL_EXIT(); \
}
#define DM9000A_EXIT() { \
CPU_CRITICAL_ENTER(); \
NetNIC_WrReg_8(DM9000A_IMR, IMR_PTI | IMR_PRI | IMR_ROI | IMR_ROOI); \
CPU_CRITICAL_EXIT(); \
}
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void NetNIC_RxISR_Handler (void); /* ISR for RX interrupts. */
static void NetNIC_TxISR_Handler (void); /* ISR for TX interrupts. */
static void NetNIC_TxPktDiscard (NET_ERR *perr);
/* ---------------- DM9000A EMAC FNCTS -------------------- */
static void DM9000A_Init (NET_ERR *perr);
static void DM9000A_Reset (void);
/* ---------------- DM9000A EMAC RX FNCTS ----------------- */
static void DM9000A_EMAC_RxEn (void);
static void DM9000A_EMAC_RxDis (void);
static void DM9000A_EMAC_RxIntEn (void);
static CPU_INT16U DM9000A_EMAC_RxPktGetSize (void);
static void DM9000A_EMAC_RxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr);
static void DM9000A_EMAC_RxPktDiscard (CPU_INT16U size);
/* ---------------- DM9000A EMAC TX FNCTS ----------------- */
static void DM9000A_EMAC_TxIntEn (void);
static void DM9000A_EMAC_TxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr);
static void DM9000A_EMAC_TxPktPrepare (void *ppkt,
CPU_INT16U size,
NET_ERR *perr);
static void DM9000A_PHY_SetMode (CPU_INT32U mode,
NET_ERR *perr);
static void DM9000A_Start (NET_ERR *perr);
static void DM9000A_Restart (NET_ERR *perr);
static CPU_INT32U DM9000A_Info (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 DM9000A
*
* 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 --------------------- */
DM9000A_Init(perr);
}
/*
*********************************************************************************************************
* DM9000A_Init()
*
* Description : (1) Initialize hardware
* (2) Reset DM9000A
* (3) Initialize PHY
* (4) Initialize & start DM9000 (see DM9000A_Start())
* (5) Initialize external interrupt controller
*
* 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) DM9000A's EEPROM for DM9000_EMAC_MAC_ADDR_SEL_EEPROM
* (2) Application code for DM9000_EMAC_MAC_ADDR_SEL_CFG
*
* (2) Interrupts MUST be enabled ONLY after ALL network initialization is complete (see also
* 'net.c Net_Init() Note #4c').
*
*********************************************************************************************************
*/
static void DM9000A_Init (NET_ERR *perr)
{
CPU_INT32U info;
NetBSP_NIC_HW_Init(); /* Initialize the processor I/O */
info = DM9000A_Info(); /* Probe DM9000A 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 */
}
DM9000A_Reset(); /* Reset the DM9000A */
DM9000A_Start(perr); /* Initialize & start the DM9000A */
if (*perr != NET_NIC_ERR_NONE) {
return;
}
NetBSP_IntInit(); /* Configure and enable AIC, not DM9000 interrupts */
/* EMAC int's are enabled by NetInit -> NetNIC_IntEn */
#if DM9000A_TX_QUEUE_MODE == DM9000A_TX_QUEUE_TWO_PACKETS
NetNIC_TxNQueued = 0; /* No packets are currently queued. */
NetNIC_TxLenQueued = 0; /* Length value is not valid. */
#endif
}
/*
*********************************************************************************************************
* DM9000A_Start()
*
* Description : Initialize & start DM9000 :
* (1) Initialize PHY.
* (2) Initialize MAC address.
* (3) Initialize interrupts.
* (4) Initiate auto-negotiation.
* (5) Enable receiver.
*
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : DM9000A_Init()
* : DM9000A_Restart()
*
* Note(s) : (1) (a) Assumes MAC address to set has previously been initialized by
*
* (1) DM9000A'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 DM9000A_Start (NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
CPU_INT16U i;
CPU_INT16U reg_val;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -