logo资料库

基于88E1512的SGMII接口千兆网驱动的应用经验.pdf

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
基于 88E1512 的 SGMII 接口千兆网驱动的应用经验 LSL 本设计是基于 DSP 的千兆网驱动,DSP 与 88E1512 通过 MDIO 接口进行配置, 千兆网数据通讯通过 DSP 与 88E1512 的 SGMII 接口连接。由于 88E1512 的资料比 较少,且网络上没有相应的驱动程序可以找到,因此在使用 88E1512 的 PHY 芯片 进行千兆网驱动程序的开发过程比较艰辛,通过个人的努力终于实现了千兆网的 功能。进行此次的应用经验分享,主要是为了减小需要开发 88E1512 驱动的难度。 其中 DSP 是基于 TI 的 TMS320C6678 进行驱动开发的。 首先,进行 88E1512 PHY 芯片的认识. 图 1 88E1510-1518 各型号的 PHY 芯片描述 我们即将讲解的 88E1512 芯片支持 RGMII 接口、SGMII 接口的千兆有线网或 千兆光纤的配置,由于 88E1512 芯片默认是基于 RGMII 的千兆有线网,如果在硬 件上使用 RGMII 的千兆有线网的朋友会发现,不需要对 PHY 芯片进行初始化,千 兆网也能够调通。但如果使用 SGMII 接口连接 PHY 芯片与 CPU 或 MCU 的,则需要 通过 MDIO 接口配置相应的寄存器。以下我们讲解的 SGMII 接口的驱动是基于 SGMII 的千兆有线网的配置,如果是基于光纤配置,软件不太一样,需要自己进 行重新配置。
图 2 RGMII 接口和 SGMII 接口的连接示意图(截图于数据手册) 驱动程序分为以下几个部分,分别是配置 Serdes 时钟、MDIO 寄存器配置、 SGMII 接口初始化、和 PHY 芯片 MDIO 接口重配置等三部分组成。 具体程序如下: /************************************************************************** **** *FUNCATION NAME : void app_PHY_88E1512Init(void) *CREATE DATE : 2019-10-18 *CREATE BY : LSL *FUNCTION : PHY芯片88E1512初始化(含时钟初始化/MDIO配置、SRGMIII配置) *************************************************************************** ***/ void app_PHY_88E1512Init(void) { configSerdes(); platform_write("Config serdes is OK!\n"); // Init_MDIO1(); PHY0_MDIO_Init(); //MDIO初始化 platform_write("PHY MDIO Config is OK!\n"); PHY0_SGMII_Init(); //SGMII初始化 platform_write("PHY SGMII Config is OK!\n"); PHY0_MDIO_Set();
} /************************************************************************** **** *FUNCATION NAME : void configSerdes(void) *CREATE DATE : 2019-10-18 *CREATE BY : LSL *FUNCTION : SGMII Serdes时钟配置 156.25-1.25GHz 倍频16 *MODIFY DATE : *INPUT : *OUTPUT : *RETURN : *OTHERS : *************************************************************************** ***/ void configSerdes(void) { CSL_SGMII_STATUS sgmii_status; /* Unlock the chip configuration registers to allow SGMII SERDES registers to * be written */ CSL_BootCfgUnlockKicker(); /* Configure the SERDES */ /* Multiply to be 8 with Quarter Rate in the Rx registers */ CSL_BootCfgSetSGMIIConfigPLL (0x00000081); //31:25 Reserved 0000000 //23:24 LOOPBACK 00 // 22 ENOC 1 //21:18 EQ 0001 //17:15 CDR 001 -- first order threshold of 17 //14:12 LOS 000 -- tie off //11:10 ALIGN 01 -- Comma Aligned //09:07 TERM 100 -- tie off (100) // 06 INVPAIR 0 //05:04 RATE 01 -- tie off (10) //00 = Full Rate, 01 = Half Rate (*0.5), 10 = Quarter Rate (*0.25) //03:01 BUSWIDTH 000 -- tie off // 00 ENRX 1 // 0000 0000 0100 0100 0000 0010 0001 0001 = 0x0044_0211 -- My estimated value // 0000 0000 0100 0100 0000 0100 0001 0001 = 0x0044_0411 -- New DV value // 0000 0000 0000 1000 0000 1000 0100 0001 = 0x0008_0841 -- Original DV value platform_delaycycles(100);
// 0000 0000 0110 0000 1100 0110 0000 0001 CSL_BootCfgSetSGMIIRxConfig (0, 0x00700621); //31:22 Reserved 0 //21:20 LOOPBACK 00 //19:18 RDTCT 00 -- tie off // 17 ENIDL 0 -- tie off // 16 MYSNC 1 -- tie off //15:12 DEMPHASIS ???? - 0001 Lets give some de-emphasis //11:08 SWING ???? // 07 CM 1 -- tie off // 06 INVPAIR 0 //05:04 RATE 01 -- tie off //03:01 BUSWIDTH 000 -- tie off // 00 ENTX 1 // 0000 0000 0011 0001 ???? ???? 1001 0001 = 0x0031_1E91 -- My estimated value // 0000 0000 0000 0001 0000 1111 0001 0001 = 0x0001_0F11 -- New DV value // 0000 0000 0100 0000 0001 1110 0100 0001 = 0x0040_1e41 -- Original DV value CSL_BootCfgSetSGMIITxConfig (0, 0x000108A1); /* Poll the SGMII0 lock bit to confirm that the sgmii module has recognized that the SERDES PLL has locked */ do { CSL_SGMII_getStatus(0, &sgmii_status); // platform_delay(1000); // platform_write("wait sgmii phy0 is lock\n"); } while (sgmii_status.bIsLocked != 1); /* for(i=0;i<10000;i++) { } */ /* Poll the SGMII1 lock bit to confirm that the sgmii module has recognized that the SERDES PLL has locked */
timeout; /************************************************************************** **** *FUNCATION NAME : void PHY0_SGMII_Init (void) *CREATE DATE : 2019-10-18 *CREATE BY : LSL *FUNCTION : PH0 SGMII接口初始化 *MODIFY DATE : *INPUT : 端口号,0和1 *OUTPUT : *RETURN : *OTHERS : *************************************************************************** ***/ void PHY0_SGMII_Init (void) { CSL_SGMII_ADVABILITY sgmiiCfg; CSL_SGMII_STATUS sgmiiStatus; uint16_t /* Reset the port before configuring it */ CSL_SGMII_doSoftReset (0); while (CSL_SGMII_getSoftResetStatus (0) != 0); /* Hold the port in soft reset and set up * the SGMII control register: * (1) Disable Master Mode * (2) Enable Auto-negotiation */ CSL_SGMII_startRxTxSoftReset (0); CSL_SGMII_disableLoopback(0); CSL_SGMII_disableMasterMode (0); CSL_SGMII_enableAutoNegotiation (0); CSL_SGMII_endRxTxSoftReset (0); /* Setup the Advertised Ability register for this port: * (1) Enable Full duplex mode * (2) Enable Auto Negotiation * (3) Enable the Link */ sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS; sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX; // sgmiiCfg.bLinkUp = 1;//LSL 2019.10.08 添加 CSL_SGMII_setAdvAbility (0, &sgmiiCfg);
} while (sgmiiStatus.bIsLinkUp != 1);//2S超时则退出 CSL_SGMII_getStatus(0, &sgmiiStatus); if (sgmiiStatus.bIsAutoNegError != 0) return; /* This is an error condition */ CSL_SGMII_getStatus(0, &sgmiiStatus); TSC_delay_ms(1); timeout+=1; //超时计数 platform_write("*******wait PHY0 link*******\n"); // } while ((sgmiiStatus.bIsLinkUp != /* Wait for SGMII Autonegotiation to complete without error */ do { } while (sgmiiStatus.bIsAutoNegComplete != 1); timeout=0; do { // 1)&&(timeout<2000));//2S超时则退出 // platform_write("*******wait PHY0 Init is OK*******\n"); /* All done with configuration. Return Now. */ return; } /************************************************************************** **** *FUNCATION NAME : Uint16 readPhyReg(uint8_t portnum,Uint32 phyaddr, Uint32 regaddr) *CREATE DATE : 2019-12-27 *CREATE BY : LSL *FUNCTION : 通过MDIO读取PHY的寄存器 *MODIFY DATE : *INPUT : *OUTPUT : *RETURN : *OTHERS : *************************************************************************** ***/ Uint16 readPhyReg(uint8_t portnum,Uint32 phyaddr, Uint32 regaddr) { Phy Id 1 Uint16 value; MDIOR->USER_GROUP[portnum].USER_ACCESS_REG = 0 // Read | ( 1 << 31 ) // [31] Go | ( 0 << 30 ) // [30] Read
while ( MDIOR->USER_GROUP[portnum].USER_ACCESS_REG & 0x80000000 ); // value = MDIOR->USER_GROUP[portnum].USER_ACCESS_REG; return value; | ( 0 << 29 ) // [29] Ack | (regaddr << 21 ) // [25-21] PHY register address | (phyaddr << 16 ) // [20-16] PHY address | ( 0 << 0 ) // [15-0] Data ; Wait for Results } /************************************************************************** **** *FUNCATION NAME : void writePhyReg(uint8_t portnum,Uint32 phyaddr, Uint32 regaddr, Uint16 data) *CREATE DATE : 2019-12-27 *CREATE BY : LSL *FUNCTION : 通过MDIO设置PHY的寄存器 *MODIFY DATE : *INPUT : *OUTPUT : *RETURN : *OTHERS : *************************************************************************** ***/ void writePhyReg(uint8_t portnum,Uint32 phyaddr, Uint32 regaddr, Uint16 data) { Phy Id 1 address Wait for Result } | ( 1 << 31 ) // [31] Go | ( 1 << 30 ) // [30] Write | ( 0 << 29 ) // [29] Ack | (regaddr << 21 ) // [25-21] PHY register | (phyaddr << 16 ) // [20-16] PHY address | ( data << 0 ); // [15-0] Data MDIOR->USER_GROUP[portnum].USER_ACCESS_REG = 0 // Read while ( MDIOR->USER_GROUP[portnum].USER_ACCESS_REG & 0x80000000 ); //
writePhyReg(portnum,phyaddr, 22, pagenum); /************************************************************************** **** *FUNCATION NAME : void setPhyPage(uint8_t portnum,Uint32 phyaddr,Uint32 pagenum) *CREATE DATE : 2019-12-27 *CREATE BY : LSL *FUNCTION : 通过MDIO设置PHY的page号 *MODIFY DATE : *INPUT : *OUTPUT : *RETURN : *OTHERS : *************************************************************************** ***/ void setPhyPage(uint8_t portnum,Uint32 phyaddr,Uint32 pagenum) { } /************************************************************************** **** *FUNCATION NAME : void PHY0_MDIO_Init(void) *CREATE DATE : 2019-10-18 *CREATE BY : LSL *FUNCTION : MDIO PHY0芯片初始化配置 *MODIFY DATE : *INPUT : 端口号,0 *OUTPUT : *RETURN : *OTHERS : *************************************************************************** ***/ void PHY0_MDIO_Init(void) { Negotiation Process; Full-duplex setPhyPage(0,APP_PORT_PHY0_ADDR,0); writePhyReg(0,APP_PORT_PHY0_ADDR, 0, 0x700);//Isolate ;Restart Auto- int regval; // int page; /*ctrl register config*/ /*link INT0 and INT1 setup*/ CSL_MDIO_enableLinkStatusChangeInterrupt(0, 0);
分享到:
收藏