update dm9000 driver

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@67 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
bernard.xiong 2009-10-02 08:06:55 +00:00
parent 1d08491cbf
commit 942ca4da63
2 changed files with 53 additions and 92 deletions

View File

@ -8,6 +8,9 @@
* DM9000 interrupt line is connected to PF7
*/
//--------------------------------------------------------
#define DM9000_PHY 0x40 /* PHY address 0x01 */
#define MAX_ADDR_LEN 6
enum DM9000_PHY_mode
{
@ -23,13 +26,6 @@ enum DM9000_TYPE
TYPE_DM9000B
};
struct dm9000_rxhdr
{
rt_uint8_t RxPktReady;
rt_uint8_t RxStatus;
rt_uint16_t RxLen;
} __attribute__((__packed__));
struct rt_dm9000_eth
{
/* inherit from ethernet device */
@ -43,22 +39,25 @@ struct rt_dm9000_eth
};
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 */
rt_inline rt_uint8_t dm9000_io_read(rt_uint16_t reg)
{
ETH_ADDR = reg;
return (rt_uint8_t) ETH_DATA;
DM9000_IO = reg;
return (rt_uint8_t) DM9000_DATA;
}
/* Write a byte to I/O port */
rt_inline void dm9000_io_write(rt_uint16_t reg, rt_uint16_t value)
{
ETH_ADDR = reg;
ETH_DATA = data;
DM9000_IO = reg;
DM9000_DATA = value;
}
/* Read a word from phyxcer */
@ -69,7 +68,9 @@ rt_inline rt_uint16_t phy_read(rt_uint16_t reg)
/* Fill the phyxcer register into REG_0C */
dm9000_io_write(DM9000_EPAR, DM9000_PHY | reg);
dm9000_io_write(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
delay_ms(100); /* Wait read complete */
dm9000_io_write(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
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)
dm9000_io_write(DM9000_EPDRL, (value & 0xff));
dm9000_io_write(DM9000_EPDRH, ((value >> 8) & 0xff));
dm9000_io_write(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
delay_ms(500); /* Wait write complete */
dm9000_io_write(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
}
@ -132,7 +135,7 @@ void rt_dm9000_isr(int irqno)
dm9000_io_write(DM9000_IMR, IMR_PAR);
/* 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 */
/* Received the coming packet */
@ -158,7 +161,7 @@ void rt_dm9000_isr(int irqno)
}
/* 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 */
@ -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_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */
dm9000_io_write(DM9000_ISR, 0x0f); /* Clear interrupt status */
dm9000_io_write(0x2D, 0x80); /* Switch LED to mode 1 */
/* set mac address */
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++)
dm9000_io_write(oft, 0xff);
@ -307,7 +311,7 @@ rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p)
rt_uint16_t* ptr;
/* 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)
{
@ -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 */
while (len)
{
dm9000_io_write(*ptr, DM9000_DATA);
DM9000_DATA = *ptr;
ptr ++; len -= 2;
}
}
@ -344,7 +348,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
/* Check packet ready or not */
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)
{
rt_uint16_t rx_status, rx_len;
@ -354,10 +358,10 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
dm9000_io_write(DM9000_ISR, 0x80); /* Stop INT request */
/* 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_len = dm9000_io_write(DM9000_DATA);
rx_status = DM9000_DATA;
rx_len = DM9000_DATA;
/* allocate buffer */
p = pbuf_alloc(PBUF_LINK, rx_len, PBUF_RAM);
@ -372,7 +376,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
while (len)
{
*data = dm9000_io_write(DM9000_DATA);
*data = DM9000_DATA;
data ++; len -= 2;
}
}
@ -385,7 +389,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
data = &dummy;
while (rx_len)
{
*data = dm9000_io_write(DM9000_DATA);
*data = DM9000_DATA;
rx_len -= 2;
}
}
@ -395,19 +399,22 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
{
if (rx_status & 0x100)
{
rt_printf("rx fifo error\n");
rt_kprintf("rx fifo error\n");
}
if (rx_status & 0x200) {
rt_printf("rx crc error\n");
rt_kprintf("rx crc error\n");
}
if (rx_status & 0x8000)
{
rt_printf("rx length error\n");
rt_kprintf("rx length error\n");
}
if (rx_len > DM9000_PKT_MAX)
{
rt_printf("rx length too big\n");
dm9000_reset();
rt_kprintf("rx length too big\n");
/* RESET device */
dm9000_io_write(DM9000_NCR, NCR_RST);
delay_ms(1000); /* delay 1ms */
}
/* it issues an error, release pbuf */
@ -423,65 +430,19 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
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()
{
dm9000_device.type = TYPE_DM9000A;
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.open = rt_dm9000_open;
dm9000_device.parent.parent.close = rt_dm9000_close;
@ -502,15 +463,14 @@ void rt_hw_dm9000_init()
void dm9000(void)
{
rt_kprintf("\n");
rt_kprintf("NCR (0x00): %02x\n", dm9000_io_read(0));
rt_kprintf("NSR (0x01): %02x\n", dm9000_io_read(1));
rt_kprintf("TCR (0x02): %02x\n", dm9000_io_read(2));
rt_kprintf("TSRI (0x03): %02x\n", dm9000_io_read(3));
rt_kprintf("TSRII (0x04): %02x\n", dm9000_io_read(4));
rt_kprintf("RCR (0x05): %02x\n", dm9000_io_read(5));
rt_kprintf("RSR (0x06): %02x\n", dm9000_io_read(6));
rt_kprintf("ISR (0xFE): %02x\n", dm9000_io_read(ISR));
rt_kprintf("NCR (0x00): %02x\n", dm9000_io_read(DM9000_NCR));
rt_kprintf("NSR (0x01): %02x\n", dm9000_io_read(DM9000_NSR));
rt_kprintf("TCR (0x02): %02x\n", dm9000_io_read(DM9000_TCR));
rt_kprintf("TSRI (0x03): %02x\n", dm9000_io_read(DM9000_TSR1));
rt_kprintf("TSRII (0x04): %02x\n", dm9000_io_read(DM9000_TSR2));
rt_kprintf("RCR (0x05): %02x\n", dm9000_io_read(DM9000_RCR));
rt_kprintf("RSR (0x06): %02x\n", dm9000_io_read(DM9000_RSR));
rt_kprintf("ISR (0xFE): %02x\n", dm9000_io_read(DM9000_ISR));
rt_kprintf("\n");
}
#endif

View File

@ -1,8 +1,9 @@
#ifndef __DM9000_H__
#define __DM9000_H__
#define ETH_ADDR (*((volatile unsigned short *) 0x6C000000)) // CMD = 0
#define ETH_DATA (*((volatile unsigned short *) 0x6C000008)) // CMD = 1
#define DM9000_IO (*((volatile rt_uint16_t *) 0x6C000000)) // CMD = 0
#define DM9000_DATA (*((volatile rt_uint16_t *) 0x6C000008)) // CMD = 1
#define RST_1() GPIO_SetBits(GPIOF,GPIO_Pin_6)
#define RST_0() GPIO_ResetBits(GPIOF,GPIO_Pin_6)