?? netdrv.cpp
字號:
cur_page = inportb(CPRADD);
SETTOPAGE0();
ENABLENETINTERRUPT;
return packet_len;
}
/*
Name: RemedyHardwareBug
Description:
According to datasheet version-16, a software reset of
at least 2.5s must be employed to PHY to remedy hardware
bugs.
Parameters:
None.
Test and revision:
Ason. 2001.11.20 <E>
star. 2002.11.5 <M>
*/
void RemedyHardwareBug(void)
{
WriteMiiRegister(0x10,0x00,0x800);
//NU_Sleep( 250 * 5 );
Sleep(5000);
// force to 10M.
WriteMiiRegister(0x10,0x00,0x1200);
// wait for 5 more seconds to make sure
// that the autonegotiation will finish.
Sleep(5000);
}
/*********************************************************************************
Name: NU_Etopen
Description: 1. Initialize hardware,
2. load interrupt service.
3.This is also the interface required by TCP/IP layer.
Parameters: ether_addr - MAC address of the card.
irq_num - external interrupt number.
buff_addr - shared memory or such things, as we don't
use shared memory anyway, this is lefted.
base_addr - base address of the I/O.
Return: NU_SUCCESS if the the procedure is success,
error code if fail.
NU_SUCCESS = 0;
-1, Reg Error.
-2, Ram Error.
Test and revision:
Ason. 2001.7 <E>
shiliangcai 2002.10 <M>
/*********************************************************************************/
INT16 NU_Etopen (UCHAR *ether_addr, UINT16 irq_num,
UINT32 buff_addr, UINT32 base_addr)
{
INT16 i, return_value;
UCHAR tempc;
// step 1, remedy hardware bug
RemedyHardwareBug();
// step 2, test NE2000 registers.
return_value = TestMacReg();
if ( NET_NO_ERROR != return_value )
{
return( return_value );
}
// step 3, test SRAM.
return_value = TestMacRam();
if ( NET_NO_ERROR != return_value )
{
return( return_value );
}
//Just for Test error ---2002/01/11
/*
// step4, initialize things in MII registers of 88796.
return_value = ConfigMacMii(0);
if ( NET_NO_ERROR != return_value )
{
return( return_value );
}
*/
// step5, config 88796 to work.
InitMacCntlr( ether_addr, 0 );
// step6, loop test, without PHY, pooling.
/*
return_value = MacLoopTest();
if ( NET_NO_ERROR != return_value )
{
// TriggerAlarm(0x0001, STR_ALM_NETINITRUNERRUD1);
return( return_value );
}
//Just for Test error ---2002/01/11
*/
// step7, reinitialize things in MII of 88796.
// beause in step 6, some MII register settings are changed.
// and set PHY to autonegotiation mode.
// input: 0:10M, 1:100M, 2:Autonegotiation.
// return_value = ConfigMacMii(0);
// if ( NET_NO_ERROR != return_value )
// return( return_value );
// step8, config 88796 to work once again.
// because in step 6, some register settings are changed,
// so, you must reinitialize the registers.
// and set to normal mode.
InitMacCntlr( ether_addr, 1 );
// step9, clear IMR of CPU and let interrupt work.
SetIntRt();
return (NU_SUCCESS);
}
///////////////////////////////////////////////////
/* del interrupt function, and use query function
Name: Net_Lisr
Description: Low level interrupt service of MAC controller 88796.
Parameter: None
Return: None
Test and revision:
Ason. 2001.7
*/
extern "C"
void Net_Lisr()
{
UCHAR tempc;
UCHAR cr_saver;
INT16 nResultLen;
UINT16 nIndex;
// first of all, read the CR
cr_saver = inportb( CRADD );
if ( cr_saver & 0x40 )
{
// say, this is page 1
// set to page 0, and there should be no problem
// to generate retransmiting, as when we set to
// page0, there are destined to be no transmit.
SETTOPAGE0();
}
tempc = inportb(ISRADD);
if ( tempc & 0x01 ) // this is a receive interrupt without any error.
{
while (TRUE)
{
#ifdef BIOS_DEBUG
g_nOneTransferTimeForTest1 = *(UINT16*)MCF5206::TCN1;
#endif
//nRtn = ReceiveAPacket( ucRecvTemp, &bufp_vb, &packet_type );
nResultLen = ReceiveAPacket(g_acNetReceiveFrame[g_nNetReceiveInIndex], RECEIVE_BUF_MAX_SIZE);
if( nResultLen > NET_FRAME_EXTRA_ADD_HEAD )
{
#ifdef BIOS_DEBUG
char acTempStr[100];
g_nRecSta ++;
sprintf(acTempStr, "Net Reiceiving Pack: %d", g_nRecSta);
TextOut(300, 220, 12, 0, acTempStr);
#endif
g_anNetReceiveFrameLength[g_nNetReceiveInIndex] = nResultLen;
nIndex = g_nNetReceiveInIndex;
g_nNetReceiveInIndex ++;
if (g_nNetReceiveInIndex == NET_RECEIVE_BUF_FRAME_COUNT)
{
g_nNetReceiveInIndex = 0;
}
if (g_nNetReceiveInIndex == g_nNetReceiveOutIndex)
{
// receiving buffer is full, so last packet is rejected
g_nNetReceiveInIndex = nIndex;
}
else
{
g_anNetReceiveFrameLength[g_nNetReceiveInIndex] = 0;
}
}
else
{
g_anNetReceiveFrameLength[g_nNetReceiveInIndex] = 0;
break;
}
}
}
if ( tempc & 0x02) // this is a transmit end interrupt without any error.
{
UCHAR cTemp = inportb(TSRADD);
if (!(cTemp & 0x01))
{
s_nErrorCount ++;
}
}
if ( tempc & 0x04 ) // this is a receive interrupt with error.
{
UCHAR cTemp = inportb(RSRADD);
if (!(cTemp & 0x01))
{
s_nErrorCount ++;
}
}
if ( tempc & 0x08 ) // this is a transmit interrupt with error
{
UCHAR cTemp = inportb(TSRADD);
if (!(cTemp & 0x01))
{
s_nErrorCount ++;
}
}
if ( tempc & 0x10 )
{
s_nErrorCount ++;
// RecoverFromBufShortage();
}
if (tempc & 0x20)
{
s_nErrorCount ++;
}
if (tempc & 0x40)
{
s_nErrorCount ++;
}
if (tempc & 0x80)
{
s_nErrorCount ++;
}
// clear the interrupt status
outportb(ISRADD, 0xff);
// and, return CR.
if ( cr_saver & 0x40 )
// only recover when interrupt context is page1.
outportb( CRADD, cr_saver );
// outportb(0x10000010,0x00); // clear the interrupt. this
// is not necessary actually
// when hardware changed.
}
//////////////////////////////////////////////////////////////////
int IsInLocalNet()
{
UCHAR tempc, cr_saver;
INT16 nResultLen;
UINT16 nIndex;
cr_saver = inportb( CRADD );
if ( cr_saver & 0x40 )
{
// say, this is page 1
// set to page 0, and there should be no problem
// to generate retransmiting, as when we set to
// page0, there are destined to be no transmit.
SETTOPAGE0();
}
tempc = inportb(ISRADD);
if( tempc & 0x01 )
{
outportb( ISRADD,tempc );
// and, return CR,only recover when interrupt context is page1.
if ( cr_saver & 0x40 )
outportb( CRADD, cr_saver );
return 1;
}
else
{
// and, return CR,only recover when interrupt context is page1.
if ( cr_saver & 0x40 )
outportb( CRADD, cr_saver );
return 0;
}
}
BOOL InitNetPort()
{
UINT32 i;
// init net buffer
g_nNetReceiveInIndex = g_nNetReceiveOutIndex = 0;
memset(g_anNetReceiveFrameLength, 0x00, sizeof(UINT16) * NET_RECEIVE_BUF_FRAME_COUNT);
s_nErrorCount = 0;
// 主程序有效,那么一定是從主程序跳過來的,那么機器ID已經(jīng)知道了
if (g_stSysFlag.stESysFlag.ucMainSysIsValid != 1)
{
s_nUpateProcessFlag = 0;
}
else
{
s_nUpateProcessFlag = 1;
}
#ifdef BIOS_DEBUG
g_nSendSta = 0;
g_nRecSta = 0;
g_nErroSta = 0;
#endif
// init const part about net frame's head
// Ether Head 6 - 11 byte
static const UCHAR NET_ET_SOURCE_ADDR[] = {0x50, 0x54, 0xab, 0x3c, 0xcf, 0x88};
// Ether Head 12 - 13 byte
static const UCHAR NET_ET_TYPE[] = {0x08, 0x00};
// IP HEAD 0 - 1 byte, Version(4)--(IHL-LENGTH OF HEAD)(4)-----SERVICETYPE(8)
static const UCHAR NET_IP_CONST1[] = {0x45, 0x10};
// IP HEAD 6 - 9 byte, ninth byte is 17 for udp
static const UCHAR NET_IP_CONST2[] = {0x00, 0x00, 0x80, 0x11};
memset(&g_stNetFrameHead, 0x00, sizeof(NETFRAMEHEAD));
memcpy(g_stNetFrameHead.stETHead.ucSrcAddr, NET_ET_SOURCE_ADDR, 6);
memcpy(g_stNetFrameHead.stETHead.ucType, NET_ET_TYPE, 2);
memcpy(g_stNetFrameHead.stIPHead.ucConstInfo1, NET_IP_CONST1, 2);
g_stNetFrameHead.stIPHead.ucIdentify[0] = 0x10;
g_stNetFrameHead.stIPHead.ucIdentify[1] = 0x02;
memcpy(g_stNetFrameHead.stIPHead.ucConstInfo2, NET_IP_CONST2, 4);
// INIT net chip
for (i = 0; i < 5; i ++)
{
if( !NU_Etopen( 0, 0, 0, 0 ) ) //0 stand for initlize network OK;
break;
Sleep(400); // delay 400ms
}
if (i == 5)
return FALSE;
// check net connecter
/* for (i = 0; i < 300; i ++)
{
if (IsInLocalNet())
break;
Sleep(400); // delay 400ms
}
if (i == 300)
return FALSE;
*/
return TRUE;
}
/*********************************************************************
* 函數(shù)名稱: ConstructEtherNetFrame
* 說 明: Construct commuciation frame by ether net,
* and protocol stack is UDP-IP(4)-ETHER(RFC 894)
* 入口參數(shù):
* void -- 無
* 返 回 值:
* BOOL -- 1, success; 0, failure
* 作 者: Shi Liangcai
* 時 間: 2002-09-31 12:07:31
*********************************************************************/
//
static UINT16 ConstructEtherNetFrame(UCHAR * ucOldPacket, UINT16 unOldNum, UCHAR * ucNewPacket)
{
// UINT16 nLength;
if( unOldNum == 0 )
return 0;
// construct UDP packet
// Get checksum of UDP Header and UDP Data
// Someone Say: It is important for it make me test for all one night to get the way of calculate the checksum
// the way of calculating UDP checksum is that : DATA + UDPHeader(8) + PERSUDO UDPHeader(12)(SrcAddr(4) + DstAddr(4) + 00 + 11(UDPPROTOCAL) + LenofUDP(2)(lenofdata + 8))
// 12 bytes in start pos are fake head, for checksum
UCHAR unUDPPacket[512];
memcpy (unUDPPacket, g_stNetFrameHead.stIPHead.ucSrcAddr, 4);
memcpy (unUDPPacket + 4, g_stNetFrameHead.stIPHead.ucDstAddr, 4);
// 0x00是保留的,0x11是UDP協(xié)議類型
*(UINT16*)(unUDPPacket + 8) = 0x0011;
// UDP長度
*(UINT16*)(unUDPPacket + 10) = (unOldNum + 8);
// real udp head
*(UINT16*)(unUDPPacket + 12 + 0) = INPORTID;
*(UINT16*)(unUDPPacket + 12 + 2) = s_nDstPort - 500;
*(UINT16*)(unUDPPacket + 12 + 4) = unOldNum + 8;
*(UINT16*)(unUDPPacket + 12 + 6) = 0x0000;
memcpy(unUDPPacket + 12 + 8, ucOldPacket, unOldNum);
*(UINT16*)(unUDPPacket + 12 + 6) =
GetNetCheckSum( (UCHAR *)unUDPPacket, (UINT16)(unOldNum + 12 + 8) );
// Construct IP Packet
*(UINT16*)(g_stNetFrameHead.stIPHead.ucLength) = unOldNum + 8 + 20;
// 首先要將該字段清0,因為算校驗和要用到該字段
*(UINT16*)(g_stNetFrameHead.stIPHead.ucHeadChecksum) = 0x0000;
*(UINT16*)(g_stNetFrameHead.stIPHead.ucHeadChecksum) =
GetNetCheckSum( (UCHAR *)(&g_stNetFrameHead.stIPHead), 20);
//
memcpy(ucNewPacket, &g_stNetFrameHead, 34); // not include UDP head
memcpy(ucNewPacket + 34, unUDPPacket + 12, unOldNum + 8);
if (g_stNetFrameHead.stIPHead.ucIdentify[1] == 0xfe)
{
g_stNetFrameHead.stIPHead.ucIdentify[0] ++;
g_stNetFrameHead.stIPHead.ucIdentify[1] = 0x02;
}
else
{
g_stNetFrameHead.stIPHead.ucIdentify[1] += 0x02;
}
return unOldNum + 8 + 20 + 14;
}
//In net where the checksum get by the way: 所有的值取反碼再想加
static UINT16 GetNetCheckSum(UCHAR *unStart, UINT16 unNum)
{
unsigned int nCheckSum;
if (unNum % 2)
{
//it is important ; when the packetlen is odd; the last byte should be treat as hight byte of word
nCheckSum = *(unStart + unNum - 1);
nCheckSum = nCheckSum << 8;
}
else
{
nCheckSum = 0;
}
unNum /= 2;
UINT16* p_temp_data = (UINT16 *)unStart;
while(unNum --)
{
nCheckSum += *(p_temp_data ++);
}
// while( nCheckSum >> 16 )
// {
nCheckSum = (nCheckSum & 0xffff) + (nCheckSum >> 16);
// }
return ~nCheckSum;
}
/*********************************************************************
* 函數(shù)名稱: NetReadString
* 說 明: get receiving data from receiving buffer which it is loop buffer
* 入口參數(shù):
* UCHAR* data data which will be read
* UINT16 length data length
* 返 回 值:
* INT16 length of data which have been read from receiving buffer
* 作 者: Shi Liangcai
* 時 間: 2002-09-29 15:57:40
*********************************************************************/
INT16 NetReadString(UCHAR* data, UINT16 length)
{
// first get head and tail, and head and tail may be changed in NET ISR
UINT16 nLen;
UINT16 nIndex;
nIndex = g_nNetReceiveInIndex;
if (nIndex == g_nNetReceiveOutIndex)
return 0;
nLen = g_anNetReceiveFrameLength[g_nNetReceiveOutIndex];
if (nLen <= NET_FRAME_EXTRA_ADD_HEAD)
return 0;
#ifdef BIOS_DEBUG
g_nOneTransferTimeForTest2 = *(UINT16*)MCF5206::TCN1;
#endif
nLen -= NET_FRAME_EXTRA_ADD_HEAD;
memcpy (data, g_acNetReceiveFrame[g_nNetReceiveOutIndex] + NET_FRAME_EXTRA_ADD_HEAD, nLen);
g_anNetReceiveFrameLength[g_nNetReceiveOutIndex] = 0;
g_nNetReceiveOutIndex ++;
if (g_nNetReceiveOutIndex == NET_RECEIVE_BUF_FRAME_COUNT)
g_nNetReceiveOutIndex = 0;
return nLen;
}
/*********************************************************************
* 函數(shù)名稱: NetWriteString
* 說 明: 將網(wǎng)絡(luò)發(fā)送數(shù)據(jù)放入發(fā)送緩沖,注意由于要對數(shù)據(jù)進行協(xié)議封裝
* 所以每次必須要等到緩沖空才可以寫入,即每一時刻,發(fā)送緩沖的數(shù)據(jù)
* 必須是獨立的一個包
* 入口參數(shù):
* UCHAR* data data which will be transmited
* UINT16 length data length
* 返 回 值:
* INT16 length of data which have been placed in transmiting buffer
* 作 者: Shi Liangcai
* 時 間: 2002-09-29 15:57:40
*********************************************************************/
INT16 NetWriteString(UCHAR* data, UINT16 length)
{
// 注意這里的data - 11,是因為定義接收緩沖時,先加了11,避免內(nèi)存搬運
// 見update.cpp中,函數(shù)update()中 UCHAR* pTempSendStr = g_acSendBuffer + NET_FRAME_EXTRA_ADD_HEAD;
UINT16 length1;
UCHAR* pTempStr = data - 11;
// 增加包頭,為了方便和老協(xié)議兼容處理使用
// extern MONITORINFO gMonitorInfo;
//3(0xaa0x550xa5) + 8(id);
pTempStr[0] = 0xaa;
pTempStr[1] = 0x55;
pTempStr[2] = 0xa5;
memcpy(pTempStr + 3, g_stSysFlag.stFSysFlag.acFlashID, 8);
// 構(gòu)造UDP包
length1 = length;
length = ConstructEtherNetFrame(pTempStr, length + 11, g_acNetTransmitBuffer);
#ifdef BIOS_DEBUG
g_nOneTransferTimeForTest4 = *(UINT16*)MCF5206::TCN1;
#endif
// DisableSysInterrupt(MCF5206::IM_EINT4);
if (TransmitAPacket(g_acNetTransmitBuffer, length) != length)
length1 = 0;
Sleep(length / 1000);
// EnableSysInterrupt(MCF5206::IM_EINT4);
#ifdef BIOS_DEBUG
char acTempStr[100];
g_nSendSta ++;
sprintf(acTempStr, "Net Sending Pack:%d", g_nSendSta);
TextOut(300, 120, 12, 0, acTempStr);
#endif
return length1;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -