diff options
| author | mbbill <[email protected]> | 2010-03-28 09:02:26 +0000 |
|---|---|---|
| committer | mbbill <[email protected]> | 2010-03-28 09:02:26 +0000 |
| commit | 9592d89769c6dd94a1a2983092ddba7206c541a8 (patch) | |
| tree | 67cb58bae51579b08fad95a21c0ba570069e1e46 | |
| parent | eb2cc84a6d9441e8739097a23c88c020320d8bb6 (diff) | |
FIX: Merged ljt8015's patch, add DM9161 support.
NOTE: The project.uv2 left not modified.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@546 bbd45198-f89e-11dd-88c7-29a3b14d5316
| -rw-r--r-- | bsp/sam7x/board.c | 6 | ||||
| -rw-r--r-- | bsp/sam7x/project.uvproj | 4 | ||||
| -rw-r--r-- | bsp/sam7x/sam7x_emac.c | 129 | ||||
| -rw-r--r-- | bsp/sam7x/sam7x_emac.h | 51 | ||||
| -rw-r--r-- | bsp/sam7x/serial.c | 12 | ||||
| -rw-r--r-- | bsp/sam7x/startup.c | 1 |
6 files changed, 183 insertions, 20 deletions
diff --git a/bsp/sam7x/board.c b/bsp/sam7x/board.c index c9a0613cb6..b25c4e5cf1 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 <rtthread.h> @@ -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 a6a5e4c84b..827847cd48 100644 --- a/bsp/sam7x/project.uvproj +++ b/bsp/sam7x/project.uvproj @@ -116,7 +116,7 @@ <Simulator> <UseSimulator>1</UseSimulator> <LoadApplicationAtStartup>1</LoadApplicationAtStartup> - <RunToMain>1</RunToMain> + <RunToMain>0</RunToMain> <RestoreBreakpoints>1</RestoreBreakpoints> <RestoreWatchpoints>1</RestoreWatchpoints> <RestoreMemoryDisplay>1</RestoreMemoryDisplay> @@ -343,7 +343,7 @@ <uThumb>0</uThumb> <VariousControls> <MiscControls></MiscControls> - <Define></Define> + <Define>RT_DEBUG</Define> <Undefine></Undefine> <IncludePath>.;..\..\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</IncludePath> </VariousControls> diff --git a/bsp/sam7x/sam7x_emac.c b/bsp/sam7x/sam7x_emac.c index 39fa8e5906..e84807f3ab 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;
+ 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");
- /* 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);
+ /* 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 49d156f94b..4a351fe9b3 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 79b436867b..19aa87666b 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 <rthw.h> @@ -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 7945a55c5e..ec6d9b495a 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 |
