Перейти к содержанию
    

ilyaprok

Участник
  • Постов

    43
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о ilyaprok

  • Звание
    Участник
    Участник
  1. вот это место я не понял: Вы не можете просто инвертировать сигнал vsync, посмотрите еще раз вот эту диаграмму, которую я приводил ранее: считайте, что этот двухмерный прямоугольник в виде кадра с камеры, ядро пересылает построчно слева направо, сверху вниз. я это вижу примерно так, может ошибся где, но суть в том, что active video - это не инверсия от vsync, как у вас
  2. У VDMA все стандартно в плане подключения сигналов, поэтому ошибки могут быть на стороне софта (то есть настройки в регистрах). Сами сигналы приходящие на VDMA желательно проверить, должен быть импульс в начале кадра TUSER, импульсы TLAST - в конце строк, так же TVALID и TREADY согласно документам на AXI-STREAM. Есть еще моменты в настройки самих ядер в Vivado, размеры буферов FIFO, ширина шин и т.д. Их нужно устанавливать исходя из скорости потока камеры и размера кадра, я бы ставил по максимуму буферы первое время, но тут я не уверен, надо поиграться. Дальше можно просто посмотреть что происходит на S2MM, главное чтобы что то было. Используйте тот код, что я кидал, только адаптируйте под параметры вашего кадра, там ошибка была в //Инициализируем AXI VDMA RegVal = Xil_In32(XPAR_AXI_VDMA_3_BASEADDR + 0x30); RegVal = RegVal | 0x108B; Xil_Out32(XPAR_AXI_VDMA_3_BASEADDR + 0x30, RegVal); надо вместо XPAR_AXI_VDMA_3_BASEADDR юзать XPAR_AXI_VDMA_0_BASEADDR. прочитайте кусок памяти командой чтения из предыдущего сообщения
  3. Напрямую, в нынешней версии SDK нет XMD консоли, щас там что то другое, не помню абривеатуру (что то типа XSCT). немножко другой синтаксис. команда чтения памяти и запись в файл выглядит так, как пример (0x01000000 360960 - это адрес и кол-во байт соответственно) mrd -bin -file "D:/Programming/ZYNQ/logs/mem22.raw" 0x01000000 360960
  4. Тут не подскажу, но возможно для ядра сигнал active_video требуется нисходящие и восходящие фронты для работы внутренней логики, а не просто константное значение. документ "AXI4-Stream Video IP and System Design Guide" UG934, там прописаны какие сигналы подавать на ядро. для видео - либо hblank vblank, либо vsync hsync. В моем случае были ~hblank ~vblank, поэтому vsync hsync я просто заземлил. Сигнал active_video должен быть в любом случае. во картинка из того документа (она есть в моей теме) Я железо дебажу немного по-другому вот как тут: видеоурок
  5. Да правильно Вы завели прерывание от VDMA? Еще нужно очистить кеш по адресу принятого кадра и подождать милисекунд 100, чтобы наверняка, дальше можно читать память как вы делали. А вообще для начала надо понять - приходит ли вообще что-нибудь в VDMA, дальше смотреть, работает ли сам VDMA, а потом только смотреть в память. То есть проследить всю цепочку от источника до пункта назначения. Как я делал: У меня были проблемы на хардварном уровне, на параллельном интерфейсе камеры - сигнал PIXCLK имел резкие фронты, которые порождали высокие гармоники, из-за чего было воспринято большее кол-во фронтов, чем ожидалось. (лечилось индуктивностью на этом сигнале, зарезались высокие гармоники), то есть желательно смотреть осциллографом все сигналы с камеры. Не должно быть сильно заваленных фронтов или сильных колебаний на фронтах. Дальше в Vivado посмотреть с ila сигналы приходящие в само ядро Video In To AXI4-Stream, проверить соответсвуют ли сигналы документам на камеру (длительности, кол-во тактов), желательно проследить несколько раз,в разных местах кадра. Если на этом этапе все хорошо, значит первое звено цепочки можно вычеркивать. Проверить как подключены сигналы из камеры к ядру, мне пришлось лепить несколько логических функция (И, НЕ) для сигналов active video и hblank, vblank, так как камера выдавала инвертированные сигналы. Дальше посмотреть какой Stream генерит ядро, тоже с помощью ila, сигналы TLAST, TUSER, TVALID, TREADY. Дальше посмотреть что генерит VDMA, там достаточно наличие хоть какой то деятельности. Проверить всю настройки VDMA, софтварную и хардварную. Проверить прогу, чтобы кеш успевал обновляться. По-началу тоже были проблемы. Я делал так, перед тем как поменять, удалить какие то сигналы из дебага, я очищал файл констрейтов, где прописаны все дебажные сигналы и ядра ila. дальше в схеме синтеза заново отмечал, создавал ядро ila, синтезировал. Вот мне добрый человек подсказал, из-за этого тоже могут быть проблемы: https://electronix.ru/forum/index.php?s=&am...t&p=1530631
  6. Вообщем если интересно, то проблема с чтением процем памяти, куда кладется инфа с DMA уже давно известна. Тут предлагается несколько путей решения: 1) отключить кэш полностью, тогда будут проблемы с быстродействием всей программы 2) пометить область памяти, куда кладется буфер кадров - некешируемым, тогда пострадает только быстродействие доступа к этому кадру 3) вручную очищать кэш при поступлении новых данных от DMA, перед чтением. (Тут лучше вместо VDMA юзать DMA, тогда при поступлении новой строки, очищаем кеш именно этой строки и таким образом когда последняя строчка будет получена - весь кадр будет закешериван с минимальной задержкой. Однако возрастает нагрузка на проц, так как придется обрабатывать каждую новую строку кадра. Либо юзать VDMA - тогда при получении всего кадра нужно ждать продолжительное время пока не обновится кэш всего кадра ) 4) Использовать ACP порт, вместо HP. Тогда кэш будет обновляться сам. Но тут надо смотреть за требуемой скоростью передачи, так как ACP медленyее чем HP. Вот ссылка на форум: форум форум2 а также тесты по скорости HP и ACP портов в прикрепленном файле (взял с того же форума, не помню ссылку) acp_faster_then_hp.pdf
  7. Если еще актуально 1) не нужно, главное правильно для вашей камеры определить настройки ядра, и подключить сигналы шины vid_io_in согласно документации на это ядро и документации на камеру. Также не забыть притянуть сигналы vid_io_in_ce, aclken, axis_enable к "1". 2) я напрямую с регистрами работал: //Сбрасываем ядро AXI VDMA RegVal = 0x04; Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, RegVal); RegVal = 0; //Дожидаемся окончания сброса ядра while(RegVal & (1 << 2)) { RegVal = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x30); } //Сбрасываем флаг прерывания RegVal = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x34); RegVal = RegVal | 0x1000; Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x34, RegVal); //Инициализируем AXI VDMA RegVal = Xil_In32(XPAR_AXI_VDMA_3_BASEADDR + 0x30); RegVal = RegVal | 0x108B; Xil_Out32(XPAR_AXI_VDMA_3_BASEADDR + 0x30, RegVal); // VDMA Interrupt Init status = XScuGic_Connect(IntrC, XPAR_FABRIC_AXI_VDMA_0_S2MM_INTROUT_INTR, (Xil_InterruptHandler)DMA_TransferEnd_Handler, NULL); if (status != XST_SUCCESS) { return XST_FAILURE; } XScuGic_SetPriorityTriggerType(IntrC, XPAR_FABRIC_AXI_VDMA_0_S2MM_INTROUT_INTR, 0, 3); XScuGic_Enable(IntrC, XPAR_FABRIC_AXI_VDMA_0_S2MM_INTROUT_INTR); //адрес первого кадра Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, ptrBufFrame); //адрес второго кадра Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+4, ptrBufFrame+752*480); //адрес третьего кадра Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+8, ptrBufFrame+2*752*480); //параметры кадра Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 752); Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 752); Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 480); #define BUF_NUMBER_FRAME 3 uint8_t ptrBufFrame[752*480*BUF_NUMBER_FRAME]__attribute__((aligned(32))); void DMA_TransferEnd_Handler(void) { u32 RegValue; //Сбрасываем флаг прерывания RegValue = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x34); RegValue = RegValue | 0x1000; Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x34, RegValue); Xil_DCacheFlushRange(((uint32_t)ptrBufFrame + cntFrame*360960), 752*480); cntFrame = (cntFrame + 1)%BUF_NUMBER_FRAME; //делаем с кадром что-то cntIntrDMA++; } 3) попробуйте в Vivado вставить debug ядро и посмотреть что есть на шинах данных между Video In To AXI4-Stream и VDMA. Похожую тему можно посмотреть тут: https://electronix.ru/forum/index.php?showtopic=144296 Но не знаю как делают люди, но у меня проблема с доступом к памяти кадра, так как после получения свежего кадра, процессор читая память на самом деле прочитает данные из кэша, в котором будет мусор либо старые данные, чтобы освежить кэш, нужно использовать функции Xil_DCacheFlushRange либо Xil_DCacheInvalidateRange. В чем разница кстати не понял. однако это занимает время, поэтому свежий кадр можно получить спустя некоторое время (у меня для области 360960 байт - 11 мс). Либо использовать массив для записи в некешируемой области памяти, но тогда с частым обращением к массиву могут быть ощутимы задержки. Короче я так и не понял как решить вопрос с кешем и DMA, как правильно с ними работать, может знатоки ответят?
  8. Да правильное направление. Действительно с RESET было не порядок. Спасибо :) В Vivado подключил порт RESET_PHY, подтянул к PULLUP. Низкий уровень заработал. Буду дальше пытать. Вам большое спасибо, что всегда помогаете)) Да попробую поиграться с инициализацией.
  9. Почему? Этот код не мой - это код из BSP драйвера. Ок, возьму на заметку, спасибо. Но вот циатата из даташита KSZ9031RN "RGMII with 3.3V/2.2V/1.8V tolerant I/O pins" Да Марвел не причем, суть не в том как функция называется, а в том, что в принципе функция низкого уровня XEmacPs_PhyRead не работает. Более того у меня на плате не AR8035, а KSZ9031RN. Нашел код для него: вот не работает. делал как в этом видео, несмотря на то, что там AR8035, в вивадо он ничего не менял: вот А так спасибо все равно
  10. Расскажите поподробнее пожалуйста. Где узнать какой полярностью идет сброс, и где конфигурация этого? Это же стандартный пример, я ничего не менял. По логике - загвоздка где то в Vivado. Но это не точно. Вот скрин портов в Вивадо:
  11. Да до самого протокола я не дошел, надо ж отчего то отталкиваться - взял пример готовый echoserver. То что там TCP - это сейчас не важно. Тут что то на низком уровне не стартует.
  12. Пытаюсь поднять echoserver данный из примеров. Зависает на моменте:. Кабель присоединен. Более того - пока проц не работает - мигают светодиоды на коннекторе ethernet. Как только стартует проц - огоньки пропадают. Не знаю является ли это каким то признаком неисправности. В дебаге выяснил что виснет в функции get_Marvell_phy_speed, а именно зацикливается на моменте: while (1) { XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); if (control & IEEE_CTRL_RESET_MASK) continue; else break; } Более того, выяснил, что функция XEmacPs_PhyRead всегда возвращает 0xFFFF, даже в других местах, везде где она вызывается. Проект пустой, к плате ничего не присоединено. Может кто сталкивался или знает в чем причина?
  13. Спасибо! получил первое изображение: Вам toshas и svedach Большое Спасибо!!!! Я прям рад! Однако вопрос возник - если идет запрос к DRAM памяти сразу несколькими мастерами как будет происходит чтение или запись? Можно например обращаться к памяти в DRAM, пока идет чтение или запись в тот же регион с помощью DMA? А если несколько DMA использовать - как они будут делить доступ? И еще вопрос по поводу глобальных переменных - где они создаются в кеше? какого уровня? И что означает эта функция, зачем очищать кэш? Xil_DCacheFlushRange Я использую по совету svedach Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x48, AddrDst); Xil_DCacheFlushRange(AddrDst, 752); Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x58, 752); И еще получается 480*60=28800 раз в секунду вызывается прерывание по DMA, это же съедает много процессорного времени?
  14. Да настроил,спасибо. С помощью функции XScuGic_SetPriorityTriggerType. Теперь все правильно работает. Остается как то скачать дамп памяти в файл и посмотреть. Пытаюсь через XSCT консоль - но не понимаю. Использую вот такую команду - mrd -bin -file mem.bin 0x01000000 360960. Но не понимаю где этот файл найти, или нужно сначала его открыть, потом записать, потом закрыть. А что за команды?
×
×
  • Создать...