📄 dm9000.c
字号:
pktsize = queue_pkt_len; /* Save current TX packet size */
}
}
}
/* Received the coming packet */
if (int_status & DM9000_RX_INTR)
{
#ifndef TASK_MODE
dmfe_packet_receive(netp);
#else
semaphore_signal(CopyGo);
/* CopyGo->semaphore_count++;*/
#endif
}
#if 0
int_status_after_clear = ior(iobase, 0xfe);
#endif
/* Re-enable interrupt mask */
iow(iobase, 0xff, IMR_DEFAULT);
#if 0
int_mask_reg2 = ior(iobase, 0xff);
#endif
outb(reg_save, iobase);
/* spin_unlock(&db->lock); */
}
/*--------------------------------------------------------------------------
Name : dmfe_packet_receive
Description : Received a packet and pass to upper layer.
Author :
----------------------------------------------------------------------------*/
#define DATA8 *(U8*)(iodata)
#define DATA16 *(U16*)(iodata)
static void dmfe_packet_receive(struct netif *netp)
{
U8 rxbyte, *rdptr, temp;
U16 i, RxStatus, RxLen, GoodPacket, tmplen;
U8 MDRAH, MDRAL;
static struct pbuf * bufReceiv; /*buffer to store the received packet*/
U16 rdadr;
#if MONITOR_RDPOINTER
/*U16 MDRAH_test[1522/2], MDRAL_test[1522/2]; */
static U32 rxbyte_err =0;
static U32 rx_cnt =0;
#endif
#if !ALLOCATE_PBUF
U16 rdptru16[1522/2];
#endif
#if PROCESS_RD_ANOTHER_TASK
void **arg; /*arg of ETHin_message_queue*/
#endif
device_wait_reset = FALSE;
#if 1 //software reset later
#if MONITOR_RDPOINTER
MDRAL=ior(iobase,0xf4);
MDRAH=ior(iobase,0xf5);
#endif
ior(iobase, 0xf0); /* Dummy read */
rxbyte = inb(iodata); /* Got most updated data */
#if MONITOR_RDPOINTER
//sttbx_Print("rxbyte = %d\n", rxbyte);
//sttbx_Print("rx_cnt = %d\n", rx_cnt++);
if (rxbyte != 1)
sttbx_Print("rxbyte error %d\n", ++rxbyte_err);
#endif
if (rxbyte != 1) //not 0 or 1, software reset
{device_wait_reset = TRUE;
goto device_soft_reset;
}
#endif
/* Check packet ready or not */
do {
/*store the value of Memory Data Read address register*/
MDRAL=ior(iobase,0xf4);
MDRAH=ior(iobase,0xf5);
ior(iobase, 0xf0); /* Dummy read */
/* After the read of this command, the read pointer of internal SRAM is unchanged */
rxbyte = inb(iodata); /* Got most updated data */
/* packet ready to receive check */
if (rxbyte == DM9000_PKT_RDY)
{
//#ifdef TASK_MODE
if (CopyGo->semaphore_count)
CopyGo->semaphore_count--;
#if MONITOR_RDPOINTER
sttbx_Print("rx_cnt = %d\n", ++rx_cnt);
#endif
//#endif
/* A packet ready now & Get status/length */
GoodPacket = TRUE;
RxStatus = (U16)0;
RxLen = (U16)0;
outb(0xf2, iobase); /*Enable Read command with address incement*/
/*ior(iobase, 0xf2); //20050801 */
/* Selecting io mode */
switch (dm9000_iomode)
{
case DM9000_BYTE_MODE:
RxStatus = inb(iodata) +
(inb(iodata) << 8);
RxLen = inb(iodata) +
(inb(iodata) << 8);
break;
case DM9000_WORD_MODE:
RxStatus = inw(iodata);
RxLen = inw(iodata);
break;
default:
break;
}
/* Packet Status check */
temp = (U8)RxStatus;
if(temp > 0x01)
{
device_wait_reset = TRUE;
}
temp = (U8)(RxStatus>>8);
if(temp & 0xbf) /* see reg06 */
{
GoodPacket = FALSE;
}
if(!GoodPacket)
{
/*drop this packet!!!*/
//(netp->if_iqdrops)++;
if (dm9000_iomode == DM9000_BYTE_MODE) {
/* Byte mode */
for (i = 0; i < RxLen; i++)
inb(iodata);
}else{
/* Word mode */
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
inw(iodata);
#if SET_RDPOINTER_MANUALLY
tmplen = (RxLen + 1) / 2;
rdadr = ((U16)MDRAH<<8) + MDRAL + (tmplen<<1) +4;
if (rdadr>0x3FFF)
rdadr = rdadr - 0x3400;
iow(iobase, 0xf4, (U8)rdadr);
iow(iobase, 0xf5, rdadr>>8);
#endif
}
continue;
}
#if ALLOCATE_PBUF
/* We allocate a pbuf chain of pbufs from the pool. */
#if ETH_PAD_SIZE
bufReceiv = pbuf_alloc(PBUF_RAW, (RxLen+ETH_PAD_SIZE), PBUF_POOL);
#else
bufReceiv = pbuf_alloc(PBUF_RAW, RxLen, PBUF_POOL);
#endif
if(bufReceiv == NULL)
{
/*printf("mem no buff!\n"); */
/*re-load the value into Memory data read address register*/
iow(iobase, 0xf4, MDRAL);
iow(iobase, 0xf5, MDRAH);
return;
}else
{
#if ETH_PAD_SIZE
rdptr = (U8 *) bufReceiv->payload + ETH_PAD_SIZE;
#else
rdptr = (U8 *) bufReceiv->payload;
#endif
#else
rdptr = (U8*)rdptru16;
#endif /*end if ALLOCATE_PBUF*/
/* Read received packet from RX SARM */
if (dm9000_iomode == DM9000_BYTE_MODE)
{
/* Byte mode */
for (i=0; i<RxLen; i++)
rdptr[i]=inb(iodata);
}else{
/* Word mode */
tmplen = (RxLen + 1) / 2;
#if SET_RDPOINTER_MANUALLY
rdadr = ((U16)MDRAH<<8) + MDRAL +4;
if (rdadr>0x3FFF)
rdadr = rdadr - 0x3400;
iow(iobase, 0xf4, (U8)rdadr);
iow(iobase, 0xf5, rdadr>>8);
outb(0xf2, iobase);
#endif
for (i = 0; i < tmplen; i++)
{
/*for test*/
/*
#if MONITOR_RDPOINTER
MDRAL_test[i] = ior(iobase,0xf4);
MDRAH_test[i] = ior(iobase,0xf5);
outb(0xf2, iobase);
#endif
*/
#if ALLOCATE_PBUF
((U16 *)rdptr)[i] = inw(iodata);
#else
rdptru16[i] = inw(iodata);
#endif
}
}
#if SET_RDPOINTER_MANUALLY
/*set the rd pointer*/
//rdadr = ((U16)MDRAH<<8) + MDRAL +RxLen +4; //for test
tmplen = (RxLen + 1) / 2;
rdadr = ((U16)MDRAH<<8) + MDRAL + (tmplen<<1) +4;
//MDRAL = ior(iobase,0xf4);
//MDRAH = ior(iobase,0xf5);
if (rdadr>0x3FFF)
rdadr = rdadr - 0x3400; /*rdadr = rdadr - 0x3FFF + 0x0C00;*/
iow(iobase, 0xf4, (U8)rdadr);
iow(iobase, 0xf5, rdadr>>8);
#endif
#if PROCESS_RD_ANOTHER_TASK
if ((arg = (void **)message_claim_timeout(ETHin_message_queue, TIMEOUT_IMMEDIATE))!= NULL)
{
arg[0] = netp;
arg[1] = bufReceiv;
message_send(ETHin_message_queue, (void *)arg);
}
else
LWIP_DEBUGF(1, ("dmfe_packet_receive: message_claim_timeout occurs\n"));
#else
ethernetif_input( netp, bufReceiv);
#endif
#if ALLOCATE_PBUF
}
#endif
}
#ifdef TASK_MODE
}while( (rxbyte == DM9000_PKT_RDY) && (!device_wait_reset ) && (CopyGo->semaphore_count));
#else
}while( (rxbyte == DM9000_PKT_RDY) && (!device_wait_reset ) );
#endif
/* re-start ethernet */
device_soft_reset: if(device_wait_reset)
{
software_reset();
}
}
#if 1
/*========================================================================================
* Name : ETHER_setMulticast *
* Description : Set the internal hardware table to filter out unwanted multicast *
* packets before they take up memory. *
Modify : Spenser
*=======================================================================================*/
static void ETHER_setMulticast(struct netif *netp)
{
static U8 ht[8]; /* hash table */
static U32 i;
U32 oft;
/*disable int*/
/* prepare hash table */
/* clear table */
for( i=0; i<8; i++)
{
ht[i] = 0;
}
ht[7] = 0x80;/*2005 8 17 add for multi cast*/
/* set filter */
for (i = 0, oft = 0x16; i < 8; i++, oft++)
iow(iobase, oft, ht[i]);
return;
}
void ETHER_closeMulticast(struct netif *netp)
{
static U8 ht[8]; /* hash table */
static U32 i;
U32 oft;
/*disable int*/
/* prepare hash table */
/* clear table */
for( i=0; i<8; i++)
{
ht[i] = 0;
}
ht[7] = 0x00;/*close multi cast*/
/* set filter */
for (i = 0, oft = 0x16; i < 8; i++, oft++)
iow(iobase, oft, ht[i]);
return;
}
/*===========================================================================
Name : ETHER_Load
Description : initialise the MAC address.
returns : 0 if success, 1 if mac adr not defined.
Modify : Spenser
===========================================================================*/
static U32 ETHER_MacLoad(struct netif *netp)
{
/* Set Node address */
iow(iobase, 0x10, 0x00);
iow(iobase, 0x11, 0x11);
iow(iobase, 0x12, 0x2F);
iow(iobase, 0x13, 0xF2);
iow(iobase, 0x14, 0x35);
iow(iobase, 0x15, 0x91);
return(0);
}
#endif
void ETHER_Config(U32 Eth_BaseAddr,
U8 Addr_Shift,
U8 dm9ks_Interrupt,
U8 Int_Level,
U8 Use16Bit,
U8 Trans_Len)
{
IO_base = Eth_BaseAddr;
ETHER_Address_Shift = Addr_Shift;
ETHER_DM9000_Interrupt = dm9ks_Interrupt;
ETHER_Interrupt_Level = Int_Level;
ETHER_USE16bit = Use16Bit;
ETHER_TRANS_Len = Trans_Len;
}
void Read_MAC(struct netif *netp)
{
/*int i;
for (i=0; i<netp->hwaddr_len; i++)
netp->hwaddr[i] = ior(iobase, i+0x10);*/
netp->hwaddr[0] =0x00;
netp->hwaddr[1] = 0x11;
netp->hwaddr[2] =0x2F;
netp->hwaddr[3] =0xF2;
netp->hwaddr[4] = 0x35;
netp->hwaddr[5] = 0x91;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -