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

📄 network.c

📁 自己写的一个基于kb9202开发板的bootloader
💻 C
字号:
#include "at91rm9200.h"#include "network.h"#include "pstring.h"static unsigned char send_buf[MAX_FRAME];		//buffer for packet to be senttypedef struct {	unsigned address;	unsigned size;} rbd_list;static rbd_list rbdl[LIST_LENGTH];				//receive buffer descriptor liststatic unsigned char mac_addr[6];				//local macstatic unsigned char ip_addr[4];				//local ipstatic unsigned char mac_serv[6];				//server macstatic unsigned char ip_serv[4];				//server ipstatic void send_packet(int);static void print_byte(unsigned char);static unsigned mii_readPhy(emac_reg_p emac, unsigned char reg){	unsigned value = 0x60020000 | (reg<<18);		emac->eth_ctl |= EMAC_MPE;	emac->eth_man = value;	while( !(emac->eth_sr&EMAC_IDLE) );	emac->eth_ctl &= ~EMAC_MPE;	return (unsigned)(emac->eth_man&0xffff);}static void get_link_speed( emac_reg_p emac ){	unsigned value1, value2;	value1 = mii_readPhy(emac, MII_STATUS1);	/* latch */	value1 = mii_readPhy(emac, MII_STATUS2);	value2 = mii_readPhy(emac, MII_STATUS2);	if( !(value2 & 0x400) )	/* not linked */		return;	if( (value1&0x4000) && (value2&0x8000) )	/* 100M, full duplex */		emac->eth_cfg |= (EMAC_SPD | EMAC_FD);	else if( (value1&0x1000) && (value2&0x2000) )	/* full duplex */		emac->eth_cfg = (emac->eth_cfg & EMAC_SPD) | EMAC_FD;	else if( (value1&0x2000) && (value2&0x4000) )	/* 100M, half duplex */		emac->eth_cfg = (emac->eth_cfg & EMAC_SPD) & ~EMAC_FD;	else if( (value1&0x800) && (value2&0x1000) )	/* 10M, half duplex */		emac->eth_cfg = emac->eth_cfg & ~EMAC_SPD & ~EMAC_FD;}static inline void set_mac_addr( emac_reg_p emac ){	mac_addr[0] = 0x00;	mac_addr[1] = 0x11;	mac_addr[2] = 0xd8;	mac_addr[3] = 0xe8;	mac_addr[4] = 0x34;	mac_addr[5] = 0x2c;	emac->eth_sa1l = mac_addr[5] | (mac_addr[4]<<8) | (mac_addr[3]<<16) | (mac_addr[2]<<24);	emac->eth_sa1h = mac_addr[1] | (mac_addr[0]<<8);}static inline void set_ip_addr( ){	ip_addr[0] = 0xac;	ip_addr[1] = 0x10;	ip_addr[2] = 0x64;	ip_addr[3] = 0xf1;}static inline void set_serv_ip( ){	ip_serv[0] = 0xac;	ip_serv[1] = 0x10;	ip_serv[2] = 0x64;	ip_serv[3] = 0xe9;}	inline void emac_configure(){	int i;	emac_reg_p emac = (emac_reg_s *)EMAC_BASE;	for(i=0;i<LIST_LENGTH;i++){		rbdl[i].address = (unsigned)( RX_BUFFER_START + MAX_FRAME*i );		rbdl[i].size = 0;	}	rbdl[LIST_LENGTH-1].address |= 0x2;	emac->eth_ctl = 0;	//emac->eth_cfg = 0;	if( !(emac->eth_sr & EMAC_LINK) )		get_link_speed( emac );	set_mac_addr( emac );	emac->eth_rbqp = (unsigned)rbdl;/* clear the receive status flag */	emac->eth_rsr |= (EMAC_BNA | EMAC_REC | EMAC_OVR);	set_ip_addr( );	set_serv_ip( );	emac->eth_cfg |= EMAC_CAF ; 	emac->eth_cfg = ( emac->eth_cfg & ~(EMAC_CLK) ) | EMAC_CLK_32;	emac->eth_ctl |= (EMAC_TE | EMAC_RE);/* clear the transfer status flag */	emac->eth_tsr |= EMAC_OVER | EMAC_COL | EMAC_RLE | EMAC_COMP | EMAC_UND;	emac->eth_tar = (unsigned)send_buf;}inline void emac_init(){	unsigned temp;	pio_reg_p pioa = (pio_reg_s *)PIOA_BASE;	pio_reg_p piob = (pio_reg_s *)PIOB_BASE;	pmc_reg_p pmc  = (pmc_reg_s *)PMC_BASE;	aic_reg_p aic  = (aic_reg_s *)AIC_BASE;/* PMC, enable the peripheral clock */	pmc->pmc_pcer = ( (unsigned) 0x1<<ID_EMAC);/* PIO multiplex, pioa, asr	*/	temp = 0x1ff80;//	temp = ETXCK | ETXEN | ETX01 | ECRS | ERX01 | ERXER | EMDC | EMDIO ;	pioa->pio_asr |= temp;	pioa->pio_bsr &= ~temp;	pioa->pio_pdr = temp;/* piob, bsr	*/	temp = 0xff000;//	temp = ETX23 | EXTER | ERX23 | ERXDV | ECOL | ERXCK;	pioa->pio_asr &= ~temp;	pioa->pio_bsr |= temp;	pioa->pio_pdr = temp;/* AIC, disable the interrupt	*/	aic->aic_idcr |= (0x1 << ID_EMAC);	aic->aic_iecr &= ~(0x1 << ID_EMAC);	emac_configure();}void arp_request( ){	arp_packet * arp = (arp_packet *) send_buf;	emac_reg_p emac = (emac_reg_s *)EMAC_BASE;/* set the mac header */	p_memset( (char *)send_buf, 0x0, 0x40);	p_memset( (char *)arp->dstAddr, 0xff, 6);	p_memcpy( (char *)mac_addr, (char *)arp->srcAddr, 6);	arp->frameLen = SWAP16( TYPE_ARP );/* fill the arp packet */	arp->hardware = SWAP16(1);	arp->protocol = SWAP16(TYPE_IP);	arp->hlen = 6;	arp->plen = 4;	arp->operation = SWAP16(1);		//request	p_memcpy( (char *)mac_addr, (char *)(arp->sendHA), 6);	p_memcpy( (char *)ip_addr, (char *)arp->sendIP, 4);	p_memset( (char *)arp->targetHA, 0, 6);	p_memcpy( (char *)ip_serv, (char *)arp->targetIP, 4);/* send the packet */	while( !(emac->eth_tsr & EMAC_BNQ) );	emac->eth_tsr |= EMAC_COMP;	emac->eth_tar = (unsigned)send_buf;	emac->eth_tcr = 0x40;}static void send_packet( int length ){	emac_reg_p emac = (emac_reg_s *)EMAC_BASE;	int i;	for(i=0; i<0x40; i++){		print_byte( send_buf[i] );		put_char( ' ' );	}	put_s( "\r\n" );	emac->eth_tcr = 0;	while( !(emac->eth_tsr & EMAC_BNQ) );	emac->eth_tsr |= EMAC_COMP;	emac->eth_tar = (unsigned)send_buf;	emac->eth_tcr = length;/*	while( !(emac->eth_tsr & EMAC_COMP) );	for(i=0; i<0x40; i++){		print_byte( send_buf[i] );		put_char( ' ' );	}	put_s( "\r\n" );*/}static void print_byte( unsigned char c ){	hex_ch hex;	p_hexToChar( c, &hex);	put_char( hex.high );	put_char( hex.low );}static int process_arp( arp_packet *addr ){	int i;	if( p_memcmp( (char *)ip_serv, (char *)addr->sendIP, 6) ){//	if( p_memcmp( (char *)ip_addr, (char *)addr->sendIP, 4 ) ){		p_memcpy( (char *)addr->sendHA, (char *)mac_serv, 6);		for(i=0; i<6; i++){			put_char( ' ' );			print_byte( mac_serv[i] );		}		return (int)0;	} else		put_char('b');	return (int)1;}int recv_packet(){	emac_reg_p emac = (emac_reg_s *)EMAC_BASE;	unsigned size, i, temp;	eth_header *addr;	arp_packet *arp;	unsigned j;	unsigned char * packet_start;	unsigned short us_temp;	unsigned char uc_temp;	while( !(emac->eth_rsr & EMAC_REC) );	emac->eth_rsr |= emac->eth_rsr;	for(i=0; i<LIST_LENGTH; i++)		if( rbdl[i].address & 0x01 ){			rbdl[i].address = rbdl[i].address & 0xfffffffe;			addr = (eth_header *) (rbdl[i].address & 0xfffffffc);			temp = SWAP16( addr->frameLen );			if( temp==TYPE_ARP ){				arp = (arp_packet *)addr;				if( p_memcmp( (char*)arp->sendIP, (char*)ip_serv, 4) ) {					us_temp = SWAP16( arp->operation );					if( us_temp==2 ) {						put_s( "got a packet from server.\r\n" );						for( j=0; j<6; j++ ) {							print_byte( arp->sendHA[j] );							put_char( '.' );						}						put_s( "\r\n" );					}				}				if( p_memcmp( (char*)arp->targetIP, (char*)ip_addr, 4) ){					us_temp =  SWAP16( arp->operation );					if( us_temp==1 ){						put_s( "got a request.\r\n" );						arp->operation = SWAP16(2);						for(j=0; j<6; j++){							arp->dstAddr[j] = arp->srcAddr[j];							arp->srcAddr[j] = mac_addr[j];							arp->targetHA[j] = arp->sendHA[j];							arp->sendHA[j] = mac_addr[j];						}						for(j=0; j<4; j++){							arp->targetIP[j] = arp->sendIP[j];							arp->sendIP[j] = ip_addr[j];						}						while( !(emac->eth_tsr & EMAC_BNQ) );						emac->eth_tsr |= EMAC_COMP;						emac->eth_tar = (unsigned)packet_start;						emac->eth_tcr = 0x40;					}					else if( us_temp==2 ) {						put_s( "The IP is:\t" );						for(j=0; j<6; j++) {							print_byte( arp->sendHA[j] );							put_char('.');						}						put_s( "\r\n" );					}				}			}		break;		}	return (int)1;}static void wait_a_second(){	int i;	for(i=0;i<24000;i++);}void arp_test(){/*	int i, j;	j = 1;*//*	put_s("begin arp test.\r\n");	for( i=0; i<3; i++ ){		arp_request();		for(j=0; j<100000; j++);	}*/	put_s( "arp test begin.\r\n" );	while( 1 ){		arp_request();		wait_a_second();		recv_packet();	}/*	while( j ){		arp_request();		i = 0;		while(i++<100000 && j )			j = recv_packet();	}*/	put_s("arp test end.\r\n");}

⌨️ 快捷键说明

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