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
This commit is contained in:
parent
eb2cc84a6d
commit
9592d89769
@ -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;
|
||||
rt_uint32_t value, tout, id1, id2;
|
||||
#ifdef DM9161
|
||||
rt_uint32_t ulBMSR,ulBMCR,i;
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
#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);
|
||||
|
@ -1,7 +1,19 @@
|
||||
#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
|
||||
#endif
|
||||
|
||||
#define MII_DM9161_ID 0x0181b8a0
|
||||
#define MII_RTL8201_ID 0x82010000
|
||||
|
||||
/* RTL8201 PHY registers. */
|
||||
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user