diff --git a/bsp/sam7x/board.c b/bsp/sam7x/board.c index c9a0613cb61a1cc8b6ca1b19db366cbe8cf3f85f..b25c4e5cf1052a383c32577a8a15caeec9fdb427 100644 --- a/bsp/sam7x/board.c +++ b/bsp/sam7x/board.c @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2006-08-23 Bernard first implementation + * 2010-03-09 ljt8015 Fix a bug in rt_hw_console_init() */ #include @@ -128,8 +129,9 @@ static void rt_hw_console_init() { /* Enable Clock for USART0 */ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US0; - /* Enable RxD0 and TxDO Pin */ - AT91C_BASE_PIOA->PIO_PDR = (1 << 5) | (1 << 6); + /* Enable RxD0 and TxD0 Pin */ + //AT91C_BASE_PIOA->PIO_PDR = (1 << 5) | (1 << 6); + AT91C_BASE_PIOA->PIO_PDR = 1 | (1 << 1);//fix bug 2010-3-9 AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | /* Reset Receiver */ AT91C_US_RSTTX | /* Reset Transmitter */ diff --git a/bsp/sam7x/project.uvproj b/bsp/sam7x/project.uvproj index a6a5e4c84bea7a6cd13300cf03454f3f82cd645c..827847cd4831b20eba53c4e8ee8395312459ad88 100644 --- a/bsp/sam7x/project.uvproj +++ b/bsp/sam7x/project.uvproj @@ -116,7 +116,7 @@ 1 1 - 1 + 0 1 1 1 @@ -343,7 +343,7 @@ 0 - + RT_DEBUG .;..\..\include;..\sam7x;..\..\finsh;..\..\net\lwip\src\include;..\..\net\lwip\src;..\..\net\lwip\src\arch\include;..\..\net\lwip\src\include\ipv4;;..\..\filesystem\dfs;..\..\filesystem\dfs\include;..\..\filesystem\dfs\filesystems\efsl\src\include;..\..\filesystem\dfs\filesystems\efsl\src\base\include;..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\include diff --git a/bsp/sam7x/sam7x_emac.c b/bsp/sam7x/sam7x_emac.c index 39fa8e5906fdd220ec504bed0a598527002ebe95..e84807f3abb5988ff0871f8d1891f6e595011467 100644 --- a/bsp/sam7x/sam7x_emac.c +++ b/bsp/sam7x/sam7x_emac.c @@ -7,6 +7,27 @@ #include "lwipopts.h" #define MAX_ADDR_LEN 6 + +#ifdef DM9161 +#define EMAC_PIO_CFG (AT91C_PB8_EMDC | \ + AT91C_PB9_EMDIO | \ + AT91C_PB2_ETX0 | \ + AT91C_PB3_ETX1 | \ + AT91C_PB10_ETX2 | \ + AT91C_PB11_ETX3 | \ + AT91C_PB1_ETXEN | \ + AT91C_PB0_ETXCK_EREFCK | \ + AT91C_PB15_ERXDV_ECRSDV | \ + AT91C_PB5_ERX0 | \ + AT91C_PB6_ERX1 | \ + AT91C_PB12_ETXER | \ + AT91C_PB13_ERX2 | \ + AT91C_PB14_ERX3 | \ + AT91C_PB17_ERXCK | \ + AT91C_PB16_ECOL | \ + AT91C_PB4_ECRS | \ + AT91C_PB7_ERXER) +#else #define EMAC_PIO_CFG (AT91C_PB0_ETXCK_EREFCK | \ AT91C_PB1_ETXEN | \ AT91C_PB2_ETX0 | \ @@ -25,6 +46,7 @@ AT91C_PB15_ERXDV_ECRSDV| \ AT91C_PB16_ECOL | \ AT91C_PB17_ERXCK) +#endif #define RB_BUFFER_SIZE 8 /* max number of receive buffers */ #define ETH_RX_BUF_SIZE 128 @@ -61,7 +83,6 @@ rt_inline void write_phy(rt_uint8_t addr, rt_uint32_t value) { AT91C_BASE_EMAC->EMAC_MAN = ((0x01<<30) | (2 << 16) | (1 << 28) | (AT91C_PHY_ADDR << 23) | (addr << 18)) | value; - /* Wait until IDLE bit in Network Status register is cleared */ while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE)); } @@ -83,7 +104,7 @@ rt_inline void sam7xether_reset_tx_desc(void) if(tb_descriptors[index].status & TxDESC_STATUS_USED) { - while(!tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF) + while(!(tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF)) { index ++; if(index >= TB_BUFFER_SIZE)index = 0; @@ -96,6 +117,7 @@ rt_inline void sam7xether_reset_tx_desc(void) } } + /* interrupt service routing */ static void sam7xether_isr(int irq) { @@ -128,15 +150,81 @@ static void sam7xether_isr(int irq) rt_inline void linksetup(void) { - rt_uint32_t value; - - /* Check if this is a RTL8201 PHY. */ - rt_uint16_t id1 = read_phy(PHY_REG_PHYID1); - rt_uint16_t id2 = read_phy(PHY_REG_PHYID2); + rt_uint32_t value, tout, id1, id2; +#ifdef DM9161 + rt_uint32_t ulBMSR,ulBMCR,i; +#endif + +#ifdef DM9161 + //PHY has internal pull down : disable MII isolate + tout = read_phy(PHY_REG_BMCR); + tout = read_phy(PHY_REG_BMCR); + tout &= ~BMCR_ISOLATE; + write_phy(PHY_REG_BMCR, tout); + + /* Check if this is a RTL8201 or DM9161 PHY. */ + id1 = read_phy(PHY_REG_PHYID1); + id2 = read_phy(PHY_REG_PHYID2); + + if (((id1 << 16) | (id2 & 0xfff0)) == MII_DM9161_ID) + { + rt_kprintf("read MII_DM9161_ID ok!\n"); + + tout = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX | + DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3; + write_phy(PHY_REG_ANAR, tout); + // Wait for PHY auto negotiation completed + i = 0; + do { + ulBMSR = read_phy(PHY_REG_BMSR); + ulBMSR = read_phy(PHY_REG_BMSR); + i++; + + if(i >= 0xffff) + break; + }while (!(ulBMSR & BMSR_ANEGCOMPLETE)); + + if(i >= 0xffff) + rt_kprintf("PHY No Link!\n"); + else + rt_kprintf("PHY auto negotiation completed!\n"); + + /* Update the MAC register NCFGR. */ + AT91C_BASE_EMAC->EMAC_NCFGR = 0; + ulBMCR = read_phy(PHY_REG_BMCR); + + if (ulBMCR & BMCR_ANENABLE) + { + /* AutoNegotiation is enabled. */ + if(!(ulBMSR & BMSR_ANEGCOMPLETE)) + { + /* Auto-negotitation in progress. */ + rt_kprintf("Auto-negotitation in progress!\n"); + return; + } + + if (ulBMCR & BMCR_SPEED100) + { + /* Speed 100Mbit is enabled. */ + AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD; + + } + if (ulBMCR & BMCR_FULLDPLX) + { + /* Full duplex is enabled. */ + AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD; + } + } + } +#else + /* Check if this is a RTL8201 or DM9161 PHY. */ + id1 = read_phy(PHY_REG_PHYID1); + id2 = read_phy(PHY_REG_PHYID2); if (((id2 << 16) | (id1 & 0xfff0)) == MII_RTL8201_ID) { - rt_uint32_t tout; + rt_kprintf("read MII_RTL8201_ID ok!\n"); + /* Configure the PHY device */ /* Use autonegotiation about the link speed. */ @@ -156,7 +244,6 @@ rt_inline void linksetup(void) if (value & BMSR_LINKST) break; /* Link is on. */ } } - value = read_phy (PHY_REG_ANLPAR); /* Update the MAC register NCFGR. */ @@ -166,6 +253,7 @@ rt_inline void linksetup(void) if (value & 0xA000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD; /* set speed */ if (value & 0xC000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD; + #endif } /* @@ -214,6 +302,8 @@ rt_inline void sam7xether_desc_init() /* initialize the interface */ rt_err_t sam7xether_init(rt_device_t dev) { + rt_uint32_t i; + /* enable peripheral clock for EMAC and PIO B */ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB | 1 << AT91C_ID_EMAC; @@ -240,10 +330,21 @@ rt_err_t sam7xether_init(rt_device_t dev) AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x08 << 8) ; AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST; - while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL)); + + i = 0; + while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL)) + { + i++; + if(i >= 0xfffff) + break; + } + + for(i=0; i<0xfffff; i++);//* 等待一段指定的时间,使PHY就绪 linksetup(); + rt_kprintf("linksetup ok!\n"); + /* Disable management port in MAC control register. */ AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; @@ -262,13 +363,16 @@ rt_err_t sam7xether_init(rt_device_t dev) AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR); /* Configure EMAC operation mode. */ - AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS); + //AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS); + // 复制所有有效帧到接收缓冲区 *不复制FCS字段 不接收广播帧 不接收1526字节长帧 + AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_CAF |AT91C_EMAC_DRFCS | AT91C_EMAC_NBC | AT91C_EMAC_BIG; AT91C_BASE_EMAC->EMAC_NCR |= (AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_WESTAT); /* update MAC address */ update_mac_address(sam7x_dev); /* enable interrupt */ + AT91C_BASE_EMAC->EMAC_IDR = 0x3fff; AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP; /* setup interrupt */ @@ -496,12 +600,13 @@ struct pbuf *sam7xether_rx(rt_device_t dev) if (pkt_len > 0) break; index ++; - if (index > RB_BUFFER_SIZE) index = 0; + if (index >= RB_BUFFER_SIZE) index = 0; } if (pkt_len) { - p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM); + //p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, pkt_len, PBUF_POOL); if(p != RT_NULL) { sam7xether_read_frame(RT_NULL, 0, pkt_len); diff --git a/bsp/sam7x/sam7x_emac.h b/bsp/sam7x/sam7x_emac.h index 49d156f94b7051c0e9deb05ee1153032865b5785..4a351fe9b3b4a7a513ae1b49d47d73dd5f5d2788 100644 --- a/bsp/sam7x/sam7x_emac.h +++ b/bsp/sam7x/sam7x_emac.h @@ -1,8 +1,20 @@ #ifndef __SAM7X_EMAC_H__ #define __SAM7X_EMAC_H__ +//#define DM9161 +#define RTL8201 + + + + +#ifdef DM9161 + #define AT91C_PHY_ADDR 31 +#else #define AT91C_PHY_ADDR 0x01 -#define MII_RTL8201_ID 0x82010000 +#endif + +#define MII_DM9161_ID 0x0181b8a0 +#define MII_RTL8201_ID 0x82010000 /* RTL8201 PHY registers. */ #define PHY_REG_BMCR 0x00 /* Basic mode control register */ @@ -22,6 +34,18 @@ #define PHY_REG_DISCR 0x17 /* Disconnect Counter register */ #define PHY_REG_RLSR 0x18 /* Hardware Reset Latch State reg. */ +/* Basic mode control register. */ +#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + #define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ #define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ #define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ @@ -59,6 +83,31 @@ #define TxDESC_STATUS_WRAP (1U << 30) #define TxDESC_STATUS_USED (1U << 31) +//----dm9161 define---- +#define DM9161_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation +#define DM9161_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation +#define DM9161_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps +#define DM9161_AUTONEG (1 << 12) // Auto-negotiation Enable +#define DM9161_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation +#define DM9161_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation +#define DM9161_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation +#define DM9161_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation +#define DM9161_COLLISION_TEST (1 << 7) // 1 = Collision test enabled 0 = Normal operation + + +#define DM9161_NP (1 << 15) // Next page Indication +#define DM9161_ACK (1 << 14) // Acknowledge +#define DM9161_RF (1 << 13) // Remote Fault +// Reserved 12 to 11 // Write as 0, ignore on read +#define DM9161_FCS (1 << 10) // Flow Control Support +#define DM9161_T4 (1 << 9) // 100BASE-T4 Support +#define DM9161_TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support +#define DM9161_TX_HDX (1 << 7) // 100BASE-TX Support +#define DM9161_10_FDX (1 << 6) // 10BASE-T Full Duplex Support +#define DM9161_10_HDX (1 << 5) // 10BASE-T Support +// Selector 4 to 0 // Protocol Selection Bits +#define DM9161_AN_IEEE_802_3 0x0001 + int sam7xether_register(char *name); #endif diff --git a/bsp/sam7x/serial.c b/bsp/sam7x/serial.c index 79b436867bb985ac7f3e1f8d3e24885833eccfcd..19aa87666b62d4a716e777b1426f29c80c4459bd 100644 --- a/bsp/sam7x/serial.c +++ b/bsp/sam7x/serial.c @@ -12,6 +12,7 @@ * 2006-08-23 Bernard first version * 2009-05-14 Bernard add RT-THread device interface * 2010-03-14 MingBai US_IMR is read-only. + * 2010-03-16 MingBai Changed interrupt source mode to level sensitive. */ #include @@ -148,12 +149,14 @@ static rt_err_t rt_serial_init (rt_device_t dev) if (serial->peripheral_id == AT91C_ID_US0) { /* set pinmux */ - AT91C_PIO_PDR = (1 << 5) | (1 << 6); + //AT91C_PIO_PDR = (1 << 5) | (1 << 6); + AT91C_PIO_PDR = 1 | (1 << 1); //fix bug 2010-3-9 } else if (serial->peripheral_id == AT91C_ID_US1) { /* set pinmux */ - AT91C_PIO_PDR = (1 << 21) | (1 << 22); + //AT91C_PIO_PDR = (1 << 21) | (1 << 22); + AT91C_PIO_PDR = (1 << 5) | (1 << 6); //fix bug 2010-3-9 } serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */ @@ -200,7 +203,10 @@ static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) /* install UART handler */ rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL); - AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5); + // SAM7X Datasheet 30.5.3: + // It is notrecommended to use the USART interrupt line in edge sensitive mode + //AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5); + AT91C_AIC_SMR(serial->peripheral_id) = 5; rt_hw_interrupt_umask(serial->peripheral_id); } diff --git a/bsp/sam7x/startup.c b/bsp/sam7x/startup.c index 7945a55c5e41996756fcba6bdc89a85853188d1d..ec6d9b495a5510f884b588396998ac6c69568f1e 100644 --- a/bsp/sam7x/startup.c +++ b/bsp/sam7x/startup.c @@ -23,6 +23,7 @@ #ifdef RT_USING_LWIP #include "sam7x_emac.h" +extern rt_err_t eth_system_device_init(void); #endif #ifdef RT_USING_FINSH