|
|
  |
Ethernet + Cyclone + Nios |
|
|
|
Dec 1 2011, 14:33
|
Группа: Участник
Сообщений: 13
Регистрация: 10-12-10
Из: RND
Пользователь №: 61 523

|
Вопрос к Гуру (ну и вообще к знатокам у кого все получилось), год назад баловался с kit CIII120+Marvel 88E1111, и с проектами которые делал dim99 и vladimuzzz, все сначала получилось, долго мучался с инициализацией Marvell, но поднял на Nios+sgDMA+TSE c использованием внутренней памяти на 128кб. в общем все работало, Ping, принимались и отправлялись UDP сообщения. После, больше пол-года занимался другими работами, вот счас опять взялся за ту же железку и столкнулся с такой проблемой: 1. Раньше при нажатии клавиши Reset, Nios перегружался и все работало прекрасно, теперь стал только после перепрошивк новой программы из Eclips перезапускатся. думал Резет вектор не правильно указан, но все осталось так же... , при этом Ethernet работал как и должен, но ближе к теме, 2. Решил добавить внешнюю ОЗУ, подключил 64mb DDR2 bot в сопс, собрал железо - Nios стартовал, вся инициализация прошла успешно. Но по Ethernet принимается только первый пакет правильно (если отпраляю Ping), а остальные пакеты почему то имеют значения не того пакета, что пришел из marvell, а пакет который CIII должен был отправить в ответ на ARP запрос... Вот, прошу помощи и совета. Прилагаю стуктуру из SOPC (Q9.1 sp2, Nios2 sp2 IDE), и карту памяти... ибо есть подозрения что дело в дескрипторах, но что делаю не так не пойму. Проект использовал от vladimuzz (за что ему очередное спасибо).
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 2 2011, 05:52
|
Группа: Участник
Сообщений: 13
Регистрация: 10-12-10
Из: RND
Пользователь №: 61 523

|
Я так понимаю что нужно alt_dcache_flush() , но праильно ли я делаю не уверен (вернее совсем не правильно делаю скорее всего). Вот исходник вашего eth_driver.c CODE #include "control.h" #include "system.h" #include "defines.h" #include "sys/alt_irq.h" #include "triple_speed_ethernet_regs.h" #include "altera_avalon_sgdma.h" #include "altera_avalon_sgdma_descriptor.h" #include "altera_avalon_sgdma_regs.h" #include "sys/alt_cache.h" #include "sys/alt_stdio.h" #include "eth_driver.h" #include "network.h" #include <errno.h>
#include "altera_avalon_tse.h"
//--------------------------------------------------------------------------------------------- //alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE; alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) 0x4000000; alt_sgdma_descriptor *currdescriptor_ptr; alt_sgdma_descriptor *nextdescriptor_ptr; alt_sgdma_descriptor *desc_pointer;
alt_sgdma_dev *sgdma_tx_dev; alt_sgdma_dev *sgdma_rx_dev;
volatile char pkt[1562] __attribute__ ((aligned (4))); volatile char pkt_copy[1562] __attribute__ ((aligned (4)));
int sem; alt_u32 p_counter; //--------------------------------------------------------------------------------------------- int MAC_init() { alt_u32 t2=0; alt_u32 t5 =0; int status=0; p_counter=0;
// /* PHY and other board peripherial initialization */ IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_MAC_BASE,PHY); // IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x00,0x3100); IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x04,0x1E1); // IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x09,0x1C0);// nnn // IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x10,0x68); //nnn IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x14,0xC53); // IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x14,0xC51);//delay to RX/TX // IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x14,0xCD1);//delay to RX/TX IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x00,0xB100); //peregrujaem MAC SOFT Reset
do { Delay(0xFFFF); t2=IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,ALTERA_TSEMAC_PHY_ADDR_STATU S); } while((t2&0x04)==0);//wait for link-up // printf("t2 %x\n",t2);
alt_u32 desc_mem_clear_count=0; for(desc_mem_clear_count=0;desc_mem_clear_count<256;++desc_mem_clear_count) { IOWR(DESCRIPTOR_MEMORY_BASE,desc_mem_clear_count,0); } currdescriptor_ptr = &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]; nextdescriptor_ptr = (alt_sgdma_descriptor *) IORD_ALTERA_TSE_SGDMA_DESC_NEXT(currdescriptor_ptr); desc_pointer = currdescriptor_ptr; desc_pointer->status&=~ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK; desc_pointer = currdescriptor_ptr;
/* 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_RX_BASE,ALTERA_AVALON_SGDMA_CONTROL_SOFTW ARERESET_MSK); IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE, 0x0); IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_TX_BASE,ALTERA_AVALON_SGDMA_CONTROL_SOFTW ARERESET_MSK); //- IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_TX_BASE, 0x0);//- // printf("SGDMA TX %x, SGDMA RX %x\n",sgdma_tx_dev, sgdma_rx_dev);
/* 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, TSE_MAC_TRANSMIT_FIFO_DEPTH - 16); //1024/4; IOWR_ALTERA_TSEMAC_TX_SECTION_FULL(TSE_MAC_BASE, 0); //16/32/4; // start transmit when there are 48 bytes IOWR_ALTERA_TSEMAC_RX_SECTION_EMPTY(TSE_MAC_BASE, TSE_MAC_RECEIVE_FIFO_DEPTH - 16); //4000/4); IOWR_ALTERA_TSEMAC_RX_SECTION_FULL(TSE_MAC_BASE, 0);//16 IOWR_ALTERA_TSEMAC_TX_CMD_STAT(TSE_MAC_BASE,ALTERA_TSEMAC_TX_CMD_STAT_TXSHIFT16_ MSK); 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); IOWR_ALTERA_TSEMAC_MAC_0(TSE_MAC_BASE,((int)(0x00) | (int)(0x07 << 8) | (int)(0xAB << 16) | (int)(0xF0 << 24))); IOWR_ALTERA_TSEMAC_MAC_1(TSE_MAC_BASE,(((int)(0x0D) | (int)(0xBA << 8)) & 0xFFFF));
int tse_mac00; int tse_mac01; tse_mac00 = IORD_ALTERA_TSEMAC_MAC_0(TSE_MAC_BASE); tse_mac01 = IORD_ALTERA_TSEMAC_MAC_1(TSE_MAC_BASE);
/*вывожу в терминал сообщение о МАК адресе и установленном IP адресе*/ printf("MAC addr setted! %X%X:%X%X:%X:%X:%X%X:%X\n",(tse_mac00&0x000000F0),(tse_mac00&0x0000000F),((tse_mac00&0x0000F000)>>8),((tse_mac00&0x00000F00)>>8),((tse_mac00&0x00FF0000)>>16), ((tse_mac00&0xFF000000)>>24),(tse_mac01&0x00F0),(tse_mac01&0x000F),((tse_mac01&0xFF00)>>8));
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; alt_dcache_flush(pkt, 4); uncached_packet_payload = (void *)alt_remap_cached ((volatile void*) pkt, 4); alt_dcache_flush(uncached_packet_payload, 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);
// alt_avalon_sgdma_construct_stream_to_mem_desc( // currdescriptor_ptr, // descriptor I want to work with // nextdescriptor_ptr, // pointer to "next" // uncached_packet_payload, // starting write_address // 0, // read until EOP // 0); while ((IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_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]); sem=0;
return status; } //---------------------------------------------------------------------------------------------
int tse_sgdmaRx_isr(void * context, alt_u32 irqnum) { alt_u32 t2=0; static int p_counter;
alt_u32 *uncached_packet_payload; t2=IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE); if (t2 & (ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK | ALTERA_AVALON_SGDMA_STATUS_DESC_COMPLETED_MSK)) { p_counter++;
IOWR_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE,ALTERA_AVALON_SGDMA_STATUS_CHAIN_C OMPLETED_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; alt_printf("Packet counter: 0x%x len bytes: 0x%x\n",p_counter, t2); alt_printf("data: |%x|%x|%x|%x|%x|%x|%x|%x| |%x|%x|%x|%x|%x|%x|%x|%x|\n", pkt[0]&0xFF,pkt[1]&0xFF,pkt[2]&0xFF,pkt[3]&0xFF,pkt[4]&0xFF,pkt[5]&0xFF,pkt[6]&0xFF,pkt[7]&0xFF, pkt[8]&0xFF,pkt[9]&0xFF,pkt[10]&0xFF,pkt[11]&0xFF,pkt[12]&0xFF,pkt[13]&0xFF,pkt[14]&0xFF,pkt[15]&0xFF); alt_printf(" |%x|%x|%x|%x|%x|%x|%x|%x| |%x|%x|%x|%x|%x|%x|%x|%x|\n", pkt[16]&0xFF,pkt[17]&0xFF,pkt[18]&0xFF,pkt[19]&0xFF,pkt[20]&0xFF,pkt[21]&0xFF,pkt[22]&0xFF,pkt[23]&0xFF, pkt[24]&0xFF,pkt[25]&0xFF,pkt[26]&0xFF,pkt[27]&0xFF,pkt[28]&0xFF,pkt[29]&0xFF,pkt[30]&0xFF,pkt[31]&0xFF); CheckPacket(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_sync_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]); t2=alt_avalon_sgdma_do_async_transfer( sgdma_rx_dev, &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]); } return 0; }
//--------------------------------Ethernet Message Send-----------------------------
int tse_mac_raw_send(char * data, unsigned data_bytes) { alt_u32 *uncached_packet_payload; alt_32 timeout; int result; if(sem!=0) /* Tx is busy*/ { alt_printf("Tx is busy\n"); return -22; } sem = 1; alt_dcache_flush(data, data_bytes); // clear bit-31 before passing it to SGDMA Driver // uncached_packet_payload = (alt_u32*)alt_remap_cached ((volatile void*) data, 4); uncached_packet_payload = (alt_u32*)alt_remap_cached ((volatile void*) data, data_bytes); /* Write data to Tx FIFO using the DMA */ // alt_dcache_flush(uncached_packet_payload, data_bytes); if( data_bytes > ALTERA_TSE_MIN_MTU_SIZE ) { alt_printf("TX Starting read adrr %x - bytes %x\n",uncached_packet_payload, data_bytes); /* make sure there is room in the FIFO. */ alt_avalon_sgdma_construct_mem_to_stream_desc( currdescriptor_ptr, // descriptor I want to work with nextdescriptor_ptr,// pointer to "next" uncached_packet_payload, // starting read address data_bytes, // # bytes 0, // don't read from constant address 1, // generate sop 1, // generate endofpacket signal 0); // atlantic channel (don't know/don't care: set to 0) result = 0;
// Make sure DMA controller is not busy from a former command // and TX is able to accept data 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("WARNING : TX SGDMA Timeout\n"); return -22; // avoid being stuck here } } // Set up the SGDMA // Clear the status and control bits of the SGDMA descriptor IOWR_ALTERA_AVALON_SGDMA_CONTROL (SGDMA_TX_BASE, 0); IOWR_ALTERA_AVALON_SGDMA_STATUS (SGDMA_TX_BASE, 0xFF); // Start SGDMA (blocking call) result = alt_avalon_sgdma_do_async_transfer( sgdma_tx_dev, (alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_TX_SGDMA_DESC_OFST]); } else { result = -3; } // printf("transfer %x\n", result); if(result < 0) /* SGDMA not available */ { alt_printf("raw_send() SGDMA not available\n"); sem = 0; return -22; /* ENP_RESOURCE and SEND_DROPPED have the same value! */ } else /* = 0, success */ { sem = 0; return 0; /*success */ } }
//---------------------------------------------------------------------------------------------
|
|
|
|
|
Dec 8 2011, 07:28
|

я только учусь...
     
Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839

|
Цитата(Postoroniy_V @ Oct 17 2007, 03:41)  тоесть стоит задача реализовать подержку TCP/IP в железе а не в софте? или всё таки в железе как здесьтут вот исходники можно взять если всё таки в железеа Вы не могли б выложить эти исходники... не получается скачать...
--------------------
If it doesn't work in simulation, it won't work on the board.
"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
|
|
|
|
|
Dec 13 2011, 11:39
|
Знающий
   
Группа: Свой
Сообщений: 851
Регистрация: 28-08-04
Пользователь №: 559

|
Добрый день! Есть плата на Cyclone III. На плате установлена микросхема PHY DP83848, две микросхемы памяти SDRAM по 32МБайт, FPGA EP3C25Q240C8N Питание микросхем 3.3V Блок схема представлена на рис. 1.
Не удается заставить работать IP модуль Triple-Speed Ethernet (далее TSE) на плате с Cyclone III. Плата заведомо рабочая. Проверку проводил в следующей последовательности. 1. В Quartus II 9.0sp2 (32-bit) собрал систему на NIOS и IP OpenCores 10/100 Ethernet MAC v 8.0.3 (далее OCM). Тестовый проект - web_server_0" работает нормально, устройство пингуется, страничка открывается. 2. Далее заменил модуль OCM на модуль TSE. Пересобрал систему, сгенерировал новый проект в "web_server_1" NIOS IDE. Сеть перестала работать. Проект для SOPC с OCM.
Проект для SOPC с TSE.
Помогите разобраться с этой проблемой. Проект прикладываю.
smv_board.zip ( 5.39 мегабайт )
Кол-во скачиваний: 150
|
|
|
|
|
Dec 13 2011, 12:47
|
Знающий
   
Группа: Свой
Сообщений: 851
Регистрация: 28-08-04
Пользователь №: 559

|
Лог работы с OCM: Цитата Copyright 1996-2008 by InterNiche Technologies. All rights reserved. Your Ethernet MAC address is 11:12:13:14:15:16 Static IP Address is 192.168.3.250 prepped 1 interface, initializing... mctest init called IP address of et1 : 192.168.3.250 Created "Inet main" task (Prio: 2) Created "clock tick" task (Prio: 3) Created "web server" task (Prio: 4)
Web Server starting up
Fetching file: /mount/rozipfs/index.html. Can't open the 404 File Not Found error page. Have you programmed the filing system into flash? [http_handle_receive] Error preparing response Страница открывается, выводится сообщение: "HTTP Error 404 Nios II Web Server Demonstration Can't find the requested file file. Have you programmed the flash filing system into flash?"т.к. нет файла rozipfsс страничкой. IP пингуется. Лог работы с TSE: Цитата Copyright 1996-2008 by InterNiche Technologies. All rights reserved. Static IP Address is 192.168.3.250 prepped 1 interface, initializing... mctest init called IP address of : 192.168.3.250 Created "Inet main" task (Prio: 2) Created "clock tick" task (Prio: 3) Created "web server" task (Prio: 4)
Web Server starting up Страница с IP 192.168.3.250 не грузится. IP не пингуется.
|
|
|
|
|
Dec 15 2011, 06:05
|
Знающий
   
Группа: Свой
Сообщений: 851
Регистрация: 28-08-04
Пользователь №: 559

|
Добавил клок 200 МГц. Снизил частоту системы до 50 МГц Посмотрел сигналы на входе и выходе TSE MAC.
между PHY и TSE Сигналы идут на TSE, от TSE сигналов нет. Соответственно со стороны TSE - ff_tx_data, ff_rx_data тоже ничего нет. клоки ff_tx_clk и ff_rx_clk есть.
На триггеры sop и wren не срабатывают. Такое ощущение, что TSE отбрасывает все пакеты как битые. Файлы stp приложил.
stp.zip ( 37.45 килобайт )
Кол-во скачиваний: 121
|
|
|
|
|
Dec 15 2011, 13:03
|

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

|
Цитата(COMA @ Dec 15 2011, 17:47)  Пробовал ставить триггеры почти на все линии. Ничего не изменилось в сигналтапе. у вас на картинках только шина MII, интересует выход приемного канала TSE (там шина avalon-st, идет на sgdma_rx_0). помимо данных, sop, valid и прочего там есть сигнал типа error Цитата Возможно модуль не до конца инициализируется. собираете debug-версию (драйвера тоже) и в пошаговую отладку. MAC-адрес устанавливается в функции tse_mac_init (файл ins_tse_mac.c). ну и попинговать комп со стороны платы тоже не мешает
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|