Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AXI Ethernet 3.0
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Dmitriyspb
Приветствую!

Нужно оживить Ethernet на ZC702 с подключенным к нему двухканальным модулем FMC

FMC из себя представляет:
Нажмите для просмотра прикрепленного файла

Поэтому в области PL надо реализовать MAC уровень ethernet..... Для этого я использую AXI_Ethernet 3.0. Получился вот такая система:
Нажмите для просмотра прикрепленного файла

Сама система работает...проверил на светодиодиках. Вот закапался когда дело дошло до этапа программирования процессора. Нашел кучу драйверов и не могу в них разобраться.
Чем и в каком порядке нужно его (AXI_Ethernet 3.0.) инициализировать? Может у кого был подобный опыт? Какие библиотеки подключать? Или может примеры у кого-нибудь есть?
Maverick
Цитата(Dmitriyspb @ Nov 17 2015, 14:17) *
Приветствую!

Нужно оживить Ethernet на ZC702 с подключенным к нему двухканальным модулем FMC

FMC из себя представляет:
Нажмите для просмотра прикрепленного файла

Поэтому в области PL надо реализовать MAC уровень ethernet..... Для этого я использую AXI_Ethernet 3.0. Получился вот такая система:
Нажмите для просмотра прикрепленного файла

Сама система работает...проверил на светодиодиках. Вот закапался когда дело дошло до этапа программирования процессора. Нашел кучу драйверов и не могу в них разобраться.
Чем и в каком порядке нужно его (AXI_Ethernet 3.0.) инициализировать? Может у кого был подобный опыт? Какие библиотеки подключать? Или может примеры у кого-нибудь есть?

это смотрели? (примеры)
Dmitriyspb
Цитата(Maverick @ Nov 17 2015, 16:52) *


смотрел. Пытаюсь и там разобраться, но вопросов много.

Есть дока на это ядро, вот на нее и делаю основной акцент

В этом документе на первой странице написано следующее:
Notes:
1. For a complete listing of supported derivative devices, see the
Embedded Edition Derivative Device Support.
2. Supported in ISE Design Suite implementations only.
3. Standalone driver details can be found in the EDK or SDK
directory (<install_directory>/doc/usenglish/xilinx_drivers.htm).

Linux OS and driver support information is available from
wiki.xilinx.com.
4. For a listing of the supported tool versions, see the ISE Design
Suite 14: Release Note Guide.
5. For more device family information, see Reference Documents.
6. Supports only 7 series devices.

Надо смотреть 3 пункт. Я именно в Standalone и использую процессорную систему.
Сходил я по указанной ссылке и действительно нашел ВАГОН драйверов. Но их там огромное количество с которым разобраться не получается. У меня маловато опыта по написанию программ на СИ. Занимался преимущественно ПЛИС/verilog.

Нашел там еще вот этот документ рассказывающий о структуре драйвера. Из него стало ясно что мне нужно реализовать драйвер "Layer 1 (Device Driver)"

начал копать предложенные дрова от Xilinx и нашел топовый
CODE

/**
*
* @file xaxiethernet_example_util.c
*
* This file implements the utility functions for the Axi Ethernet example code.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a asa 6/30/10 First release based on the ll temac driver
* 3.01a srt 02/03/13 Added support for SGMII mode (CR 676793).
* 02/14/13 Added support for Zynq (CR 681136).
* 3.02a srt 04/24/13 Modified parameter *_SGMII_PHYADDR to *_PHYADDR, the
* config parameter C_PHYADDR applies to SGMII/1000BaseX
* modes of operation and added support for 1000BaseX mode
* (CR 704195). Added function *_ConfigureInternalPhy()
* for this purpose.
* 04/24/13 Added support for RGMII mode.
* 3.02a srt 08/06/13 Fixed CR 717949:
* Configures external Marvel 88E1111 PHY based on the
* axi ethernet physical interface type and allows to
* operate in specific interface mode without changing
* jumpers on the Microblaze board.
*
* </pre>
*
******************************************************************************/

/***************************** Include Files *********************************/

#include "xaxiethernet_example.h"
#if !defined (__MICROBLAZE__) && !defined(__PPC__)
#include "sleep.h"
#endif

/************************** Variable Definitions ****************************/

/*
* Local MAC address
*/
char AxiEthernetMAC[6] = { 0x00, 0x0A, 0x35, 0x01, 0x02, 0x03 };

/******************************************************************************/
/**
*
* Set the MAC addresses in the frame.
*
* @param FramePtr is the pointer to the frame.
* @param DestAddr is the Destination MAC address.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrFormatMAC(EthernetFrame *FramePtr, char *DestAddr)
{
char *Frame = (char *) FramePtr;
char *SourceAddress = AxiEthernetMAC;
int Index;

/*
* Destination address
*/
for (Index = 0; Index < XAE_MAC_ADDR_SIZE; Index++) {
*Frame++ = *DestAddr++;
}

/*
* Source address
*/
for (Index = 0; Index < XAE_MAC_ADDR_SIZE; Index++) {
*Frame++ = *SourceAddress++;
}
}

/******************************************************************************/
/**
*
* Set the frame type for the specified frame.
*
* @param FramePtr is the pointer to the frame.
* @param FrameType is the Type to set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrFormatType(EthernetFrame *FramePtr, u16 FrameType)
{
char *Frame = (char *) FramePtr;

/*
* Increment to type field
*/
Frame = Frame + 12;

FrameType = Xil_Htons(FrameType);
/*
* Set the type
*/
*(u16 *) Frame = FrameType;
}

/******************************************************************************/
/**
* This function places a pattern in the payload section of a frame. The pattern
* is a 8 bit incrementing series of numbers starting with 0.
* Once the pattern reaches 256, then the pattern changes to a 16 bit
* incrementing pattern:
* <pre>
* 0, 1, 2, ... 254, 255, 00, 00, 00, 01, 00, 02, ...
* </pre>
*
* @param FramePtr is a pointer to the frame to change.
* @param PayloadSize is the number of bytes in the payload that will be
* set.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameSetPayloadData(EthernetFrame *FramePtr,
int PayloadSize)
{
unsigned BytesLeft = PayloadSize;
u8 *Frame;
u16 Counter = 0;

/*
* Set the frame pointer to the start of the payload area
*/
Frame = (u8 *) FramePtr + XAE_HDR_SIZE;

/*
* Insert 8 bit incrementing pattern
*/
while (BytesLeft && (Counter < 256)) {
*Frame++ = (u8) Counter++;
BytesLeft--;
}

/*
* Switch to 16 bit incrementing pattern
*/
while (BytesLeft) {
*Frame++ = (u8) (Counter >> 8); /* high */
BytesLeft--;

if (!BytesLeft)
break;

*Frame++ = (u8) Counter++; /* low */
BytesLeft--;
}
}

/******************************************************************************/
/**
*
* Set the frame VLAN info for the specified frame.
*
* @param FramePtr is the pointer to the frame.
* @param VlanNumber is the VlanValue insertion position to set in frame.
* @param Vid is the 4 bytes Vlan value (TPID, Priority, CFI, VID)
* to be set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrVlanFormatVid(EthernetFrame *FramePtr,
u32 VlanNumber, u32 Vid)
{
char *Frame = (char *) FramePtr;

/*
* Increment to type field
*/
Frame = Frame + 12 + (VlanNumber * 4);

Vid = Xil_Htonl(Vid);

/*
* Set the type
*/
*(u32 *) Frame = Vid;
}

/******************************************************************************/
/**
*
* Set the frame type for the specified frame.
*
* @param FramePtr is the pointer to the frame.
* @param FrameType is the Type to set in frame.
* @param VlanNumber is the VLAN friendly adjusted insertion position to
* set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrVlanFormatType(EthernetFrame *FramePtr,
u16 FrameType, u32 VlanNumber)
{
char *Frame = (char *) FramePtr;

/*
* Increment to type field
*/
Frame = Frame + 12 + (VlanNumber * 4);

FrameType = Xil_Htons(FrameType);

/*
* Set the type
*/
*(u16 *) Frame = FrameType;
}

/******************************************************************************/
/**
* This function places a pattern in the payload section of a frame. The pattern
* is a 8 bit incrementing series of numbers starting with 0.
* Once the pattern reaches 256, then the pattern changes to a 16 bit
* incrementing pattern:
* <pre>
* 0, 1, 2, ... 254, 255, 00, 00, 00, 01, 00, 02, ...
* </pre>
*
* @param FramePtr is a pointer to the frame to change.
* @param PayloadSize is the number of bytes in the payload that will be set.
* @param VlanNumber is the VLAN friendly adjusted insertion position to
* set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameSetVlanPayloadData(EthernetFrame *FramePtr,
int PayloadSize, u32 VlanNumber)
{
unsigned BytesLeft = PayloadSize;
u8 *Frame;
u16 Counter = 0;

/*
* Set the frame pointer to the start of the payload area
*/
Frame = (u8 *) FramePtr + XAE_HDR_SIZE + (VlanNumber * 4);

/*
* Insert 8 bit incrementing pattern
*/
while (BytesLeft && (Counter < 256)) {
*Frame++ = (u8) Counter++;
BytesLeft--;
}

/*
* Switch to 16 bit incrementing pattern
*/
while (BytesLeft) {
*Frame++ = (u8) (Counter >> 8); /* high */
BytesLeft--;

if (!BytesLeft)
break;

*Frame++ = (u8) Counter++; /* low */
BytesLeft--;
}
}

/******************************************************************************/
/**
* This function verifies the frame data against a CheckFrame.
*
* Validation occurs by comparing the ActualFrame to the header of the
* CheckFrame. If the headers match, then the payload of ActualFrame is
* verified for the same pattern Util_FrameSetPayloadData() generates.
*
* @param CheckFrame is a pointer to a frame containing the 14 byte header
* that should be present in the ActualFrame parameter.
* @param ActualFrame is a pointer to a frame to validate.
*
* @return - XST_SUCCESS if successful.
* - XST_FAILURE in case of failure.
*
* @note None.
*
******************************************************************************/
int AxiEthernetUtilFrameVerify(EthernetFrame * CheckFrame,
EthernetFrame * ActualFrame)
{
unsigned char *CheckPtr = (unsigned char *) CheckFrame;
unsigned char *ActualPtr = (unsigned char *) ActualFrame;
u16 BytesLeft;
u16 Counter;
int Index;


/*
* Compare the headers
*/
for (Index = 0; Index < XAE_HDR_SIZE; Index++) {
if (CheckPtr[Index] != ActualPtr[Index]) {
return XST_FAILURE;
}
}

Index = 0;

BytesLeft = *(u16 *) &ActualPtr[12];
BytesLeft = Xil_Ntohs(BytesLeft);
/*
* Get the length of the payload, do not use VLAN TPID here.
* TPID needs to be verified.
*/
while ((0x8100 == BytesLeft) || (0x88A8 == BytesLeft) ||
(0x9100 == BytesLeft) || (0x9200 == BytesLeft)) {
Index++;
BytesLeft = *(u16 *) &ActualPtr[12+(4*Index)];
BytesLeft = Xil_Ntohs(BytesLeft);
}

/*
* Validate the payload
*/
Counter = 0;
ActualPtr = &ActualPtr[14+(4*Index)];

/*
* Check 8 bit incrementing pattern
*/
while (BytesLeft && (Counter < 256)) {
if (*ActualPtr++ != (u8) Counter++) {

return XST_FAILURE;
}
BytesLeft--;
}

/*
* Check 16 bit incrementing pattern
*/
while (BytesLeft) {
if (*ActualPtr++ != (u8) (Counter >> 8)) { /* high */
return XST_FAILURE;
}

BytesLeft--;

if (!BytesLeft)
break;

if (*ActualPtr++ != (u8) Counter++) { /* low */
return XST_FAILURE;
}

BytesLeft--;
}

return XST_SUCCESS;
}

/******************************************************************************/
/**
* This function sets all bytes of a frame to 0.
*
* @param FramePtr is a pointer to the frame itself.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameMemClear(EthernetFrame * FramePtr)
{
u32 *Data32Ptr = (u32 *) FramePtr;
u32 WordsLeft = sizeof(EthernetFrame) / sizeof(u32);

/*
* Frame should be an integral number of words
*/
while (WordsLeft--) {
*Data32Ptr++ = 0;
}
}

/******************************************************************************/
/**
*
* This function detects the PHY address by looking for successful MII status
* register contents (PHY register 1). It looks for a PHY that supports
* auto-negotiation and 10Mbps full-duplex and half-duplex. So, this code
* won't work for PHYs that don't support those features, but it's a bit more
* general purpose than matching a specific PHY manufacturer ID.
*
* Note also that on some (older) Xilinx ML4xx boards, PHY address 0 does not
* properly respond to this query. But, since the default is 0 and asssuming
* no other address responds, then it seems to work OK.
*
* @param The Axi Ethernet driver instance
*
* @return The address of the PHY (defaults to 0 if none detected)
*
* @note None.
*
******************************************************************************/
/* Use MII register 1 (MII status register) to detect PHY */
#define PHY_DETECT_REG 1

/* Mask used to verify certain PHY features (or register contents)
* in the register above:
* 0x1000: 10Mbps full duplex support
* 0x0800: 10Mbps half duplex support
* 0x0008: Auto-negotiation support
*/
#define PHY_DETECT_MASK 0x1808

u32 AxiEthernetDetectPHY(XAxiEthernet * AxiEthernetInstancePtr)
{
u16 PhyReg;
int PhyAddr;

for (PhyAddr = 31; PhyAddr >= 0; PhyAddr--) {
XAxiEthernet_PhyRead(AxiEthernetInstancePtr, PhyAddr,
PHY_DETECT_REG, &PhyReg);

if ((PhyReg != 0xFFFF) &&
((PhyReg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
/* Found a valid PHY address */
return PhyAddr;
}
}

return 0; /* Default to zero */
}

/******************************************************************************/
/**
* Set PHY to loopback mode. This works with the marvell PHY common on ML40x
* evaluation boards
*
* @param Speed is the loopback speed 10, 100, or 1000 Mbit
*
******************************************************************************/
/* IEEE PHY Specific definitions */
#define PHY_R0_CTRL_REG 0
#define PHY_R3_PHY_IDENT_REG 3

#define PHY_R0_RESET 0x8000
#define PHY_R0_LOOPBACK 0x4000
#define PHY_R0_ANEG_ENABLE 0x1000
#define PHY_R0_DFT_SPD_MASK 0x2040
#define PHY_R0_DFT_SPD_10 0x0000
#define PHY_R0_DFT_SPD_100 0x2000
#define PHY_R0_DFT_SPD_1000 0x0040
#define PHY_R0_ISOLATE 0x0400

/* Marvel PHY 88E1111 Specific definitions */
#define PHY_R20_EXTND_CTRL_REG 20
#define PHY_R27_EXTND_STS_REG 27

#define PHY_R20_DFT_SPD_10 0x20
#define PHY_R20_DFT_SPD_100 0x50
#define PHY_R20_DFT_SPD_1000 0x60
#define PHY_R20_RX_DLY 0x80

#define PHY_R27_MAC_CONFIG_GMII 0x000F
#define PHY_R27_MAC_CONFIG_MII 0x000F
#define PHY_R27_MAC_CONFIG_RGMII 0x000B
#define PHY_R27_MAC_CONFIG_SGMII 0x0004

/* Marvel PHY 88E1116R Specific definitions */
#define PHY_R22_PAGE_ADDR_REG 22
#define PHY_PG2_R21_CTRL_REG 21

#define PHY_REG21_10 0x0030
#define PHY_REG21_100 0x2030
#define PHY_REG21_1000 0x0070

/* Marvel PHY flags */
#define MARVEL_PHY_88E1111_MODEL 0xC0
#define MARVEL_PHY_88E1116R_MODEL 0x240
#define PHY_MODEL_NUM_MASK 0x3F0

/******************************************************************************/
/**
*
* This function sets the PHY to loopback mode. This works with the marvell PHY
* common on ML40x evaluation boards.
*
* @param AxiEthernetInstancePtr is a pointer to the instance of the
* AxiEthernet component.
* @param Speed is the loopback speed 10, 100, or 1000 Mbit.
*
* @return - XST_SUCCESS if successful.
* - XST_FAILURE, in case of failure..
*
* @note None.
*
******************************************************************************/
int AxiEthernetUtilEnterLoopback(XAxiEthernet *AxiEthernetInstancePtr,
int Speed)
{
u16 PhyReg0;
signed int PhyAddr;
u8 PhyType;
u16 PhyModel;
u16 PhyReg20; /* Extended PHY specific Register (Reg 20)
of Marvell 88E1111 PHY */
u16 PhyReg21; /* Control Register MAC (Reg 21)
of Marvell 88E1116R PHY */

/* Get the Phy Interface */
PhyType = XAxiEthernet_GetPhysicalInterface(AxiEthernetInstancePtr);

/* Detect the PHY address */
if (PhyType != XAE_PHY_TYPE_1000BASE_X) {
PhyAddr = AxiEthernetDetectPHY(AxiEthernetInstancePtr);
} else {
PhyAddr = XPAR_AXIETHERNET_0_PHYADDR;
}

XAxiEthernet_PhyRead(AxiEthernetInstancePtr, PhyAddr,
PHY_R3_PHY_IDENT_REG, &PhyModel);
PhyModel = PhyModel & PHY_MODEL_NUM_MASK;

/* Clear the PHY of any existing bits by zeroing this out */
PhyReg0 = PhyReg20 = PhyReg21 = 0;

switch (Speed) {
case XAE_SPEED_10_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_10;
PhyReg20 |= PHY_R20_DFT_SPD_10;
PhyReg21 |= PHY_REG21_10;
break;

case XAE_SPEED_100_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_100;
PhyReg20 |= PHY_R20_DFT_SPD_100;
PhyReg21 |= PHY_REG21_100;
break;

case XAE_SPEED_1000_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_1000;
PhyReg20 |= PHY_R20_DFT_SPD_1000;
PhyReg21 |= PHY_REG21_1000;
break;

default:
AxiEthernetUtilErrorTrap("Intg_LinkSpeed not 10, 100, or 1000 mbps");
return XST_FAILURE;
}

/* RGMII mode Phy specific registers initialization */
if ((PhyType == XAE_PHY_TYPE_RGMII_2_0) ||
(PhyType == XAE_PHY_TYPE_RGMII_1_3)) {
if (PhyModel == MARVEL_PHY_88E1111_MODEL) {
PhyReg20 |= PHY_R20_RX_DLY;
/*
* Adding Rx delay. Configuring loopback speed.
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R20_EXTND_CTRL_REG,
PhyReg20);
} else if (PhyModel == MARVEL_PHY_88E1116R_MODEL) {
/*
* Switching to PAGE2
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr,
PHY_R22_PAGE_ADDR_REG, 2);
/*
* Adding Tx and Rx delay. Configuring loopback speed.
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr,
PHY_PG2_R21_CTRL_REG, PhyReg21);
/*
* Switching to PAGE0
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr,
PHY_R22_PAGE_ADDR_REG, 0);
}
PhyReg0 &= (~PHY_R0_ANEG_ENABLE);
}

/* Configure interface modes */
if (PhyModel == MARVEL_PHY_88E1111_MODEL) {
if ((PhyType == XAE_PHY_TYPE_RGMII_2_0) ||
(PhyType == XAE_PHY_TYPE_RGMII_1_3)) {
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R27_EXTND_STS_REG,
PHY_R27_MAC_CONFIG_RGMII);
} else if (PhyType == XAE_PHY_TYPE_SGMII) {
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R27_EXTND_STS_REG,
PHY_R27_MAC_CONFIG_SGMII);
} else if ((PhyType == XAE_PHY_TYPE_GMII) ||
(PhyType == XAE_PHY_TYPE_MII)) {
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R27_EXTND_STS_REG,
PHY_R27_MAC_CONFIG_GMII );
}
}

/* Set the speed and put the PHY in reset, then put the PHY in loopback */
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG,
PhyReg0 | PHY_R0_RESET);
AxiEthernetUtilPhyDelay(AXIETHERNET_PHY_DELAY_SEC);
XAxiEthernet_PhyRead(AxiEthernetInstancePtr,PhyAddr,
PHY_R0_CTRL_REG, &PhyReg0);
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG,
PhyReg0 | PHY_R0_LOOPBACK);

if ((PhyType == XAE_PHY_TYPE_SGMII) ||
(PhyType == XAE_PHY_TYPE_1000BASE_X)) {
AxiEthernetUtilConfigureInternalPhy(AxiEthernetInstancePtr, Speed);
}

AxiEthernetUtilPhyDelay(1);

return XST_SUCCESS;
}

/******************************************************************************/
/**
*
* This function is called by example code when an error is detected. It
* can be set as a breakpoint with a debugger or it can be used to print out the
* given message if there is a UART or STDIO device.
*
* @param Message is the text explaining the error
*
* @return None
*
* @note None
*
******************************************************************************/
void AxiEthernetUtilErrorTrap(char *Message)
{
static int Count = 0;

Count++;

#ifdef STDOUT_BASEADDRESS
xil_printf("%s\r\n", Message);
#endif
}

/******************************************************************************/
/**
*
* For Microblaze we use an assembly loop that is roughly the same regardless of
* optimization level, although caches and memory access time can make the delay
* vary. Just keep in mind that after resetting or updating the PHY modes,
* the PHY typically needs time to recover.
*
* @return None
*
* @note None
*
******************************************************************************/
void AxiEthernetUtilPhyDelay(unsigned int Seconds)
{
#if defined (__MICROBLAZE__) || defined(__PPC__)
static int WarningFlag = 0;

/* If MB caches are disabled or do not exist, this delay loop could
* take minutes instead of seconds (e.g., 30x longer). Print a warning
* message for the user (once). If only MB had a built-in timer!
*/
if (((mfmsr() & 0x20) == 0) && (!WarningFlag)) {
WarningFlag = 1;
}

#define ITERS_PER_SEC (XPAR_CPU_CORE_CLOCK_FREQ_HZ / 6)
asm volatile ("\n"
"1: \n\t"
"addik r7, r0, %0 \n\t"
"2: \n\t"
"addik r7, r7, -1 \n\t"
"bneid r7, 2b \n\t"
"or r0, r0, r0 \n\t"
"bneid %1, 1b \n\t"
"addik %1, %1, -1 \n\t"
:: "i"(ITERS_PER_SEC), "d" (Seconds));
#else
sleep(Seconds);
#endif
}

/******************************************************************************/
/**
*
* This function configures the internal phy for SGMII and 1000baseX modes.
* *
* @param AxiEthernetInstancePtr is a pointer to the instance of the
* AxiEthernet component.
* @param Speed is the loopback speed 10, 100, or 1000 Mbit.
*
* @return - XST_SUCCESS if successful.
* - XST_FAILURE, in case of failure..
*
* @note None.
*
******************************************************************************/
int AxiEthernetUtilConfigureInternalPhy(XAxiEthernet *AxiEthernetInstancePtr,
int Speed)
{
u16 PhyReg0;
signed int PhyAddr;

PhyAddr = XPAR_AXIETHERNET_0_PHYADDR;

/* Clear the PHY of any existing bits by zeroing this out */
PhyReg0 = 0;
XAxiEthernet_PhyRead(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG, &PhyReg0);

PhyReg0 &= (~PHY_R0_ANEG_ENABLE);
PhyReg0 &= (~PHY_R0_ISOLATE);

switch (Speed) {
case XAE_SPEED_10_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_10;
break;
case XAE_SPEED_100_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_100;
break;
case XAE_SPEED_1000_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_1000;
break;
default:
AxiEthernetUtilErrorTrap(
"Intg_LinkSpeed not 10, 100, or 1000 mbps\n\r");
return XST_FAILURE;
}

AxiEthernetUtilPhyDelay(1);
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG, PhyReg0);
return XST_SUCCESS;
};



Тут много разных функций. Помогите пожалуйста определиться с необходимыми для меня.

Вот основные файлы этого драйвера.
dm.pogrebnoy
Это не топовый, это утилиты для формирования/обработки пакетов, где-то есть более топовыйsm.gif
Начните вот отсюда:
https://yadi.sk/i/phSLYE8PkX9in
Dmitriyspb
Цитата(dm.pogrebnoy @ Nov 17 2015, 18:38) *
Это не топовый, это утилиты для формирования/обработки пакетов, где-то есть более топовыйsm.gif
Начните вот отсюда:
https://yadi.sk/i/phSLYE8PkX9in


Спасибо большое. Я почему-то там еще не смотрел=) Пошел читать=))
Dmitriyspb
Цитата(dm.pogrebnoy @ Nov 17 2015, 18:38) *
Это не топовый, это утилиты для формирования/обработки пакетов, где-то есть более топовыйsm.gif
Начните вот отсюда:
https://yadi.sk/i/phSLYE8PkX9in


Начал. Нашел пример
Нажмите для просмотра прикрепленного файла

загрузил:
CODE
/******************************************************************************
*
* Copyright © 2008 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (cool.gif that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xemaclite_ping_reply_example.c
*
* This file contains an EmacLite ping reply example in polled mode. This example
* will generate a ping reply when it receives a ping request packet from the
* external world.
*
* @note
*
* The local IP address is set to 172.16.63.121. User needs to update
* LocalIpAddr variable with a free IP address based on the network on which
* this example is to be run.
*
* The local MAC address is set to 0x000A35030201. User can update LocalMacAddr
* variable with a valid MAC address. The first three bytes contains
* the manufacture ID. 0x000A35 is XILINX manufacture ID.
*
* This program will respond continuously to a number of ping requests as defined
* by MAX_PING_REPLIES in this file.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ktn 20/08/08 First release
* 3.00a ktn 10/22/09 Updated example to use the macros that have been changed
* in the driver to remove _m from the name of the macro.
* 3.01a ktn 08/06/10 Updated the example to support little endian MicroBlaze.
*
* </pre>
*
*****************************************************************************/

/***************************** Include Files *********************************/

#include "xparameters.h"
#include "xstatus.h"
#include "xemaclite.h"
#include "xil_io.h"

/************************** Constant Definitions *****************************/

/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID

/*
* Change this parameter to limit the number of ping replies sent by this
* program.
*/
#define MAX_PING_REPLIES 10 /* Maximum number of ping replies */

#define BROADCAST_PACKET 1 /* Broadcast packet */
#define MAC_MATCHED_PACKET 2 /* Dest MAC matched with local MAC */
#define IP_ADDR_SIZE 4 /* IP Address size in Bytes */
#define ARP_REQUEST 0x0001 /* ARP Request bits in Rx packet */
#define ARP_REPLY 0x0002 /* ARP status bits indicating reply */
#define ARP_PACKET_SIZE 0x3C /* ARP packet len 60 Bytes */
#define ICMP_PACKET_SIZE 0x4A /* ICMP packet length 74 Bytes
* including Src and Dest MAC Address */
#define BROADCAST_ADDR 0xFFFF /* Broadcast Address */
#define CORRECT_CKSUM_VALUE 0xFFFF /* Correct checksum value */
#define IDENT_FIELD_VALUE 0x9263 /* Identification field (random num) */

/*
* Definitions for the locations and length of some of the fields in a
* IP packet. The lengths are defined in Half-Words (2 bytes).
*/
#define ETHER_PROTO_TYPE_LEN 1 /* Ethernet protocol Type length */
#define SRC_MAC_ADDR_LOC 3 /* Source MAC address location */
#define MAC_ADDR_LEN 3 /* MAC address length */
#define ETHER_PROTO_TYPE_LOC 6 /* Ethernet Proto type location */

#define ARP_HW_TYPE_LEN 1 /* Hardware Type length */
#define ARP_PROTO_TYPE_LEN 1 /* Protocol Type length */
#define ARP_HW_ADD_LEN 1 /* Hardware address length */
#define ARP_PROTO_ADD_LEN 1 /* Protocol address length */
#define ARP_ZEROS_LEN 9 /* Length to be filled with zeros */
#define ARP_REQ_STATUS_LOC 10 /* ARP request location */
#define ARP_REQ_SRC_IP_LOC 14 /* Src IP address location of ARP request */
#define ARP_REQ_DEST_IP_LOC_1 19 /* Destination IP's 1st half word location */
#define ARP_REQ_DEST_IP_LOC_2 20 /* Destination IP's 2nd half word location */

#define IP_VERSION_LEN 1 /* IP Version length */
#define IP_PACKET_LEN 1 /* IP Packet length field */
#define IP_FRAG_FIELD_LEN 1 /* Fragment field len in ICMP packet */
#define IP_TTL_ICM_LEN 1 /* Time to live and ICM fields length */
#define IP_ADDR_LEN 2 /* Size of IP address in half-words */
#define IP_CSUM_LOC_BACK 5 /* IP checksum location from end of frame */
#define IP_HDR_START_LOC 7 /* IP header start location */
#define IP_HDR_LEN 10 /* IP Header length */
#define IP_FRAG_FIELD_LOC 10 /* Fragment field location */

#define ICMP_TYPE_LEN 1 /* ICMP Type length */
#define ICMP_ECHO_FIELD_LEN 2 /* Echo field length in half-words */
#define ICMP_REQ_SRC_IP_LOC 13 /* Src IP address location of ICMP request */
#define ICMP_ECHO_FIELD_LOC 17 /* Echo field location */
#define ICMP_DATA_START_LOC 17 /* Data field start location */
#define ICMP_DATA_LEN 18 /* ICMP data length */
#define ICMP_DATA_LOC 19 /* ICMP data location including
identifier number and sequence number */
#define ICMP_DATA_CSUM_LOC_BACK 19 /* Data checksum location from end of
frame */
#define ICMP_DATA_FIELD_LEN 20 /* Data field length */

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Function Prototypes ******************************/

static int EmacLitePingReplyExample(u16 DeviceId);

static void ProcessRecvFrame(XEmacLite *InstancePtr);

static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length);

/************************** Variable Definitions *****************************/

/*
* Set up a local MAC address.
*/
static u8 LocalMacAddr[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x0A, 0x35, 0x02, 0x22, 0x5E
};

/*
* The IP address was set to 172.16.63.121. User need to set a free IP address
* based on the network on which this example is to be run.
*/
static u8 LocalIpAddr[IP_ADDR_SIZE] =
{
172, 16, 63, 121
};

static XEmacLite EmacLiteInstance; /* Instance of the EmacLite driver */

/*
* Buffers used for Transmission and Reception of Packets. These are declared as
* global so that they are not a part of the stack.
*/
static u8 RxFrame[XEL_MAX_FRAME_SIZE];
static u8 TxFrame[XEL_MAX_FRAME_SIZE];

/*
* Variable used to indicate the length of the received frame.
*/
u32 RecvFrameLength = 0;

/*
* Variable used to indicate the number of Ping replies sent.
*/
u32 NumOfPingReplies;


/****************************************************************************/
/**
*
* This function is the main function of the Ping reply example in
* polled mode.
*
* @param None.
*
* @return XST_FAILURE to indicate failure, otherwise XST_SUCCESS
* is returned.
*
* @note None.
*
*****************************************************************************/
int main()
{
int Status;

/*
* Run the EmacLite Ping reply example.
*/
Status = EmacLitePingReplyExample(EMAC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* The entry point for the EmacLite Ping reply example in polled mode.
*
* @param DeviceId is device ID of the XEmacLite Device.
*
* @return XST_FAILURE to indicate failure, otherwise XST_SUCCESS is
* returned.
*
* @note This is in a continuous loop generating a specified number of
* ping replies as defined by MAX_PING_REPLIES.
*
******************************************************************************/
int EmacLitePingReplyExample(u16 DeviceId)
{
int Status;
XEmacLite *EmacLiteInstPtr = &EmacLiteInstance;
XEmacLite_Config *ConfigPtr;
NumOfPingReplies = 0;

/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}

Status = XEmacLite_CfgInitialize(EmacLiteInstPtr,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

/*
* Set the MAC address.
*/
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalMacAddr);

/*
* Empty any existing receive frames.
*/
XEmacLite_FlushReceive(EmacLiteInstPtr);

while (1) {

/*
* Wait for a Receive packet.
*/
while (RecvFrameLength == 0) {
RecvFrameLength = XEmacLite_Recv(EmacLiteInstPtr,
(u8 *)RxFrame);
}

/*
* Process the Receive frame.
*/
ProcessRecvFrame(EmacLiteInstPtr);
RecvFrameLength = 0;

/*
* If the number of ping replies sent is equal to that
* specified by the user then exit out of this loop.
*/
if (NumOfPingReplies == MAX_PING_REPLIES) {

return XST_SUCCESS;
}

}
}

/******************************************************************************/
/**
*
* This function processes the received packet and generates the corresponding
* reply packets.
*
* @param InstancePtr is a pointer to the instance of the EmacLite.
*
* @return None.
*
* @note This function assumes MAC does not strip padding or CRC.
*
******************************************************************************/
static void ProcessRecvFrame(XEmacLite *InstancePtr)
{
u16 *RxFramePtr;
u16 *TxFramePtr;
u16 *TempPtr;
u16 CheckSum;
u32 NextTxBuffBaseAddr;
int Index;
int PacketType = 0;

TxFramePtr = (u16 *)TxFrame;
RxFramePtr = (u16 *)RxFrame;

/*
* Determine the next expected Tx buffer address.
*/
NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr);

/*
* Check the packet type.
*/
Index = MAC_ADDR_LEN;
TempPtr = (u16 *)LocalMacAddr;
while (Index--) {
if (Xil_Ntohs((*(RxFramePtr + Index)) == BROADCAST_ADDR) &&
(PacketType != MAC_MATCHED_PACKET)) {
PacketType = BROADCAST_PACKET;
} else if (Xil_Ntohs((*(RxFramePtr + Index)) == *(TempPtr + Index)) &&
(PacketType != BROADCAST_PACKET)) {
PacketType = MAC_MATCHED_PACKET;
} else {
PacketType = 0;
break;
}
}

/*
* Process broadcast packet.
*/
if (PacketType == BROADCAST_PACKET) {

/*
* Check for an ARP Packet if so generate a reply.
*/
if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) ==
XEL_ETHER_PROTO_TYPE_ARP) {

/*
* IP address of the local machine.
*/
TempPtr = (u16 *)LocalIpAddr;

/*
* Check destination IP address of the packet with
* local IP address.
*/
if (
((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_1)) == *TempPtr++) &&
((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_2)) == *TempPtr++)) {

/*
* Check ARP packet type(request/reply).
*/
if (Xil_Ntohs(*(RxFramePtr + ARP_REQ_STATUS_LOC)) ==
ARP_REQUEST) {

/*
* Add destination MAC address
* to the reply packet (i.e) source
* address of the received packet.
*/
Index = SRC_MAC_ADDR_LOC;
while (Index < (SRC_MAC_ADDR_LOC +
MAC_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Add source (local) MAC address
* to the reply packet.
*/
Index = 0;
TempPtr = (u16 *)LocalMacAddr;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}

/*
* Add Ethernet proto type H/W
* type(10/3MBps),H/W address length and
* protocol address len (i.e)same as in
* the received packet
*/
Index = ETHER_PROTO_TYPE_LOC;
while (Index < (ETHER_PROTO_TYPE_LOC +
ETHER_PROTO_TYPE_LEN +
ARP_HW_TYPE_LEN +
ARP_HW_ADD_LEN
+ ARP_PROTO_ADD_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Add ARP reply status to the reply
* packet.
*/
*TxFramePtr++ = Xil_Htons(ARP_REPLY);

/*
* Add local MAC Address
* to the reply packet.
*/
TempPtr = (u16 *)LocalMacAddr;
Index = 0;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}

/*
* Add local IP Address
* to the reply packet.
*/
TempPtr = (u16 *)LocalIpAddr;
Index = 0;
while (Index < IP_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++ ;
Index++;
}

/*
* Add Destination MAC Address
* to the reply packet from the received
* packet.
*/
Index = SRC_MAC_ADDR_LOC;
while (Index < (SRC_MAC_ADDR_LOC +
MAC_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Add Destination IP Address
* to the reply packet.
*/
Index = ARP_REQ_SRC_IP_LOC;
while (Index < (ARP_REQ_SRC_IP_LOC +
IP_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Fill zeros as per protocol.
*/
Index = 0;
while (Index < ARP_ZEROS_LEN) {
*TxFramePtr++ = 0x0000;
Index++;
}

/*
* Transmit the Reply Packet.
*/
XEmacLite_Send(InstancePtr,
(u8 *)&TxFrame,
ARP_PACKET_SIZE);
}
}
}
}

/*
* Process packets whose MAC address is matched.
*/
if (PacketType == MAC_MATCHED_PACKET) {

/*
* Check ICMP packet.
*/
if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) ==
XEL_ETHER_PROTO_TYPE_IP) {

/*
* Check the IP header checksum.
*/
CheckSum = CheckSumCalculation(RxFramePtr,
IP_HDR_START_LOC,
IP_HDR_LEN);

/*
* Check the Data field checksum.
*/
if (CheckSum == CORRECT_CKSUM_VALUE) {
CheckSum = CheckSumCalculation(RxFramePtr,
ICMP_DATA_START_LOC,
ICMP_DATA_FIELD_LEN);
if (CheckSum == CORRECT_CKSUM_VALUE) {

/*
* Add destination address
* to the reply packet (i.e)source
* address of the received packet.
*/
Index = SRC_MAC_ADDR_LOC;
while (Index < (SRC_MAC_ADDR_LOC +
MAC_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Add local MAC address
* to the reply packet.
*/
Index = 0;
TempPtr = (u16 *)LocalMacAddr;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}

/*
* Add protocol type
* header length and, packet
* length(60 Bytes) to the reply packet.
*/
Index = ETHER_PROTO_TYPE_LOC;
while (Index < (ETHER_PROTO_TYPE_LOC +
ETHER_PROTO_TYPE_LEN +
IP_VERSION_LEN +
IP_PACKET_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Identification field a random number
* which is set to IDENT_FIELD_VALUE.
*/
*TxFramePtr++ = IDENT_FIELD_VALUE;

/*
* Add fragment type, time to live and
* ICM field. It is same as in the
* received packet.
*/
Index = IP_FRAG_FIELD_LOC;
while (Index < (IP_FRAG_FIELD_LOC +
IP_TTL_ICM_LEN +
IP_FRAG_FIELD_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Checksum first set to 0 and
* added in this field later.
*/
*TxFramePtr++ = 0x0000;

/*
* Add Source IP address
*/
Index = 0;
TempPtr = (u16 *)LocalIpAddr;
while (Index < IP_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}

/*
* Add Destination IP address.
*/
Index = ICMP_REQ_SRC_IP_LOC;
while (Index < (ICMP_REQ_SRC_IP_LOC +
IP_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}

/*
* Calculate checksum, and
* add it in the appropriate field.
*/
CheckSum = CheckSumCalculation(
(u16 *)TxFrame,
IP_HDR_START_LOC,
IP_HDR_LEN);
CheckSum = ~CheckSum;
*(TxFramePtr - IP_CSUM_LOC_BACK) =
Xil_Htons(CheckSum);

/*
* Echo reply status & checksum.
*/
Index = ICMP_ECHO_FIELD_LOC;
while (Index < (ICMP_ECHO_FIELD_LOC +
ICMP_ECHO_FIELD_LEN)) {
*TxFramePtr++ = 0x0000;
Index++;
}

/*
* Add data to buffer which was
* received from the packet.
*/
Index = ICMP_DATA_LOC;
while (Index < (ICMP_DATA_LOC +
ICMP_DATA_LEN)) {
*TxFramePtr++ =
(*(RxFramePtr + Index));
Index++;
}

/*
* Generate checksum for the data and
* add it in the appropriate field.
*/
CheckSum = CheckSumCalculation(
(u16 *)TxFrame,
ICMP_DATA_START_LOC,
ICMP_DATA_FIELD_LEN);
CheckSum = ~CheckSum;
*(TxFramePtr - ICMP_DATA_CSUM_LOC_BACK)
= Xil_Htons(CheckSum);

/*
* Transmit the frame.
*/
XEmacLite_Send(InstancePtr,
(u8 *)&TxFrame,
ICMP_PACKET_SIZE);

/*
* Increment the number of
* Ping replies sent.
*/
NumOfPingReplies++;

}
}
}
}
}

/*****************************************************************************/
/**
*
* This function calculates the checksum and returns a 16 bit result.
*
* @param RxFramePtr is a 16 bit pointer for the data to which checksum
* is to be calculated.
* @param StartLoc is the starting location of the data from which the
* checksum has to be calculated.
* @param Length is the number of halfwords(16 bits) to which checksum is
* to be calculated.
*
* @return It returns a 16 bit checksum value.
*
* @note This can also be used for calculating checksum. The ones
* complement of this return value will give the final checksum.
*
******************************************************************************/
static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length)
{
u32 Sum = 0;
u16 CheckSum = 0;
int Index;

/*
* Add all the 16 bit data.
*/
Index = StartLoc;
while (Index < (StartLoc + Length)) {
Sum = Sum + Xil_Ntohs(*(RxFramePtr + Index));
Index++;
}

/*
* Add upper 16 bits to lower 16 bits.
*/
CheckSum = Sum;
Sum = Sum >> 16;
CheckSum = Sum + CheckSum;
return CheckSum;
}



Вот этот код изначально ругается,что ему чего-то не хватает.
Так и должно быть????? Надо ручками копаться и копировать в рабочий каталог того что не хватает?
Dmitriyspb
Цитата(Dmitriyspb @ Nov 18 2015, 16:58) *
Вот этот код изначально ругается,что ему чего-то не хватает.
Так и должно быть????? Надо ручками копаться и копировать в рабочий каталог того что не хватает?


Очень занятно получается..... rolleyes.gif Повторно импортировал референсный проект с драйверами и все ошибки куда-то исчезли.... Подглючивает система=)))
0xFFFF
разбираюсь с тем же вопросом.
подскажите, пожалуйста:
1. почему вы использовали AXI Ethernet Lite а не AXI Ethernet Subsistem ?
2. что получилось по скорости ? просто для меня критично 1Gb.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.