Jump to content
    

если используете MII, то надо подать на tx_clk 25MHz, gtx_clk в данном режиме не используется
На tx_clk TSE?

 

Тут я кажется запутался. Схема соединения Циклона и PHY говорит о том, что на циклон, а значит на tse толжна поступать частота (125 мГц ??? ) от ноги tx_clk PHY. Я так понял, что запитать передатчик PHY нужно от Циклона частотой 125 мГц. Или 25 мГц?

post-39850-1365157752_thumb.jpg

Или все не так?

Обратил внимание, что если на вход gtx_clk PHY ничего не подать, то передатчик как-будто умолкает - светодиод ENET0_LED_TX передатчика не мигает.

Edited by Acvarif

Share this post


Link to post
Share on other sites

tx_clk в режиме MII будет либо 25 либо 2.5 MHz. если там лог. 0, значит PHY определил гигабитный линк. про gtx_clk сказано: This clock can be stopped when the device is in 10/100BASE_T modes (опора для PLL видимо с ноги XTAL берется). вы по регистрам смотрели, какой линк?

Share this post


Link to post
Share on other sites

tx_clk в режиме MII будет либо 25 либо 2.5 MHz. если там лог. 0, значит PHY определил гигабитный линк. про gtx_clk сказано: This clock can be stopped when the device is in 10/100BASE_T modes (опора для PLL видимо с ноги XTAL берется). вы по регистрам смотрели, какой линк?

Понятно. tx_clk которое идет из PHY на TSE Циклон должно быть 25мГц. Но как понять can be stopped? Оставить этот вход PHY свободным или посадить на 0?

По регистрам не смотрел. По светодиоду понятно, что линк на 1000 (горит ENET0_LINK_1000). Хотя должен быть на 100 (перемычка jp1 поставлена на MII MODE).

В функции инициализации МАС инициализация PHY - только проверка установления линка.

.....

    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_0_BASE,PHY);
    t2=IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0,1);
    while((IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,PHY,0x01)&0x04)==0)
    {
        Delay(0xFFFF);
    }
    t2=IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0,1);

//PHY_LEDS=ACT+LINK----------------------------------------------------------------------
    t2=IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,PHY,0x1e);
    t2|=0x4000;
    IOWR_ALTERA_TSEMAC_MDIO(TSE_0_BASE,PHY,0x1e,t2);
    for(t2=0;t2<256;++t2)
    {
        IOWR(ONCHIP_MEMORY2_0_BASE,t2,0);
    }
....

Для ksz872 этого вполне достаточно

Нужно-ли еще что-то для инициализации 88е1111 в режиме MII?

Посадил вход gtx_clk на 0 светодиод передатчика перестал мигать. Линк все также остался на 1000.

Edited by Acvarif

Share this post


Link to post
Share on other sites

в Control register бит 6 выставить в "0", бит 13 - в "1", это принудительно включит 100мбит. скорее всего после этого надо еще sw_reset сделать. но это грязный хак, лучше в auto-neg 100mbit прописать. личку гляньте.

Share this post


Link to post
Share on other sites

в Control register бит 6 выставить в "0", бит 13 - в "1", это принудительно включит 100мбит. скорее всего после этого надо еще sw_reset сделать. но это грязный хак

Спасибо.

Прежде чем приступить пытаюсь глубже уяснить макросы чтения и записи данных в регистры phy.

Например чтение регистра PHY

IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID1);

забито как

#define IORD_ALTERA_TSEMAC_MDIO(base, mdio, reg_num) \
  IORD_16DIRECT(base, 0x200 + (mdio * 0x80) + (reg_num * sizeof(alt_u32)) )

Все понятно, кроме... Что такое mdio? Физический адрес PHY, который можно определить через ID PHY?

 

лучше в auto-neg 100mbit прописать
Получается, что нужно в 1 выставить 8_й бит врегистре 4. Только их там 2. Не врубился что такое Fiber и Copper.
Edited by Acvarif

Share this post


Link to post
Share on other sites

Все понятно, кроме... Что такое mdio? Физический адрес PHY, который можно определить через ID PHY?

TSE может быть присоединен к нескольким PHY (до 32) (включая PCS в трансиверах кристаллов серий GX), поэтому есть 2 набора регистров. Наборы соответствуют адресам PHY в регистрах mdio_addr0, mdio_addr1

Share this post


Link to post
Share on other sites

TSE может быть присоединен к нескольким PHY (до 32) (включая PCS в трансиверах кристаллов серий GX), поэтому есть 2 набора регистров. Наборы соответствуют адресам PHY в регистрах mdio_addr0, mdio_addr1

Тоесть если к TSE присоединен только один PHY то значение mdio в макросе типа IORD_ALTERA_TSEMAC_MDIO(base, mdio, reg_num) будет 0?

Виноват, но не врубился, зчем тогда нужен физический адрес PHY который определяется через PHY Identifier 1?

Например чтение состояние линка (ksz8721)

    while((IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,PHY,0x01)&0x04)==0)
    {
        Delay(0xFFFF);
    }

будет нормальное если PHY будет равно 0х1 или 0х1f или просто 0. Если PHY выставить 0х2 цикл виснет.

Перед этим нужно записать MDIO адрес IOWR_ALTERA_TSEMAC_MDIO_ADDR0(base, data)

Не врубаюсь куда он (MDIO адрес ) записывается? В какое место PHY? Или это пишется в нужный регистр tse для того, чтобы потом правильно общаться с регистрами phy?

В качестве подготовки общения с регистрами PHY 88e1111 сделал такую процедуру на ksz8721 - проверка чтения из регистров управления и статуса и записи в регистр управл.

    IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_0_BASE,PHY); // PHY равно 0х1
    ru=IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0,0);
    alt_printf("Reg_Contr_R = %x \n", ru);
    IOWR_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0, 0, ru | 0x80);
    ru=IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0,0);
    alt_printf("Reg_Contr_W = %x \n", ru);

    rs=IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0,1);
    alt_printf("Reg_Stat = %x \n", rs);

На выходе имею

Reg_Contr_R = 3100

Reg_Contr_W = 3180

Reg_Stat = 786d

Тоесть чтение и запись в регистры ksz8721работает как надо

При попытке повторить то же на DE2-115 (88у1111) выдаются все ffff

Тоесть регистры не читаются. PHY выставил как 0х10 (так он и определяется). Тоесть выполнил команду IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_0_BASE, 0х10);

Не знаю, что и думать...

Edited by Acvarif

Share this post


Link to post
Share on other sites

Спасибо.

Все получилось. В смысле доступ к регистрам PHY есть.

    for (t=0;t<33;t++) {
        IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_0_BASE, t);
        alt_printf("Probing PHY at address %x ...\n", t);
        r = IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID1);
        if (r == 0x0141)/*88e1111*/{
            alt_printf("PHY address:%x\n", t);
            alt_printf("PHY_ID1:%x\n", r);
            alt_printf("PHY_ID2:%x\n", IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID2));
            alt_printf("PHY_CONTROL:%x\n", IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE, 0, 0));
            alt_printf("PHY_STATUS:%x\n", IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE, 0, 1));
            break;
        }
    }

PHY определилось как 0х10. Данные регистров статуса и управления читаются нормально.

Теперь попробую включить скорость 100 через регистр управления и последующий программный сброс...

Edited by Acvarif

Share this post


Link to post
Share on other sites

Тоесть если к TSE присоединен только один PHY то значение mdio в макросе типа IORD_ALTERA_TSEMAC_MDIO(base, mdio, reg_num) будет 0?

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

Виноват, но не врубился, зчем тогда нужен физический адрес PHY который определяется через PHY Identifier 1?

Например чтение состояние линка (ksz8721)

    while((IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE,PHY,0x01)&0x04)==0)
    {
        Delay(0xFFFF);
    }

здесь явно косяк, наверное какая-то старая версия. я с багами пишу, да :) д.б. 0 или 1

Перед этим нужно записать MDIO адрес IOWR_ALTERA_TSEMAC_MDIO_ADDR0(base, data)

да, если используется нулевой банк регистров

Не врубаюсь куда он (MDIO адрес ) записывается? В какое место PHY? Или это пишется в нужный регистр tse для того, чтобы потом правильно общаться с регистрами phy?

да, он лежит в регистре и вставляется во время MDIO-транзакции

 

Share this post


Link to post
Share on other sites

Спасибо. По MDIO все прояснилось.

Пытаюсь заставить 88e1111 запуститься на скорости 100

Последовательно делаю

t = IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE, 0, 0); // чтение регистра упр. в t
IOWR_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0, 0, t | 0x2000); // установка бит 13 - 1, бит 6 - 0 (скорость 100)
t = IORD_ALTERA_TSEMAC_MDIO(TSE_0_BASE, 0, 0); // чтение регистра упр. в t
IOWR_ALTERA_TSEMAC_MDIO(TSE_0_BASE,0, 0, t | 0xb100); // программный сброс

Линк устанавливается, но гад на 1000

 

Share this post


Link to post
Share on other sites

Проверьте 12 бит, он должен быть сброшен, чтобы отключить auto-neg

Да. Спасибо. Оно. Скорость включилась на 100. Светодиод приемника на входящие пакеты реагирует, но реально приема нет - с этим буду разбираться потом. Покак задача запустить передатчик. Он почему-то виснет на функции tse_mac_raw_send((char*)ethmass_ptr, 1168); Да и с тактированием пока не понятно.

Поскольку в режиме MII GTX_CLK не нужно (This clock can be stopped when the device is in 10/100BASE_T modes ) - то опорные клоки для TX и RX очевидно 88е1111 формирует у себя и подает на MAC(FPGA). Проверю это утверждение путем вывода этих клоков на свободные ноги FPGA...

Edited by Acvarif

Share this post


Link to post
Share on other sites

Передатчик заработал. Пакеты передает правильно.

Партачит приемник. Принимает один(два) раза и замолкает. Пакеты принимает правильно (все байты на месте).

Похоже, что у меня .sdc не совсем подходит от ksz8721. В нем сделано так

#создаются все выходные клоки PLL
derive_pll_clocks -create_base_clocks 

create_clock -period 40 -name txclk [get_ports {enet0_tx_clk}]
create_clock -period 40 -name txclk_virt 
set_clock_groups -exclusive -group {txclk txclk_virt}
set_output_delay -clock { txclk_virt } -rise -max 11 [get_ports {enet0_tx_d[0] enet0_tx_d[1] enet0_tx_d[2] enet0_tx_d[3] enet0_tx_en}]

create_clock -period 40 -name rxclk [get_ports {enet0_rx_clk}]
set_input_delay -clock { rxclk } 1 [get_ports {enet0_rx_d[0] enet0_rx_d[1] enet0_rx_d[2] enet0_rx_d[3] enet0_rx_dv enet0_rx_err}]

Edited by Acvarif

Share this post


Link to post
Share on other sites

попробуйте с такими констрейнами (названия портов подправьте):

#RX path
create_clock -name rx_virtualclk -period 40
create_clock -period 40 -name rxclk [get_ports {eth_rxclk}] -waveform {20ns 40ns}
set_clock_groups -exclusive -group {rxclk rx_virtualclk}
set phy_tco_max 10
set phy_tco_min -10
set_input_delay -clock rx_virtualclk -max $phy_tco_max [get_ports {eth_rxd* eth_rxerr}]
set_input_delay -clock rx_virtualclk -min $phy_tco_min [get_ports {eth_rxd* eth_rxerr}]
#TX path
set phy_tsu 10
set phy_th 0
set_output_delay -clock { txclk_virt } -rise -max $tsu [get_ports {eth_txd* eth_txen}]
set_output_delay -clock { txclk_virt } -rise -min -$th [get_ports {eth_txd* eth_txen}]

Share this post


Link to post
Share on other sites

попробуйте с такими констрейнами (названия портов подправьте):

#RX path
create_clock -name rx_virtualclk -period 40
create_clock -period 40 -name rxclk [get_ports {eth_rxclk}] -waveform {20ns 40ns}
set_clock_groups -exclusive -group {rxclk rx_virtualclk}
set phy_tco_max 10
set phy_tco_min -10
set_input_delay -clock rx_virtualclk -max $phy_tco_max [get_ports {eth_rxd* eth_rxerr}]
set_input_delay -clock rx_virtualclk -min $phy_tco_min [get_ports {eth_rxd* eth_rxerr}]
#TX path
set phy_tsu 10
set phy_th 0
set_output_delay -clock { txclk_virt } -rise -max $tsu [get_ports {eth_txd* eth_txen}]
set_output_delay -clock { txclk_virt } -rise -min -$th [get_ports {eth_txd* eth_txen}]

Попробовал только для RX, пока тоже самое - один два приема.

create_clock -name rx_virtualclk -period 40
create_clock -period 40 -name rxclk [get_ports {enet0_rx_clk}] -waveform {20ns 40ns}
set_clock_groups -exclusive -group {rxclk rx_virtualclk}
set phy_tco_max 10
set phy_tco_min -10
set_input_delay -clock rx_virtualclk -max $phy_tco_max [get_ports {enet0_rx_d* enet0_rx_err}]
set_input_delay -clock rx_virtualclk -min $phy_tco_min [get_ports {enet0_rx_d* enet0_rx_err}]

Для tx

set phy_tsu 10
set phy_th 0
set_output_delay -clock { txclk_virt } -rise -max $tsu [get_ports {enet0_tx_d* enet0_tx_en}]
set_output_delay -clock { txclk_virt } -rise -min -$th [get_ports {enet0_tx_d* enet0_tx_en}]

Выскакивает ошибка

Error: can't read "tsu": no such variable
    while executing
"set_output_delay -clock { txclk_virt } -rise -max $tsu [get_ports {enet0_tx_d* enet0_tx_en}]"

Попробую еще изменить объем FIFO TSE (увеличить). На DE0Nano хватает 128 байт для приемника. Пакеты на прием имеют 96 байт.

Edited by Acvarif

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...