vadimuzzz
Nov 26 2009, 03:34
по поводу нулевых CRC и SRC-MAC есть мысль: похоже косяк в настройках, выключен режим CRC offload и включена замена MAC-адреса тем, что лежит в регистрах(а они, видимо, нулевые). выложите код инициализации. ну и raw_send до кучи. по поводу SOPC: я не стал делать отдельное ОЗУ для дескрипторов, а замапил все в одну кучу. логика такая: выигрыш, который дает размещение пакета в отдельной памяти в момент приема/передачи пакета нивелируется тем, что когда пакет принят и проц хочет в нем поковыряться, придется копировать данные в основное ОЗУ, чтобы не блокировать прием.
нашел ошибку - неправильно формируется дескриптор.
Проверяю через alt_avalon_sgdma_check_descriptor_status(desc) и выдает разные ошибки, теперь вот сижу пытаюсь сделать нормальный дескриптор.
vadimuzzz
Nov 26 2009, 08:49
Цитата(dim99 @ Nov 26 2009, 14:13)

нашел ошибку - неправильно формируется дескриптор.
Проверяю через alt_avalon_sgdma_check_descriptor_status(desc) и выдает разные ошибки, теперь вот сижу пытаюсь сделать нормальный дескриптор.
так это, код инициализации выкладывайте и raw_send, быстрее дело пойдет
вот что есть на данный момент:
Цитата
alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE;
alt_sgdma_descriptor *currdescriptor_ptr;
int tse_mac_raw_sendM(char * data, unsigned data_bytes)
{
unsigned int* ActualData;//pointer to the transmitting data
unsigned length = 128;
int tx_length;
char buf2[1560];
char *uncached_pkt = alt_remap_uncached ((volatile void*) pkt, 256);
char *uncached_buf2 = alt_remap_uncached ((volatile void*) buf2, 1560);
uncached_pkt[0]=0xCC;
uncached_pkt[1]=0xCC;
int k=0;
for(k=2;k<254;k++){
uncached_pkt[k]=0xA5;
}
uncached_pkt[254]=0xEE;
uncached_pkt[255]=0xEE;
int i=0;
for(i=0;i<length;i++) {
uncached_buf2[i] = uncached_pkt[i];
}
ActualData = (unsigned int*)buf2;
//-------------------
//clear bit-31 before passing it to SGDMA Driver
ActualData = (unsigned int*)alt_remap_cached ((volatile void*) ActualData, 256);
if( length > ALTERA_TSE_MIN_MTU_SIZE ) {
/* make sure there is room in the FIFO. */
alt_avalon_sgdma_construct_mem_to_stream_desc(
(alt_sgdma_descriptor *) desc, // descriptor I want to work with
(alt_sgdma_descriptor *) desc,// pointer to "next"
(alt_u32 *) ActualData, // starting read address
(length), // # bytes
1, // 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)
int desc_stat=1;
desc_stat = alt_avalon_sgdma_check_descriptor_status(desc);//if 0 then packet is good
desc->read_burst = 128;
desc->write_burst = 128;
tx_length = tse_mac_sTxWriteM(desc);
}
return 0;
}
desc_stat = 119
проверяет в контрольном регистре дескриптора Owned_by_HW и выдает
#define EINPROGRESS 119 /* Connection already in progress */
пока char * data, unsigned data_bytes не использую.
дальше беру функцию из tse:
Код
alt_32 tse_mac_sTxWriteM(alt_sgdma_descriptor *txDesc)
{
alt_32 timeout;
alt_u8 result = 0;
alt_u16 actualBytesTransferred;
// Make sure DMA controller is not busy from a former command
// and TX is able to accept data
timeout = 0;
//tse_dprintf("\nWaiting while tx SGDMA is busy......... ");
while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE/*mi->tx_sgdma->base*/) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ) {
if(timeout++ == ALTERA_TSE_SGDMA_BUSY_TIME_OUT_CNT) {
//tse_dprintf(4, "WARNING : TX SGDMA Timeout\n");
return 0;//error//ENP_RESOURCE; // 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/*mi->tx_sgdma->base*/, 0);
IOWR_ALTERA_AVALON_SGDMA_STATUS (SGDMA_TX_BASE/*mi->tx_sgdma->base*/, 0xFF);
// Start SGDMA (blocking call)
[i]result = alt_avalon_sgdma_do_sync_transfer(sgdma_tx_dev/*mi->tx_sgdma*/, &txDesc[0]);[/i]
alt_u32 sgdma_res = 0;
sgdma_res = IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE);
/* perform cache save read to obtain actual bytes transferred for current sgdma descriptor */
actualBytesTransferred = IORD_ALTERA_TSE_SGDMA_DESC_ACTUAL_BYTES_TRANSFERRED(&txDesc[0]);
int frame_transmited=0;
frame_transmited = IORD_16DIRECT(TSE_MAC_BASE,0x068);//frame trans
// frame_transmited = IORD_16DIRECT(TSE_MAC_BASE,0x0F0);//octets trans
// frame_transmited = IORD_16DIRECT(TSE_MAC_BASE,0x08C);//ifOutErrors
// frame_transmited = IORD_16DIRECT(TSE_MAC_BASE,0x088);//ifInErrors
return actualBytesTransferred;
}
vadimuzzz
Nov 26 2009, 10:03
1. char buf2[1560]; - должен иметь квалификатор volatile, иначе компилятор может наоптимизировать, что без поллитры не разберешься.
2. почему
1, // don't read from constant address - в оригинале 0. по логике тоже д.б. 0
3.
Цитата
desc->read_burst = 128;
desc->write_burst = 128;
это зачем?
4. char buf2[1560] надо сделать глобальной переменной, иначе неясно, что произойдет при выходе из raw_send(функция не дожидается окончания передачи пакета)
5. tse_mac_sTxWriteM(desc) - код не меняли? таймаут сколько стоит?
6. код инициализации MAC/PHY тоже выкладывайте.
7.
Код
sgdma_tx_dev = alt_avalon_sgdma_open("/dev/sgdma_tx");
if(!sgdma_tx_dev) {
dprintf("[triple_speed_ethernet_init] Error opening TX SGDMA\n");
return ENP_RESOURCE;
}
не забыли?
хотя по п.4 наврал, там синхронная передача вроде. но все равно, глобальная лучше для отладки.
vadimuzzz
Nov 26 2009, 10:15
для полноты картины еще содержимое регистров MAC/PHY после инициализации. ну и контроллеров dma после сброса.
да, еще чему равно (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE/*mi->tx_sgdma->base*/) в
Код
while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE/*mi->tx_sgdma->base*/) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ) {
if(timeout++ == ALTERA_TSE_SGDMA_BUSY_TIME_OUT_CNT) {
//tse_dprintf(4, "WARNING : TX SGDMA Timeout\n");
return 0;//error//ENP_RESOURCE; // avoid being stuck here
}
}
Так, микросхему не настраиваю и только читаюб регистры:
0 - контрольный - 0х1140
1 - статус - 0х7969
После мас инициализации следующие данные:
контрольного регистра 0х00008213
По дма:
контроль - 0
IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE/*mi->tx_sgdma->base*/) - 0
vadimuzzz
Nov 26 2009, 13:46
Цитата(dim99 @ Nov 26 2009, 16:42)

После мас инициализации следующие данные:
контрольного регистра 0х00008213
1. включена опция замены MAC-адреса в пакете, нужно сконфигурировать mac0 и mac1
2. включен loopback - зачем?
Цитата(vadimuzzz @ Nov 26 2009, 16:46)

1. включена опция замены MAC-адреса в пакете, нужно сконфигурировать mac0 и mac1
2. включен loopback - зачем?
mac0 и mac1 вроде правильно настроены, потому чот пакет принимаемый на компе содержит mac адрес правильный.
loopback уже от нечего делать включал, вдруг заработает )
пытался вручную HW_OWN_BY выставить на 0 чтобы не формировалась ошибка дескриптора, в итоге пакет не отправился.
vadimuzzz
Nov 26 2009, 14:11
Цитата(dim99 @ Nov 26 2009, 16:42)

1 - статус - 0х7969
бит 2 не установлен - линк отсутствует
Цитата(dim99 @ Nov 26 2009, 16:42)

По дма:
контроль - 0
IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE/*mi->tx_sgdma->base*/) - 0
странно, а в какой момент взводится сигнал BUSY? изначально ведь 0. и еще про сброс dma:
Цитата
Software can reset the core by writing to this bit twice. Upon the
second write, the core is reset. The logic which sequences the
software reset process then resets itself automatically.
обратите внимание на слово
twice (это из мана по dma)
Цитата(vadimuzzz @ Nov 26 2009, 17:11)

обратите внимание на слово twice (это из мана по dma)
Так вроде использую SGdma или он использует ядро dma?
vadimuzzz
Nov 26 2009, 14:43
Цитата(dim99 @ Nov 26 2009, 20:23)

Так вроде использую SGdma или он использует ядро dma?
sgdma, конечно. 5-й том, глава 21
Может вручную попробовать создать дескриптор?
vadimuzzz
Nov 27 2009, 06:42
ошибку со сбросом sgdma исправили? что сейчас в регистрах после сброса? в какой момент взводится сигнал BUSY в контроллере sgdma? линк появился в PHY Status? код последний выложите.
Цитата(dim99 @ Nov 27 2009, 12:08)

Может вручную попробовать создать дескриптор?
дело не в дескрипторе, а в том, что устройство занято. вопрос в том, в какой момент после сброса это происходит. в отладчике пускаете?
Цитата(vadimuzzz @ Nov 27 2009, 09:42)

ошибку со сбросом sgdma исправили? что сейчас в регистрах после сброса? в какой момент взводится сигнал BUSY в контроллере sgdma? линк появился в PHY Status? код последний выложите.
дело не в дескрипторе, а в том, что устройство занято. вопрос в том, в какой момент после сброса это происходит. в отладчике пускаете?
что-то не могу понять смысл установки этого бита.
Цитата
4 BUSY R/C (1)(3)) Indicates that descriptors are being processed;
the linked list of descriptors is not yet completed.
(1) This bit must be cleared after a read is performed. Write one to clear this bit.
(3) This bit is continuously updated by the hardware.
Этот бит показывает, что дескрипторы обрабатываются или создаются
список дескрипторов еще не готов.
1) бит должен быть очищен после того, как операция чтения выполнена. для очистки запишите 1
3) этот бит постоянно обновляется железом.
то есть 0 это занятое устройство?
как тогда его освободить?
vadimuzzz
Nov 27 2009, 13:24
этот бит взводит функция alt_avalon_sgdma_construct_mem_to_stream_desc()
Цитата
This function constructs a single SG-DMA descriptor in the memory specified in
alt_avalon_sgdma-descriptor *desc for an Avalon-MM to Avalon-ST transfer. The
destination (write) data for the transfer goes to the Avalon-ST interface connected to the SG-DMA
controller's streaming write port. The function sets the OWNED_BY_HW bit in the descriptor's control
field, marking the completed descriptor as ready to run. The descriptor is processed when the
SG-DMA controller receives the descriptor and the RUN bit is 1.
пожалуй, плохая идея вызывать функцию так
Код
alt_avalon_sgdma_construct_mem_to_stream_desc(
(alt_sgdma_descriptor *) desc, // descriptor I want to work with
(alt_sgdma_descriptor *) desc,// pointer to "next"
(alt_u32 *) ActualData, // starting read address
(length), // # 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)
указатель на "next" д.б. другим (нужен еще один дескриптор).
вот почему:
Цитата
The function sets the OWNED_BY_HW bit in the descriptor's control field, marking the completed
descriptor as ready to run. The descriptor is processed when the SG-DMA controller receives the
descriptor and the RUN bit is 1.
The next field of the descriptor being constructed is set to the address in *next. The
OWNED_BY_HW bit of the descriptor at *next is explicitly cleared. Once the SG-DMA completes
processing of the *desc, it does not process the descriptor at *next until its OWNED_BY_HW bit is
set. To create a descriptor chain, you can repeatedly call this function using the previous call's
*next pointer in the *desc parameter.
OWNED_BY_HW =1 значит, что дескриптор готов к обработке устройством и можно вызывать, например, alt_avalon_sgdma_do_sync_transfer(). второй дескриптор смысловой нагрузки не несет, затычка, но память под него выделить надо.
Цитата
This bit determines whether hardware or software has write access
to the current register.
When this bit is set to 1, the core can update the descriptor and
software should not access the descriptor due to the possibility of
race conditions. Otherwise, it is safe for software to update the
descriptor.
Попробую сделать нормальный next descriptor и отправить.
Попробовал сделать второй нормальный дескриптор:
определил его:
alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE;
alt_sgdma_descriptor *currdescriptor_ptr = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE + 10;
и запустил debug:
дошел до
alt_avalon_sgdma_construct_mem_to_stream_desc( //&transmit_descriptors[buffer_counter]
/*(alt_sgdma_descriptor *)*/ &desc[0], // descriptor I want to work with
/*(alt_sgdma_descriptor *)*/ &currdescriptor_ptr[0],// pointer to "next"
(alt_u32 *) ActualData, // starting read address
(length), // # 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
Нажмите для просмотра прикрепленного файла int desc_stat=1;
desc_stat = alt_avalon_sgdma_check_descriptor_status(desc);//if 0 then packet is good
Нажмите для просмотра прикрепленного файлапонятное дело пакет пошел нулевым.
vadimuzzz
Nov 30 2009, 08:05
Цитата
alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE;
alt_sgdma_descriptor *currdescriptor_ptr = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE + 10;
а смещение не маловато будет? сколько размер дескриптора? код еще выложите с последними правками, в памяти освежить. да, еще перед вызовом alt_avalon_sgdma_construct_mem_to_stream_desc поставьте чтение статус-регистров в sgdma, что там?
upd: лучше писать вот так:
Код
alt_sgdma_descriptor *currdescriptor_ptr = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE + sizeof(alt_sgdma_descriptor);
alt_u32 sgdma_res = 0;
sgdma_res = IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE);
Пишет 0 после прохода.
После формирования та же ошибка в dec = -119
Нажмите для просмотра прикрепленного файла
vadimuzzz
Nov 30 2009, 10:03
по поводу "ошибки 119" это не баг, это фича:
alt_avalon_sgdma_construct_mem_to_stream_desc() взводит бит OWNED_BY_HW у текущего дескриптора, а alt_avalon_sgdma_check_descriptor_status() в этом случае возвращает не 0 :
Цитата
Returns 0 if the descriptor is error-free, not owned by hardware, or a previously requested transfer
completed normally. Other return codes are defined in errno.h.
копаем дальше - tse_mac_sTxWriteM(desc);
предлагаю вариант с дескрипорами как в альтеровском драйвере
Код
alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE;
alt_sgdma_descriptor *currdescriptor_ptr;
alt_sgdma_descriptor *nextdescriptor_ptr;
...
currdescriptor_ptr = &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST];
nextdescriptor_ptr = (alt_sgdma_descriptor *) IORD_ALTERA_TSE_SGDMA_DESC_NEXT(currdescriptor_ptr);
currdescriptor_ptr->status&=~ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK;
...
alt_avalon_sgdma_construct_mem_to_stream_desc( //&transmit_descriptors[buffer_counter]
/*(alt_sgdma_descriptor *)*/ &desc[0], // descriptor I want to work with
/*(alt_sgdma_descriptor *)*/ &desc[1],// pointer to "next"
(alt_u32 *) ActualData, // starting read address
(length), // # bytes
0, // don't read from constant address
1, // generate sop
1, // generate endofpacket signal
0);
vadimuzzz
Dec 1 2009, 09:31
пытаюсь воспроизвести на своей плате. пока передачи нет, подвисает на вызове alt_avalon_sgdma_do_sync_transfer(). а пакеты с нулями идут. MAC их сам отправляет. это для управления бриджами.
хехе, получилось

заменил вызов alt_avalon_sgdma_do_sync_transfer() следующим кодом:
Код
IOWR_ALTERA_AVALON_SGDMA_CONTROL (TX_SGDMA_BASE/*mi->tx_sgdma->base*/, 0);
IOWR_ALTERA_AVALON_SGDMA_STATUS (TX_SGDMA_BASE/*mi->tx_sgdma->base*/, 0xFF);
// Start SGDMA (blocking call)
IOWR_ALTERA_AVALON_SGDMA_NEXT_DESC_POINTER(TX_SGDMA_BASE,(alt_u32) txDesc);
IOWR_ALTERA_AVALON_SGDMA_CONTROL (TX_SGDMA_BASE,
ALTERA_AVALON_SGDMA_CONTROL_RUN_MSK|
ALTERA_AVALON_SGDMA_CONTROL_STOP_DMA_ER_MSK|
IORD_ALTERA_AVALON_SGDMA_CONTROL(TX_SGDMA_BASE));
while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(TX_SGDMA_BASE/*mi->tx_sgdma->base*/) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ) {
}
IOWR_ALTERA_AVALON_SGDMA_CONTROL(TX_SGDMA_BASE,
IORD_ALTERA_AVALON_SGDMA_CONTROL(TX_SGDMA_BASE)&~ALTERA_AVALON_SGDMA_CONTROL_RUN_MSK);
и вуаля
upd: нашел ошибку у себя - sgdma_tx_dev = alt_avalon_sgdma_open("/dev/tx_sgdma"); возвращала 0 из-за опечатки, исправил, теперь alt_avalon_sgdma_do_sync_transfer() пашет, пакеты идут. на всякий случай код в аттаче.
Попытался предыдущим способом сделать - та же песня.
Завидую вам, что получилось )
Спасибо за аттач, в ближайшие дни попробую, пока готовлюсь к конференции, времени практически нет =/
Появился срочный вопрос, есть ли возможность прошить flash без max II?
появится собственная плата, на которой нет max II но soft проект хотелось бы хранить на flash.
Посмотрел есть вохможность вроде бы через parallel flash loader заливать проекты, но пока что вижу только pof и sof, а нужен именно flash.
Может быть есть конвертер по типу sof2flash только наоборот flash2sof?
vadimuzzz
Dec 7 2009, 15:36
maxii - это распаянный на плате USB-blaster, он не подключен к FLASH. подключен он к циклону через JTAG. FLASH шьется при помощи PFL (см. AN478). соответственно, плате д.б. JTAG, этого достаточно для всего. см. также cyclone3-handbook, стр. 9-33.
Пролистал 478, но до конца не разобрался.
На макетной плате прошиваю *.flash через nios ide.
теперь на новой не dev kit плате хочу прошить тот же *.flash, чтобы с флэшки грузился soft проекта.
Jtag на ней есть.
PFL шьет pof, как я понял.
Что для прошивки *.flash надо?
vadimuzzz
Dec 8 2009, 01:43
Цитата(dim99 @ Dec 7 2009, 23:37)

Пролистал 478, но до конца не разобрался.
На макетной плате прошиваю *.flash через nios ide.
теперь на новой не dev kit плате хочу прошить тот же *.flash, чтобы с флэшки грузился soft проекта.
Jtag на ней есть.
PFL шьет pof, как я понял.
Что для прошивки *.flash надо?
дык и на новой будете шить через nios-ide. вся разница в том, что usb-blaster(или другой программатор) будет внешний. flash-programmer в nios-ide генерит все pof`ы и что-там-еще-надо, а потом заливает это по цепочке PC->JTAG->Cyclone3(с ядром ниос)->Flash. при самом первом включении зальете sof с ядром ниоса в циклон, после этого спокойно пользуетесь flash-programmer`ом
Огромное спасибо за пояснение.
Продолжил работу с CIII и ethernet.
Разобрался с отправкой пакета. Оказалось необходимо инициализировать массив данных.
Причем радует формат передаваемых данных, когда в отправленном пакете первые 16 байтов используются для служебных нужд - адрес отправителя, получателя и тип протокола.
Возникла другая проблема: при пошаговой отладке пакет успешно отправляется вместе с данными.
Когда пытаюсь пройти до контрольной точки весь процесс - инициализацию PHY, настройку MAC и отправку пакета, то пакет передается без данных.
видимо что-то не успевает подготовиться, пока так и не выяснил, что именно.
Хотя ставил и задержку после инициализации всего, что можно.
Смотрю в wireshark:
пакет без данных - если не инициализировать массив передаваемых данных и когда в run или до контрольной точки через f8 прогоняю
12:22:23,424,452 ETHER
|0 |00|00|00|00|00|00|
00|07|ab|f0|0d|ba|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|0
0|
00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|
где 00 07 ab f0 0d ba mac адрес TSE
пакет с данными - если через debug и f6
+---------+---------------+----------+
12:25:12,769,879 ETHER
|0 |02|03|04|05|06|07|
00|07|ab|f0|0d|ba|0e|0f|10|11|12|13|14|15|16|17|18|19|1a|1b|1c|1d|1e|1f|20|21|22|23|24|25|26|27|2
8|29|
2a|2b|2c|2d|2e|2f|00|00|00|00|00|00|00|00|00|00|00|00|00|00|
Вероятно не поспевает кто-то, может dma...
Сейчас хотелось бы разобраться, почему в run и пошаговой отладке до контрольной точки(f8) не отправляется пакет?
архив с последним софтом прилагается
Нажмите для просмотра прикрепленного файла
vadimuzzz
Jan 27 2010, 17:17
навскидку: похоже на фокусы с кэшами, еще volatile надо бы поставить в объявлении pkt.
надо бы еще по регистрам пробежаться при инициализации, я уже все забыл.
С volatile та же песня.
Причем проверял даже так:
Ставлю контрольную точку после передачи первого пакета и прохожу всю инициализацию - в итоге пакет без данных.
Затем продолжаю в пошаговом режиме и передаю нормальный пакет.
После формирования пакета вызовите функцию alt_dcache_flush - должно помочь.
Для уменьшения накладных расходов выровняйте атрибутами массив(ы) по модулю размера линии кэша данных.
Цитата(vetal @ Jan 27 2010, 21:18)

После формирования пакета вызовите функцию alt_dcache_flush - должно помочь.
Для уменьшения накладных расходов выровняйте атрибутами массив(ы) по модулю размера линии кэша данных.
За alt_dcache_flush спасибо, завтра с утра попробую.
А можно чуточку поподробнее про атрибуты или какая это глава в nios software handbook?
Цитата
А можно чуточку поподробнее про атрибуты или какая это глава в nios software handbook?
Это в документации на GCC : files\gnu-tools\gcc\Variable-Attributes.html
Спасибо vetal.
После доавбления alt_dcache_flush проблема разрешилась.
Теперь пытаюсь написать прием пакета.
Хочу выяснить до конца алгоритм приема пакета.
1. задаем обработчик прерывания alt_avalon_sgdma_register_callback(sgdma_rx_dev,(alt_avalon_sgdma_callback)&tse_sgdmaRx_isr, ... )
2. пришел пакет - обрабатываем в tse_sgdmaRx_isr
2.1 создаем дескриптор для входящего пакета - tse_mac_rcv
2.2 принимаем пакет - tse_mac_aRxRead
Хотелось бы узнать, алгоритм соответствует действительности?
И является ли alt_avalon_sgdma_register_callback тем самым обработчик прерывания или что это такое?
(в примерах на sgdma никакой обработки не было в этой процедуре).
vadimuzzz
Jan 29 2010, 01:39
почти так. собственно обработчик прерывания прячется в недрах HAL,
alt_avalon_sgdma_register_callback регистрирует пользовательский обработчик, он запускается позже.
2.2 tse_mac_aRxRead выполняет асинхронное копирование из FIFO в память, куда указывает дескриптор. т.е. выполнение программы в этом месте блокируется до окончания копирования.
Продолжаю бороться с приемом пакета.
Поставил callback обработку на isr, теперь пытаюсь поймать это прерывание от приходящего пакета.
пингую адрес(192.168.37.5 к примеру), пакет идет как broadcast, загорается led приема, но в isr так и не заходит, хотя ставлю там контрольную точку.
может где-то (кроме callback )необходимо разрешить прерывания?
В примере есть int tse_sgdma_read_init(), не пойму его смысл. В нем формируется дескриптор и сразу идет обработка входящего пакета в независимости оттого. есть он или нет.
Собственно вопросы:
1. Как зайти в обработчик isr?
2. Нужен ли и зачем int tse_sgdma_read_init() ?
вот последний код с полностью рабочей отправкой и хромающим приемом:
Нажмите для просмотра прикрепленного файла
vadimuzzz
Feb 9 2010, 02:18
в обработчик не заходит, потому что само прерывание не сконфигурировано. это и делается в функции tse_sgdma_read_init(), она вызывается после register_callback. в ней формируется дескриптор и регистры DMA. tse_sgdma_read_init() вызывается только в начале, т.к. код, который в ней содержится есть и в обработчике прерывания. в принципе, код tse_sgdma_read_init() можно перекинуть в MAC_Init.
Цитата(vadimuzzz @ Feb 9 2010, 05:18)

в обработчик не заходит, потому что само прерывание не сконфигурировано. это и делается в функции tse_sgdma_read_init(), она вызывается после register_callback. в ней формируется дескриптор и регистры DMA. tse_sgdma_read_init() вызывается только в начале
Добавил read_init после определения isr в register_callback, никакого эффекта.
Уже попробовал определить через alt_irq_register, все равно не заходит.
Уже и irq_enable_all ставил...
В software handbook написано - чтобы зайти в isr поставьте контрольную точку. естественно ставил и не хочет заходить.
Как можно посмотреть генерируется ли это прерывание и почему не заходит?
vadimuzzz
Feb 11 2010, 10:29
давайте содержимое регистров DMA после read_init
стыд-то какой.
нашел своего слона:
в
Код
alt_u32 TseMacRxRead(alt_sgdma_descriptor *rxDesc)
{
alt_u32 sgdma_status_rx = 0;
sgdma_status_rx = IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE);
alt_u32 sgdma_control_rx = 0;
sgdma_control_rx = IORD_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE);
alt_u8 result = 0;
while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ){
}
[b]result = alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, (alt_sgdma_descriptor *) &rxDesc[0]);[/b]
return 0;
}
сначала эта строка была в цикле while и естественно ничего не конфигурировалось....
Ну вот, пакеты отправляю, принимаю.
Единственное, осталось пару вопросов, связанных с приемом:
После инициализации isr, отправляю пару пакетов, затем пингую (одним пакетом) плату и остаюсь навеки в обработчике прерывания(не выходит).
То есть после обработки пакета опять и опять заходит в TseMacSgDmaRxIsr и там остается.
Еще одно интересное замечание:
Код
if((IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK )){
TseMacRxRead([b]desc[/b]);
}
если оставить desc, то данные заносятся в массив pkt, если оставить currdescriptor_ptr, то ничего не записывается.
Причем если стоит desc, то данные записываются в pkt до прерывания. захожу в него а массив уже забит новыми данными, хотя по идее он только после
TseMacRxRead их туда скопирует.
В общем, есть подозрение, что нужно выделить отдельные дескрипторы для приема пакетов.
Решил избавиться от приема всяких broadcast пакетов и отключил promiscious(отвечает за broadcast пакеты)
считываю контрольный регистр tse_mac: cmd_cfg = 0x203
казалось бы пинг не должен проходить и все, что имеет ff в destination, но все равно заходит в isr обработчик.
vadimuzzz
Mar 13 2010, 10:42
Цитата(dim99 @ Mar 12 2010, 20:01)

если оставить desc, то данные заносятся в массив pkt, если оставить currdescriptor_ptr, то ничего не записывается.
Причем если стоит desc, то данные записываются в pkt до прерывания. захожу в него а массив уже забит новыми данными, хотя по идее он только после
TseMacRxRead их туда скопирует.
В общем, есть подозрение, что нужно выделить отдельные дескрипторы для приема пакетов.
а currdescriptor_ptr куда указывает? данные и должны там оказываться раньше, чем прерывание произойдет. дескриптора надо дескрипторов достаточно 2 - по 1 на прием и передачу
Цитата
Решил избавиться от приема всяких broadcast пакетов и отключил promiscious(отвечает за broadcast пакеты)
считываю контрольный регистр tse_mac: cmd_cfg = 0x203
казалось бы пинг не должен проходить и все, что имеет ff в destination, но все равно заходит в isr обработчик.
promiscuous не имеет отношения к broadcast. в нормальном режиме (promisc выключен) броадкасты проходят, это необходимо для работы сети (ARP, например). в неразборчивом режиме принимаются пакеты с другим dest адресом (но не броадкаст). так что отличие только в unicast пакетах.
выкладывайте код
C broadcast вроде разобрался.
Я думал, что процедура приема пакета немного другая:
1.пакет приходит на PHY
2.копируется в FIFO MAC
3. из FIFO MAC по прерыванию пользовательская isr копирует в нужную область памяти
Как же получается так, что до прерывания isr данные попадают в мой массив?
Еще не нравится, что в TseMacReceive не выполняется условие:
Код
if ((desc_stat & ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) )
получается, что и дескриптор для приема не формируется нормальный, а используется тот, который был создан в процедуре отправки,
либо инициализированный в TseMacSgDmaReadInit.
currdescriptor_ptr указывает на дескриптор, в котором адрес для передачи данных = 0, понятно что записи не будет.
Собственно только 1 вопрос, почему не выходит из цикла обработки прерывания, когда получаю пакет(тем более, что пакет 1, а обработка зависает будто их много). Проверял IORD_ALTERA_TSEMAC_RX_SECTION_EMPTY, постоянно = 0.
code attached
Нажмите для просмотра прикрепленного файла
vadimuzzz
Mar 14 2010, 17:32
Процедура приема пакета такая:
1. пакет поступает в PHY, оттуда кидается в MAC
2. FIFO не хранит пакет целиком, может быть даже меньше пакета размером. по сути MAC - устройство с avalon-streaming интерфейсом. вся работа ведется с SGDMA.
3. инициализируется цепочка дескрипторов. SGDMA берет дескриптор и пишет из avalon-streaming в память, которая указана в дескрипторе.
4. по наступлении заданных условий генерируется прерывание (пакет к этому времени уже лежит в памяти, см. п.3)
Теперь по дескрипторам. На текущий момент (вплоть до версии 9.1) длина цепочки дескрипторов в драйвере равна 1. т.е. активный дескриптор всегда один, тот что next - просто заглушка. поэтому тупо забиваем константы (кстати, чему они у вас равны?)
Код
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);
этот код
Код
if ((desc_stat & ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) )
и не может выполниться, он же макросами обложен (а длина цепочки дескрипторов в драйвере равна 1, см. выше):
Код
#if ALTERA_TSE_SGDMA_RX_DESC_CHAIN_SIZE > 1
вот константы для дескрипторов из моего драйвера:
Код
#define ALTERA_TSE_FIRST_TX_SGDMA_DESC_OFST 0
#define ALTERA_TSE_SECOND_TX_SGDMA_DESC_OFST 1
#define ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST 2
#define ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST 3
вот это
Код
rx_section = IORD_ALTERA_TSEMAC_RX_SECTION_EMPTY(sgdma_rx_dev);
- вообще бред, sgdma_rx_dev не имеет никакого отношения к tse_mac. опять же повторюсь, после инициализации mac вся работа ведется
только с sgdma. с дескрипторами порядок наведите, все должно работать. ну и по вашему вопросу: в каком месте в обработчике висит?
Спасибо, разобрался.
Теперь осталось сделать программу управляющую из-под pc.
vadimuzzz
Mar 15 2010, 23:56
Цитата(dim99 @ Mar 15 2010, 22:32)

Теперь осталось сделать программу управляющую из-под pc.
можно на Qt писать:
http://qt.nokia.com/products. там уйма готовых функций для работы с TCP и UDP. и примеров в хелпе вагон.
Появился хороший вопрос:
Отправляю пакеты с pc, естественно посылается еще куча всего (broadcast к примеру), как среди этих всех пакетов отсеять свои?
Понятно, что нужно определить какую-то служебную информацию в пакете, чтоб считать его своим.
И как быть, если нужно обработать или скопировать пришедшие данные, когда уже пришел следующий пакет и возникает прерывание, ведь после него все мои данные от предыдущего пакета сотрутся?
Или нужно выключать dma, а после обработки включать и отсылать пакет на PC с сообщением об успешном приеме, чтобы синхронизироваться.
В общем, не пойму я пока этого процесса, где его можно подсмотреть?
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.