Statement of originality:

This original tutorial was created by ALINX Electronic Technology (Shanghai) Co., Ltd. (ALINX), and the copyright belongs to the company. If you want to reprint, you need to authorize and indicate the source.

Applicable board models:

AXU2CGA/AXU2CGB/AXU3EG/AXU4EV-E/AXU4EV-P/AXU5EV-E/AXU5EV-P /AXU9EG/AXU15EG

The vivado project directory is “ps_hello/vivado”

The vitis project directory is “ps_net/vitis”

Software Engineer Job Content

The following is the responsibility of software engineers.

The development board has two channels of Gigabit Ethernet, which are connected through the RGMII interface. This experiment demonstrates how to use the LWIP template that comes with Vitis to perform Gigabit Ethernet TCP communication on the PS side.

Although LWIP is a lightweight protocol stack, if you have never used it before, it will be difficult to use it. It is recommended to be familiar with the relevant knowledge of LWIP first.

1. Vitis program development

1.1 LWIP library modification

Since the built-in LWIP library can only recognize some phy chips, if the phy chip used by the development board is not within the default support range, the library file needs to be modified. You can also directly replace the original library with the modified library.

1) Find the library file directory “X:\xxx\Vitis\2020.1\data\embeddedsw\ThirdParty\sw_services”

2) Find the files “xaxiemacif_physpeed.c” and “xemacpsif_physpeed.c” in the directory “lwip211_v1_2\src\contrib\ports\xilinx\netif” to be modified.

3) Modify the “xaxiemacif_physpeed.c” file on the PL side and add relevant macro definitions

4) Add phy speed acquisition function

unsignedintget_phy_speed_ksz9031(XAxiEthernet*xaxiemacp,u32phy_addr){u16control;u16status;u16partner_capabilities;xil_printf("StartPHYautonegotiation\r\n");XAxiEthernet_PhyWrite(xaxiemacp,phy_addr,IEEE_PAGE_ADDRESS_REGISTER,2);XAxiEthernet_PhyRead(xaxiemacp,phy_addr,IEEE_CONTROL_REG_MAC,&control);//control|=IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;control&=~(0x10);XAxiEthernet_PhyWrite(xaxiemacp,phy_addr,IEEE_CONTROL_REG_MAC,control);XAxiEthernet_PhyWrite(xaxiemacp,phy_addr,IEEE_PAGE_ADDRESS_REGISTER,0);XAxiEthernet_PhyRead(xaxiemacp,phy_addr,IEEE_AUTONEGO_ADVERTISE_REG,&control);control|=IEEE_ASYMMETRIC_PAUSE_MASK;control|=IEEE_PAUSE_MASK;control|=ADVERTISE_100;control|=ADVERTISE_10;XAxiEthernet_PhyWrite(xaxiemacp,phy_addr,IEEE_AUTONEGO_ADVERTISE_REG,control);XAxiEthernet_PhyRead(xaxiemacp,phy_addr,IEEE_1000_ADVERTISE_REG_OFFSET,&control);control|=ADVERTISE_1000;XAxiEthernet_PhyWrite(xaxiemacp,phy_addr,IEEE_1000_ADVERTISE_REG_OFFSET,control);XAxiEthernet_PhyWrite(xaxiemacp,phy_addr,IEEE_PAGE_ADDRESS_REGISTER,0);XAxiEthernet_PhyRead(xaxiemacp,phy_addr,IEEE_COPPER_SPECIFIC_CONTROL_REG,&control);control|=(7<12);  max number of gigabit attempts */="" control |="">12);><11);  enable downshift */="" xaxiethernet_phywrite(xaxiemacp, phy_addr, ieee_copper_specific_control_reg,="" control);="" xaxiethernet_phyread(xaxiemacp, phy_addr, ieee_control_reg_offset,&control);="" control |=" IEEE_CTRL_AUTONEGOTIATE_ENABLE;" control |=" IEEE_STAT_AUTONEGOTIATE_RESTART;" xaxiethernet_phywrite(xaxiemacp, phy_addr, ieee_control_reg_offset, control);="" xaxiethernet_phyread(xaxiemacp, phy_addr, ieee_control_reg_offset,&control);="" control |=" IEEE_CTRL_RESET_MASK;" xaxiethernet_phywrite(xaxiemacp, phy_addr, ieee_control_reg_offset, control);="" while(1){="" xaxiethernet_phyread(xaxiemacp, phy_addr, ieee_control_reg_offset,&control);="" if(control & ieee_ctrl_reset_mask)="" continue;="" else="" break;="" }="" xil_printf("waiting for phy to complete autonegotiation.\r\n");="" xaxiethernet_phyread(xaxiemacp, phy_addr, ieee_status_reg_offset,&status);="" while(!(status & ieee_stat_autonegotiate_complete)){="" sleep(1);="" xaxiethernet_phyread(xaxiemacp, phy_addr, ieee_status_reg_offset,="" &status);="" }="" xil_printf("autonegotiation complete \r\n");="" xaxiethernet_phyread(xaxiemacp, phy_addr,0x1f,&partner_capabilities);="" if((partner_capabilities &0x40)="=0x40)/* 1000Mbps */" return1000;="" elseif((partner_capabilities &0x20)="=0x20)/* 100Mbps */" return100;="" elseif((partner_capabilities &0x10)="=0x10)/* 10Mbps */" return10;="" else="">11);>

5) Modify the function “get_IEEE_phy_speed” to add support for KSZ9031.

unsignedget_IEEE_phy_speed(XAxiEthernet*xaxiemacp){u16phy_identifier;u16phy_model;u8phytype;#ifdefXPAR_AXIETHERNET_0_BASEADDRu32phy_addr=detect_phy(xaxiemacp);/*GetthePHYIdentifierandModelnumber*/XAxiEthernet_PhyRead(xaxiemacp,phy_addr,PHY_IDENTIFIER_1_REG,&phy_identifier);XAxiEthernet_PhyRead(xaxiemacp,phy_addr,PHY_IDENTIFIER_2_REG,&phy_model);/*DependinguponwhatmanufacturerPHYisconnected,adifferentmaskis*neededtodeterminethespecificmodelnumberofthePHY.*/if(phy_identifier==MARVEL_PHY_IDENTIFIER){phy_model=phy_model&MARVEL_PHY_MODEL_NUM_MASK;if(phy_model==MARVEL_PHY_88E1116R_MODEL){returnget_phy_speed_88E1116R(xaxiemacp,phy_addr);}elseif(phy_model==MARVEL_PHY_88E1111_MODEL){returnget_phy_speed_88E1111(xaxiemacp,phy_addr);}}elseif(phy_identifier==TI_PHY_IDENTIFIER){phy_model=phy_model&TI_PHY_DP83867_MODEL;phytype=XAxiEthernet_GetPhysicalInterface(xaxiemacp);if(phy_model==TI_PHY_DP83867_MODEL&&phytype==XAE_PHY_TYPE_SGMII){returnget_phy_speed_TI_DP83867_SGMII(xaxiemacp,phy_addr);}if(phy_model==TI_PHY_DP83867_MODEL){returnget_phy_speed_TI_DP83867(xaxiemacp,phy_addr);}}elseif(phy_identifier==MICREL_PHY_IDENTIFIER){xil_printf("Phy%disKSZ9031\n\r",phy_addr);get_phy_speed_ksz9031(xaxiemacp,phy_addr);}else{LWIP_DEBUGF(NETIF_DEBUG,("XAxiEthernetget_IEEE_phy_speed:DetectedPHYwithunknownidentifier/model.\r\n"));}#endif#ifdefPCM_PMA_CORE_PRESENTreturnget_phy_negotiated_speed(xaxiemacp,phy_addr);#endif}

6) Modify the “xemacpsif_physpeed.c” file on the PS side to add macro definitions

7) Add phy speed acquisition function

staticu32_tget_phy_speed_ksz9031(XEmacPs*xemacpsp,u32_tphy_addr){u16_ttemp;u16_tcontrol;u16_tstatus;u16_tstatus_speed;u32_ttimeout_counter=0;u32_ttemp_speed;u32_tphyregtemp;xil_printf("StartPHYautonegotiation\r\n");XEmacPs_PhyWrite(xemacpsp,phy_addr,IEEE_PAGE_ADDRESS_REGISTER,2);XEmacPs_PhyRead(xemacpsp,phy_addr,IEEE_CONTROL_REG_MAC,&control);control|=IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;XEmacPs_PhyWrite(xemacpsp,phy_addr,IEEE_CONTROL_REG_MAC,control);XEmacPs_PhyWrite(xemacpsp,phy_addr,IEEE_PAGE_ADDRESS_REGISTER,0);XEmacPs_PhyRead(xemacpsp,phy_addr,IEEE_AUTONEGO_ADVERTISE_REG,&control);control|=IEEE_ASYMMETRIC_PAUSE_MASK;control|=IEEE_PAUSE_MASK;control|=ADVERTISE_100;control|=ADVERTISE_10;XEmacPs_PhyWrite(xemacpsp,phy_addr,IEEE_AUTONEGO_ADVERTISE_REG,control);XEmacPs_PhyRead(xemacpsp,phy_addr,IEEE_1000_ADVERTISE_REG_OFFSET,&control);control|=ADVERTISE_1000;XEmacPs_PhyWrite(xemacpsp,phy_addr,IEEE_1000_ADVERTISE_REG_OFFSET,control);XEmacPs_PhyWrite(xemacpsp,phy_addr,IEEE_PAGE_ADDRESS_REGISTER,0);XEmacPs_PhyRead(xemacpsp,phy_addr,IEEE_COPPER_SPECIFIC_CONTROL_REG,&control);control|=(7<12);  max number of gigabit attempts */="" control |="">12);><11);  enable downshift */="" xemacps_phywrite(xemacpsp, phy_addr, ieee_copper_specific_control_reg,="" control);="" xemacps_phyread(xemacpsp, phy_addr, ieee_control_reg_offset,&control);="" control |=" IEEE_CTRL_AUTONEGOTIATE_ENABLE;" control |=" IEEE_STAT_AUTONEGOTIATE_RESTART;" xemacps_phywrite(xemacpsp, phy_addr, ieee_control_reg_offset, control);="" xemacps_phyread(xemacpsp, phy_addr, ieee_control_reg_offset,&control);="" control |=" IEEE_CTRL_RESET_MASK;" xemacps_phywrite(xemacpsp, phy_addr, ieee_control_reg_offset, control);="" while(1){="" xemacps_phyread(xemacpsp, phy_addr, ieee_control_reg_offset,&control);="" if(control & ieee_ctrl_reset_mask)="" continue;="" else="" break;="" }="" xemacps_phyread(xemacpsp, phy_addr, ieee_status_reg_offset,&status);="" xil_printf("waiting for phy to complete autonegotiation.\r\n");="" while(!(status & ieee_stat_autonegotiate_complete)){="" sleep(1);="" xemacps_phyread(xemacpsp, phy_addr,="" ieee_copper_specific_status_reg_2,&temp);="" timeout_counter++;="" if(timeout_counter ="=30){" xil_printf("auto negotiation error \r\n");="" return;="" }="" xemacps_phyread(xemacpsp, phy_addr, ieee_status_reg_offset,&status);="" }="" xil_printf("autonegotiation complete \r\n");="" xemacps_phyread(xemacpsp, phy_addr,0x1f,="" &status_speed);="" if((status_speed &0x40)="=0x40)/* 1000Mbps */" return1000;="" elseif((status_speed &0x20)="=0x20)/* 100Mbps */" return100;="" elseif((status_speed &0x10)="=0x10)/* 10Mbps */" return10;="" else="" return0;="">11);>

8) Modify the function “get_IEEE_phy_speed” to add support for KSZ9031

staticu32_tget_IEEE_phy_speed(XEmacPs*xemacpsp,u32_tphy_addr){u16_tphy_identity;u32_tRetStatus;XEmacPs_PhyRead(xemacpsp,phy_addr,PHY_IDENTIFIER_1_REG,&phy_identity);if(phy_identity==MICREL_PHY_IDENTIFIER){RetStatus=get_phy_speed_ksz9031(xemacpsp,phy_addr);}elseif(phy_identity==PHY_TI_IDENTIFIER){RetStatus=get_TI_phy_speed(xemacpsp,phy_addr);}elseif(phy_identity==PHY_REALTEK_IDENTIFIER){RetStatus=get_Realtek_phy_speed(xemacpsp,phy_addr);}else{RetStatus=get_Marvell_phy_speed(xemacpsp,phy_addr);}returnRetStatus;}

1.2 Create APP project based on LWIP template

2. Download and debug

The test environment requires a router that supports dhcp. The development board can automatically obtain an IP address when connected to the router. The experimental host and the development board are in the same network and can communicate with each other.

2.1 Ethernet test

1) Connect the serial port and open the serial port debugging terminal, connect the Ethernet cable at the PS end to the router, and run the Vitis download program

2) You can see that the serial port prints out some information, and you can see that the automatically obtained address is “192.168.1.63”, the connection speed is 1000Mbps, and the tcp port is 7

3) Connect using telnet

4) When a character is input, the development board returns the same character

3. Experiment summary

Through the experiment, we have a deeper understanding of the development of the Vitis program. This experiment simply explains how to create an LWIP application. LWIP can complete protocols such as UDP and TCP. In subsequent tutorials, we will provide specific applications based on Ethernet, such as ADC The collected data is sent through Ethernet, and the camera data is sent to the host computer for display through Ethernet.

Leave a Reply

Your email address will not be published.