LPC2388驱动PHY-DP83848

原创 2015年11月19日 08:27:37

项目中使用的UCOS/II实时操作系统,在确保硬件电路正常后需要先完成的工作是驱动PHY-DP83848网口芯片,通过查资料确定芯片物理地址的定义

在驱动程序中初始化完芯片的参数后,可以读取芯片的参数确定芯片是否正常启动,

程序中需先确定 PHY芯片的地址值是否与硬件上设计的一致,

id1 = read_PHY (PHY_REG_IDR1);

id2 = read_PHY (PHY_REG_IDR2);

函数的末尾处读取的芯片的参数,各寄存器如下,

PHY_REG_BMCR,PHY_REG_BMSR, PHY_REG_ANAR,PHY_REG_ANLPAR,PHY_REG_ANER,PHY_REG_ANNPTR,PHY_REG_STS  ,PHY_REG_RBR   

这些寄存器的值与注释一样则说明DP83848驱动成功。这些寄存器的默认值可通过查手册确定。


以下为驱动程序主要代码,

long Init_EMAC(void)
{
 long xReturn = pdPASS;

 // Keil: function modified to access the EMAC
 // Initializes the EMAC ethernet controller
 volatile unsigned int regv,tout,id1,id2;

 /* Enable P1 Ethernet Pins. */
 /* Enable P1 Ethernet Pins. */
 PINSEL2 &= ~0xF03F330F;
 PINSEL2 = configPINSEL2_VALUE;
 PINSEL3 = (PINSEL3 & ~0x0000000F) | 0x00000005;
 /* Power Up the EMAC controller. */
 PCONP |= 0x40000000;
 //vTaskDelay( 1 );
 //OSTimeDly(1);
 /* Reset all EMAC internal modules. */
 MAC_MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
 MAC_COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES;
 /* A short delay after reset. */
 //vTaskDelay( 1 );
 //for (tout = 100; tout; tout--);
 OSTimeDly(1);
 /* Initialize MAC control registers. */
 MAC_MAC1 = MAC1_PASS_ALL;
 MAC_MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
 MAC_MAXF = ETH_MAX_FLEN;
 MAC_CLRT = CLRT_DEF;
 MAC_IPGR = IPGR_DEF;
 /*PCLK=18MHz, clock select=6, MDC=18/6=3MHz */  

 /* Enable RMII interface. */
 // MAC_COMMAND = CR_RMII | CR_PASS_RUNT_FRM;
 MAC_COMMAND = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;
 /* Reset Reduced MII Logic. */
 MAC_SUPP = SUPP_RES_RMII;
 OSTimeDly(1);
  MAC_SUPP = 0;

 /* Put the DP83848C in reset mode */
 write_PHY (PHY_REG_BMCR, 0x8000);
 write_PHY (PHY_REG_BMCR, 0x8000);
 /* Wait for hardware reset to end. */
 for (tout = 0; tout < 1000; tout++) {
   //vTaskDelay( 10 );
   OSTimeDly(10);
   regv = read_PHY (PHY_REG_BMCR);
   if (!(regv & 0x8000)) {
     /* Reset complete */
     break;
   }
 }
 /* Check if this is a DP83848C PHY. */
 id1 = read_PHY (PHY_REG_IDR1);
 id2 = read_PHY (PHY_REG_IDR2);
 if (((id1 << 16) | (id2 & 0xFFF0)) == DP83848C_ID) {
   /* Configure the PHY device */
   /* Use autonegotiation about the link speed. */
   write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
   /* Wait to complete Auto_Negotiation. */
   for (tout = 0; tout < 10; tout++) {
     //vTaskDelay( 100 );
 OSTimeDly(50);
     regv = read_PHY (PHY_REG_BMSR);
     if (regv & 0x0020) {
       /* Autonegotiation Complete. */
       break;
     }
   }
 }
 else
 {
   xReturn = pdFAIL;
 }
 /* Check the link status. */
 if( xReturn == pdPASS )
 {
   xReturn = pdFAIL;
   for (tout = 0; tout < 10; tout++) {
     //vTaskDelay( 100 );
 OSTimeDly(50);
     regv = read_PHY (PHY_REG_STS);
     if (regv & 0x0001) {
       /* Link is on. */
       xReturn = pdPASS;
       break;
     }
   }
 }
 if( xReturn == pdPASS )
 {
   /* Configure Full/Half Duplex mode. */
   if (regv & 0x0004) {
     /* Full duplex is enabled. */
     MAC_MAC2    |= 0x31; 
     //MAC_COMMAND |= CR_FULL_DUP;
 MAC_COMMAND |= 0x640;//RMII½Ó¿Ú È«Ë«¹¤
     MAC_IPGT     = IPGT_FULL_DUP;
   }
   else {
     /* Half duplex mode. */
     MAC_IPGT = IPGT_HALF_DUP;
   }
   /* Configure 100MBit/10MBit mode. */
   if (regv & 0x0002) {
     /* 10MBit mode. */
     MAC_SUPP = 0;
   }
   else {
     /* 100MBit mode. */
     MAC_SUPP = SUPP_SPEED;
   }
   /* Set the Ethernet MAC Address registers */
   MAC_SA0 = (emacETHADDR0 << 8) | emacETHADDR1;
   MAC_SA1 = (emacETHADDR2 << 8) | emacETHADDR3;
   MAC_SA2 = (emacETHADDR4 << 8) | emacETHADDR5;
   /* Initialize Tx and Rx DMA Descriptors */
  EMACTxDescriptorInit();
    EMACRxDescriptorInit();
    MAC_MAC1 |= 0x0002;/* [1]-Pass All Rx Frame */

   /* Receive Broadcast and Perfect Match Packets */
   //MAC_RXFILTERCTRL = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
   MAC_RXFILTERCTRL =  RFC_BCAST_EN | RFC_PERFECT_EN;

   /* 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

   /* Create the semaphore used ot wake the uIP task. */
   // vSemaphoreCreateBinary( xEMACSemaphore );

/* Reset all interrupts */
MAC_INTCLEAR  = 0xFFFF;

   /* Enable receive and transmit mode of MAC Ethernet core */
   MAC_COMMAND  |= (CR_RX_EN | CR_TX_EN);
   MAC_MAC1     |= MAC1_REC_EN;
 }

 /******************************************************/
  EINTSTA = 0;

  MAC_INTENABLE = 0x000C;/** Enable all interrupts except SOFTINT and WOL */

regv = read_PHY(PHY_REG_BMSR);
if( (regv & 0x0004) ==0 )  //判断驱动是否成功
INITSTATUS = 0;
else
INITSTATUS = 1;
 /*
id1 = read_PHY(PHY_REG_BMCR);//0x3000
id1 = read_PHY(PHY_REG_BMSR);//0x786D
id1 = read_PHY(PHY_REG_ANAR);//0x1E1        
id1 = read_PHY(PHY_REG_ANLPAR);//0xCDE1
id1 = read_PHY(PHY_REG_ANER);//0x0F
id1 = read_PHY(PHY_REG_ANNPTR );//0x2801
id1 = read_PHY(PHY_REG_STS );     //0x0615
id1 = read_PHY(PHY_REG_RBR );      //0x21
id1 = read_PHY(PHY_REG_PHYCR ); //0x8021
 */
return xReturn;
}
// Keil: function added to write PHY
void write_PHY (int PhyReg, int Value)
{
 unsigned int tout;

 MAC_MADR = DP83848C_DEF_ADR | PhyReg;
 MAC_MWTD = Value;
 /* Wait utill operation completed */
 tout = 0;
 for (tout = 0; tout < MII_WR_TOUT; tout++) {
   if ((MAC_MIND & MIND_BUSY) == 0) {
     break;
   }
 }
}

// Keil: function added to read PHY
unsigned short read_PHY (unsigned char PhyReg) 
{
 unsigned int tout;

 MAC_MADR = DP83848C_DEF_ADR | PhyReg;
 MAC_MCMD = MCMD_READ;
 /* Wait until operation completed */
 tout = 0;
 for (tout = 0; tout < MII_RD_TOUT; tout++) {
   if ((MAC_MIND & MIND_BUSY) == 0) {
     break;
   }
 }
 MAC_MCMD = 0;
 return (MAC_MRDD);
}
void EMACRxDescriptorInit( void )
{
    uint32 i;
    uint32 *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 = (uint32 *)(RX_DESCRIPTOR_ADDR + i * 8);
*rx_desc_addr = (uint32)(EMAC_RX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
*(rx_desc_addr+1) = (uint32)(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 = (uint32 *)(RX_STATUS_ADDR + i * 8);
*rx_status_addr = (uint32)0;/* initially, set both status info and hash CRC to 0 */
*(rx_status_addr+1) = (uint32)0; 
    }
    MAC_RXCONSUMEINDEX = 0x0; /* RX descriptor points to zero */
    return;
}

void EMACTxDescriptorInit( void )
{
    uint32 i;
    uint32 *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 = (uint32 *)(TX_DESCRIPTOR_ADDR + i * 8);/* two words at a time, packet and control */
*tx_desc_addr = (uint32)(EMAC_TX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
*(tx_desc_addr+1) = (uint32)(EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE - 1));/* set size only */
    }
    
    for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
    {
tx_status_addr = (uint32 *)(TX_STATUS_ADDR + i * 4);/* TX status, one word only, status info. */
*tx_status_addr = (uint32)0;/* initially, set status info to 0 */
    }
    MAC_TXPRODUCEINDEX = 0x0; /* TX descriptors point to zero */
    return;
}

版权声明:未经许可,请勿转载。Copyright © Valiant 2008-2015 all rights reserved.



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

DP83848CVV PHY芯片封装等资料

  • 2012年11月16日 08:41
  • 27KB
  • 下载

RMII模式以太网PHY芯片DP83848C的应用

摘要:介绍了美国国家半导体公司的PHY芯片DP83848C的功能特性;给出了在RMII(Reduced Medium Independent Interface,精简的介质无关接口)模式下的硬件电路及...

STM32_DP83848网卡

  • 2017年09月14日 09:52
  • 1.24MB
  • 下载

STM32F107+UCOS+LwIP+DP83848+RMII+MDK

  • 2016年12月14日 17:45
  • 11.08MB
  • 下载

LPC2388+UCOS/II+LWIP移植

在主任务中先初始化网卡参数,tcpip_init(NULL, NULL)中会创建TCP/IP的任务,在次任务中会不断发送ARP广播,查询在整个网段内是否有目标IP地址的设备,当有对应的设 备响应并把自...

STM32F107实现DP83848-UDP-TCP通信程序

  • 2014年12月20日 00:44
  • 840KB
  • 下载

基于arm7的(lpc2388)flash的读写操作

开始工作不久就碰到一个flash读写的问题。是一块lpc2388的芯片(arm7),开始总是抱着一arm11的flash读写的方式去看数据手册。看了好长时间都没有一个很好的解决方发。后来我在keil的...

DP83848CVV.pdf

  • 2012年05月23日 02:28
  • 2.98MB
  • 下载

再次调试STM32F407+DP83848

早在还没有毕业前,就调试过STM32F407+DP83848,这次又调试了一次,居然花了2天时间。STM32支持两种工业级标准的接口,来与外部物理层 PHY模块相连,分别是独立于介质的接口(MII)和...

LPC2388开发板用户手册

  • 2012年03月08日 15:03
  • 3.28MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LPC2388驱动PHY-DP83848
举报原因:
原因补充:

(最多只允许输入30个字)