⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netdrv.cpp

📁 coldfire5206芯片的boot程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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已经知道了
	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;
}

/*********************************************************************
* 函数名称:		ConstructEtherNetFrame
* 说	明:		Construct commuciation frame by ether net, 
*				and protocol stack  is  UDP-IP(4)-ETHER(RFC 894)
* 入口参数:
*				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协议类型
	*(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;
}

/*********************************************************************
* 函数名称:		NetReadString
* 说	明:		get receiving data from receiving buffer which it is loop buffer
* 入口参数:	
*				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;
}

/*********************************************************************
* 函数名称:		NetWriteString
* 说	明:		将网络发送数据放入发送缓冲,注意由于要对数据进行协议封装
*				所以每次必须要等到缓冲空才可以写入,即每一时刻,发送缓冲的数据
*				必须是独立的一个包
* 入口参数:	
*				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,避免内存搬运
	// 见update.cpp中,函数update()中	UCHAR* pTempSendStr  =  g_acSendBuffer + NET_FRAME_EXTRA_ADD_HEAD;
	UINT16 length1;
	UCHAR* pTempStr = data - 11;

	// 增加包头,为了方便和老协议兼容处理使用
//	extern MONITORINFO		gMonitorInfo;
	//3(0xaa0x550xa5) + 8(id);
	pTempStr[0] = 0xaa;
	pTempStr[1] = 0x55;
	pTempStr[2] = 0xa5;
	memcpy(pTempStr + 3, g_stSysFlag.stFSysFlag.acFlashID, 8);

	// 构造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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -