提交 9592d897 编写于 作者: M mbbill

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
上级 eb2cc84a
......@@ -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 */
......
......@@ -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>
......
......@@ -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);
......
#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
......@@ -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);
}
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册