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

📄 netdrv.cpp

📁 coldfire5206芯片平台的自捡程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	// but i don't know why the two bits writable can not be set.
	// WriteMiiRegister(0x10,31,0x0);
	
	return( NET_NO_ERROR );
}

/*
Name:         ReceiveAPacket
Description:  This routine will received a packet now 
              dangling on the MAC buffer, and "ReadPage" is 
			  a global thing.
Parameters:   buf - the buffer used to hold the packet.
Returns:      0 - A packet is successfully received.
              1 - No packet is found.
			  2 - this is a viewbed packet, and we care about it, saved.
			  3 - this is a viewbed packet, but we don't care about it, discard.
			  -1 - NET_ERROR_PAKLEN.
Test and revision:
              Ason. 2001.7
*/
// for debug 
unsigned long thistimesernum;
unsigned long lasttimesernum;
unsigned long serialnumerror = 0;
unsigned long trigger = 0;
INT16 ReceiveAPacket( UCHAR *tcpip_buf, UCHAR *vb_buf, UINT16 *type )
{
	UCHAR tempc, cur_page;
	UINT16 packet_len;
	UINT16 return_value = NET_NO_ERROR;
	UINT16 packet_type;
//	UCHAR  temp_buf[18];   // temporary buffer to hold packet head.
	UCHAR  temp_buf[24];   // temporary buffer to hold packet head.

    *type = packet_type = NET_PTL_NOONE;

    SETTOPAGE0
	tempc = inportb(RSRADD);

	// when set to page1, there should be an interrupt entry protection.
	SETTOPAGE1
    cur_page = inportb(CPRADD);
	SETTOPAGE0
	
    if ( ReadPage == cur_page )
		return( NET_ERROR_NOPAKIN );
	else 
    {
        // read packet head.
        // return_value = RemoteRead( ((UINT16)ReadPage) << 8 , 9, (UINT16*)temp_buf );
		// for debug.
		return_value = RemoteRead( ((UINT16)ReadPage) << 8 , 12, (UINT16*)temp_buf );
		if ( NET_NO_ERROR != return_value )
			return( return_value );

		// here, something must be done to make sure VB protocol
		// packets goes else where.
		if (   0xff == temp_buf[10] 
			&& 0xff == temp_buf[11] 
			&& 0xff == temp_buf[12]
			&& 0xff == temp_buf[13] )
		{
             if ( temp_buf[14] & 0x80 ) 
                 // this is a packet holding general information.
				 packet_type =  NET_PTL_VIEWBEDCARE;
			 else
			 {
                 // this is a packet holding real-time data.
				 //if ( temp_buf[15] == VBCtrl.ViewBedFocus )
				     packet_type = NET_PTL_VIEWBEDCARE;
				 //else
				   //  packet_type = NET_PTL_VIEWBEDNOTCARE;
			 }

			 // for debug only.
			 thistimesernum = *((unsigned long *)&temp_buf[18]);
			 if ( trigger > 10 )
			 {
			  if ( thistimesernum != lasttimesernum + 1 )
				 serialnumerror++; 
			 }
			 else
				 trigger++;
			 lasttimesernum = thistimesernum;
		}
		else
		    packet_type = NET_PTL_TCPIP;
		*type = packet_type;
		       
		
        packet_len = ((UINT16)256) * temp_buf[3] + temp_buf[2]
                      - 14;
		if ( packet_len > RECEIVE_BUF_SIZE - 14 )
			return( NET_ERROR_PAKLEN );
		
		if ( NET_PTL_TCPIP == packet_type  )
		{
			memcpy(tcpip_buf,&temp_buf[4],14);
			// read the whole packet in.
			return_value = RemoteRead( (((UINT16)ReadPage) << 8) + 18, ( packet_len + 1 ) >> 1, (UINT16 *)(tcpip_buf + 14) );
		}
		else if ( packet_type == NET_PTL_VIEWBEDCARE )
		{
            memcpy(vb_buf,&temp_buf[4],14);
			return_value = RemoteRead( (((UINT16)ReadPage) << 8) + 18, ( packet_len + 1 ) >> 1, (UINT16 *)(vb_buf + 14) );
		}

		if ( NET_NO_ERROR == return_value )
		{
			MacState.Rcv.PacketReallyReceived++;
			if ( NET_PTL_TCPIP == packet_type )
				MacState.Rcv.PacketReallyReceivedTcpip++;
			else if ( NET_PTL_VIEWBEDCARE == packet_type )
				MacState.Rcv.PacketReallyReceivedVBCare++;
			else if ( NET_PTL_VIEWBEDNOTCARE == packet_type )
				MacState.Rcv.PacketReallyReceivedVBNotCare++;
		}
        // move the BNYR to next page.
		
        SETTOPAGE0
        outportb( BNRYADD,ReadPage );
        ReadPage = temp_buf[1];
        
		SETTOPAGE1
        cur_page = inportb(CPRADD);
		SETTOPAGE0
    		
		return( NET_NO_ERROR );
	}
}


/*
Name:         MacLoopTest
Description:  Do two kinds of loop test: 1. internal loop
                                         2. internal loop with HPY
		  
Parameters:   None.
Returns:      Error code or NET_NO_ERROR
Test and revision:
              Ason. 2001.7
*/
INT16 MacLoopTest(void)
{
	
	INT16 i,return_value,looptimes;
	UCHAR tempc,cur_page;
	UINT16 tempus;
	UINT16 packet_type;
	BOOL  return_value_bool;
	
	for ( i = 0; i < 256; i++ )
	    SndLoopBuf[i] = i;
	SndLoopBuf[0] = 0xff;  // make it a broadcast address.
	SndLoopBuf[1] = 0xff;
	SndLoopBuf[2] = 0xff;
	SndLoopBuf[3] = 0xff;
	SndLoopBuf[4] = 0xff;
	SndLoopBuf[5] = 0xff;  // must make sure that [6],[7],[8],[9] will never be
		                   // 0xff to make it a non-viewbed packet.


	// first of all, set loop mode 1.
	SETTOPAGE0
	outportb(TCRADD,0x22);
    
	// start the MAC controller.
	STARTCNTLR

    for ( looptimes = 0; looptimes < 1000; looptimes++ )
	{
	   // clear receive buffer. 
	   for ( i = 0; i < 260; i++ )
   		  RcvLoopBuf[i] = i + 1;
 
       // "RemoteWrite" will not change register page.
	   return_value = TransmitAPacket( (UINT16*)SndLoopBuf, 128 );
	   if ( NET_NO_ERROR != return_value )
	    	return( return_value );
	
	   // polling for received state.
	   i = 0;
	   while( TRUE )
	   {
          tempc = inportb(ISRADD);
		  if ( tempc & 0x01 )
		       break;
		  wait(3);
		  if ( i++ > NET_TMO_LOOPWT )
		    	break;
	   }
	   if ( i > NET_TMO_LOOPWT )
          return( NET_ERROR_LOOPRSP );
		
	   return_value = ReceiveAPacket(RcvLoopBuf,RcvLoopBuf,&packet_type);
	   if ( NET_NO_ERROR != return_value )
  	       return( return_value );
	
	   if ( memcmp( SndLoopBuf, &(RcvLoopBuf[0]), 256 ) )
	       return( NET_ERROR_LOOPERR );

       // clear receive bit.
       SETTOPAGE0
	   outportb(ISRADD,0x01);	

	}

    
	// first of all, set loop mode 2.
    outportb(TCRADD,0x24);   // 0xa4 for internal loop with PHY,

	if ( NET_NO_ERROR !=  ReadMiiRegister(0x10,0x00,&tempus) )
		return( NET_ERROR_MIIRD );
	tempus |= 0x4000;        // set PHY loop;
	WriteMiiRegister(0x10,0x00,tempus);


	for ( looptimes = 0; looptimes < 1000; looptimes++ )
	{
	   // clear all the received bytes.
       for ( i = 0; i < 260; i++ )
	      RcvLoopBuf[i] = i + 1;
	
       // transmit a packet.
	   return_value = TransmitAPacket( (UINT16*)SndLoopBuf, 128 );
	   if ( NET_NO_ERROR != return_value )
	    	return( return_value );
		
	   i = 0;
	   while( TRUE )
	   {
           tempc = inportb(ISRADD);
		   if ( tempc & 0x01 )
		        break;
		   wait(3);
		   if ( i++ > NET_TMO_LOOPWT )
		    	break;
	   }
	   if ( i > NET_TMO_LOOPWT )
           return( NET_ERROR_LOOPRSP );

	   return_value = ReceiveAPacket(RcvLoopBuf, RcvLoopBuf, &packet_type );
       if ( NET_NO_ERROR != return_value )
	       return(return_value);
    
	   if ( memcmp( SndLoopBuf, &(RcvLoopBuf[0]), 256 ) )
	       return( NET_ERROR_LOOPERR );

       // clear receive bit.
       SETTOPAGE0
	   outportb(ISRADD,0x01);	
	}

    return( NET_NO_ERROR );  

}

/*
Name:        NU_Get_Address
Description: This file is used to return MAC address, as we don't use EEPROM
             or such things to determine MAC address, we just return it from 
			 bed number.
Parameters:  ether_addr - hold MAC address to return.
             not_used - things not used, but required by interface.
			 io_base - io base of MAC, as we don't use it, let it be, required
			 by interface.
Return:      always return success.
Test and revision:
             Ason. 2001.7

*/
INT16 NU_Get_Address (UCHAR *ether_addr, UINT32 not_used, UINT32 io_base)
{
	
	*ether_addr = BED_ETHER_ADDR_AREA1;
	*(ether_addr + 1) = BED_ETHER_ADDR_AREA2;
	*(ether_addr + 2) = BED_ETHER_ADDR_AREA3;
	*(ether_addr + 3) = BED_ETHER_ADDR_AREA4;
	*(ether_addr + 4) = BED_ETHER_ADDR_AREA5;
	*(ether_addr + 5) = BED_ETHER_ADDR_AREA6 + 0;
	
	return 0;
}

/*
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>          

*/
void RemedyHardwareBug(void)
{
	WriteMiiRegister(0x10,0x00,0x800);
	
	wait( 1000 * 5 );

	// force to autonegotiation and restart it.
	WriteMiiRegister(0x10,0x00,0x00);

    // wait for 5 more seconds to make sure 
	// that the autonegotiation will finish.
	wait( 1000 * 5 );

}


/*
Name:        NU_Etopen                                                             
Description: 1. Initialize hardware, 2. load interrupt service. 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
*/
INT16 NU_Etopen (UCHAR *ether_addr, UINT16 irq_num,
		 UINT32 buff_addr, UINT32 base_addr)
{
    INT16 return_value;
	UCHAR tempc;

	RemedyHardwareBug();

	// step1, initialize statistics of MAC layer.
	InitStatistics();
		
	// step2, test NE2000 registers.
	return_value = TestMacReg();
    if (  NET_NO_ERROR != return_value )
		return( return_value );

	// step3, test SRAM.
	return_value = TestMacRam();
	if (  NET_NO_ERROR != return_value )
		return( return_value );

/*
	// 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, both with PHY and without PHY, pooling.
	return_value = MacLoopTest();
	if ( NET_NO_ERROR != return_value )
		return( return_value );

	// 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 ( NET_NO_ERROR );
}


/*
Name:           NU_Xmit_Packet                                                        
Description:    interface function, transmit a packet immediately.
Parameters:     pack_addr - the packet address
                num_msg_bytes - the packet length.
Return:         .
Test and revision:
                Ason. 2001.7.

*/
INT16 NU_Xmit_Packet(UCHAR *pack_addr, UINT16 num_msg_bytes)
{
    // according to IEEE802.3, packet length not including checksum
	// should be at least 60 bytes.
	// and the hardware will add CRC automatically.
	// we say that CRC will be appended by transmitter, what's the
	// meaning of it? length is actual size of the packet or
	// the size should be actual size plus 4(CRC length?).
	// refer to data sheet, size is only actual size.
	if ( num_msg_bytes % 2 )
	    num_msg_bytes++;
	if ( num_msg_bytes < TRANSMIT_BUF_MIN_SIZE )
		num_msg_bytes = TRANSMIT_BUF_MIN_SIZE;          // add PAD.
	else if ( num_msg_bytes > TRANSMIT_BUF_SIZE ) 
        return( -1 );		                            // MTU exceeded.
	      
	if ( NET_NO_ERROR != TransmitAPacket( (UINT16 *)pack_addr, num_msg_bytes / 2 ) )
		return( -1 );
	
	return( 0 );
}


/*
Name:        Net_Lisr
Description: Low level interrupt service of MAC controller 88796.
Parameter:   None
Return:      None
Test and revision:
             Ason. 2001.7
*/
void Net_Lisr(void)
{
	MacInt();
	outportb(0x10000010,0x00);            // clear the interrupt. this
	                                      // is not necessary actually 
	                                      // when hardware changed.
} 



// following are debug functions.
// restart autonegotiation.
INT16 RestartAutoNeg(void)
{
    
	INT16 return_value;    
	UINT16 tempus;
	
    return_value = ReadMiiRegister(0x10,0x00,&tempus);
	   if (  NET_NO_ERROR != return_value )
		     return( -1 );

    tempus |= 0x0200;    // restart autonegotiation.

	WriteMiiRegister(0x10,0x00,tempus);
	return(0);
}


⌨️ 快捷键说明

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