gosu-art 0 November 23, 2012 Posted November 23, 2012 · Report post Почему максимум 0xff00? Да ХЗ, не задумывался, может с большими разрядностями счетчиков (а там похоже 16) скорость просаживается, или еще какие проблемы. Вобщем, раз написано так- так и делал. Я имел в виду, что в доке такую цифру не нашел :rolleyes: Ну вроде начинает получаться: 1. память под дескрипторы и данные alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE; unsigned char* pkt = MEM_RX_BASE 2. создаю дескрипторы alt_avalon_sgdma_register_callback(sgdma_rx_dev,(alt_avalon_sgdma_callback)&tse_sgdmaRx_isr,(alt_u16)ALTERA_AVALON_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK,sgdma_rx_dev); alt_u32 *uncached_packet_payload; uncached_packet_payload = pkt; //(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); while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(S_SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ); uncached_packet_payload = pkt+(256); alt_avalon_sgdma_construct_stream_to_mem_desc( (alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST], // descriptor I want to work with (alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST], // pointer to "next" (uncached_packet_payload), // starting write_address 0, // read until EOP 0); 3. Запускаю последний созданный дескриптор IOWR_ALTERA_AVALON_SGDMA_CONTROL(S_SGDMA_RX_BASE, ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK); desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST].control=128; //выставляю OWNED_BY_HW для первого дескриптора while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(S_SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ); alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST]); условие на прерывание #define ALTERA_TSE_SGDMA_INTR_MASK ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_ERROR_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK В прерывании проверяю ошибки, статусы. в конце делаю if(n_desc==0) { t2=alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]); n_desc=1; } else { alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST]); n_desc=0; } Все работает. Но мне теперь нужно убрать прерывание и что бы SGDMA молотил поток сам по себе. Убираю..., в результате выполняется один дескриптор (п.3) и все, дальше ничего :crying: Как их зациклить друг на друга в бесконечном цикле? Quote Share this post Link to post Share on other sites More sharing options...
alexPec 6 November 23, 2012 Posted November 23, 2012 · Report post В коде долго разбираться, можете чего-то не заметить, вы посмотрите на результат - найдите адрес дескрипторов (dma->buffer_ptrs->buffer_ptrs[0]->desc_base, если несколько буферов, то у каждого дескрипторы посмотрите). На примере mem to stream (под рукой просто был, Ваш по аналогии) такая картинка должна быть (прил). Зеленый - источник(у вас д.б. ноль, зато получатель - не ноль), синий - след. дескриптор, размер - 0xff00, дальше desc_control, desc_status, actual bytes transferred. Нас интересует в основном desc_control (байт красным выделен) - видно, что ВЕЗДЕ owned by HW равно 1 (старший бит), там в первом дескрипторе 84 - четверка генерирует сигнал SOP, в последнем - 81, однерка генерирует EOP, пусть вас это не смущает, т.е. везде desc_control одинаковый. Отображена память под 5 дескрипторов, последний видно что закольцован на первый. Крутится постоянно, это дма на дисплей, без вмешательства и прерываний, только данные в буфере меняю, они на экране отображаются. Почему только в первом-то OWNED_BY_HW? Везде поставьте, должно работать Про 0xff00 - чет сходу тоже не могу найти, когда курил внимательно - точно помню, где-то было сказано. Quote Share this post Link to post Share on other sites More sharing options...
gosu-art 0 November 26, 2012 Posted November 26, 2012 · Report post Почему только в первом-то OWNED_BY_HW? Везде поставьте, должно работать Т.к. после вызова alt_avalon_sgdma_construct_stream_to_mem_desc он автоматом ставит OWNED_BY_HW, а в предыдущем созданном снимает. Во второй тоже пробовал ставить принудительно - ничего :crying: Вот дескрипторы перед запуском: Так же как и было - один выполняется на втором виснет: Если первым запустить другой дескриптор, то зависает сразу :laughing: А теперь самое интересное :santa2: Если поставить брэйкпойнт на alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST]); а потом "продолжить", то все работает как надо В чем дело :blink: ? Quote Share this post Link to post Share on other sites More sharing options...
alexPec 6 November 26, 2012 Posted November 26, 2012 · Report post Чего-то не совсем все ясно, вы, когда дескрипторы уже сформированы, сделайте такой же дамп как я привел, по адресу у вас получается 0x13c40, это ведь первый дескриптор? Ато я вижу bytes to transfer у Вас 0, это же не правильно. Надо в памяти перед запуском смотреть, корка то туда лезет за дескрипторами, а в оболочке ниоса и кривость может какая есть. И бит OWNED BY HW когда обнуляется, во время создания дескрипторов или после транзакции? Если во время создания, то подпилите напильником процедуру создания, я тоже так делал, как раз с этим битом что-то такое было. И с этим do aysnc transfer - он ведь вообще один раз по вашей задумке вызываться должен, если ставим брейк на него, то бесконечно работает дма, не тормозится? Quote Share this post Link to post Share on other sites More sharing options...
gosu-art 0 November 26, 2012 Posted November 26, 2012 · Report post Вот созданные дескрипторы до вызова alt_avalon_sgdma_do_async_transfer(брейкпойнт ща на нем). Жмем "Resume" и все работает. alt_avalon_sgdma_do_async_transfer вызывается 1 раз Теперь перезапускаю систему(в том числе конфигурирую плис) убираю брэйк с async_transfer и ставлю на передаче пакета. После нее, собственно (256 байт), и должен заводится SGDMA_RX. Выполняю функцию: Вроде все норм - 256 байт принял. После этого снова посылаю пакет 256 байт, но теперь он должен обработаться, по идее, другим дескриптором. Оправляю... И ничего, SGDMA завис :crying: больше он работать не будет. Сигнал READY не выставляется, еще к тому же левый адрес выставился 0х00011200 а должен быть 0х00011000, но похоже это от предыдущей транзакции. Может выравнивать чего нужно? Quote Share this post Link to post Share on other sites More sharing options...
alexPec 6 November 26, 2012 Posted November 26, 2012 · Report post Первое что в голову приходит - а почему размер-то передаваемых данных выставлен в ноль (bytes to transfer)? Может из-за нулевого размера не тормозится трансфер и заезжает на область памяти, где переменные какие-нибудь лежат? Косвенно это подтверждается тем что адрес после трансфера меняется - не должно быть. Попробуйте размер корректный выставить. По вашей картинке значение должно лежать по моему в адресе 0x13818-0x1381B (для первого дескриптора). Дальше думать будем если не пойдет... Quote Share this post Link to post Share on other sites More sharing options...
gosu-art 0 November 27, 2012 Posted November 27, 2012 · Report post Первое что в голову приходит - а почему размер-то передаваемых данных выставлен в ноль (bytes to transfer)? Может из-за нулевого размера не тормозится трансфер и заезжает на область памяти, где переменные какие-нибудь лежат? Косвенно это подтверждается тем что адрес после трансфера меняется - не должно быть. Попробуйте размер корректный выставить. По вашей картинке значение должно лежать по моему в адресе 0x13818-0x1381B (для первого дескриптора). Дальше думать будем если не пойдет... Красным я выделил невыполнившийся дескриптор. а ниже со значением 0х100808(запуск начинается с него) это как раз предыдущий, тут все нормально. Что касается с заежанием на область памяти, то я специально сделал отдельную двухпортовую память. Одна сторона SGDMA вторая проц. Даже если превыситься размер буфера, то будет крутится внутри этого порта, только данные испортятся. Но похоже он next дескиптор не прогружает т.к. сигнал READY не выставляется. вот как должно быть, это когда с брэйкпойнтом: Запись начинается с 0x11100. +256 в конце получаем 0х11200. ready находится в неактивном состоянии (прогружается дескриптор, я так понял) и потом поднимается обратно уже с необходимым следующим адресом 0х11000. Вот так все работает. Сейчас же если не ставить брэйк то выполнятся 1 дескриптор который вызываю через do_async и на этом все и заканчивается. READY больше не активен после передачи. Попробую еще в QSYSe собраться 12,1 :rolleyes: Ща пока в SOPC работаю 11,1 Quote Share this post Link to post Share on other sites More sharing options...
alexPec 6 November 27, 2012 Posted November 27, 2012 · Report post И все же, почему количество передаваемых байт в дескрипторе 0? Откуда он берется, не должен быть 0. А в статус-регистре и контрол-регистре после сбоя (когда останавливается ДМА) что лежит? Может ошибка какая, из-за этого и стопорится следующий трансфер? У меня все на Q9.1 сделано. Quote Share this post Link to post Share on other sites More sharing options...
gosu-art 0 November 28, 2012 Posted November 28, 2012 · Report post В общем я тут поковырял alt_avalon_sgdma_construct_stream_to_mem_desc и нашел там такую строчку IOWR_8DIRECT(&next->control, 0, (next->control & ~ALTERA_AVALON_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK)); Т.е сброс OWNED_BY_HW у следующего дескриптора. И поэтому когда я создаю четыре дескриптора(для примера) и у последнего указываю next на пустую заглушку. Все 4 выполняются и происходит останов. Если последний указываю на первый, и вызываю alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[0]); то транзакции вообще не происходит, а если вызвать второй alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[1]); то выполняются 2,3,4 дескрипторы на первом зависает. И даже если принудительно поставить desc[0].control=OWNED_BY_HW_MSK; то все равно ничего не проходит. Причем смотрю дамп памяти дескриптора - бит установлен. В итоге убрал я в этой функции снятие OWNED_BY_HW и все заработало нормально. Но на сколько это правильное решение :1111493779: ? Quote Share this post Link to post Share on other sites More sharing options...
alexPec 6 November 28, 2012 Posted November 28, 2012 · Report post В общем я тут поковырял alt_avalon_sgdma_construct_stream_to_mem_desc и нашел там такую строчку IOWR_8DIRECT(&next->control, 0, (next->control & ~ALTERA_AVALON_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK)); Т.е сброс OWNED_BY_HW у следующего дескриптора. И поэтому когда я создаю четыре дескриптора(для примера) и у последнего указываю next на пустую заглушку. Все 4 выполняются и происходит останов. Если последний указываю на первый, и вызываю alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[0]); то транзакции вообще не происходит, а если вызвать второй alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[1]); то выполняются 2,3,4 дескрипторы на первом зависает. И даже если принудительно поставить desc[0].control=OWNED_BY_HW_MSK; то все равно ничего не проходит. Причем смотрю дамп памяти дескриптора - бит установлен. В итоге убрал я в этой функции снятие OWNED_BY_HW и все заработало нормально. Но на сколько это правильное решение :1111493779: ? Все верно, я об этом и говорил, что во всех дескрипторах в итоге должен стоять в 1 OWNED BY HW. Где ноль - тот не выполняется, транзакция тормозится. Ошибок то при торможении нет? Статусы посмотрите, может тормоз то не из-за дескрипторов возникает, а ошибка какая. PS Хотя если все работает, то... :bb-offtopic: (С) Папа программист в глубокой отладке... Сын подходит: -Папа, а почему солнышко встает? -Встает? -Да -Каждый день? -Да -И не глючит? -Нет -Ради бога ничего не трогай и не меняй!!! Quote Share this post Link to post Share on other sites More sharing options...
gosu-art 0 November 29, 2012 Posted November 29, 2012 · Report post Теперь работает прием и передача (256 байт) без участия проца. Поток идет через гигабитный оптический TSE, правда пока передающее буфера статические, не меняют свои значения. Сбои по СRC и переполнениям отсутствуют. 2 alexPec Спасибо за помощь ! Quote Share this post Link to post Share on other sites More sharing options...
Копейкин 0 January 30, 2013 Posted January 30, 2013 · Report post Прошу подсказать, где ошибся... Использую аналогичный SG-DMA stream-to-memory. QII 9.1sp2 Идея: SG-DMA пишет постоянно из потока в память, дескрипторы (16 шт) закольцованы и нужны прерывания каждые 8 пройденых дескрипторов. Дескрипторы указывают на память, выделенную под область данных в отправляемых далее пакетах. Т.е. память не сплошная, поэтому 16 дескрипторов, по числу пакетов. Пока 8 заполняются, 8 передаются. Такой вот пинг-понг... int AD7760_prepare_sgdma() { ad7760_sgdma = alt_avalon_sgdma_open(SGDMA_1_NAME); // check if( ad7760_sgdma == NULL) { //TRACE_STR("--> Failed to open SG_DMA_1 Stream-to-memory!\r\n"); return (-1); } alt_avalon_sgdma_register_callback( ad7760_sgdma, AD7760_callback, (ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_MAX_DESC_PROCESSED_MSK | (8<<ALTERA_AVALON_SGDMA_CONTROL_MAX_DESC_PROCESSED_OFST) ), NULL); return 0; } Дескрипторы: void AD7760_prepare_loop_descr_chain() { int i; for( i = 0; i<16; i++ ) { alt_avalon_sgdma_construct_stream_to_mem_desc( adchi_desc[i], (i < 15) ? adchi_desc[i+1] : adchi_desc[0], (alt_u32*)pFastPacket[i]->data, // Area in external SRAM FAST_PACKET_BODY_SIZE_BYTES, // in bytes 0 ); // non-fixed write address } adchi_desc[0]->control |= ALTERA_AVALON_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK; // Last-first descriptor } Стартуем void AD7760_start_sgdma() { alt_avalon_sgdma_do_async_transfer( ad7760_sgdma, adchi_desc[0] ); } Функция AD7760_callback() только устанавливает флаги для главного цикла приложения. Проблема в том, что прерывание приходит, но (судя по времени) когда всё кольцо из 16 дескрипторов выполнится 16 раз. Сейчас переделал под обработку одного выполненного дескриптора и процессором отсчитываю 8 прерываний, всё работает но некрасиво, самому не нравится. Где промахнулся,а ??? Quote Share this post Link to post Share on other sites More sharing options...
alexPec 6 January 30, 2013 Posted January 30, 2013 · Report post Где промахнулся,а ??? Прерывание то какое стоит? Судя по вашей задаче должно быть IE_CHAIN_COMPLETED - по завершению цепочки дескрипторов (в вашем случае 2х8). Есть еще IE_DESCRIPTOR_COMPLETED - после каждого дескриптора Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 January 30, 2013 Posted January 30, 2013 (edited) · Report post Дескрипторы указывают на память, выделенную под область данных в отправляемых далее пакетах. Т.е. память не сплошная, поэтому 16 дескрипторов, по числу пакетов. Пока 8 заполняются, 8 передаются. Такой вот пинг-понг... Если далее отправляются Ethernet пакеты то не нужен пинг-понг и прерывания. Нужно организовать всего-лишь задержку начала передачи пакетов после начала заполнения памяти, тоесть после выполнения команды alt_avalon_sgdma_do_async_transfer( ad7760_sgdma, adchi_desc[0] ); Все будет крутиться почти одновременно. Единственное, скорость заполнения должна быть в районе скорости передачи. Если это Ethernet 100Base то скорость заполнения должна быть примерно такая-же Edited January 30, 2013 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
Копейкин 0 January 30, 2013 Posted January 30, 2013 · Report post Acvarif, там всё сложнее. DMA заполняет только часть пакета, правда большую, но часть. Имеется несколько типов пакетов, разной длины, разным адресатам. Пока заполняются данные 8 пакетов этого АЦП, передаются другие 8 пакетов + еще данные других датчиков. Поэтому такая система. Прерывание то какое стоит? Судя по вашей задаче должно быть IE_CHAIN_COMPLETED - по завершению цепочки дескрипторов (в вашем случае 2х8). Есть еще IE_DESCRIPTOR_COMPLETED - после каждого дескриптора Прерывания по количеству выполненых дескрипторов: (ALTERA_AVALON_SGDMA_CONTROL_IE_MAX_DESC_PROCESSED_MSK | (8<<ALTERA_AVALON_SGDMA_CONTROL_MAX_DESC_PROCESSED_OFST) ) т.к. строится зацикленная цепочка дескрипторов и бит PARK установлен, т.е. OWNED_BY_HW не чистится... Quote Share this post Link to post Share on other sites More sharing options...