|
|
  |
Ethernet + Cyclone + Nios |
|
|
|
Mar 24 2014, 04:13
|
Группа: Новичок
Сообщений: 5
Регистрация: 14-06-12
Из: Минск
Пользователь №: 72 323

|
Цитата(vadimuzzz @ Mar 19 2014, 03:56)  единственное, что в голову приходит - проблемы с i/o на стыке плис/phy (кривые констрейны, например). стоит пробежаться сигналтапом по цепочке, начиная с выхода sgdma. правда, если шина связи с phy - rgmii, то сами ноги посмотреть не удастся, но можно добраться до их ddr-регистров Потыкал сигналтапом в tse И sgdma_tx. При передаче больших пакетов происходила установка бита m_tx_err в единицу, после чего данные не передавались, ходя во в внутренние фифошки тсе данные поступали до eop sgdma (при малых пакетах до 200 байт этот бит не устанавливался и пересылка завершалась хорошо). Не могу понять из-за чего происходила ошибка передачи - при установке бита других сигналов не появлялось. Дальше урезал проект для размещения ресурсов под сигналтап (плата небольшая - neek на циклоне 3). Из урезки существенным являлось замена sdram на ssram. В новой схеме пакеты передаются успешно при любой длинне. Так что буду работать дальше, всем спасибо ) Проблема пока не актуальна, но хотелось бы понять кто как решает похожие проблемы. В старой схеме ддр работала на 133 МГц, периферия на 133/2 МГц (tse, sgdma, etc), режим tse - mii (small mac). В новой cхеме - ssram на 100 МГц, периферия 60 МГц, tse - small mac. Констрэйны не менял и не вникал что к чему, т.к. в доках про их необходимость мало чего написано и пока проходит мимо
|
|
|
|
|
Aug 5 2014, 12:02
|
Группа: Новичок
Сообщений: 4
Регистрация: 19-05-14
Пользователь №: 81 706

|
День добрый! Имеется кит. Разбираюсь на нем с TSE. SSS для примера запустился без проблем. Теперь пытаюсь запустить драйвер, написанный уважаемым vadimuzzz, но все попытки тщетны. Железную часть беру из вышеприведенного примера без изменений. Доступ к регистрам PHY (8е1111) есть, значение после инициализации controlPHY = 1140, statusPHY = 796d. В прерывание приемника не попадаю, при передаче лампочка горит, но в wireshark тихо. Версия QII 13.1, на это и грешу: Цитата(doom13 @ Feb 26 2014, 11:54)  Здравствуйте. Возник вопрос по Triple Speed Ethernet: чем же TSE v13 отличается от TSE v12? С предыдущей версией ip проект работает, при переходе на новую начинаются сбои (прерывание от sgdma_rx вообще перестало работать, sgdma_tx - виснет после передачи нескольких пакетов). Пока оставил старую версию ядра, но как-то не нравится ругательство Qsys о использовании устаревшей версии. Возникала ли у кого-нибудь подобная проблема? P.S. хотя может быть все что угодно - я глубоко начинающий ПЛИСовод и до просветления еще ой как далеко.
|
|
|
|
|
Aug 5 2014, 20:54
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Alexander_35 @ Aug 5 2014, 15:02)  Теперь пытаюсь запустить драйвер, написанный уважаемым vadimuzzz, но все попытки тщетны. Железную часть беру из вышеприведенного примера без изменений. Доступ к регистрам PHY (8е1111) есть, значение после инициализации controlPHY = 1140, statusPHY = 796d. В прерывание приемника не попадаю, при передаче лампочка горит, но в wireshark тихо. Раз лампочка при передаче загорается - MAC передаёт данные на PHY. У Вас для связи MAC-PHY используется RGMII, попробуйте подвигать "клок" TXC (RXC) относительно данных. Если не ошибаюсь, биты управления данной задержкой находятся в регистре PHY 0x1B.Бит 20.1 - RGMII TX Timing Control, бит 20.7 - RGMII RX Timing Control. Цитата(Alexander_35 @ Aug 5 2014, 15:02)  Версия QII 13.1, на это и грешу: С TSE v13 у меня так и не заработало (правда, сильно и не разбирался, оставил TSE 12 версии), железо и софт одни и те же, но как только ставим TSE v13 всё ложится. C TSE v12 проект отлично работает без каких-либо сбоев.
|
|
|
|
|
Aug 6 2014, 06:48
|
Группа: Новичок
Сообщений: 4
Регистрация: 19-05-14
Пользователь №: 81 706

|
Спасибо за совет, но к сожалению не помогло. Буду разбираться.
|
|
|
|
|
Aug 7 2014, 10:56
|
Группа: Новичок
Сообщений: 4
Регистрация: 19-05-14
Пользователь №: 81 706

|
С констрейнами у меня пока трудновато, поэтому поставил те, что vadimuzzz предлагал, поправив названия портов: Код #RX path create_clock -name rx_virtualclk -period 40 create_clock -period 40 -name rxclk [get_ports {enet_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 {enet_rxd* enet_rx_dv}] set_input_delay -clock rx_virtualclk -min $phy_tco_min [get_ports {enet_rxd* enet_rx_dv}] #TX path set phy_tsu 10 set phy_th 0 set_output_delay -clock { txclk_virt } -rise -max $phy_tsu [get_ports {enet_txd* enet_tx_en}] set_output_delay -clock { txclk_virt } -rise -min -$phy_th [get_ports {enet_txd* enet_tx_en}] Знаю что это для GMII, поэтому не факт что я сделал корректно. Причем, как я понял, изначально в альтеровском примере констрейнов на RGMII нет, тем не менее SSS запускается. Или я не прав?
|
|
|
|
|
Aug 14 2014, 14:48
|
Группа: Новичок
Сообщений: 4
Регистрация: 19-05-14
Пользователь №: 81 706

|
vadimuzzz, спасибо за констрейны! doom13, в доке на TSE, правда версии 14, написано: Код In the new user interface in Qsys, for a design that has a MAC function, you have to manually connect the exposed ports or terminate them. И дальше нарисована таблица, что к чему подключить. Попробуйте.
|
|
|
|
|
Aug 15 2014, 07:43
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Alexander_35 @ Aug 14 2014, 17:48)  doom13, в доке на TSE, правда версии 14, написано: Код In the new user interface in Qsys, for a design that has a MAC function, you have to manually connect the exposed ports or terminate them. И дальше нарисована таблица, что к чему подключить. Попробуйте. Попробовал, не пошло. Отличие только в версии TSE, v12 работает, v13 нет.
|
|
|
|
|
Oct 27 2014, 13:35
|
Группа: Новичок
Сообщений: 3
Регистрация: 28-10-13
Пользователь №: 78 932

|
Всем привет! Возникла проблема при работе с модулем TSE и нет никаких предположений в какую сторону копать. Очень надеюсь на вашу помощь! Я пытаюсь при помощи NIOS и модуля TSE выплюнуть тестовую посылку в Ethernet. За основу взял проект vadimuzzz. В main_memory я при помощи Nios записываю 10 тестовых слов, которые и хочу передать в одной посылке через Ethernet. TSE настроен на работу по интерфейсу RGMII. Mac Options модуля можно увидеть на фото ниже. Запустить пытаюсь на чипе KSZ9031. Я считываю все данные из descriptor_memory при помощи SGDMA_tx и передаю их на модуль UDP. Этот модуль формирует на выходе посылку и передает ее на модуль TSE, который в свою очередь никак на это не реагирует. Очень прошу вашей помощи! Тырните носом в мою ошибку или подскажите в каком направлении ее искать. Скрин QSYS системы и листинг программы для NIOS:
Код #include <altera_avalon_sgdma.h> #include <altera_avalon_sgdma_descriptor.h> #include <altera_avalon_sgdma_regs.h> #include <udp_tx_offload_regs.h> #include "system.h" #include <altera_avalon_tse.h>
#include "sys/alt_stdio.h" #include "sys/alt_irq.h" #include <stdio.h> #include <unistd.h>
/* * ----------------------------------------------------------------------------------------------------------------------------------------- */ struct mac_struct { /* EXAMPLE * 00-1C-23-17-4A-CB * mac_hi = 0x17231c00 * mac_lo = 0x0000CB4a * */ unsigned int mac_hi; unsigned int mac_lo; };
typedef union { struct mac_struct mac_addr; unsigned char mac_arr[6]; } mac_addr_t;
typedef union { unsigned int addr; unsigned char ad_arr[4]; } ip4_addr_t;
mac_addr_t MY_MAC_ADDR; ip4_addr_t MY_IP_ADDR;
// Create sgdma transmit and receive devices alt_sgdma_dev * sgdma_tx_dev; alt_sgdma_dev * sgdma_rx_dev;
// Allocate descriptors in the descriptor_memory (onchip memory) alt_sgdma_descriptor tx_descriptor __attribute__ (( section ( ".descriptor_memory" ))); alt_sgdma_descriptor tx_descriptor_end __attribute__ (( section ( ".descriptor_memory" )));
/* * ----------------------------------------------------------------------------------------------------------------------------------------- */
void TSE_init1(void) { alt_u32 /*t,*1=0,*/t2=0; int status=0;
#define PHY 0x4
/* PHY and other board peripherial initialization */ IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_MAC_BASE,PHY); alt_printf("TSE_MAC_REV:%x\n", IORD_ALTERA_TSEMAC_REV(TSE_MAC_BASE)); alt_printf("PHY_ID1:%x\n", IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID1)); alt_printf("PHY_ID2:%x\n", IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE, 0, ALTERA_TSEMAC_PHY_ADDR_PHY_ID2)); do { t2=IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_STATUS); } while((t2&0x04)==0);//wait for link-up
/* Get the Rx and Tx SGDMA addresses */ sgdma_tx_dev = alt_avalon_sgdma_open("/dev/sgdma_tx"); sgdma_rx_dev = alt_avalon_sgdma_open("/dev/sgdma_rx"); IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_TX_BASE,ALTERA_AVALON_SGDMA_CONTROL_SOFTWARERESET_MSK); IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_TX_BASE, 0x0); /* reset the mac */
IOWR_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE , ALTERA_TSEMAC_CMD_SW_RESET_MSK /*| ALTERA_TSEMAC_CMD_TX_ENA_MSK | ALTERA_TSEMAC_CMD_RX_ENA_MSK*/); while(IORD_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE) & ALTERA_TSEMAC_CMD_SW_RESET_MSK) { }
/* Initialize MAC registers */
IOWR_ALTERA_TSEMAC_FRM_LENGTH(TSE_MAC_BASE, ALTERA_TSE_MAC_MAX_FRAME_LENGTH); IOWR_ALTERA_TSEMAC_RX_ALMOST_EMPTY(TSE_MAC_BASE, 8); IOWR_ALTERA_TSEMAC_RX_ALMOST_FULL(TSE_MAC_BASE, 8); IOWR_ALTERA_TSEMAC_TX_ALMOST_EMPTY(TSE_MAC_BASE, 8); IOWR_ALTERA_TSEMAC_TX_ALMOST_FULL(TSE_MAC_BASE, 3); IOWR_ALTERA_TSEMAC_TX_SECTION_EMPTY(TSE_MAC_BASE, 240); //1024/4; IOWR_ALTERA_TSEMAC_TX_SECTION_FULL(TSE_MAC_BASE, 16); //32/4; // start transmit when there are 48 bytes IOWR_ALTERA_TSEMAC_RX_SECTION_EMPTY(TSE_MAC_BASE, 240); //4000/4); IOWR_ALTERA_TSEMAC_RX_SECTION_FULL(TSE_MAC_BASE, 16); IOWR_ALTERA_TSEMAC_TX_CMD_STAT(TSE_MAC_BASE,0); IOWR_ALTERA_TSEMAC_RX_CMD_STAT(TSE_MAC_BASE,ALTERA_TSEMAC_RX_CMD_STAT_RXSHIFT16_MSK); IOWR_ALTERA_TSEMAC_RX_CMD_STAT(TSE_MAC_BASE,0); IOWR_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE, ALTERA_TSEMAC_CMD_TX_ENA_MSK | ALTERA_TSEMAC_CMD_RX_ENA_MSK | /*ALTERA_TSEMAC_CMD_TX_ADDR_INS_MSK |*/ ALTERA_TSEMAC_CMD_RX_ERR_DISC_MSK | ALTERA_TSEMAC_CMD_PAD_EN_MSK | ALTERA_TSEMAC_CMD_CRC_FWD_MSK); IOWR_ALTERA_TSEMAC_MAC_0(TSE_MAC_BASE, MY_MAC_ADDR.mac_addr.mac_hi); IOWR_ALTERA_TSEMAC_MAC_1(TSE_MAC_BASE, MY_MAC_ADDR.mac_addr.mac_lo); }
int UDP_init() { int status=0;
UDP_TX_OFFLOAD_WR_CSR(UDP_TX_OFFLOAD_0_BASE, 0x1); UDP_TX_OFFLOAD_WR_MAC_DST_HI(UDP_TX_OFFLOAD_0_BASE, 0x2819BEC8); UDP_TX_OFFLOAD_WR_MAC_DST_LO(UDP_TX_OFFLOAD_0_BASE, 0x0000179B); UDP_TX_OFFLOAD_WR_MAC_SRC_HI(UDP_TX_OFFLOAD_0_BASE, MY_MAC_ADDR.mac_addr.mac_hi); UDP_TX_OFFLOAD_WR_MAC_SRC_LO(UDP_TX_OFFLOAD_0_BASE, MY_MAC_ADDR.mac_addr.mac_lo); UDP_TX_OFFLOAD_WR_IP_SRC(UDP_TX_OFFLOAD_0_BASE, MY_IP_ADDR.ad_arr); UDP_TX_OFFLOAD_WR_IP_DST(UDP_TX_OFFLOAD_0_BASE, 0x0100A8C0); UDP_TX_OFFLOAD_WR_UDP_PORTS(UDP_TX_OFFLOAD_0_BASE, 0xE000); UDP_TX_OFFLOAD_WR_IP_HDR_HI(UDP_TX_OFFLOAD_0_BASE, 0x0); UDP_TX_OFFLOAD_WR_IP_HDR_LO(UDP_TX_OFFLOAD_0_BASE, 0x00004011/*0x0200FF11*/); UDP_TX_OFFLOAD_WR_AUX_CONFIG(UDP_TX_OFFLOAD_0_BASE, 0x0800);
return status; }
void add_phy_to_profile() {
/* supported PHY definition */
/* ------------------------------ */ /* KSZ9031 */ /* ------------------------------ */ enum { KSZ9031_OUI = 0x10A1, KSZ9031_MODEL = 0x22, KSZ9031_REV = 0x02 };
alt_tse_phy_profile KSZ9031 = { "KSZ9031", /* Micrel KSZ9031 */ KSZ9031_OUI, /* OUI */ KSZ9031_MODEL, /* Vender Model Number */ KSZ9031_REV, /* Model Revision Number */ 0x1F, /* Location of Status Register */ 5, /* Location of Speed Status */ 3, /* Location of Duplex Status */ 0 /* Location of Link Status */ /*&KSZ9031_phy_cfg,*/ /* function pointer to configure Micrel KSZ8893M */ /*&KSZ9031_link_status_read*/ /* Function pointer to read from PHY specific status register */ };
/* add supported PHY to profile */ alt_tse_phy_add_profile(&KSZ9031); }
int main(void) { alt_putstr("Start Work!\n"); /* MAC ADDRESS * 00-07-AB-F0-0D-BA * IP ADDRESS * 192.168.0.3*/ MY_MAC_ADDR.mac_addr.mac_hi = 0xF0AB0700; MY_MAC_ADDR.mac_addr.mac_lo = 0x0000BA0D; MY_IP_ADDR.ad_arr[3] = 192; MY_IP_ADDR.ad_arr[2] = 168; MY_IP_ADDR.ad_arr[1] = 0; MY_IP_ADDR.ad_arr[0] = 3;
unsigned int i; unsigned int* adr; unsigned int test_data; adr = (unsigned int*) MAIN_MEMORY_BASE;
test_data = 0xFF00AA64;
adr = (unsigned int*) MAIN_MEMORY_BASE; for(i = 0; i < 10; i += 1) { *adr = test_data; adr += 1; test_data += 1; }
// Открываем SGDMA sgdma_tx_dev = alt_avalon_sgdma_open(SGDMA_TX_NAME); if (sgdma_tx_dev == NULL) { alt_printf ("Error: could not open scatter-gather dma transmit device\n"); return -1; } else alt_printf ("Opened scatter-gather dma transmit device\n");
alt_tse_phy_init(); add_phy_to_profile(); TSE_init1(); UDP_init();
UDP_TX_OFFLOAD_WR_PACKET_LEN(UDP_TX_OFFLOAD_0_BASE, 10);
alt_u32 *uncached_packet_payload; uncached_packet_payload = (alt_u32*)alt_remap_cached ((volatile void*) MAIN_MEMORY_BASE, 4); adr = (unsigned int*) MAIN_MEMORY_BASE;
alt_avalon_sgdma_construct_mem_to_stream_desc( &tx_descriptor, // descriptor I want to work with &tx_descriptor_end, // pointer to "next" uncached_packet_payload, 40, 0, 1, 1, 0);
int timeout; timeout = 0; while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ) { if(timeout++ == ALTERA_TSE_SGDMA_BUSY_TIME_OUT_CNT) { alt_printf("tse_mac_raw_send: WARNING - TX SGDMA Timeout\n"); return -22; // avoid being stuck here } } IOWR_ALTERA_AVALON_SGDMA_CONTROL (SGDMA_TX_BASE, 0); IOWR_ALTERA_AVALON_SGDMA_STATUS (SGDMA_TX_BASE, 0xFF); // Set up non-blocking transfer of sgdma transmit descriptor alt_avalon_sgdma_do_async_transfer( sgdma_tx_dev, &tx_descriptor);
/* Event loop never exits. */
while (1);
return 0; }
|
|
|
|
|
Oct 27 2014, 23:57
|

Гуру
     
Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988

|
Цитата Запустить пытаюсь на чипе KSZ9031. С этого момента поподробнее, плиз. Как разведена шина RGMII на плате? Там есть два варианта: делать rx_clk большей длины, чем rx_d либо крутить тайминги через регистры PHY. Данный проект я последний раз заводил на KSZ9021, все дорожки на RGMII были одной длины и задержки я крутил через регистры (попутно выяснилось, что в чипе KSZ9021 есть баг). То, что данные ушли в MAC, но не дошли до хоста - почти наверняка кривые тайминги/констрейны. Осциллографом еще на gtx_clk/tx_d/tx_en гляньте для уверенности.
|
|
|
|
|
Oct 30 2014, 07:44
|
Группа: Новичок
Сообщений: 3
Регистрация: 28-10-13
Пользователь №: 78 932

|
Цитата(vadimuzzz @ Oct 28 2014, 03:57)  С этого момента поподробнее, плиз. Как разведена шина RGMII на плате? Там есть два варианта: делать rx_clk большей длины, чем rx_d либо крутить тайминги через регистры PHY. Данный проект я последний раз заводил на KSZ9021, все дорожки на RGMII были одной длины и задержки я крутил через регистры (попутно выяснилось, что в чипе KSZ9021 есть баг). То, что данные ушли в MAC, но не дошли до хоста - почти наверняка кривые тайминги/констрейны. Осциллографом еще на gtx_clk/tx_d/tx_en гляньте для уверенности. rx_clk короче чем rx_d На gtx_clk 25MHz, как и нужно. tx_en в нуле а вот с tx_d самая проблема, эти сигналы всегда висят в нуле, это видно в сигналтабе, я их смотрю непосредственно как выход модуля tse.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|