📄 network.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 + -