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

📄 dm9000.c

📁 硬件设计LPC2138+DM9000AE
💻 C
📖 第 1 页 / 共 3 页
字号:
				pktsize = queue_pkt_len; /* Save current TX packet size */	
			}
		}
		
	}

	/* Received the coming packet */
	if (int_status & DM9000_RX_INTR)
	{ 
#ifndef TASK_MODE		
		dmfe_packet_receive(netp);
#else
		semaphore_signal(CopyGo);	
	/*	CopyGo->semaphore_count++;*/
#endif		
	}

	#if 0
	int_status_after_clear = ior(iobase, 0xfe);
	#endif

	
	/* Re-enable interrupt mask */ 
	iow(iobase, 0xff, IMR_DEFAULT);

	#if 0
	int_mask_reg2 = ior(iobase, 0xff);
	#endif
	
	outb(reg_save, iobase); 
/*	spin_unlock(&db->lock); 	*/




}


/*--------------------------------------------------------------------------
	Name	: dmfe_packet_receive
	Description	: Received a packet and pass to upper layer.
	Author	: 
----------------------------------------------------------------------------*/
#define	DATA8				*(U8*)(iodata)
#define	DATA16				*(U16*)(iodata)

static void dmfe_packet_receive(struct netif *netp)
{
	U8 rxbyte, *rdptr, temp;
	U16 i, RxStatus, RxLen, GoodPacket, tmplen;
	U8 	MDRAH, MDRAL;
	static   struct pbuf *  bufReceiv; /*buffer to store the received packet*/

	U16 rdadr;		
		#if MONITOR_RDPOINTER
	/*U16 MDRAH_test[1522/2],	 MDRAL_test[1522/2];		*/			
	static U32 rxbyte_err =0;
	static U32 rx_cnt =0;
		#endif
		
		#if !ALLOCATE_PBUF 
	U16 rdptru16[1522/2];
		#endif

		#if PROCESS_RD_ANOTHER_TASK
	 void **arg; 		/*arg of ETHin_message_queue*/ 
		#endif
	
	device_wait_reset = FALSE;
		
#if 1  //software reset later
		#if MONITOR_RDPOINTER
	MDRAL=ior(iobase,0xf4);
	MDRAH=ior(iobase,0xf5);
		#endif
		
	ior(iobase, 0xf0);	/* Dummy read */
	rxbyte = inb(iodata);	/* Got most updated data */
		#if MONITOR_RDPOINTER
			//sttbx_Print("rxbyte = %d\n", rxbyte);   
			//sttbx_Print("rx_cnt = %d\n", rx_cnt++);
			if (rxbyte != 1)
				sttbx_Print("rxbyte error  %d\n", ++rxbyte_err);   

		#endif		
	
	if (rxbyte != 1) 		//not 0 or 1, software reset
			{device_wait_reset = TRUE;
			goto device_soft_reset;
			}
	
#endif		
	
	/* Check packet ready or not */
	do {			
	
		/*store the value of Memory Data Read address register*/
		MDRAL=ior(iobase,0xf4);
		MDRAH=ior(iobase,0xf5);
		
		ior(iobase, 0xf0);			/* Dummy read */
		/* After the read of this command, the read pointer of internal SRAM is unchanged		*/
		rxbyte = inb(iodata);	/* Got most updated data */

		/* packet ready to receive check */
		if (rxbyte == DM9000_PKT_RDY) 
		{
			//#ifdef TASK_MODE
			if (CopyGo->semaphore_count)
				CopyGo->semaphore_count--;	
			
				#if MONITOR_RDPOINTER
			       	sttbx_Print("rx_cnt = %d\n", ++rx_cnt);
				#endif
			//#endif	


		
		    /* A packet ready now  & Get status/length */
			GoodPacket = TRUE;
			
			RxStatus = (U16)0;
			RxLen    = (U16)0;
			

			outb(0xf2, iobase);	 /*Enable Read command with address incement*/
			/*ior(iobase, 0xf2);	   //20050801	*/
			
		    /* Selecting io mode */		
			switch (dm9000_iomode) 
			{
				case DM9000_BYTE_MODE: 
 				    RxStatus = inb(iodata) + 
				               (inb(iodata) << 8);
				    RxLen = inb(iodata) + 
					    (inb(iodata) << 8);
				    break;
			  case DM9000_WORD_MODE:
				    RxStatus = inw(iodata);
				    RxLen    = inw(iodata);
				    break;
			  default:
				    break;
			}

			/* Packet Status check */
			temp = (U8)RxStatus;
			if(temp > 0x01)
			{
				device_wait_reset = TRUE;
			}
			
			temp = (U8)(RxStatus>>8);
			if(temp & 0xbf)	/* see reg06	*/
			{
				GoodPacket = FALSE;				
			}
			
			
			if(!GoodPacket)
			{
				/*drop this packet!!!*/
					//(netp->if_iqdrops)++;
					
					if (dm9000_iomode == DM9000_BYTE_MODE) {
						/* Byte mode */
						for (i = 0; i < RxLen; i++)
							inb(iodata);
					}else{
						/* Word mode */
						tmplen = (RxLen + 1) / 2;
						for (i = 0; i < tmplen; i++)
							inw(iodata);
						
						#if SET_RDPOINTER_MANUALLY
						tmplen = (RxLen + 1) / 2;
						rdadr = ((U16)MDRAH<<8) + MDRAL + (tmplen<<1) +4; 
						if (rdadr>0x3FFF)
							rdadr = rdadr - 0x3400;					
						iow(iobase, 0xf4, (U8)rdadr);
						iow(iobase, 0xf5, rdadr>>8);	
						#endif
					}	
				continue;
			}
				
				
  			
	#if ALLOCATE_PBUF 
				/* We allocate a pbuf chain of pbufs from the pool. */	
				#if ETH_PAD_SIZE
    					bufReceiv = pbuf_alloc(PBUF_RAW, (RxLen+ETH_PAD_SIZE), PBUF_POOL);		
				#else
  					bufReceiv = pbuf_alloc(PBUF_RAW, RxLen, PBUF_POOL);		
				#endif
	
			if(bufReceiv == NULL)
			{
				/*printf("mem no buff!\n");	*/
				/*re-load the value into Memory data read address register*/
				iow(iobase, 0xf4, MDRAL);
				iow(iobase, 0xf5, MDRAH);
				return;
			}else
			{	
				#if ETH_PAD_SIZE
    					rdptr = (U8 *) bufReceiv->payload + ETH_PAD_SIZE;
				#else					
					rdptr = (U8 *) bufReceiv->payload;	
				#endif

	#else
		rdptr = (U8*)rdptru16;
	#endif	/*end 	if ALLOCATE_PBUF*/		
	
				/* Read received packet from RX SARM */
				if (dm9000_iomode == DM9000_BYTE_MODE)
				{
					/* Byte mode */
					for (i=0; i<RxLen; i++)
						rdptr[i]=inb(iodata);
						
				}else{
					/* Word mode */
					tmplen = (RxLen + 1) / 2;

				#if SET_RDPOINTER_MANUALLY
					rdadr = ((U16)MDRAH<<8) + MDRAL +4;	 
					if (rdadr>0x3FFF)
						rdadr = rdadr - 0x3400;					
					iow(iobase, 0xf4, (U8)rdadr);
					iow(iobase, 0xf5, rdadr>>8);	
					outb(0xf2, iobase);	
				#endif
				
					for (i = 0; i < tmplen; i++)
						{
						/*for test*/
						/*		
						#if MONITOR_RDPOINTER
						MDRAL_test[i] = ior(iobase,0xf4);	
						MDRAH_test[i] = ior(iobase,0xf5);		
						
						outb(0xf2, iobase);			
						#endif
						*/	

						#if ALLOCATE_PBUF 
						((U16 *)rdptr)[i] = inw(iodata);	
						#else
						rdptru16[i] = inw(iodata);	
						#endif	
						
						}

				}

			#if SET_RDPOINTER_MANUALLY
				/*set the rd pointer*/
				//rdadr = ((U16)MDRAH<<8) + MDRAL +RxLen +4;		//for test
				tmplen = (RxLen + 1) / 2;
				rdadr = ((U16)MDRAH<<8) + MDRAL + (tmplen<<1) +4; 	
			
				//MDRAL  = ior(iobase,0xf4);	
				//MDRAH = ior(iobase,0xf5);				
				if (rdadr>0x3FFF)
						rdadr = rdadr - 0x3400;	/*rdadr = rdadr - 0x3FFF + 0x0C00;*/				
				iow(iobase, 0xf4, (U8)rdadr);
				iow(iobase, 0xf5, rdadr>>8);	
			#endif		

				
			

				#if PROCESS_RD_ANOTHER_TASK
					if ((arg = (void **)message_claim_timeout(ETHin_message_queue, TIMEOUT_IMMEDIATE))!= NULL)
					{
						arg[0] = netp;
						arg[1] = bufReceiv;
						message_send(ETHin_message_queue, (void *)arg);
					}
					else
						LWIP_DEBUGF(1,  ("dmfe_packet_receive: message_claim_timeout occurs\n"));		
				#else
					ethernetif_input( netp, bufReceiv);		
				#endif
		#if ALLOCATE_PBUF
			}
		#endif
		}

	#ifdef TASK_MODE
	}while( (rxbyte == DM9000_PKT_RDY)  && (!device_wait_reset ) &&  (CopyGo->semaphore_count));	
	#else
	}while( (rxbyte == DM9000_PKT_RDY)  && (!device_wait_reset )  );
	#endif


/* re-start ethernet */
device_soft_reset:	if(device_wait_reset)
	{
		software_reset();
		
	}
	
}

#if 1
/*========================================================================================
 *	Name 			:  ETHER_setMulticast                                                   * 
 *	Description	:  Set the internal hardware table to filter out unwanted multicast       *
 *    			   packets before they take up memory.               					 		  *
 	Modify		: Spenser
 *=======================================================================================*/
static void ETHER_setMulticast(struct netif *netp)
{

	static U8 ht[8];  		/* hash table */
	static U32 i;
	U32 oft;
	
	/*disable int*/
		
	/* prepare hash table */
  	
    	/* clear table */
    	for( i=0; i<8; i++) 
    	{
    		ht[i] = 0;
    	}	
		
	ht[7] = 0x80;/*2005 8 17 add for multi cast*/
    	

  	/* set filter */ 
  	for (i = 0, oft = 0x16; i < 8; i++, oft++)
  		iow(iobase, oft, ht[i]);
  		 	  			
	return;
}		



void ETHER_closeMulticast(struct netif *netp)
{

	static U8 ht[8];  		/* hash table */
	static U32 i;
	U32 oft;
	
	/*disable int*/
		
	/* prepare hash table */
  	
    	/* clear table */
    	for( i=0; i<8; i++) 
    	{
    		ht[i] = 0;
    	}	
		
	ht[7] = 0x00;/*close multi cast*/
    	

  	/* set filter */ 
  	for (i = 0, oft = 0x16; i < 8; i++, oft++)
  		iow(iobase, oft, ht[i]);
  		 	  			
	return;
}


/*===========================================================================
	Name 			:  	ETHER_Load
	Description : 	initialise the MAC address.
	returns		: 0 if success, 1 if mac adr not defined.
	Modify		: Spenser
 ===========================================================================*/
static U32 ETHER_MacLoad(struct netif *netp)
{
	/* Set Node address */
	iow(iobase,	0x10, 0x00);
	iow(iobase,	0x11, 0x11);
	iow(iobase,	0x12, 0x2F);
	iow(iobase,	0x13, 0xF2);
	iow(iobase,	0x14, 0x35);
	iow(iobase,	0x15, 0x91);	
  	
	return(0);
}
#endif

void ETHER_Config(U32 Eth_BaseAddr, 
                    U8 Addr_Shift,
                    U8 dm9ks_Interrupt,
                    U8 Int_Level,
                    U8 Use16Bit,
                    U8 Trans_Len)
{
    IO_base = Eth_BaseAddr;
    ETHER_Address_Shift = Addr_Shift;
    ETHER_DM9000_Interrupt = dm9ks_Interrupt;
    ETHER_Interrupt_Level = Int_Level;
    ETHER_USE16bit = Use16Bit;
    ETHER_TRANS_Len = Trans_Len;
}


void  Read_MAC(struct netif *netp)
{ 
	/*int i;
  	for (i=0; i<netp->hwaddr_len; i++)
  		netp->hwaddr[i] = ior(iobase, i+0x10);*/


	netp->hwaddr[0] =0x00;
	netp->hwaddr[1] = 0x11;
	netp->hwaddr[2] =0x2F;
	netp->hwaddr[3] =0xF2;
	netp->hwaddr[4] = 0x35;
	netp->hwaddr[5] = 0x91;	
}



⌨️ 快捷键说明

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