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

📄 driver.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	{
		//NU_Control_Interrupts( pre_int_level );
		//ENABLENETINTERRUPT
		return( NET_ERROR_DMATMO );
	}

	outportb( ISRADD, 0x40 );
	
	//NU_Control_Interrupts( pre_int_level );
	//ENABLENETINTERRUPT
	return( NET_NO_ERROR );

}




/*
Name:		  ConfigMacMii
Description:  set neccessary things in MII register set, 
			  as 10M/100M, duplex and such staff.
Parameters:   mode, 0 - 10M, 1-100M, 2- autonegotiation.
Return: 	  TRUE, success, FALSE, fail.
Test and revision:
			  Ason, 2001.7.
*/
INT16 ConfigMacMii(INT16 mode)
{

	INT16 return_value;
	UINT32 i;
	UINT16 tempus;
	UCHAR tempc;

	SETTOPAGE0
	outportb(CRADD,0x21);
	wait(3);

	// reset MII register set.
	tempus = 0x8000;
	WriteMiiRegister(0x10,0x00,tempus); // 0x10 is the PHY ID of our internal PHY,
										// you may refer to 88796 data sheet. 
	i = 0;
	while( 1 )
	{
	   return_value = ReadMiiRegister(0x10,0x00,&tempus);
	   if (  NET_NO_ERROR != return_value )
		   return( NET_ERROR_PHYREAD );
	   if ( ! ( tempus & 0x8000 ) )
		   break;
	   wait(1);
	   if ( i++ > NET_TMO_MIIRST )
		   return( NET_ERROR_MIIRST );
	}
	
	tempus &= 0xcfff;	   // clear 10/100/auto-negotiation bit.
	if ( 2 == mode)
	  tempus |= 0x1000;    // set auto negotiation.  
	else if ( 1 == mode )
	  tempus |= 0x2000;    // set to 100M.
	
	tempus &= 0xfeff;		// set to half duplex.
	WriteMiiRegister(0x10,0x00,tempus);

	// say i am not capable of 100Base-TX and 100Base-T.
	// Why say I am not capable of 100M?s
	// WriteMiiRegister(0x10,0x04,0x0061);
	
	// say i will see interrupt of link state/jabber/remote fault/false carrier.
	// 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
*/
int16 ReceiveAPacket( unsigned char *tcpip_buf, unsigned char *vb_buf, uint16 *type )
{
	UCHAR tempc, cur_page;
	UINT16 packet_len;
	UINT16 return_value = NET_NO_ERROR;
	UINT16 packet_type;
	UCHAR  temp_buf[24];   // temporary buffer to hold packet head.


	DISABLENETINTERRUPT
	

	*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 )
	{
		
		ENABLENETINTERRUPT
		return( NET_ERROR_NOPAKIN );	//packet len error
	}
	else 
	{
		// read packet head.
		return_value = RemoteRead( ((UINT16)ReadPage) << 8 , 12, (UINT16*)temp_buf );
		if ( NET_NO_ERROR != return_value )
		{
			
			ENABLENETINTERRUPT
			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
			 {
			 	#if 0
                 // this is a packet holding real-time data.
				 if ( temp_buf[15] == VBCtlr.ViewBedFocus )
				     packet_type = NET_PTL_VIEWBEDCARE;
				 else
				     packet_type = NET_PTL_VIEWBEDNOTCARE;
				#endif
			 }

		}
		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 )
		{
			
			ENABLENETINTERRUPT
			return( NET_ERROR_PAKLEN );	//packet len error
		}
		
		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) );
			// here, judge if the packet is for upgrading.
			
		}
		else if ( NET_PTL_VIEWBEDCARE == packet_type )
		{
			memcpy(vb_buf,&temp_buf[4],14);
			return_value = RemoteRead( (((UINT16)ReadPage) << 8) + 18, ( packet_len + 1 ) >> 1, (UINT16 *)(vb_buf + 14) );
		}
		else
		{			
		}

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

/*
Name:			NUTransmit
Description:	1. place buffer used by transmitter back to freelist.
				2. if there are some packet waiting to be transmitted,
				   transmitte it.
				3. Why this is never called? Let me probe in TCP/IP stack
				   But at least obviously, for UDP, buffer could be released
				   when transmit, TCP, when acknowledge comes in, it also 
				   can be released by TCP/IP stack.
Parameters: 	None.
Return: 		None.
Test and revision:
				Ason. 2001.8
*/
void NUTransmit(void)
{
	struct transq *item;
	
	if( trans_list.head )
	{
		// Dequeue the transmitted item. 
		item = (struct transq *) dll_dequeue ((tqe_t *) &trans_list);

		// If this buffer does not contain a TCP data segment deallocate
		// the buffer.	If it does it will be deallocated when an ack for
		// the data is received. 
		if(item->pkt_type == OTHER_PKT)
		{
			//	Place the buffer back on the freelist. 
			dll_enqueue((tqe_t *)&buffer_freelist, (tqe_t *)item->buffer);
		}

		// Place the transmit item on the freelist to be reused. 
		dll_enqueue((tqe_t *)&trans_freelist, (tqe_t *)item);

		// If there is another item on the list, transmit it. 
		if(trans_list.head)   // why should this happen?
		{
			// enable interrupt and transmit the next packet.
			// maybe will never come here as we use PACKET mode 
			// in upper layer which delivers packets promptly.
			// NU_Xmit_Packet((uchar *)trans_list.head->pkt,
			//		   (uint16) trans_list.head->length);
			// for debug.
			
		}
	}
}  


/*
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);
	
	NU_Sleep( 100 * 5 );

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

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

}

/*
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()
{
	TestCount++;
	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);
}

/*
Name:		  NetCtlrHisr
Description:  HISR routine for received data from NIC.
Parameters:   None.
Return: 	  None.
Test and revision:
			  Ason. 2001.7
*/
void NetCtlrHisr(void)
{	
	struct pqueue HUGE *buf_ptr;
	UCHAR *bufp_tcpip, *bufp_vb;
	UINT16 packet_type;
	UCHAR buf_flag;	// 1 - RcvLoopBuf; 0 - Recv_List
	UCHAR tempc;


	if ( 1 ==  BufShortHappen )
		RecoverFromBufShortage();
	
	if ( 1 == ReceiveIntHappen )
	{
	   while( 1 )
	   {
	   	  //step1, allocate buffer for receive packet
		  if ( NU_NULL == (( buf_ptr = dll_update_lists(&buffer_freelist, &Recv_List )) ))
		  {
			  bufp_tcpip = RcvLoopBuf;		  // give a buffer
			  MacState.IPBufShortTimes++;
			  buf_flag = 1;
		  }
		  else
		  {
			  bufp_tcpip = buf_ptr->packet;
			  buf_flag = 0;
		  }

		  //step2, begin receive packet
		  // if receive error, quit while loop
		  if ( NET_NO_ERROR != ReceiveAPacket( bufp_tcpip, bufp_vb, &packet_type ) )
		  {
			  // error, free the buffer.
			  if ( 0 == buf_flag )
			  {
				 dll_update_lists( &Recv_List, &buffer_freelist );
				// ReleaseVBBuffer( bufp_vb );
			  }
			  break;
		  }
		  //if receive success, when packet tppe is tcp, set tcp event
		  else	
		  {
			  if ( NET_PTL_TCPIP == packet_type )
			  {
				dll_update_lists(&Recv_List, &buffer_list);
				NU_Set_Events(&Buffers_Available, (UNSIGNED)2, NU_OR);
			  }  
			  else
			  {
				 if ( 0 == buf_flag )
					dll_update_lists( &Recv_List, &buffer_freelist );
			  }
		  }
	   }
	   ReceiveIntHappen = 0;	
	 }
	 
	 if ( 1 == TransmitHappen )
	 {
	   NUTransmit();
	   TransmitHappen = 0;
	 }
}

/****************************************************************************/
/* FUNCTION 																*/
/*																			*/
/*	  NU_Etopen 															*/
/*																			*/
/* DESCRIPTION																*/
/*																			*/
/*	  This function will handle the initilization of the Ethernet H/W you	*/
/*	  are using for communication, and will load the interrupt information	*/
/*	  if you are using it.													*/
/*																			*/
/* CALLED BY																*/
/*																			*/
/*	  dlayerinit in file net.c												*/
/*																			*/
/* CALLS																	*/
/*																			*/
/*																			*/
/* INPUTS																	*/
/*																			*/
/*	  schar * : pointer to the string containing the ethernet address		*/
/*	  sshort  : interrupt level that the ethernet board should use to		*/
/*				inform the driver software of changing conditions.			*/
/*	  ulint   : Starting address of the current buffer being used for		*/
/*				storing recv and xmit buffers.								*/
/*	  ulint   : I/0 base address of the current ethernet board, should be	*/
/*				defined in the chipint.h file. Used to offset base and		*/
/*				setup the internal register.								*/
/*																			*/
/* OUTPUTS																	*/
/*																			*/
/*	  sshort  : Returns NU_FALSE always.									*/
/*																			*/
/* HISTORY																	*/
/*																			*/
/*		  NAME			  DATE		REMARKS 								*/
/*																			*/
/*																			*/
/****************************************************************************/
sshort NU_Etopen (uchar *ether_addr, uint16 irq_num,
				 ulint buff_addr, ulint base_addr)
{
	INT16 i;
	INT16 return_value;
	UCHAR tempc;
	STATUS  status;
    VOID    *pointer;

	RemedyHardwareBug();

	// step0, initialize protection instructure.
	for ( i = 0; i < NU_PROTECT_SIZE; i++ )
	   MacProtect.words[i] = 0;

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

	// step3, test SRAM.
	return_value = TestMacRam();
	if (  NET_NO_ERROR != return_value )
	{
		//TriggerAlarm(0x0001,STR_ALM_NETINITERRRAM );
		return( return_value );
	}

	// step5, config 88796 to work.
	InitMacCntlr( ether_addr, 0 );

	// 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 );
	//here, we init lisr and hisr, no like ason, who register lisr in init.s file, 
	//and create hisr in main func  -lili
	/* read old, load new */
//	#if 0

    status = NU_Register_LISR (irq_num, Net_Lisr, &NU_old_vect_routine);
	if(status != NU_SUCCESS)
	{
		return NU_FALSE;
	}
//	#endif

    // create the HISR for receiving packets from the Ethernet card 
    status = NU_Allocate_Memory (&System_Memory, &pointer, 1024, NU_NO_SUSPEND);
    if (status != NU_SUCCESS)
    {
		return NU_FALSE;
    }

    status = NU_Create_HISR (&NetControllerHisr, "NetCtlr",
                                NetCtlrHisr, 1, pointer, 1024);
    if (status != NU_SUCCESS)
    {
		return NU_FALSE;
    } 

	// step9, clear IMR of CPU and let interrupt work.
	SetIntRt();


	return (NU_SUCCESS);
}  /* end NU_Etopen routine */

void Write_Printer(unsigned char dat)
{
    outportb(PDPRADD,dat);
}

void Test_Printer()
{
    outportb(PCPRADD,0x08);          //init  printer	
    while(1)
    {
    	Write_Printer(0x55);         //write data to port
    	wait(3);
    	Write_Printer(0xAA);
    	wait(3);
    }	
}
    

⌨️ 快捷键说明

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