我照着技创的极品arm做了一块板子,s3c2440的,网片为dm9000ae,cpu可以识别读出DM9000的id,但是与pc相连时出现: U-Boot 1.1.2 (Jan 2 2008 - 10:49:23)
U-Boot code: 33C00000 -> 33C2B19C BSS: -> 33C64BCC
RAM Configuration:
Bank #0: 30000000 64 MB
Get flash bank 0 size @ 0x0
Total Flash bank's sizes: 0x200000
protect monitor 2b19c bytes @ address 0
Flash: 2 MB
NAND:Flash chip found:
Manufacturer ID: 0xEC, Chip ID: 0x76 (Samsung unknown 64Mb)
1 flash chips found. Total nand_chip size: 64 MB
64 MB
*** Warning - bad CRC, using default environment
Silicon Motion 501 not detected
In: serial
Out: serial
Err: serial
Found DM9000 ID:90000a46 at address 10000000, ethaddr = 08:00:3e:26:0a:5b!
DM9000 work in 16 bus width
Not link of ethernet
SD Initialize fail..
Hit any key to stop autoboot: 0
MDS522C@Xlongtech # set ipaddr 192.168.3.15
MDS522C@Xlongtech # set serverip 192.168.3.96
MDS522C@Xlongtech # t 30038000 eboot.nb0
DM9000 work in 16 bus width
Not link of ethernet
TFTP from server 192.168.3.96; our IP address is 192.168.3.15
Filename 'eboot.nb0'.
Load address: 0x30038000
Loading: T T T T T T T T T T
Retry count exceeded; starting again
TFTP from server 192.168.3.96; our IP address is 192.168.3.15
Filename 'eboot.nb0'.
Load address: 0x30038000
Loading: T T T T 一直重复,感觉与pc没有连接上,拔掉网线的现象与这个一摸一样,驱动程序如下: #include <common.h> #include <command.h> #include <net.h>
#ifdef CONFIG_DRIVER_DM9000
#if (CONFIG_COMMANDS & CFG_CMD_NET) #define DM9000_VID_L 0x28 #define DM9000_VID_H 0x29 #define DM9000_PID_L 0x2A #define DM9000_PID_H 0x2B #define DM9000_ID 0x90000A46 #define DM9000_INT_MII 0x00 #define DM9000_PPTR *(volatile u16 *)(DM9000_BASE) #define DM9000_PDATA *(volatile u16 *)(DM9000_BASE + 4) static unsigned char ior(int reg); static int polling_times;
/* edit by davicom */ static void eth_mem_test (void) { u8 i; u16 j , k ; iow(0x00, 3); udelay(50); /* delay 100us */ iow(0x00, 2); iow(0xff , 0x00);
printf("\n <DM9000A> REG R/W TEST "); for(i = 0; i < 7; i++) { iow(0x16 + i, (0x5a + i)); if(ior(0x16 + i) != (0x5a + i)) break; iow(0x16 + i, 0x00); } if(i != 7) printf("===> REG R/W FALSE "); else printf("===> REG R/W PASS "); for(i = 0 ; i < 0x4 ; i++) { //if((i * 0x1000) != ((ior(0xf4)<<8)+ior(0xf5))) //{ // printf("\n io mode error or data jump error"); // break; //} k = 0xaa55; printf("\n <DM9000A> FIFO TEST R: %02x%02x W: %02x%02x ", ior(0xf5) , ior(0xf4) , ior(0xfa) , ior(0xfb)); DM9000_PPTR = 0xf8; for(j = 0 ; j < 0x1000 ; j += 2) { k -= 0x0303; DM9000_PDATA = k; } DM9000_PPTR = 0xf0; k = DM9000_PDATA; k = DM9000_PDATA; k = 0xaa55; DM9000_PPTR = 0xf2; for(j = 0 ; j < 0x1000 ; j += 2) { k -= 0x0303; if (DM9000_PDATA != k)break; } if(j != 0x1000) { printf("===> FIFO TEST R/W FALSE "); break; } else printf("===> FIFO TEST R/W PASS "); } } /* edit by davicom */
/* packet page register access functions */ static u32 GetDM9000ID(void) { u32 id_val;
DM9000_PPTR = DM9000_PID_H; id_val = (DM9000_PDATA & 0xff) << 8; DM9000_PPTR = DM9000_PID_L; id_val+= (DM9000_PDATA & 0xff); id_val = id_val << 16; DM9000_PPTR = DM9000_VID_H; id_val += (DM9000_PDATA & 0xff) << 8; DM9000_PPTR = DM9000_VID_L; id_val += (DM9000_PDATA & 0xff);
return id_val; }
static unsigned short get_reg (int regno) { DM9000_PPTR = regno; return (unsigned short) DM9000_PDATA; }
static void put_reg (int regno, unsigned short val) { DM9000_PPTR = regno; DM9000_PDATA = val; }
static void iow(int reg, u8 value) { DM9000_PPTR = reg; DM9000_PDATA = value & 0xff; }
static unsigned char ior(int reg) { DM9000_PPTR = reg; return DM9000_PDATA & 0xff; }
static void eth_reset (void) { int IoMode; u8 tmp; //printf("---->eth_reset \n"); iow(0x1f, 0x00);/* Enable PHY , Let GPIO0 output value = 0*/ udelay(50);
iow(0, 3);/* register 0 set 1 in order to reset, auto clean after 10us*/ udelay(50);/* delay 100us */ iow(0, 3);/* register 0 set 1 in order to reset, auto clean after 10us*/ udelay(50);/* delay 100us */
IoMode = ior(0xfe) >> 6; /* ISR bit7:6 keeps I/O mode */ if(!IoMode) printf("DM9000 work in 16 bus width\n"); else if(IoMode == 2) printf("DM9000 work in 8 bus width\n"); else if(IoMode == 1) printf("DM9000 work in 32 bus width\n"); else printf("DM9000 work in wrong bus width, error\n"); iow(0, 0); iow(0x8, 0x3f);/*Back Pressure Threshold Register*/ iow(0x2f, 0);/*Special Mode*/ iow(0x1, 0x2c);/*Clear Wakeup, TX1 and TX2 complete status*/ //iow(0xfe, 0x0f); iow(0x5, 0x31);/* enable rx fuction */ iow(0xff, 0x80); //iow(0x1e, 0x01); /* Let GPIO0 output */ //iow(0xff, 0x80); /* disable interrupt and sram read/write point auto return*/ //iow(0x01, 0xc); /* clear TX status */ //iow(0x5, 0x33); /* enable rx fuction, note: must set promiscuous mode */ //iow(0x5, 0x31); /* enable rx fuction */ //ior(0x6); //iow(0x2, 1); /* enable tx fuction */ IoMode = ior(0x01); if(IoMode & 0x40) printf("Link on ethernet at:%d Mbps\n", (IoMode & 0x80) ? 10:100); else printf("Not link of ethernet\n"); //printf("<---- eth_reset \n"); }
void DM9000_get_enetaddr (uchar * addr) { int i, oft; unsigned char env_enetaddr[6]; char *tmp = getenv ("ethaddr"); char *tmp1 = tmp; char *end; u32 ID;
for (i=0; i<6; i++) { env_enetaddr = tmp ? simple_strtoul(tmp, &end, 16) : 0; if (tmp) tmp = (*end) ? end+1 : end; } memcpy (addr, env_enetaddr, 6); ID = GetDM9000ID(); if ( ID != DM9000_ID){ printf("not found the dm9000\n"); return;} printf("Found DM9000 ID:%x at address %x, ethaddr = %s!\n", ID, DM9000_BASE, tmp1); eth_reset (); for (i = 0, oft = 0x10; i < 6; i++, oft++) iow(oft, addr); iow(0x1d, 0x80);/*receive broadcast packets*/ return; }
void eth_halt (void) { GetDM9000ID(); }
int eth_init (bd_t * bd) { //eth_mem_test(); eth_reset(); polling_times=0; return 0; }
/* Get a data block via Ethernet */ extern int eth_rx (void) { int i; unsigned short rxlen; unsigned short *addr; unsigned short status; u8 RxRead; u8 *tmp; polling_times++; //printf("Read address=0x%04x %04x\n",ior(0xf4), ior(0xf5)); ior(0xf4); ior(0xf5); RxRead = ior(0xf0); RxRead = (DM9000_PDATA) & 0xff; RxRead = (DM9000_PDATA) & 0xff; RxRead = (DM9000_PDATA) & 0xff; RxRead = (DM9000_PDATA) & 0xff; RxRead = (DM9000_PDATA) & 0xff; RxRead = (DM9000_PDATA) & 0xff;
//printf("Read address=0x%04x %04x\n",ior(0xfa), ior(0xfb)); //udelay(1000); if (RxRead != 1) /* no data */ return 0;
DM9000_PPTR = 0xf2; /* set read ptr ++ */
status = DM9000_PDATA; /* get stat */ rxlen = DM9000_PDATA; /* get len */ //printf("rxlen = %d\n", rxlen); if (rxlen > PKTSIZE_ALIGN + PKTALIGN) printf ("packet too big! %d %d\n", rxlen, PKTSIZE_ALIGN + PKTALIGN);
for (addr = (unsigned short *) NetRxPackets[0], i = rxlen >> 1; i > 0; i--) *addr++ = DM9000_PDATA; if (rxlen & 1) *addr = DM9000_PDATA;
/* Pass the packet up to the protocol layers. */ NetReceive (NetRxPackets[0], rxlen);
return rxlen; }
/* Send a data block via Ethernet. */ extern int eth_send (volatile void *packet, int length) { volatile unsigned short *addr; int tmo; u8 TxStatus; int length1 = length; int IoMode; retry: TxStatus = ior(0x01); TxStatus = TxStatus & 0xc; #if 0
/* Test to see if the chip has allocated memory for the packet */ if (!TxStatus) { printf ("unable to send packet; retrying... %d\n", TxStatus); for (tmo = get_timer (0) + CFG_HZ; get_timer (0) < tmo;); /*NOP*/; IoMode = ior(0x01); if(IoMode & 0x40) eth_reset (); goto retry; } #endif //printf("polling times = %d\n",polling_times); DM9000_PPTR = 0xf8; /* data copy ready set */ /* copy data */ for (addr = packet; length > 0; length -= 2) { //printf("[%02x][%02x]", *(u8 *)addr, *((u8 *)addr + 1)); DM9000_PDATA = *addr++; } //printf("\n"); iow(0xfd, (length1 >> 8) & 0xff); /*set transmit leng */ iow(0xfc, length1 & 0xff); /* start transmit */ iow(0x02, 1); polling_times=0; return 0; } #endif /* COMMANDS & CFG_NET */
#endif /* CONFIG_DRIVER_DM9000 */ 电路检查没有发现问题!! 希望各位大虾帮看看啊!!! 谢谢了!!! |