搜索
bottom↓
回复: 8

RTT下载到周立功LPC1700开发板,网卡不能初始化,请教解决方案

[复制链接]

出0入0汤圆

发表于 2010-11-8 18:00:21 | 显示全部楼层 |阅读模式
开发板上没有SD卡,注释掉文件系统显示

\ | /
- RT -     Thread Operating System
/ | \ 0.3.1 build Nov  8 2010
2006 - 2010 Copyright by rt-thread team
To initialize device:e0 failed. The error code is -1
TCP/IP initialized!

应该是说网卡加载有问题,请问应该怎么排除啊

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-11-8 18:23:12 | 显示全部楼层
调试驱动,可能硬件配置是不相同的,如PHY

出0入0汤圆

 楼主| 发表于 2010-11-9 14:07:24 | 显示全部楼层
哦,多谢!

有没有这方面的文档可以参考的。

出0入0汤圆

 楼主| 发表于 2010-11-9 16:32:35 | 显示全部楼层
我的开发板上面的PHY是KSZ8041NL
RTT里面定义的好像是DP83848C

我应该修改哪个文件?emac.h\emac.c?

出0入0汤圆

发表于 2010-11-9 16:39:08 | 显示全部楼层
修改里面PHY的部分,
可以参考周公的资料.最好修改好后给个补丁.造福大众.

出0入0汤圆

 楼主| 发表于 2010-11-9 18:18:56 | 显示全部楼层
我是一个初学者,感谢楼上的回复

听你的口气,我瞎猜的emac.h\emac.c这两个文件应该猜对了。

周公的例程里,有一个描述网卡硬件的文件,内容是
#define EMAC_RAM_ADDR                0x2007c000
#define EMAC_RAM_SIZE                0x00004000

/* The Ethernet RAM is configured as below, the starting of EMAC_DESCRIPTOR_ADDR depends
on the EMAC_DESCRIPTOR_COUNT or the TOTAL_DESCRIPTOR_SIZE, at this point, the
EMAC_DESCRIPTOR_COUNT for both TX and RX is set to 16:

   EMAC_RAM_ADDR        0x2007c000
   .
   .
   .
   EMAC_DMA_END                EMAC_RAM_ADDR + EMAC_RAM_SIZE - TOTAL_DESCRIPTOR_SIZE
   TX_DESCRIPTOR_ADDR = EMAC_DESCRIPTOR_ADDR = EMAC_RAM_END(EMAC_RAM_ADDR+EMAC_RAM_SIZE) - TOTAL_DESCRIPTOR
   TX_STATUS_ADDR = TX_DESCRIPTOR_ADDR + TX_DESCRIPTOR_SIZE
   RX_DESCRIPTOR_ADDR = TX_DESCRIPTOR_ADDR + TX_DESCRIPTOR_SIZE + TX_STATUS_SIZE
   RX_STATUS_ADDR = RX_DESCRIPTOR_ADDR + RX_STATUS_SIZE
   ( RX_STATUS_ADDR + RX_STATUS_SIZE = EMAC_RAM_END )!!!!!
   EMAX_RAM_END        0x7FE04000

   Please note that, the descriptors have to be aligned to the 32 bit boundary!!!
   Below descriptor addresses have been carefully aligned to the 32-bit boundary.
   If not, the descriptors have to be re-aligned!!!
*/

#define EMAC_TX_DESCRIPTOR_COUNT        0x0004
#define EMAC_RX_DESCRIPTOR_COUNT        0x0004
#define TX_DESCRIPTOR_SIZE        (EMAC_TX_DESCRIPTOR_COUNT * 8)
#define RX_DESCRIPTOR_SIZE        (EMAC_RX_DESCRIPTOR_COUNT * 8)
#define TX_STATUS_SIZE                (EMAC_TX_DESCRIPTOR_COUNT * 4)
#define RX_STATUS_SIZE                (EMAC_RX_DESCRIPTOR_COUNT * 8)
#define TOTAL_DESCRIPTOR_SIZE        (TX_DESCRIPTOR_SIZE + RX_DESCRIPTOR_SIZE + TX_STATUS_SIZE + RX_STATUS_SIZE)
#define EMAC_DESCRIPTOR_ADDR        (EMAC_RAM_ADDR + EMAC_RAM_SIZE - TOTAL_DESCRIPTOR_SIZE)

#define TX_DESCRIPTOR_ADDR        EMAC_DESCRIPTOR_ADDR
#define TX_STATUS_ADDR                (EMAC_DESCRIPTOR_ADDR + TX_DESCRIPTOR_SIZE)
#define RX_DESCRIPTOR_ADDR        (TX_STATUS_ADDR + TX_STATUS_SIZE)
#define RX_STATUS_ADDR                (RX_DESCRIPTOR_ADDR + RX_DESCRIPTOR_SIZE)

#define EMAC_DMA_ADDR                EMAC_RAM_ADDR

#define EMAC_BLOCK_SIZE                        0x600
#define EMAC_TX_BLOCK_NUM                4       
#define EMAC_RX_BLOCK_NUM                4
#define TOTAL_EMAC_BLOCK_NUM        8

#define EMAC_BUFFER_SIZE        (EMAC_BLOCK_SIZE * (EMAC_TX_BLOCK_NUM + EMAC_RX_BLOCK_NUM ))
#define EMAC_TX_BUFFER_ADDR        EMAC_RAM_ADDR
#define EMAC_RX_BUFFER_ADDR        (EMAC_RAM_ADDR + EMAC_BLOCK_SIZE * EMAC_TX_BLOCK_NUM)
/* EMAC Descriptor TX and RX Control fields */
#define EMAC_TX_DESC_INT                0x80000000
#define EMAC_TX_DESC_LAST                0x40000000
#define EMAC_TX_DESC_CRC                0x20000000
#define EMAC_TX_DESC_PAD                0x10000000
#define EMAC_TX_DESC_HUGE                0x08000000
#define EMAC_TX_DESC_OVERRIDE        0x04000000

#define EMAC_RX_DESC_INT                0x80000000

/* EMAC Descriptor status related definition */
#define TX_DESC_STATUS_ERR                0x80000000
#define TX_DESC_STATUS_NODESC        0x40000000
#define TX_DESC_STATUS_UNDERRUN        0x20000000
#define TX_DESC_STATUS_LCOL                0x10000000
#define TX_DESC_STATUS_ECOL                0x08000000
#define TX_DESC_STATUS_EDEFER        0x04000000
#define TX_DESC_STATUS_DEFER        0x02000000
#define TX_DESC_STATUS_COLCNT        0x01E00000/* four bits, it's a mask, not exact count */

#define RX_DESC_STATUS_ERR                0x80000000
#define RX_DESC_STATUS_LAST                0x40000000
#define RX_DESC_STATUS_NODESC        0x20000000
#define RX_DESC_STATUS_OVERRUN        0x10000000
#define RX_DESC_STATUS_ALGNERR        0x08000000
#define RX_DESC_STATUS_RNGERR        0x04000000
#define RX_DESC_STATUS_LENERR        0x02000000
#define RX_DESC_STATUS_SYMERR        0x01000000
#define RX_DESC_STATUS_CRCERR        0x00800000
#define RX_DESC_STATUS_BCAST        0x00400000
#define RX_DESC_STATUS_MCAST        0x00200000
#define RX_DESC_STATUS_FAILFLT        0x00100000
#define RX_DESC_STATUS_VLAN                0x00080000
#define RX_DESC_STATUS_CTLFRAM        0x00040000

#define DESC_SIZE_MASK                        0x000007FF/* 11 bits for both TX and RX   */

/* EMAC interrupt controller related definition */
#define EMAC_INT_RXOVERRUN        0x01 << 0
#define EMAC_INT_RXERROR        0x01 << 1
#define EMAC_INT_RXFINISHED        0x01 << 2
#define EMAC_INT_RXDONE                0x01 << 3
#define EMAC_INT_TXUNDERRUN        0x01 << 4
#define EMAC_INT_TXERROR        0x01 << 5
#define EMAC_INT_TXFINISHED        0x01 << 6
#define EMAC_INT_TXDONE                0x01 << 7
#define EMAC_INT_SOFTINT        0x01 << 12
#define EMAC_INT_WOL                0x01 << 13

还有一个应该是跟PHY有关的文件
#define HARDWARE_GLOBALS
#include "../../../config.h"
#include "../include/cfg_net.h"
#include         "LPC1700_ADD_R.h"

union  REC_BUFF_UNION        REC_BUFF[MAX_REC_BUFF];
/* EMAC MODULE ID        */
#define PHILIPS_EMAC_MODULE_ID        ((0x3902 << 16) | 0x2000)

INT32U      tempreg1,tempreg;
INT16U PHYREG[80];
INT16U PHYID;
INT16U EINTSTA;
INT8U  LINKSTATUS;
volatile INT32U RXOverrunCount = 0;
volatile INT32U RXErrorCount = 0;

volatile INT32U TXUnderrunCount = 0;
volatile INT32U TXErrorCount = 0;
volatile INT32U RxFinishedCount = 0;
volatile INT32U TxFinishedCount = 0;
volatile INT32U TxDoneCount = 0;
volatile INT32U RxDoneCount = 0;

volatile INT32U CurrentRxPtr = EMAC_RX_BUFFER_ADDR;
volatile INT32U ReceiveLength = 0;
volatile INT32U PacketReceived = FALSE;

INT16U EthernetPHYRead(INT8U paddr,INT8U raddr)
{
        INT16U temp16;
       
        MAC_MCMD = 1;                                        //enable read
        MAC_MADR = ((paddr&0X1F) <<8 ) + (raddr&0X1F);
        while(MAC_MIND & 0X01);
        MAC_MCMD = 0;
        temp16 = MAC_MRDD;
        return temp16;       
}
/******************************************************************************
** Function name:                EMAC_TxEnable/EMAC_TxDisable
**
** Descriptions:                EMAC TX API modules
**
** parameters:                        None
** Returned value:                None
**
******************************************************************************/
void EMAC_TxEnable( void )
{
    MAC_COMMAND |= 0x02;
    return;
}

void EMAC_TxDisable( void )
{
    MAC_COMMAND &= ~0x02;
    return;
}

/******************************************************************************
** Function name:                EMAC_RxEnable/EMAC_RxDisable
**
** Descriptions:                EMAC RX API modules
**
** parameters:                        None
** Returned value:                None
**
******************************************************************************/
void EMAC_RxEnable( void )
{
    MAC_COMMAND |= 0x01;
    MAC_MAC1 |= 0x01;
    return;   
}

void EMAC_RxDisable( void )
{
    MAC_COMMAND &= ~0x01;
    MAC_MAC1 &= ~0x01;
    return;
}
void WritePHY( INT32U PHYReg, INT32U PHYData )
{
    MAC_MCMD = 0x0000;                        /* write command */
    MAC_MADR = 0X0300 | PHYReg;        /* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */
    MAC_MWTD = PHYData;
    while ( MAC_MIND != 0 );
    return;
}

void Write_PHY (INT16U phyadd,int PhyReg, int Value)
{
  unsigned int tout;

  MAC_MADR = (phyadd<<8) | PhyReg;
  MAC_MWTD = Value;

  /* Wait utill operation completed */
  tout = 0;
  for (tout = 0; tout < 50000; tout++) {
    if ((MAC_MIND & 1) == 0) {
      break;
    }
  }
}
/*****************************************************************************
** Function name:                ReadPHY
**
** Descriptions:                Read data from the PHY port
**
** parameters:                        PHY register
** Returned value:                PHY data
**
*****************************************************************************/

INT32U ReadPHY( INT16U phyadd,INT32U PHYReg )
{
    INT32U i32;
    MAC_MCMD = 0x0001;                        /* read command */
    i32 = (phyadd<<8) | PHYReg;        /* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */
    MAC_MADR = i32;
    while ( MAC_MIND != 0 );
    MAC_MCMD = 0x0000;
    return( MAC_MRDD );
}
unsigned short Read_PHY ( INT16U phyadd ,unsigned char PhyReg)
{
  unsigned int tout;

  MAC_MADR = (phyadd<<8) | PhyReg;
  MAC_MCMD = 1;

  /* Wait until operation completed */
  for (tout = 0; tout < 50000; tout++) {
    if ((MAC_MIND & 1) == 0) {
      break;
    }
  }
  MAC_MCMD = 0;
  return (MAC_MRDD);
}

/*****************************************************************************
** Function name:                EMACTxDesciptorInit
**
** Descriptions:                initialize EMAC TX descriptor table
**
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void EMACTxDescriptorInit( void )
{
    INT32U i;
    INT32U *tx_desc_addr, *tx_status_addr;
   
    /*-----------------------------------------------------------------------------      
     * setup the Tx status,descriptor registers --
     * Note, the actual tx packet data is loaded into the ahb2_sram16k memory as part
     * of the simulation
     *----------------------------------------------------------------------------*/
    MAC_TXDESCRIPTOR = TX_DESCRIPTOR_ADDR;        /* Base addr of tx descriptor array */
    MAC_TXSTATUS = TX_STATUS_ADDR;                /* Base addr of tx status */
    MAC_TXDESCRIPTORNUM = EMAC_TX_DESCRIPTOR_COUNT - 1;        /* number of tx descriptors, 16

*/

    for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
    {
                tx_desc_addr = (INT32U *)(TX_DESCRIPTOR_ADDR + i * 8);        /* two words at

a time, packet and control */
                *tx_desc_addr = (INT32U)(EMAC_TX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
                *(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE - 1));       

/* set size only */
    }
   
    for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
    {
                tx_status_addr = (INT32U *)(TX_STATUS_ADDR + i * 4);        /* TX status,

one word only, status info. */
                *tx_status_addr = (INT32U)0;                /* initially, set status info to

0 */
    }
    MAC_TXPRODUCEINDEX = 0x0;        /* TX descriptors point to zero */
    return;
}

/*****************************************************************************
** Function name:                EMACRxDesciptorInit
**
** Descriptions:                initialize EMAC RX descriptor table
**
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void EMACRxDescriptorInit( void )
{
    INT32U i;
    INT32U *rx_desc_addr, *rx_status_addr;
   
    /*-----------------------------------------------------------------------------      
     * setup the Rx status,descriptor registers --
     * Note, the actual rx packet data is loaded into the ahb2_sram16k memory as part
     * of the simulation
     *----------------------------------------------------------------------------*/
    MAC_RXDESCRIPTOR = RX_DESCRIPTOR_ADDR;        /* Base addr of rx descriptor array */
    MAC_RXSTATUS = RX_STATUS_ADDR;                        /* Base addr of rx status */
    MAC_RXDESCRIPTORNUM = EMAC_RX_DESCRIPTOR_COUNT - 1;        /* number of rx descriptors, 16

*/

    for ( i = 0; i < EMAC_RX_DESCRIPTOR_COUNT; i++ )
    {
                /* two words at a time, packet and control */
                rx_desc_addr = (INT32U *)(RX_DESCRIPTOR_ADDR + i * 8);
                *rx_desc_addr = (INT32U)(EMAC_RX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
                *(rx_desc_addr+1) = (INT32U)(EMAC_RX_DESC_INT | (EMAC_BLOCK_SIZE - 1));       

/* set size only */   
    }

    for ( i = 0; i < EMAC_RX_DESCRIPTOR_COUNT; i++ )
    {
                /* RX status, two words, status info. and status hash CRC. */
                rx_status_addr = (INT32U *)(RX_STATUS_ADDR + i * 8);       
                *rx_status_addr = (INT32U)0;        /* initially, set both status info and

hash CRC to 0 */
                *(rx_status_addr+1) = (INT32U)0;
    }
    MAC_RXCONSUMEINDEX = 0x0;        /* RX descriptor points to zero */
    return;
}

/**********************************************************************
**函数原型:    void         SetMacID()
**入口参数:                *mac_ptr
**出口参数:                无
**返 回 值:        无            
**说    明:        设置芯片物理地址,物理地址已经存储在程序空间内
************************************************************************/
void SetMacID(INT8U * mac_ptr)   
{

        MAC_SA0 = mac_ptr[0]*256+mac_ptr[1];
    MAC_SA1 = mac_ptr[2]*256+mac_ptr[3];
    MAC_SA2 = mac_ptr[4]*256+mac_ptr[5];
        //把MAC地址写入MY——MAC——ID中
       
}
INT32U EMACSend( INT32U *EMACBuf, INT32U length )
{
    INT32U *tx_desc_addr;
    INT32U TxProduceIndex;
    INT32U TxConsumeIndex;
    INT32U i, templen;

    TxProduceIndex = MAC_TXPRODUCEINDEX;
    TxConsumeIndex = MAC_TXCONSUMEINDEX;

    if ( TxConsumeIndex != TxProduceIndex )
    {
                return ( FALSE );
    }

    if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
    {
                /* reach the limit, that probably should never happen */
                /* To be tested */
                MAC_TXPRODUCEINDEX = 0;
    }

    if ( length > EMAC_BLOCK_SIZE )
    {
                templen = length;
                for ( i = 0; (INT32U)(length/EMAC_BLOCK_SIZE) + 1; i++ )
                {
                    templen = length - EMAC_BLOCK_SIZE;
                    /* two words at a time, packet and control */
                    tx_desc_addr = (INT32U *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
                    /* descriptor status needs to be checked first */
                    if ( templen % EMAC_BLOCK_SIZE )
                    {
                                /* full block */
                                *tx_desc_addr = (INT32U)(EMACBuf + i * EMAC_BLOCK_SIZE);
                                /* set TX descriptor control field */
                                *(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT |

(EMAC_BLOCK_SIZE - 1));
                                TxProduceIndex++;
                                if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
                            {
                                    TxProduceIndex = 0;
                                }
                                MAC_TXPRODUCEINDEX = TxProduceIndex;        /* transmit now

*/
                    }
                    else
                    {
                                /* last fragment */
                                *tx_desc_addr = (INT32U)(EMACBuf + i * EMAC_BLOCK_SIZE);
                                /* set TX descriptor control field */
                                *(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT |

EMAC_TX_DESC_LAST | (templen -1) );
                                TxProduceIndex++;                /* transmit now */
                                if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
                            {
                                    TxProduceIndex = 0;
                                }
                                MAC_TXPRODUCEINDEX = TxProduceIndex;        /* transmit now

*/
                                break;
                    }   
                }
    }
    else
    {
                tx_desc_addr = (INT32U *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
                /* descriptor status needs to be checked first */
                *tx_desc_addr = (INT32U)(EMACBuf);
                /* set TX descriptor control field */
                *(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT | EMAC_TX_DESC_LAST |

EMAC_TX_DESC_PAD| (length -1));
                TxProduceIndex++;                /* transmit now */
                if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
                {
                    TxProduceIndex = 0;
                }
                MAC_TXPRODUCEINDEX = TxProduceIndex;
    }
    return ( TRUE );
}
/**********************************************************************
**函数原型:    void                 Send_Packet(struct _pkst *TxdData)
**入口参数:                struct _pkst *TxdData        :指向要发送数据的结构指针
**              
**出口参数:                无
**返 回 值:        无              
**说    明:        发送数据包,以太网底层驱动程序,所有的数据发送都要通过该程序
************************************************************************/
void Send_Packet(struct _pkst *TxdData)//  
{

        struct _pkst *ExPtr;//
        INT8U *TEPTR;
        INT8U *rxptr;
        INT16U ii,length=0,jj;
        INT32U intstat;
       
        length=length+TxdData->length;
        ExPtr=TxdData->STPTR;
        while(ExPtr!=NULL)//计算出要发送的数据的总长度
        {       
                length=length+ExPtr->length;
                ExPtr=ExPtr->STPTR;
        }
        ii=length;
       
        rxptr = (INT8U *)EMAC_TX_BUFFER_ADDR;
        TEPTR=TxdData->DAPTR;
        for(ii=0;ii<TxdData->length;ii++)
        {
                *rxptr = *TEPTR;
                rxptr++;
                TEPTR++;
        }
        ExPtr=TxdData->STPTR;
        while(ExPtr!=NULL)
        {
                TEPTR=ExPtr->DAPTR;
                for(ii=0;ii<ExPtr->length;ii++)
                {
                        *rxptr = *TEPTR;
                        rxptr++;
                        TEPTR++;       
                }
                ExPtr=ExPtr->STPTR;
        }
        //如果少于60
       
        ii=length;
        if(length<60)
        {
                //如果数据长度<60字节,设置长度为60字节
                ii=60;
        }
        rxptr = (INT8U *)EMAC_TX_BUFFER_ADDR;
    EMACSend((INT32U *)rxptr,ii);
        /***************************************/
        //重发数据的处理
       
        for(length=0;length<6;length++)        //最多重发6次
        {
                for(jj=0;jj<1000;jj++)
                {//检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃
                        intstat = MAC_INTSTATUS;
                        intstat |= EINTSTA;  
                        if ( intstat & EMAC_INT_TXDONE )
                        {
                            TxDoneCount++;
                            break;
                        }
        }
                if(intstat & EMAC_INT_TXDONE)//表示发送成功,判断发送状态寄存器TSR,决定

是否出错
                {
                        MAC_INTCLEAR = 0x0f;//EMAC_INT_TXDONE;
                        EINTSTA &= 0xf0;
                        break;
                }
                EMACSend((INT32U *)rxptr,ii);       //to sendpacket;
        }
       
        /**************************************/
        //OS_EXIT_CRITICAL();
}
INT32U EMACReceiveFractions( INT32U StartIndex, INT32U EndIndex, INT32U * dataptr32 )
{
    INT32U i, RxLength = 0;
    INT32U RxSize;
    INT32U *rx_status_addr,*rx_desc_addr,*rx_data_addr;

    for ( i = StartIndex; i < EndIndex; i++ )
    {
                /* Get RX status, two words, status info. and status hash CRC. */
                rx_status_addr = (INT32U *)(RX_STATUS_ADDR + StartIndex * 8);
                rx_desc_addr = (INT32U *)(RX_DESCRIPTOR_ADDR + StartIndex * 8);
                rx_data_addr = (INT32U *)(*rx_desc_addr);
                RxSize = (*rx_status_addr & DESC_SIZE_MASK) - 1;
                for(i=0;i<(RxSize+3)/4;i++)
                        dataptr32=*rx_data_addr++;
                /* two words at a time, packet and control */
                CurrentRxPtr += EMAC_BLOCK_SIZE;
                StartIndex++;
                /* last fragment of a frame */
                if ( *rx_status_addr & RX_DESC_STATUS_LAST )
                {
                    /* set INT bit and RX packet size */
                    MAC_RXCONSUMEINDEX = StartIndex;
                    RxLength += RxSize;
                    break;
                }
                else        /* In the middle of the frame, the RxSize should be

EMAC_BLOCK_SIZE */
                                /* In the emac.h, the EMAC_BLOCK_SIZE has been set to

the largest
                                ethernet packet length to simplify the process, so, it

should not
                                come here in any case to deal with fragmentation.

Otherwise,
                                fragmentation and repacking will be needed. */
                {
                    /* set INT bit and maximum block size */
                    MAC_RXCONSUMEINDEX = StartIndex;
                    /* wait until the whole block is received, size is EMAC_BLOCK_SIZE. */
                    while ( (*rx_status_addr & DESC_SIZE_MASK) != (EMAC_BLOCK_SIZE - 1));
                    RxLength += RxSize;
                }
    }
    return( RxLength );
}
/******************************************************************************
** Function name:                EMACHandler
**
** Descriptions:                EMAC interrupt handler
**
** parameters:                        None
** Returned value:                None
**
******************************************************************************/
void InitNic(INT8U num);
void EMACHandler (INT32U IntStatus)
{

    //IENABLE;                                /* handles nested interrupt */

    IntStatus = MAC_INTSTATUS;
    IntStatus |= EINTSTA;     
    if ( IntStatus != 0 )        /* At least one interrupt */
    {
                if ( IntStatus & EMAC_INT_RXOVERRUN )
                {
                    MAC_INTCLEAR = EMAC_INT_RXOVERRUN;
                        RXOverrunCount++;
                        //InitNic(0);
                        EMACRxDescriptorInit();
                        //IDISABLE;
                        //VICVectAddr = 0;                /* Acknowledge Interrupt */
                        return;
                }

                if ( IntStatus & EMAC_INT_RXERROR )
                {
                        MAC_INTCLEAR = EMAC_INT_RXERROR;
                        RXErrorCount++;
                        //InitNic(0);
                        //IDISABLE;
                        //VICVectAddr = 0;                /* Acknowledge Interrupt */
                        return;
                }
       
                if ( IntStatus & EMAC_INT_RXFINISHED )
                {
                    MAC_INTCLEAR = EMAC_INT_RXFINISHED;
                    RxFinishedCount++;
                    /* Below should never happen or RX is seriously wrong */
                    //while ( MAC_RXPRODUCEINDEX != (MAC_RXCONSUMEINDEX - 1) );
                }

                if ( IntStatus & EMAC_INT_TXUNDERRUN )
                {
                        MAC_INTCLEAR = EMAC_INT_TXUNDERRUN;
                        TXUnderrunCount++;
                        //IDISABLE;
                        //VICVectAddr = 0;                /* Acknowledge Interrupt */
                        return;
                }
                if ( IntStatus & EMAC_INT_TXERROR )
                {
                        MAC_INTCLEAR = EMAC_INT_TXERROR;
                        TXErrorCount++;
                        //IDISABLE;
                        //VICVectAddr = 0;                /* Acknowledge Interrupt */
                        return;
                }

                if ( IntStatus & EMAC_INT_TXFINISHED )
                {
                    MAC_INTCLEAR = EMAC_INT_TXFINISHED;
                    TxFinishedCount++;
                }
                EINTSTA &= 0x88;
    }   
    //IDISABLE;
    //VICVectAddr = 0;                /* Acknowledge Interrupt */
        return;
}
/**********************************************************************
**函数原型:    unsigned char * Rec_Packet()
**入口参数:?无
**出口参数:                返回数据指针                        unsigned char *
**返 回 值:        NULL                                  没有新数据包
**              unsigned char *         接收到新数据包
**说    明:        查询是否有新数据包并接收进缓冲区
************************************************************************/
INT8U Rec_Packet()
{
        static INT8U REC_BUFF_NUM=0;
        INT32U * REC_BUFF_PTR_DWORDS;
        INT8U * REC_BUFF_PTR_BYTES;
        INT32U RxProduceIndex, RxConsumeIndex;
    INT32U RxLength = 0;
        INT32U Counter = 0;
        INT32U IntStatus;
        INT16U templink;
       
        templink = Read_PHY(PHYID ,1 );
        if( (templink & 0x0004) ==0 )
        {
                LINKSTATUS = 0;
                OSTimeDly(4);
                templink = Read_PHY(PHYID ,1 );
                if( templink & 0x0004 )
                {
                        InitNic(0);
                }
                return 0;  
        }
        if(LINKSTATUS == 0)
                InitNic(0);
        OS_ENTER_CRITICAL();
       
rea1:
        IntStatus = MAC_INTSTATUS;
        IntStatus |= EINTSTA;
        if ( IntStatus & EMAC_INT_RXDONE )
        {
                MAC_INTCLEAR = EMAC_INT_RXDONE;
                EINTSTA &= (~EMAC_INT_RXDONE);
                RxDoneCount++;
        }
        else
        {
                EMACHandler(IntStatus);
                OS_EXIT_CRITICAL();
                return 0;
        }
        RxProduceIndex = MAC_RXPRODUCEINDEX;
    RxConsumeIndex = MAC_RXCONSUMEINDEX;

    if ( RxProduceIndex == EMAC_RX_DESCRIPTOR_COUNT )
    {
                /* reach the limit, that probably should never happen */
                //MAC_RXPRODUCEINDEX = 0;
                CurrentRxPtr = EMAC_RX_BUFFER_ADDR;
    }

        //此时表示有新的数据包在缓冲区里
        /* a packet has arrived. */
    if ( RxProduceIndex != RxConsumeIndex )
           {                        //在任何操作都最好返回page0
                if(REC_BUFF_NUM==MAX_REC_BUFF)//接收缓冲区号清零
                {
                        REC_BUFF_NUM=0;
                }
                REC_BUFF_PTR_DWORDS=REC_BUFF[REC_BUFF_NUM].Dwords;//设定接收缓冲区的起始

地址
                //=======================================
                if ( RxProduceIndex < RxConsumeIndex )        /* Wrapped around already *///翻

转了
                {
                    /* take care of unwrapped, RxConsumeIndex to EMAC_RX_DESCERIPTOR_COUNT

*/
                    RxLength += EMACReceiveFractions( RxConsumeIndex,

EMAC_RX_DESCRIPTOR_COUNT, REC_BUFF_PTR_DWORDS );
                        Counter++;
                    PacketReceived = TRUE;            
       
                    /* then take care of wrapped, 0 to RxProduceIndex */
                    if ( RxProduceIndex > 0 )
                    {
                                RxLength += EMACReceiveFractions( 0, RxProduceIndex,

REC_BUFF_PTR_DWORDS );
                                Counter++;
                    }
                }
                else                                        /* Normal process *///正常顺序
                {
                    RxLength += EMACReceiveFractions( RxConsumeIndex, RxProduceIndex,

REC_BUFF_PTR_DWORDS );
                        Counter++;       
                }
                REC_BUFF_PTR_BYTES = REC_BUFF[REC_BUFF_NUM].bytes;
#ifdef Little_End
                if((((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0008)//可以减少对

数据缓冲取的利用
                        ||(((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0608))//不

过如果缓冲区足够大就最好不要
#endif
#ifdef Big_End
                if((((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0800)//可以减少对

数据缓冲取的利用
                        ||(((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0806))//不

过如果缓冲区足够大就最好不要
#endif
                {
                        REC_BUFF_NUM++;
                        OS_EXIT_CRITICAL();
                        Rec_Ethernet_Packed(REC_BUFF_PTR_BYTES,0);
                        OS_ENTER_CRITICAL();
                        goto rea1;
                        //可以直接退出。
                }
                else
                        goto rea1;
        }//end of if(bnry!=curr)
        OS_EXIT_CRITICAL();
        return(0);
}
INT32U intcnt;
void Ethernet_Exception(void)
{
        extern OS_EVENT                  *RecPackedFlag;
        OS_ENTER_CRITICAL();
        OSIntEnter();
        OSSemPost(RecPackedFlag);
        EINTSTA |= MAC_INTSTATUS;
        MAC_INTCLEAR = 0XFF;
        intcnt++;
        OSIntExit();
        OS_EXIT_CRITICAL();
}
/**********************************************************************
**函数原型:     void         InitNic()
**入口参数:?无
**出口参数:                无
**返 回 值:?无              
**说    明:?对芯片的工作寄存器进行设置,各个寄存器的用法可参考文档和
**                                络芯片的数据手册
************************************************************************/
INT16U dulxp,speed;
void InitNic(INT8U num)  
{
        INT32U i;
       
        PCONP |= 0X40000000;
    /* Set the PIN to RMII */
   // PINSEL2 &= 0x0fc0ccf0;
    //PINSEL2 |= 0X50151105; //PINSEL2 = 0x50151105;        /* selects P1

[0,1,4,8,9,10,14,15] */
    //PINSEL3 &= 0xfffffff0;
    //PINSEL3 |= 0X00000005; //PINSEL3 = 0x00000005;        /* selects P1[17:16] */
  //  i = rMAC_MODULEID;
  //  if(i == OLD_EMAC_MODULE_ID)
            PINSEL2 |= (1)|(1<<2)|(1<<8)|(1<<16)|(1<<18)|(1<<20)|(1<<28)|(1<<30);        /*

selects P1[0,1,4,8,9,10,14,15] */
   // else
            //PINSEL2 |= (1)|(1<<2)|(1<<8)|(1<<16)|(1<<18)|(1<<20)|(1<<28)|(1<<30);
    PINSEL3 |= 0x00000005;        /* selects P1[17:16] */
   
   
   
    /* reset : soft,simulation,mcs/rx,rx,mcs/tx,tx */
    MAC_MAC1 = 0xCF00;        /* [15],[14],[11:8] -> soft resets all MAC internal modules */
    /* RegReset,TxReset,RxReset */
    MAC_COMMAND = 0x0038;        /* reset all datapaths and host registers */

    for ( i = 0; i < 0x40; i++ );        /* short delay after reset */
    MAC_MAC1 = 0x0;                /* deassert all of the above soft resets in MAC1 */

    EMAC_TxDisable();
    EMAC_RxDisable();
   
    MAC_MAC2 = 0x00;                /* initialize MAC2 register to default value */

    /* Non back to back inter-packet gap */
    MAC_IPGR = 0x0012;        /* use the default value recommended in the users manual */

    MAC_CLRT = 0x370F;        /* Use the default value in the users manual */
    MAC_MAXF = 0x0600;        /* Use the default value in the users manual */
   
    /* PHY Select RMII */
    ///rECOMMAND |= (1<<9);
    /* Initial MII Mgmt */
    // rMCFG |= (7<<2) + 1;                   //clk div 28,address increment
    //MAC_MCFG = 0x801d;
    //MAC_MCFG |= 0x0019;        /* host clock divided by 20, no suppress preamble, no

scan increment */
    MAC_MCFG |= 0x0018;
    /* RMII configuration */
    //MAC_COMMAND |= 0x0200;
    MAC_COMMAND = 0x0240;
    //MAC_SUPP = 0x0900;        /* RMII setting, PHY support: [8]=0 ->10 Mbps mode, =1

-> 100 Mbps mode */
    /*  (note bit 4 was set in original test, although spec says its unused) */
    //for ( i = 0; i < 0x20; i++ );        /* short delay */
    //MAC_SUPP = 0x0100;
   MAC_SUPP = 0x0000;
   
   // probe phy address
        for(i=0;i<32;i++)
        {
            PHYID = Read_PHY(i , 2 );
            if(PHYID == 0X0022)
                    break;
    }
    if(i >= 32)
            while(1);
    PHYID = i;
    /// PHY RESET
    Write_PHY(PHYID, 0, 0x9200 );
        do
        {
                OSTimeDly(OS_TICKS_PER_SEC);
                tempreg = Read_PHY(PHYID, 0x1f );
                if(tempreg&0x001c)
                        break;
        }while(1);
        OSTimeDly(OS_TICKS_PER_SEC);
        tempreg = Read_PHY(PHYID, 0x1f );
    //for(i=0;i<32;i++)
    //        PHYREG = Read_PHY(PHYID ,i );
    tempreg &= 0x001c;
    /* INPUT MAC ADDRESS */
   SetMacID(NetPort[num].My_Mac);
   
    if(tempreg == 0x0018)//100fdx
    {
            dulxp = 1;
            speed = 100;
            MAC_MAC2 = 0x31;                /* half duplex, CRC and PAD enabled. */
                MAC_SUPP |= 0x0100;                /* RMII Support Reg. speed is set to

100M */
                MAC_COMMAND |= 0x0640;
                /* back to back int-packet gap */
                MAC_IPGT = 0x0015;                /* IPG setting in half duplex mode */
    }
    else if(tempreg == 0x0008)//100hdx
    {
            dulxp = 0;
            speed = 100;
            MAC_MAC2 = 0x30;                /* full duplex, CRC and PAD enabled. */
                MAC_SUPP |= 0x0100;                /* RMII Support Reg. speed is set to

100M */
                MAC_COMMAND |= 0x0240;
                /* back to back int-packet gap */
                MAC_IPGT = 0x0012;        /* IPG setting in full duplex mode */
    }
    else if(tempreg == 0x0014)//10fdx
    {
            dulxp = 1;
            speed = 10;
            MAC_MAC2 = 0x31;                /* full duplex, CRC and PAD enabled. */
                MAC_SUPP = 0;        /* RMII Support Reg. speed is set to 10M */
                MAC_COMMAND |= 0x0640;
                /* back to back int-packet gap */
                MAC_IPGT = 0x0015;                /* IPG setting in full duplex mode */
    }
    else if(tempreg == 0x0004)//10hdx
    {
            dulxp = 0;
            speed = 10;
            MAC_MAC2 = 0x30;                /* half duplex, CRC and PAD enabled. */
                MAC_SUPP = 0;        /* RMII Support Reg. speed is set to 10M */
                MAC_COMMAND |= 0x0240;
                /* back to back int-packet gap */
                MAC_IPGT = 0x0012;                /* IPG setting in half duplex mode */
    }
    EMACTxDescriptorInit();
    EMACRxDescriptorInit();

    MAC_MAC1 |= 0x0002;                /* [1]-Pass All Rx Frame */
       
    /* Set up RX filter, accept broadcast and perfect station */
    MAC_RXFILTERCTRL = 0x0022;        /* [1]-accept broadcast, [5]accept perfect */
        MAC_RXFILTERCTRL |= 0x0005;//MULTICAST_UNICAST
    MAC_RXFILTERCTRL |= 0x0018;//ENABLE_HASH
   
    MAC_INTCLEAR = 0xFFFF;        /* clear all MAC interrupts */   
    /* MAC interrupt related register setting */
    //if ( install_irq( EMAC_INT, (void *)EMACHandler, HIGHEST_PRIORITY ) == FALSE )
    //{
        //        return (FALSE);
    //}
        EMAC_RxEnable();
    EMAC_TxEnable();
    LINKSTATUS = 1;
    EINTSTA = 0;
    //vicIrqFuncSet(44, 5, (unsigned int)Ethernet_Exception);
    zyIsrSet (NVIC_ETHR, (unsigned long)Ethernet_Exception, PRIO_FOUR);
    MAC_INTENABLE = 0x000c;        /* Enable all interrupts except SOFTINT and WOL */

                               
}
INT16U swap_int16(INT16U temp)
{INT16U temp1;
temp1=(temp&0xff00)>>8;
temp=(temp&0x00ff)<<8;
return(temp+temp1);
}
INT32U swap_int32(INT32U temp)
{
        union   w  temp232,temp132;
        temp232.dwords=temp;
        temp132.bytes.byte0=temp232.bytes.byte3;
        temp132.bytes.byte1=temp232.bytes.byte2;
        temp132.bytes.byte2=temp232.bytes.byte1;
        temp132.bytes.byte3=temp232.bytes.byte0;
        return(temp132.dwords);
}

INT16U Char2ToInt16(INT8U * temp)
{
        INT16U temp16;
        temp16=((INT16U)(*temp))<<8;
        temp++;
        temp16=temp16+(INT16U)(*temp);
        return(temp16);
}

INT32U Char4ToInt32(INT8U * temp)
{
        INT32U temp32;
        temp32=((INT32U)(*temp))<<24;
        temp++;
        temp32=temp32+(((INT32U)(*temp))<<16);
        temp++;
        temp32=temp32+(((INT32U)(*temp))<<8);
        temp++;
        temp32=temp32+(INT32U)(*temp);
        return(temp32);
}
/**********************************************************************
**函数原型:     void         int_ex1() interrupt 2
**入口参数:?无
**出口参数:                无
**返 回 值:?无              
**说    明:?RTL8019AS中断服务程序
************************************************************************/
/*
void int_ex1() interrupt 2
{
//        OS_INT_ENTER();

  EX_RAM INT8U i,TEMP;
  EX1=0;
  iic++;
  TEMP=Reg00;
  page(0);
  i=Reg07;
  
        if((i&&0x10)==0x10)
        {
        OSSemIntPost(RecBufOverFlowFlag);
        }
        else if((i&&0x01)==0x01)
        OSSemIntPost(RecPackedFlag);
        Reg07=0XFF;
        Reg00=TEMP;
        OSIntExit();
        }
        INT8U rec_data()
        {
        INT8U i,TEMP;
        TEMP=Reg00;
        page(0);
        i=Reg07;
        Reg07=0XFF;
        Reg00=TEMP;
        if((i&&0x01)==0x01)
        return (0);
        return(1);
       
          }
*/

出0入0汤圆

 楼主| 发表于 2010-11-9 18:20:19 | 显示全部楼层
我对这些底层的东西不懂,能不能指导一下,或者有没有相关的文档。

要是弄好了,肯定要共享出来的。

出0入0汤圆

发表于 2011-12-15 16:36:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-19 17:19:25 | 显示全部楼层
关注。周立功的程序有问题?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-11 03:08

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表