提交 942ca4da 编写于 作者: B bernard.xiong

update dm9000 driver

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@67 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 1d08491c
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
* DM9000 interrupt line is connected to PF7 * DM9000 interrupt line is connected to PF7
*/ */
//-------------------------------------------------------- //--------------------------------------------------------
#define DM9000_PHY 0x40 /* PHY address 0x01 */
#define MAX_ADDR_LEN 6 #define MAX_ADDR_LEN 6
enum DM9000_PHY_mode enum DM9000_PHY_mode
{ {
...@@ -23,13 +26,6 @@ enum DM9000_TYPE ...@@ -23,13 +26,6 @@ enum DM9000_TYPE
TYPE_DM9000B TYPE_DM9000B
}; };
struct dm9000_rxhdr
{
rt_uint8_t RxPktReady;
rt_uint8_t RxStatus;
rt_uint16_t RxLen;
} __attribute__((__packed__));
struct rt_dm9000_eth struct rt_dm9000_eth
{ {
/* inherit from ethernet device */ /* inherit from ethernet device */
...@@ -43,22 +39,25 @@ struct rt_dm9000_eth ...@@ -43,22 +39,25 @@ struct rt_dm9000_eth
}; };
static struct rt_dm9000_eth dm9000_device; static struct rt_dm9000_eth dm9000_device;
void delay_ms(rt_uint32_t dt) static void delay_ms(rt_uint32_t ms)
{ {
rt_uint32_t len;
for (;ms > 0; ms --)
for (len = 0; len < 100; len++ );
} }
/* Read a byte from I/O port */ /* Read a byte from I/O port */
rt_inline rt_uint8_t dm9000_io_read(rt_uint16_t reg) rt_inline rt_uint8_t dm9000_io_read(rt_uint16_t reg)
{ {
ETH_ADDR = reg; DM9000_IO = reg;
return (rt_uint8_t) ETH_DATA; return (rt_uint8_t) DM9000_DATA;
} }
/* Write a byte to I/O port */ /* Write a byte to I/O port */
rt_inline void dm9000_io_write(rt_uint16_t reg, rt_uint16_t value) rt_inline void dm9000_io_write(rt_uint16_t reg, rt_uint16_t value)
{ {
ETH_ADDR = reg; DM9000_IO = reg;
ETH_DATA = data; DM9000_DATA = value;
} }
/* Read a word from phyxcer */ /* Read a word from phyxcer */
...@@ -69,7 +68,9 @@ rt_inline rt_uint16_t phy_read(rt_uint16_t reg) ...@@ -69,7 +68,9 @@ rt_inline rt_uint16_t phy_read(rt_uint16_t reg)
/* Fill the phyxcer register into REG_0C */ /* Fill the phyxcer register into REG_0C */
dm9000_io_write(DM9000_EPAR, DM9000_PHY | reg); dm9000_io_write(DM9000_EPAR, DM9000_PHY | reg);
dm9000_io_write(DM9000_EPCR, 0xc); /* Issue phyxcer read command */ dm9000_io_write(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
delay_ms(100); /* Wait read complete */ delay_ms(100); /* Wait read complete */
dm9000_io_write(DM9000_EPCR, 0x0); /* Clear phyxcer read command */ dm9000_io_write(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
val = (dm9000_io_read(DM9000_EPDRH) << 8) | dm9000_io_read(DM9000_EPDRL); val = (dm9000_io_read(DM9000_EPDRH) << 8) | dm9000_io_read(DM9000_EPDRL);
...@@ -86,7 +87,9 @@ rt_inline void phy_write(rt_uint16_t reg, rt_uint16_t value) ...@@ -86,7 +87,9 @@ rt_inline void phy_write(rt_uint16_t reg, rt_uint16_t value)
dm9000_io_write(DM9000_EPDRL, (value & 0xff)); dm9000_io_write(DM9000_EPDRL, (value & 0xff));
dm9000_io_write(DM9000_EPDRH, ((value >> 8) & 0xff)); dm9000_io_write(DM9000_EPDRH, ((value >> 8) & 0xff));
dm9000_io_write(DM9000_EPCR, 0xa); /* Issue phyxcer write command */ dm9000_io_write(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
delay_ms(500); /* Wait write complete */ delay_ms(500); /* Wait write complete */
dm9000_io_write(DM9000_EPCR, 0x0); /* Clear phyxcer write command */ dm9000_io_write(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
} }
...@@ -132,7 +135,7 @@ void rt_dm9000_isr(int irqno) ...@@ -132,7 +135,7 @@ void rt_dm9000_isr(int irqno)
dm9000_io_write(DM9000_IMR, IMR_PAR); dm9000_io_write(DM9000_IMR, IMR_PAR);
/* Got DM9000 interrupt status */ /* Got DM9000 interrupt status */
int_status = ior(DM9000_ISR); /* Got ISR */ int_status = dm9000_io_read(DM9000_ISR); /* Got ISR */
dm9000_io_write(DM9000_ISR, int_status); /* Clear ISR status */ dm9000_io_write(DM9000_ISR, int_status); /* Clear ISR status */
/* Received the coming packet */ /* Received the coming packet */
...@@ -158,7 +161,7 @@ void rt_dm9000_isr(int irqno) ...@@ -158,7 +161,7 @@ void rt_dm9000_isr(int irqno)
} }
/* Re-enable interrupt mask */ /* Re-enable interrupt mask */
dm9000_io_write(DM9000_IMR, db->imr_all); dm9000_io_write(DM9000_IMR, dm9000_device.imr_all);
} }
/* RT-Thread Device Interface */ /* RT-Thread Device Interface */
...@@ -203,10 +206,11 @@ static rt_err_t rt_dm9000_init(rt_device_t dev) ...@@ -203,10 +206,11 @@ static rt_err_t rt_dm9000_init(rt_device_t dev)
dm9000_io_write(DM9000_SMCR, 0); /* Special Mode */ dm9000_io_write(DM9000_SMCR, 0); /* Special Mode */
dm9000_io_write(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */ dm9000_io_write(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */
dm9000_io_write(DM9000_ISR, 0x0f); /* Clear interrupt status */ dm9000_io_write(DM9000_ISR, 0x0f); /* Clear interrupt status */
dm9000_io_write(0x2D, 0x80); /* Switch LED to mode 1 */
/* set mac address */ /* set mac address */
for (i = 0, oft = 0x10; i < 6; i++, oft++) for (i = 0, oft = 0x10; i < 6; i++, oft++)
dm9000_io_write(oft, dm9000_device->dev_addr[i]); dm9000_io_write(oft, dm9000_device.dev_addr[i]);
for (i = 0, oft = 0x16; i < 8; i++, oft++) for (i = 0, oft = 0x16; i < 8; i++, oft++)
dm9000_io_write(oft, 0xff); dm9000_io_write(oft, 0xff);
...@@ -307,7 +311,7 @@ rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p) ...@@ -307,7 +311,7 @@ rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p)
rt_uint16_t* ptr; rt_uint16_t* ptr;
/* Move data to DM9000 TX RAM */ /* Move data to DM9000 TX RAM */
dm9000_io_write(DM9000_MWCMD, DM9000_IO); DM9000_IO = DM9000_MWCMD;
for (q = p; q != NULL; q = q->next) for (q = p; q != NULL; q = q->next)
{ {
...@@ -317,7 +321,7 @@ rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p) ...@@ -317,7 +321,7 @@ rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p)
/* use 16bit mode to write data to DM9000 RAM */ /* use 16bit mode to write data to DM9000 RAM */
while (len) while (len)
{ {
dm9000_io_write(*ptr, DM9000_DATA); DM9000_DATA = *ptr;
ptr ++; len -= 2; ptr ++; len -= 2;
} }
} }
...@@ -344,7 +348,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev) ...@@ -344,7 +348,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
/* Check packet ready or not */ /* Check packet ready or not */
dm9000_io_read(DM9000_MRCMDX); /* Dummy read */ dm9000_io_read(DM9000_MRCMDX); /* Dummy read */
len = dm9000_io_read(DM9000_DATA); /* Got most updated data */ len = DM9000_DATA; /* Got most updated data */
if (len) if (len)
{ {
rt_uint16_t rx_status, rx_len; rt_uint16_t rx_status, rx_len;
...@@ -354,10 +358,10 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev) ...@@ -354,10 +358,10 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
dm9000_io_write(DM9000_ISR, 0x80); /* Stop INT request */ dm9000_io_write(DM9000_ISR, 0x80); /* Stop INT request */
/* A packet ready now & Get status/length */ /* A packet ready now & Get status/length */
DM9000_outb(DM9000_MRCMD, DM9000_IO); DM9000_IO = DM9000_MRCMD;
rx_status = dm9000_io_write(DM9000_DATA); rx_status = DM9000_DATA;
rx_len = dm9000_io_write(DM9000_DATA); rx_len = DM9000_DATA;
/* allocate buffer */ /* allocate buffer */
p = pbuf_alloc(PBUF_LINK, rx_len, PBUF_RAM); p = pbuf_alloc(PBUF_LINK, rx_len, PBUF_RAM);
...@@ -372,7 +376,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev) ...@@ -372,7 +376,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
while (len) while (len)
{ {
*data = dm9000_io_write(DM9000_DATA); *data = DM9000_DATA;
data ++; len -= 2; data ++; len -= 2;
} }
} }
...@@ -385,7 +389,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev) ...@@ -385,7 +389,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
data = &dummy; data = &dummy;
while (rx_len) while (rx_len)
{ {
*data = dm9000_io_write(DM9000_DATA); *data = DM9000_DATA;
rx_len -= 2; rx_len -= 2;
} }
} }
...@@ -395,19 +399,22 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev) ...@@ -395,19 +399,22 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
{ {
if (rx_status & 0x100) if (rx_status & 0x100)
{ {
rt_printf("rx fifo error\n"); rt_kprintf("rx fifo error\n");
} }
if (rx_status & 0x200) { if (rx_status & 0x200) {
rt_printf("rx crc error\n"); rt_kprintf("rx crc error\n");
} }
if (rx_status & 0x8000) if (rx_status & 0x8000)
{ {
rt_printf("rx length error\n"); rt_kprintf("rx length error\n");
} }
if (rx_len > DM9000_PKT_MAX) if (rx_len > DM9000_PKT_MAX)
{ {
rt_printf("rx length too big\n"); rt_kprintf("rx length too big\n");
dm9000_reset();
/* RESET device */
dm9000_io_write(DM9000_NCR, NCR_RST);
delay_ms(1000); /* delay 1ms */
} }
/* it issues an error, release pbuf */ /* it issues an error, release pbuf */
...@@ -423,64 +430,18 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev) ...@@ -423,64 +430,18 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
return p; return p;
} }
{
u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
u16 RxStatus, RxLen = 0;
u32 tmplen, i;
/* Status check: this byte must be 0 or 1 */
if (rxbyte > 1) {
DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */
DM9000_DBG("rx status check: %d\n", rxbyte);
}
/* A packet ready now & Get status/length */
DM9000_outb(DM9000_MRCMD, DM9000_IO);
RxStatus = DM9000_inw(DM9000_DATA);
RxLen = DM9000_inw(DM9000_DATA);
/* Read received packet from RX SRAM */
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA);
if ((RxStatus & 0xbf00) || (RxLen < 0x40)
|| (RxLen > DM9000_PKT_MAX))
{
if (RxStatus & 0x100)
{
rt_printf("rx fifo error\n");
}
if (RxStatus & 0x200) {
rt_printf("rx crc error\n");
}
if (RxStatus & 0x8000)
{
rt_printf("rx length error\n");
}
if (RxLen > DM9000_PKT_MAX)
{
rt_printf("rx length too big\n");
dm9000_reset();
}
}
else
{
/* Pass to upper layer */
DM9000_DBG("passing packet to upper layer\n");
NetReceive(NetRxPackets[0], RxLen);
return RxLen;
}
}
void rt_hw_dm9000_init() void rt_hw_dm9000_init()
{ {
dm9000_device.type = TYPE_DM9000A; dm9000_device.type = TYPE_DM9000A;
dm9000_device.imr_all = IMR_PAR | IMR_PTM | IMR_PRM; dm9000_device.imr_all = IMR_PAR | IMR_PTM | IMR_PRM;
dm9000_device.dev_addr[0] = 0x01;
dm9000_device.dev_addr[1] = 0x60;
dm9000_device.dev_addr[2] = 0x6E;
dm9000_device.dev_addr[3] = 0x11;
dm9000_device.dev_addr[4] = 0x02;
dm9000_device.dev_addr[5] = 0x0F;
dm9000_device.parent.parent.init = rt_dm9000_init; dm9000_device.parent.parent.init = rt_dm9000_init;
dm9000_device.parent.parent.open = rt_dm9000_open; dm9000_device.parent.parent.open = rt_dm9000_open;
...@@ -502,15 +463,14 @@ void rt_hw_dm9000_init() ...@@ -502,15 +463,14 @@ void rt_hw_dm9000_init()
void dm9000(void) void dm9000(void)
{ {
rt_kprintf("\n"); rt_kprintf("\n");
rt_kprintf("NCR (0x00): %02x\n", dm9000_io_read(0)); rt_kprintf("NCR (0x00): %02x\n", dm9000_io_read(DM9000_NCR));
rt_kprintf("NSR (0x01): %02x\n", dm9000_io_read(1)); rt_kprintf("NSR (0x01): %02x\n", dm9000_io_read(DM9000_NSR));
rt_kprintf("TCR (0x02): %02x\n", dm9000_io_read(2)); rt_kprintf("TCR (0x02): %02x\n", dm9000_io_read(DM9000_TCR));
rt_kprintf("TSRI (0x03): %02x\n", dm9000_io_read(3)); rt_kprintf("TSRI (0x03): %02x\n", dm9000_io_read(DM9000_TSR1));
rt_kprintf("TSRII (0x04): %02x\n", dm9000_io_read(4)); rt_kprintf("TSRII (0x04): %02x\n", dm9000_io_read(DM9000_TSR2));
rt_kprintf("RCR (0x05): %02x\n", dm9000_io_read(5)); rt_kprintf("RCR (0x05): %02x\n", dm9000_io_read(DM9000_RCR));
rt_kprintf("RSR (0x06): %02x\n", dm9000_io_read(6)); rt_kprintf("RSR (0x06): %02x\n", dm9000_io_read(DM9000_RSR));
rt_kprintf("ISR (0xFE): %02x\n", dm9000_io_read(ISR)); rt_kprintf("ISR (0xFE): %02x\n", dm9000_io_read(DM9000_ISR));
rt_kprintf("\n"); rt_kprintf("\n");
} }
#endif #endif
#ifndef __DM9000_H__ #ifndef __DM9000_H__
#define __DM9000_H__ #define __DM9000_H__
#define ETH_ADDR (*((volatile unsigned short *) 0x6C000000)) // CMD = 0 #define DM9000_IO (*((volatile rt_uint16_t *) 0x6C000000)) // CMD = 0
#define ETH_DATA (*((volatile unsigned short *) 0x6C000008)) // CMD = 1 #define DM9000_DATA (*((volatile rt_uint16_t *) 0x6C000008)) // CMD = 1
#define RST_1() GPIO_SetBits(GPIOF,GPIO_Pin_6) #define RST_1() GPIO_SetBits(GPIOF,GPIO_Pin_6)
#define RST_0() GPIO_ResetBits(GPIOF,GPIO_Pin_6) #define RST_0() GPIO_ResetBits(GPIOF,GPIO_Pin_6)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册