acvarif 0 April 5, 2013 Posted April 5, 2013 (edited) · Report post если используете MII, то надо подать на tx_clk 25MHz, gtx_clk в данном режиме не используетсяНа tx_clk TSE? Тут я кажется запутался. Схема соединения Циклона и PHY говорит о том, что на циклон, а значит на tse толжна поступать частота (125 мГц ??? ) от ноги tx_clk PHY. Я так понял, что запитать передатчик PHY нужно от Циклона частотой 125 мГц. Или 25 мГц? Или все не так? Обратил внимание, что если на вход gtx_clk PHY ничего не подать, то передатчик как-будто умолкает - светодиод ENET0_LED_TX передатчика не мигает. Edited April 5, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
vadimuzzz 0 April 5, 2013 Posted April 5, 2013 · Report post 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 берется). вы по регистрам смотрели, какой линк? Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 5, 2013 Posted April 5, 2013 (edited) · Report post 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 April 5, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
vadimuzzz 0 April 5, 2013 Posted April 5, 2013 · Report post в Control register бит 6 выставить в "0", бит 13 - в "1", это принудительно включит 100мбит. скорее всего после этого надо еще sw_reset сделать. но это грязный хак, лучше в auto-neg 100mbit прописать. личку гляньте. Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 8, 2013 Posted April 8, 2013 (edited) · Report post в 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 April 8, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
vadimuzzz 0 April 8, 2013 Posted April 8, 2013 · Report post Все понятно, кроме... Что такое mdio? Физический адрес PHY, который можно определить через ID PHY? TSE может быть присоединен к нескольким PHY (до 32) (включая PCS в трансиверах кристаллов серий GX), поэтому есть 2 набора регистров. Наборы соответствуют адресам PHY в регистрах mdio_addr0, mdio_addr1 Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 8, 2013 Posted April 8, 2013 (edited) · Report post 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 April 8, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 8, 2013 Posted April 8, 2013 (edited) · Report post Спасибо. Все получилось. В смысле доступ к регистрам 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 April 8, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
vadimuzzz 0 April 9, 2013 Posted April 9, 2013 · Report post Тоесть если к 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-транзакции Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 9, 2013 Posted April 9, 2013 · Report post Спасибо. По 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 Quote Share this post Link to post Share on other sites More sharing options...
vadimuzzz 0 April 9, 2013 Posted April 9, 2013 · Report post Проверьте 12 бит, он должен быть сброшен, чтобы отключить auto-neg Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 9, 2013 Posted April 9, 2013 (edited) · Report post Проверьте 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 April 9, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 9, 2013 Posted April 9, 2013 (edited) · Report post Передатчик заработал. Пакеты передает правильно. Партачит приемник. Принимает один(два) раза и замолкает. Пакеты принимает правильно (все байты на месте). Похоже, что у меня .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 April 9, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
vadimuzzz 0 April 10, 2013 Posted April 10, 2013 · Report post попробуйте с такими констрейнами (названия портов подправьте): #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}] Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 April 10, 2013 Posted April 10, 2013 (edited) · Report post попробуйте с такими констрейнами (названия портов подправьте): #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 April 10, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...