Перейти к содержанию
    

Добрый день всем.

 

Необходима реализация обмена ПК-ПЛИС по Ethernet.

Имеется дев.борд Стратикс 4.

 

Нашел в форуме такую фразу от vadimuzzz:

 

Последовательность запуска марвеловского PHY такая:

 

1. Запись по адресу 0 значения 0x8000 (SwRst==1)

2. Задержка

3. Запись по адресу 0 значения 0х1000 (AutoNeg==1)

4. Задержка

5. Чтение значения из адреса 1, проверка бита 2 (Link==1), если не установлен - 1)

6. Запись по адресу 27 нижних бит [3:0] == 4'b1111 (GMII,copper)//смотреть доки на плату, это для девборды циклон-3!

7. При RGMII IF - запись по адресу 20 прочитанного значения с установленными битами 7,1//смотреть доки на плату, это для девборды циклон-3!

8. Повторять пункты 1-5, до установления линка. (SwRst)

В Квартусе создал систему:

post-59925-1359082805_thumb.png

Настройки TSE:

post-59925-1359082815_thumb.png post-59925-1359082824_thumb.png post-59925-1359082830_thumb.png post-59925-1359082835_thumb.png

 

В Ниосе пытаюсь инициализировать железо, а именно для начала добиться линка:

 

    alt_u32 t2=0;

    IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, 0);  // PHY and other board peripheral initialization
    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, PHY);
    do
    {
        // Control Register .15 = 1 - Reset
        IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 0, 0x8000);
        Delay(0xFFFF);
        // (.13=0, .6=1) - 1000 Mbps, .12=1 - Enable Auto-Negatiation,
        IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 0, 0x1040);
        Delay(0xFFFF);
        // read Control Register
        t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 1);
        Delay(0xFFFF);
        // Control Register .15 = 1 - Reset
        IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 0, t2 | 0x8000);
        Delay(0xFFFF);
        // read Staus Register
        t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 1);
        alt_printf("Reg 1 : %x\n",t2);
        //check Link
        if( (t2&0x0004)==0 )
        {
            // Control Register .15 = 1 - Reset
            IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 0, t2 | 0x8000);
            Delay(0xFFFF);
        }
        // .15=1 - Copper, (.3:.0)='0100' - SGMII without Clock with SGMII Auto-Neg to copper
        IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 27, 0x8004);
        Delay(0xFFFF);
        // read Staus Register
        t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, 1);
        alt_printf("Reg 1 : %x\n",t2);
    }
    while( (t2&0x0004)==0 );

в итоге на экране сполшные 9 выводятся.

 

Подскажите что-нибудь по этому поводу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вы как-то своеобразно поняли мою фразу ;)

у меня следующие соображения:

  1. вы совершенно напрасно столько ресетов напихали
  2. указывать скорость в явном виде имеет смысл только если не используется auto-neg
  3. четвертых стратиксов два (E и GX), китов тоже два. какие там PHY стоят, альтеровцам писать лень, схему отдельно выложить - тоже. поэтому то, что написано ниже я узнал, посмотрев в хрустальный шар, пока качаются доки. (т.е. я предположил, что вы правильно указали режим связи с phy - sgmii и что киты сделаны на марвеле).

пример процедуры сброса/инициализфции 88e1111 с rgmii:

    /* PHY and other board peripherial initialization */
    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_MAC_BASE,PHY);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x1B);//Extended PHY Specific Status Register
    t2 &= 0xFFF0;
    IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x1B,t2|0xB);//RGMII to Copper
    t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x14);//Extended PHY Specific Control Register
    IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x14,t2|0x82);//Add Delay to RX_CLK for RXD Outputs; Add Delay to GTX_CLK for TXD Inputs
    t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL);
    IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL,t2|PCS_CTL_sw_reset);//Previous Operations Require SW Reset
    do
    {
        t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_STATUS);
    }
    while((t2&0x04)==0);//wait for link-up

как видите сброс происходит только один раз, после установки недефолтных настроек.

для sgmii, видимо, д.б. так:

    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_MAC_BASE,PHY);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x1B);//Extended PHY Specific Status Register
    t2 &= 0xFFF0;
    IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x1B,t2|0x4);//SGMII to Copper without clock
    t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x14);//Extended PHY Specific Control Register
    IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x14,t2&(~0x82));//Disable RGMII timing control
    t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL);
    IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL,t2|PCS_CTL_sw_reset);//Previous Operations Require SW Reset
    do
    {
        t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_STATUS);
    }
    while((t2&0x04)==0);//wait for link-up

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ПЛИС на плате стоит Stratix IV GX (EP4SGX230KF40C2)

Из rm_sivgx_fpga_dev_board.pdf:

post-59925-1359096140_thumb.png

Это схема подключения:

post-59925-1359096145_thumb.png

 

Очередная попытка инита:

 

    alt_u32 t2=0;


    t2 = IORD_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE);
    alt_printf("TSE Command Reg : %x\n",t2);
    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, 0);  // PHY and other board peripheral initialization
    IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, PHY);

    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,0,0x1B);//Extended PHY Specific Status Register
    alt_printf("Reg 27 : %x\n",t2);

    t2 &= 0xFFF0;
    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,0,0x1B,t2|0x4);//SGMII to Copper without clock

    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,0,0x14);//Extended PHY Specific Control Register
    alt_printf("Reg 20 : %x\n",t2);

    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,0,0x14,t2&(~0x82));//Disable RGMII timing control

    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL);
    alt_printf("Reg 0 : %x\n",t2);

    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL,t2|PCS_CTL_sw_
reset);//Previous Operations Require SW Reset
    do
    {
        t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,0,ALTERA_TSEMAC_PHY_ADDR_STATUS);
        alt_printf("Reg 1 : %x\n",t2);
        t2 = IORD_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE);
        alt_printf("TSE Command Reg : %x\n",t2);
    }
    while((t2&0x04)==0);//wait for link-up

На консоль выводится следующее:

TSE Command Reg : 0
Reg 27 : 0
Reg 20 : 0
Reg 0 : 1140
Reg 1 : 9
TSE Command Reg : 0
Reg 1 : 9
TSE Command Reg : 0
Reg 1 : 9
TSE Command Reg : 0
Reg 1 : 9
TSE Command Reg : 0
Reg 1 : 9
TSE Command Reg : 0
Reg 1 : 9
TSE Command Reg : 0
...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а адрес PHY правильный? ЕМНИП, он задается во время сброса strap-пинами.

я об этом:

IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, PHY);

проверьте ID-регистры PHY (адреса 2 и 3).

да, и почему у вас именно

IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, PHY);

а не

IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, PHY);

?

 

на всякий случай, пример автоматического определения адреса (надо только ID на марвеловский заменить, у меня микрел):

for (t=0;t<33;t++) {
    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(ETH_0_TRIPLE_SPEED_ETHERNET_0_BASE, t);
    alt_printf("Probing PHY at address %x ...\n", t);
    r = IORD_ALTERA_TSEMAC_MDIO(ETH_0_TRIPLE_SPEED_ETHERNET_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID1);
    if (r == 0x22)/*KSZ9021*/{
        alt_printf("PHY address:%x\n", t);
        alt_printf("PHY_ID1:%x\n", r);
        alt_printf("PHY_ID2:%x\n", IORD_ALTERA_TSEMAC_MDIO(ETH_0_TRIPLE_SPEED_ETHERNET_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID2));
        break;
    }
}
/*
если t<32 - это адрес
если t==32 - PHY не найден
*/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из даташита на марвел:

CONFIG[0] configures PHY_ADDR[2:0] bits of the physical address.

CONFIG[1] configures PHY_ADDR[4:3] and ENA_PAUSE options.

тогда из схемы подключения получается, что у меня PHY = 0;

 

Такая проверка:

    alt_u32 t,r;
    for (t=0;t<33;t++)
    {
        IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, 0);
        IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, t);
        alt_printf("PHY_ID1:%x\n", IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID1));
        alt_printf("PHY_ID2:%x\n", IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID2));
    }

выдает все ноли, т.е. ID не найден.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

выдает все ноли, т.е. ID не найден.

как делали MDIO? там нужен bidir-буфер - не напутали с его сигналами (особенно управление)?

пример:

ALT_IOBUF u5
(
    .i(mac_mdo),//from MAC
    .oe(!mac_oe),//from MAC, inverse polarity!
    .o(mac_mdi),//to MAC
    .io(phy_mdio)//pin
);
defparam u5.io_standard = "2.5V";
defparam u5.current_strength = "minimum current";
defparam u5.enable_bus_hold = "on";
defparam u5.weak_pull_up_resistor = "off";//у меня на плате стоит внешний

 

или ноги неправильно назначены

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В настройках TSE выставил PHY_ID=0х0000001F

post-59925-1359346541_thumb.png

В Квартусе подцепил систему:

 

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

LIBRARY altera; 
USE altera.altera_primitives_components.all; 

entity tse_first is
    port
    (
        clk_in_50                : in std_logic;
        external_reset_n        : in std_logic;
        external_led            : out std_ulogic_vector(15 downto 0) := (others => '1');
        external_mdc            : out std_logic;
        external_mdio            : inout std_logic;
        external_rxp            : in std_logic;
        external_txp            : out std_logic;
        external_reset_n_out    : out std_logic
    );
end tse_first;

architecture tse_first of tse_first is

component qSys is
    port
    (
        clk_clk                                                   : in  std_logic := 'X'; -- clk
        reset_reset_n                                             : in  std_logic := 'X'; -- reset_n
        triple_speed_ethernet_0_conduit_connection_mdio_out       : out std_logic;        -- mdio_out
        triple_speed_ethernet_0_conduit_connection_mdio_oen       : out std_logic;        -- mdio_oen
        triple_speed_ethernet_0_conduit_connection_mdio_in        : in  std_logic := 'X'; -- mdio_in
        triple_speed_ethernet_0_conduit_connection_mdc            : out std_logic;        -- mdc
        triple_speed_ethernet_0_conduit_connection_led_an         : out std_logic;        -- led_an
        triple_speed_ethernet_0_conduit_connection_led_char_err   : out std_logic;        -- led_char_err
        triple_speed_ethernet_0_conduit_connection_led_link       : out std_logic;        -- led_link
        triple_speed_ethernet_0_conduit_connection_led_disp_err   : out std_logic;        -- led_disp_err
        triple_speed_ethernet_0_conduit_connection_led_crs             : out std_logic;
        triple_speed_ethernet_0_conduit_connection_led_col             : out std_logic;
        triple_speed_ethernet_0_conduit_connection_txp            : out std_logic;        -- txp
        triple_speed_ethernet_0_conduit_connection_rxp            : in  std_logic := 'X'; -- rxp
        triple_speed_ethernet_0_conduit_connection_ref_clk        : in  std_logic := 'X'; -- ref_clk
        triple_speed_ethernet_0_conduit_connection_rx_recovclkout : out std_logic         -- rx_recovclkout
    );
end component qSys;

component iobuf IS
    PORT
    (
        datain        : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
        oe                : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
        dataio        : INOUT STD_LOGIC_VECTOR (0 DOWNTO 0);
        dataout        : OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
    );
END component iobuf;

    signal internal_mdio_out        : std_logic := '0';
    signal internal_mdio_oen        : std_logic := '0';
    signal internal_mdio_in            : std_logic := '0';
    signal internal_LED_AN            : std_logic := '0';
    signal internal_LED_CHAR_ERR    : std_logic := '0';
    signal internal_LED_LINK        : std_logic := '0';
    signal internal_LED_DISP_ERR    : std_logic := '0';
    signal internal_LED_CRS            : std_logic := '0';
    signal internal_LED_COL            : std_logic := '0';
    signal internal_rx_recovclkout    : std_logic := '0';
    ---
    signal counter_pause            : integer := 0;

begin

    external_led(0)        <= not internal_LED_LINK;
    external_led(1)        <= not internal_LED_AN;
    external_led(2)        <= not internal_LED_CHAR_ERR;
    external_led(3)        <= not internal_LED_DISP_ERR;
    ---
    
--- Reset
process (clk_in_50)
begin
    if clk_in_50'event and clk_in_50 = '1' then

        if( counter_pause >= 10000 ) then
            external_reset_n_out    <= '1';
            external_led(4)            <= '0';
        else
            external_reset_n_out    <= '0';
            counter_pause            <= counter_pause + 1;
            external_led(4)            <= '1';
        end if;
        
    end if;
end process;
    
iobuf_pm : iobuf
    PORT map
    (
        datain(0)        => internal_mdio_in,            --: IN STD_LOGIC_VECTOR (0 DOWNTO 0);
        oe(0)                => not internal_mdio_oen,    --: IN STD_LOGIC_VECTOR (0 DOWNTO 0);
        dataio(0)        => external_mdio,            --: INOUT STD_LOGIC_VECTOR (0 DOWNTO 0);
        dataout(0)        => internal_mdio_out            --: OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
    );

qSys_pm : qSys
    port map
    (
        clk_clk                                                   => clk_in_50,                --: in  std_logic := 'X'; -- clk
        reset_reset_n                                             => external_reset_n,            --: in  std_logic := 'X'; -- reset_n
        triple_speed_ethernet_0_conduit_connection_mdio_out       => internal_mdio_out,            --: out std_logic;        -- mdio_out
        triple_speed_ethernet_0_conduit_connection_mdio_oen       => internal_mdio_oen,            --: out std_logic;        -- mdio_oen
        triple_speed_ethernet_0_conduit_connection_mdio_in        => internal_mdio_in,            --: in  std_logic := 'X'; -- mdio_in
        triple_speed_ethernet_0_conduit_connection_mdc            => external_mdc,            --: out std_logic;        -- mdc
        triple_speed_ethernet_0_conduit_connection_led_an         => internal_LED_AN,            --: out std_logic;        -- led_an
        triple_speed_ethernet_0_conduit_connection_led_char_err   => internal_LED_CHAR_ERR,        --: out std_logic;        -- led_char_err
        triple_speed_ethernet_0_conduit_connection_led_link       => internal_LED_LINK,            --: out std_logic;        -- led_link
        triple_speed_ethernet_0_conduit_connection_led_disp_err   => internal_LED_DISP_ERR,        --: out std_logic;        -- led_disp_err
        triple_speed_ethernet_0_conduit_connection_led_crs      => internal_LED_CRS,
        triple_speed_ethernet_0_conduit_connection_led_col      => internal_LED_COL,
        triple_speed_ethernet_0_conduit_connection_txp            => external_txp,            --: out std_logic;        -- txp
        triple_speed_ethernet_0_conduit_connection_rxp            => external_rxp,            --: in  std_logic := 'X'; -- rxp
        triple_speed_ethernet_0_conduit_connection_ref_clk        => clk_in_50,                --: in  std_logic := 'X'; -- ref_clk
        triple_speed_ethernet_0_conduit_connection_rx_recovclkout => internal_rx_recovclkout        --: out std_logic         -- rx_recovclkout
    );


end tse_first;

В Ниосе прописываю:

    alt_u32 t,r;
    for (t=0;t<33;t++)
    {
        IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, 0);
        Delay(0xFFFF);
        IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, t);
        Delay(0xFFFF);
        alt_printf("Probing PHY at address %x ...\n", t);
        alt_printf("PHY_ID1:%x\n", IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID1));
        Delay(0xFFFF);
        alt_printf("PHY_ID2:%x\n", IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID2));
        Delay(0xFFFF);
    }

В консоли получаю:

Probing PHY at address 0 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 1 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 2 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 3 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 4 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 5 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 6 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 7 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 8 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 9 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address a ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address b ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address c ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address d ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address e ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address f ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 10 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 11 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 12 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 13 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 14 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 15 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 16 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 17 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 18 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 19 ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 1a ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 1b ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 1c ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 1d ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 1e ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 1f ...
PHY_ID1:1f
PHY_ID2:0
Probing PHY at address 20 ...
PHY_ID1:1f
PHY_ID2:0

В ДШ на Марвел:

post-59925-1359346550_thumb.pngpost-59925-1359346555_thumb.png

 

Вопрос:

1. Что за адрес я прописываю в настройках TSE?()

2. Какого "художника" не получается считать идентификаторы, описанные в ДШ на Марвел???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у вас неправильно подключен iobuf:

triple_speed_ethernet_0_conduit_connection_mdio_out д.б. соединен с портом datain в iobuf, а

 

triple_speed_ethernet_0_conduit_connection_mdio_in - с портом dataout

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно!

Спасибо за замечание.

 

НО!!! При переподключении вывод в консоль остался таким же. :crying: :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

видимо, на mdio0 висит PCS, а PHY - на mdio1.

попробуйте так:

    alt_u32 t,r;
    for (t=0;t<33;t++)
    {
        IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, 1f);//PCS ?
        IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, t);// Marvel?
        Delay(0xFFFF);
        alt_printf("Probing PHY at address %x ...\n", t);
        alt_printf("PHY_ID1:%x\n", IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 1, ALTERA_TSEMAC_PHY_ADDR_PHY_ID1));
        Delay(0xFFFF);
        alt_printf("PHY_ID2:%x\n", IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 1, ALTERA_TSEMAC_PHY_ADDR_PHY_ID2));
        Delay(0xFFFF);
    }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, нашел свой адрес: 0.

 

Теперь при следующем коде:

 

    alt_u32 t2=0;

    t2 = IORD_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE);
    alt_printf("TSE Command Reg : %x\n",t2);
    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, 0x1f);  // PHY and other board peripheral initialization
    IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, 0);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1B);//Extended PHY Specific Status Register
    alt_printf("Reg 27 : %x\n",t2);
    t2 &= 0xFFF0;
    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1B,t2|0x4);//SGMII to Copper without clock
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1B);//Extended PHY Specific Status Register
    alt_printf("Reg 27 : %x\n",t2);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14);//Extended PHY Specific Control Register
    alt_printf("Reg 20 : %x\n",t2);
    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14,t2&(~0x82));//Disable RGMII timing control
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14);//Extended PHY Specific Control Register
    alt_printf("Reg 20 : %x\n",t2);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,ALTERA_TSEMAC_PHY_ADDR_CONTROL);
    alt_printf("Reg 0 : %x\n",t2);
    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,ALTERA_TSEMAC_PHY_ADDR_CONTROL,t2|PCS_CTL_sw_
reset);//Previous Operations Require SW Reset
   do
    {
        t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,ALTERA_TSEMAC_PHY_ADDR_CONTROL);
        alt_printf("Reg 0 : %x\n",t2);
        t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,ALTERA_TSEMAC_PHY_ADDR_STATUS);
        alt_printf("Reg 1 : %x\n",t2);
    }
    while((t2&0x04)==0);//wait for link-up

получаю в консоль:

TSE Command Reg : 0
Reg 27 : 8484
Reg 27 : 8484
Reg 20 : c68
Reg 20 : c68
Reg 0 : 1140
Reg 0 : 1140
Reg 1 : 7949
Reg 0 : 1140
Reg 1 : 7949
Reg 0 : 1140
Reg 1 : 7949
...
Reg 0 : 1140
Reg 1 : 7949
...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, линк появился, нужно было подождать несколько секунд.

 

Теперь не могу перехватить прерывание при приеме.

Функция инита:

int MAC_init()
{
    alt_u32 /*t,*1=0,*/t2=0;
    int status=0;
    p_counter=0;

    MYMAC_ADDR[0]= 0x00; MYMAC_ADDR[1]= 0x07; MYMAC_ADDR[2]= 0xAB; MYMAC_ADDR[3]= 0xF0; MYMAC_ADDR[4]= 0x0D; MYMAC_ADDR[5]= 0xBA;
    IP4_ADDR[0]= 0xC9; IP4_ADDR[1]= 0x01; IP4_ADDR[2]= 0x01; IP4_ADDR[3]= 0x01; // IP-Address = "201.1.1.1"

    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TRIPLE_SPEED_ETHERNET_0_BASE, 0x1f);  // PHY and other board peripheral initialization
    IOWR_ALTERA_TSEMAC_MDIO_ADDR1(TRIPLE_SPEED_ETHERNET_0_BASE, 0);

    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1B);//Extended PHY Specific Status Register
    alt_printf("Reg 27 : %x\n",t2);

    t2 &= 0xFFF0;
    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1B,t2|0x4);//SGMII to Copper without clock
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1B);//Extended PHY Specific Status Register
    alt_printf("Reg 27 : %x\n",t2);

    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14);//Extended PHY Specific Control Register
    alt_printf("Reg 20 : %x\n",t2);

    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14,t2&(~0x82));//Disable RGMII timing control
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14);//Extended PHY Specific Control Register
    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE, 1, 0x14, t2|0x01); // Transmitter Enable
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14);//Extended PHY Specific Control Register
    alt_printf("Reg 20 : %x\n",t2);

    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,ALTERA_TSEMAC_PHY_ADDR_CONTROL);
    alt_printf("Reg 0 : %x\n",t2);

    IOWR_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,ALTERA_TSEMAC_PHY_ADDR_CONTROL,t2|PCS_CTL_sw_
reset);//Previous Operations Require SW Reset
   do
    {
        t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,ALTERA_TSEMAC_PHY_ADDR_STATUS);
//        alt_printf("Reg 1 : %x\n",t2);
    }
    while((t2&0x04)==0);//wait for link-up

    alt_printf("end of wait for link-up\n");

    /* Get the Rx and Tx SGDMA addresses */
    sgdma_tx_dev = alt_avalon_sgdma_open(TX_SGDMA_NAME);
    if(!sgdma_tx_dev) {
        alt_printf("[triple_speed_ethernet_init] Error opening RX SGDMA\n");
          return ENP_RESOURCE;
    }
    sgdma_rx_dev = alt_avalon_sgdma_open(RX_SGDMA_NAME);
    if(!sgdma_tx_dev) {
        alt_printf("[triple_speed_ethernet_init] Error opening TX SGDMA\n");
          return ENP_RESOURCE;
    }
    printf("[triple_speed_ethernet_init] RX SGDMA: [%s] & TX SGDMA: [%s] is opening\n",sgdma_rx_dev->name,sgdma_tx_dev->name);
    IOWR_ALTERA_AVALON_SGDMA_CONTROL(RX_SGDMA_BASE,ALTERA_AVALON_SGDMA_CONTROL_SOFTWARERESET_MSK);
    IOWR_ALTERA_AVALON_SGDMA_CONTROL(RX_SGDMA_BASE, 0x0);
    
    /* reset the mac */ 
    
    IOWR_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE , ALTERA_TSEMAC_CMD_SW_RESET_MSK | ALTERA_TSEMAC_CMD_TX_ENA_MSK | ALTERA_TSEMAC_CMD_RX_ENA_MSK | ALTERA_TSEMAC_CMD_PROMIS_EN_MSK);
    while(IORD_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE) & ALTERA_TSEMAC_CMD_SW_RESET_MSK)
    {
    }
    alt_printf("end of reset the mac\n");
    
    /* Initialize MAC registers */
    
    IOWR_ALTERA_TSEMAC_FRM_LENGTH(TRIPLE_SPEED_ETHERNET_0_BASE, ALTERA_TSE_MAC_MAX_FRAME_LENGTH);
    IOWR_ALTERA_TSEMAC_RX_ALMOST_EMPTY(TRIPLE_SPEED_ETHERNET_0_BASE, 8);
    IOWR_ALTERA_TSEMAC_RX_ALMOST_FULL(TRIPLE_SPEED_ETHERNET_0_BASE, 8);
    IOWR_ALTERA_TSEMAC_TX_ALMOST_EMPTY(TRIPLE_SPEED_ETHERNET_0_BASE, 8);
    IOWR_ALTERA_TSEMAC_TX_ALMOST_FULL(TRIPLE_SPEED_ETHERNET_0_BASE,  3);
    IOWR_ALTERA_TSEMAC_TX_SECTION_EMPTY(TRIPLE_SPEED_ETHERNET_0_BASE, TRIPLE_SPEED_ETHERNET_0_TRANSMIT_FIFO_DEPTH - 16); //1024/4;
    IOWR_ALTERA_TSEMAC_TX_SECTION_FULL(TRIPLE_SPEED_ETHERNET_0_BASE,  16); //32/4; // start transmit when there are 48 bytes
    IOWR_ALTERA_TSEMAC_RX_SECTION_EMPTY(TRIPLE_SPEED_ETHERNET_0_BASE, TRIPLE_SPEED_ETHERNET_0_RECEIVE_FIFO_DEPTH - 16); //4000/4);
    IOWR_ALTERA_TSEMAC_RX_SECTION_FULL(TRIPLE_SPEED_ETHERNET_0_BASE,  16);
    IOWR_ALTERA_TSEMAC_TX_CMD_STAT(TRIPLE_SPEED_ETHERNET_0_BASE,0);
    IOWR_ALTERA_TSEMAC_RX_CMD_STAT(TRIPLE_SPEED_ETHERNET_0_BASE,0);
    IOWR_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE, ALTERA_TSEMAC_CMD_TX_ENA_MSK | ALTERA_TSEMAC_CMD_RX_ENA_MSK | ALTERA_TSEMAC_CMD_TX_ADDR_INS_MSK | ALTERA_TSEMAC_CMD_PROMIS_EN_MSK);
    IOWR_ALTERA_TSEMAC_MAC_0(TRIPLE_SPEED_ETHERNET_0_BASE,((int)(0x00) | (int)(0x07 <<  8) | (int)(0xAB << 16) | (int)(0xF0 << 24)));
    IOWR_ALTERA_TSEMAC_MAC_1(TRIPLE_SPEED_ETHERNET_0_BASE,(((int)(0x0D) | (int)(0xBA <<  8)) & 0xFFFF));
    alt_avalon_sgdma_register_callback(sgdma_rx_dev,(alt_avalon_sgdma_callback)&tse_sgdmaRx_isr,(alt_u16)ALTERA_TSE_SGDMA_INTR_MASK,sgdma_rx_dev);

    alt_u32 *uncached_packet_payload;
    uncached_packet_payload = (void *)alt_remap_cached ((volatile void*) pkt, 4);
    alt_avalon_sgdma_construct_stream_to_mem_desc(
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST],  // descriptor I want to work with
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST],  // pointer to "next"
            uncached_packet_payload,            // starting write_address
            0,                                  // read until EOP
            0);
    while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(RX_SGDMA_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) );
    t2=alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]);

    t2 = IORD_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE);
    alt_printf("TSE Command Reg : 0x%x\n",t2);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x0);
    alt_printf("Reg 0 : 0x%x\n",t2);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1);
    alt_printf("Reg 1 : 0x%x\n",t2);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x14);//Extended PHY Specific Control Register
    alt_printf("Reg 20 : 0x%x\n",t2);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x1B);//Extended PHY Specific Status Register
    alt_printf("Reg 27 : 0x%x\n",t2);
    t2 = IORD_ALTERA_TSEMAC_MDIO(TRIPLE_SPEED_ETHERNET_0_BASE,1,0x12);
    alt_printf("Reg 18 : 0x%x\n",t2);

    if( sgdma_rx_dev->callback == NULL )
        alt_printf("callback RX SGDMA is NULL\n");
    else
        alt_printf("callback RX SGDMA is NOT NULL\n");

    sem=0;

    return status;
}

Обработчик:

int tse_sgdmaRx_isr(void * context, alt_u32 irqnum)
{
    alt_u32 t2=0;
    alt_u32 *uncached_packet_payload;
    t2=IORD_ALTERA_AVALON_SGDMA_STATUS(RX_SGDMA_BASE);
    if (t2 & (ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK | 
                     ALTERA_AVALON_SGDMA_STATUS_DESC_COMPLETED_MSK))
    {
        p_counter++;
        alt_printf("Packet counter:%x\n",p_counter);
        IOWR_ALTERA_AVALON_SGDMA_STATUS(RX_SGDMA_BASE,ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK);
        t2=IORD_ALTERA_TSE_SGDMA_DESC_STATUS(&desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]);
        /*check status and handle packet*/
        if( (t2 & 
          (ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK | 
           ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK | 
           ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK |
           ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK | 
           ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK | 
           ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK | 
           ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK ) ) == 0)
        {
            t2=IORD_16DIRECT(&desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST].actual_bytes_transferred, 0)-2;
            CheckPacket((void*)pkt,t2);
        }
        else
        {
            alt_printf("RX descriptor reported error. Packet dropped\n");
        }
        uncached_packet_payload = (void *)alt_remap_cached ((volatile void*) pkt, 4);
        alt_avalon_sgdma_construct_stream_to_mem_desc(
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST],  // descriptor I want to work with
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST],  // pointer to "next"
            uncached_packet_payload,            // starting write_address
            0,                                  // read until EOP
            0);                                 // don't write to constant address
        t2=alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]);
    }
    return 0;
}

 

В обработчике на строчке: t2=IORD_ALTERA_AVALON_SGDMA_STATUS(RX_SGDMA_BASE); ставлю точку останова

 

После запуска в режиме отладки в консоль выводится следующее:

Reg 27 : 8484
Reg 27 : 8484
Reg 20 : c68
Reg 20 : c69
Reg 0 : 1140
end of wait for link-up
[triple_speed_ethernet_init] RX SGDMA: [/dev/rx_sgdma] & TX SGDMA: [/dev/tx_sgdma] is opening
end of reset the mac
TSE Command Reg : 0x203
Reg 0 : 0x1140
Reg 1 : 0x796d
Reg 20 : 0xc69
Reg 27 : 0x8484
Reg 18 : 0x0
callback RX SGDMA is NOT NULL

С компа делаю: ping 201.1.1.1 и ping 201.1.1.255, и ничего не происходит.

Нет прерывания или обработчик не правильно подцеплен??

Изменено пользователем billidean

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если с sgdma проблем нет (по вашим логам вроде так, но стоит попробовать включить loopback), то надо смотреть в сторону i/o. я с sgmii не работал. встречал только, что там нужен блок ALTGX_RECONFIG, чего-то там крутить в трансивере. что-то не вижу в примерах для этой борды ничего про eth. по-моему в ките cycloneivgx тоже sgmii используется, надо там глянуть

upd: http://www.altera.com/support/examples/dow...ard-4sgx230.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за помощь. ping заработал. Ответ на комп идет.

Ошибки были следующие:

1. В QSys была тактовая 50МГц, перевел на 100МГц

2. В QSys не было связи cpu.data_master с deskriptor_memory.s1

3. В Квартусовском проекте было:

    clk_clk => clk_in_50,
    ...
    triple_speed_ethernet_0_conduit_connection_ref_clk        => clk_in_50,

сделал:

    clk_clk => clk_in_100,
    ...
    triple_speed_ethernet_0_conduit_connection_ref_clk        => clk_in_125,

4. В фнкции tse_mac_raw_send было:

uncached_packet_payload = (alt_u32*)alt_remap_cached ((volatile void*) data, 4);

сделал:

uncached_packet_payload = (alt_u32*)alt_remap_uncached((volatile void*)data, data_bytes);

Изменено пользователем billidean

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...