|
CY7C68013A постоянная булочная передача, прога для компа |
|
|
|
 |
Ответов
(15 - 29)
|
Feb 13 2007, 20:03
|

Гуру
     
Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359

|
Извиняюсь, три дня на работе без инета  Посмотрел как сделано в примере "стример" что в комплекте с CyAPI.lib лежит... Сделал усе как там (и как вы говорите) - поток отдельный, очередь из четырех (вполне хватило)... Без проблем принимаю данные на скорости около 10 МБАйт/с, сколько камера и передает, пакеты не теряю (по флагам сморю). Теперь последняя проблема: на компе получаю картинку, но нет синхронизации... Выход вижу такой - по кадровому импульсу контроллер заполняет еще одну точку булочную, а на компе когда дождался приема от этой точки - начинаю ждать приема строк.... Кто бы как сделал?
--------------------
Быть. torizin-liteha@yandex.ru
|
|
|
|
|
Feb 13 2007, 22:00
|
Местный
  
Группа: Свой
Сообщений: 205
Регистрация: 16-10-05
Пользователь №: 9 704

|
Цитата(torik @ Feb 13 2007, 19:03)  Теперь последняя проблема: на компе получаю картинку, но нет синхронизации... Выход вижу такой - по кадровому импульсу контроллер заполняет еще одну точку булочную, а на компе когда дождался приема от этой точки - начинаю ждать приема строк.... Кто бы как сделал? IMHO, проще всего в качестве самой первой точки строки передавать маркерный байт. Таким образом полезный кадр уменьшится на одну точку. Думаю, для видеокамеры это совершенно некритично. Таким образом, самая первая строка передается, например, с маркерным байтом 0xFF или 0x00, а последующие с каким-нибудь другим кодом. У меня так сделано в ультразвуковом сканере. Правда, у меня строк не более 192-х, поэтому я передаю маркерный байт 0xFF для особого М-луча, а для остальных - просто их номера. На приемной стороне я копирую вторую точку на место первой, чтобы число точек в луче осталось 512.
--------------------
MPEG-4 - в массы!
|
|
|
|
|
Feb 14 2007, 22:10
|
Местный
  
Группа: Свой
Сообщений: 205
Регистрация: 16-10-05
Пользователь №: 9 704

|
Цитата(torik @ Feb 14 2007, 18:19)  ыхы - вот только маркерный байт не подет - остальные данные тоже могут быть любыми, т.е. за 300 кБайт кадра встретится не раз любое число... Это не важно. Просто передаешь в каждом пакете только первый байт - маркерный и все. На стороне приемника не задумываясь смотришь на этот первый байт. Если 0xFF - то первая строка (начало кадра), если не 0xFF, то обычная следующая строка. При передаче, конечно, обеспечиваешь, чтобы первый байт был не байтом данных, а именно этим маркерным байтом (т.е. для начала кадра ставишь первый байт в 0xFF, а для всех последующих - в 0x00). Цитата(torik @ Feb 14 2007, 18:19)  И вдогонку - делать синхронизацию путем передачи по еще одной булочной точке пакета из нескольких байт - правильно ли? Не думаю, что правильно. Дело в том, что если применяются две булочные ендпойнты, то нет гарантии, что они передадутся строго в нужном порядке, т.к. булочная передача в принципе не гарантирует время доставки пакета. Используй маркерный байт, не ошибешься :-) Ведь в этом случае ты гарантируешь, что каждый пакет содержит верную информацию о синхронизации (первая это строка, или не первая).
--------------------
MPEG-4 - в массы!
|
|
|
|
|
Feb 15 2007, 13:57
|
Местный
  
Группа: Свой
Сообщений: 205
Регистрация: 16-10-05
Пользователь №: 9 704

|
Цитата(torik @ Feb 15 2007, 10:44)  И остался не решенным вопрос по прерываниям - нет ли какого-нибудь примера реализации прерывания INT0 на СИ? Никаких проблем. Создаешь функцию, например, "INT0_isr" и назначаешь ей вектор прерывания INT0: Код BYTE InterruptCounter = 0;
void INT0_isr(void) interrupt INT0_VECT { // Делаем что-нибудь в прерывании, например, приращаем некий счетчик InterruptCounter++; } Это порождает корректный машинный код: Код ; FUNCTION INT0_isr (BEGIN) ; SOURCE LINE # 373 ; SOURCE LINE # 375 0000 0500 R INC InterruptCounter ; SOURCE LINE # 376 0002 32 RETI ; FUNCTION INT0_isr (END) И все дела. Только нужно не забыть вставить эту функцию в тот файл, где нет прагмы: #pragma NOIV // Do not generate interrupt vectors Иначе вектор прерывания компилятором не будет сгенерирован.
--------------------
MPEG-4 - в массы!
|
|
|
|
|
Feb 15 2007, 14:10
|
Местный
  
Группа: Свой
Сообщений: 205
Регистрация: 16-10-05
Пользователь №: 9 704

|
Цитата(torik @ Feb 15 2007, 10:44)  Тут правда все равно остается проблема - строка равна 640 байт, а PKTEND я не использую, т.е. почти в середине каждой строки будет еще один ненужный байт! (на крайняк придется использовать PKTEND) Кстати, вот эта твоя задача - еще один пример, когда размер ендпойнты желательно иметь больше 512 байт! Я с Сайпресом сейчас переписываюсь по этому поводу. После нескольких банальных ответов, они наконец поняли, что я так просто не отстану :-) Я добился у них информации, что на данной микросхеме можно получить скорость в 20-30 МБ/сек для Interrupt endpoint с размером пакета 1024 байта. Но примера реализации такого режима у них нема. Тогда после нескольких циклов обмена письмами я послал им свои пробные проекты (в CY7C68013A просто непрерывно генерятся пакеты, а на PC крутится приложение Streamer и подсчитывает скорость передачи этих пакетов). Вот уже 9 дней они молчат... Видать, озадачил я их :-) Когда получу ответ - сообщу в форуме, как обещал.
--------------------
MPEG-4 - в массы!
|
|
|
|
|
Feb 15 2007, 19:13
|

Гуру
     
Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359

|
Тэкс, прерывания не спасли  Возможно дело в программе на компутере... Попытаюсь описать проблему: С камеры идут следущие сигналы: - кадровые импульсы на вход INT0, прерывание срабатывает по фронту - данные 8 разрядов идут на FIFO (PORTB, восьмиразрядный режым) - на вход IFCLK идет тактовый сигнал с камеры (передним фронтом тактирует данные) - на вход SLWR подаются строчные (ну почти, там еще гасящие учтены) импульсы, т.е. во время строки (640 байт) разрешается запись в ФИФО. Всего между кадровыми 480 строчных импульсов. Между задним фронтом кадрового импульса и первой строкой примерно 6500 тактов. - еще адрес точки задается равным 10 на выводах FIFOADR0,1 Инициализация в сапрасовском МК следующая: Код void TD_Init(void) { PORTACFG = 1; //PA0 будет входом прерывания от кадров
PORTCCFG = 0; //этот порт в принципе не используется OEC = 0x0b; //так только чтобы флаги выводить на светодиоды IOC = 0x0e;
SYNCDELAY; CPUCS = 0x10; SYNCDELAY; IFCONFIG = 0xcb; //при включении ФИФО внутреннее //тактирование, чтобы хрень не принимать SYNCDELAY; REVCTL = 0x03; // must set REVCTL.0 and REVCTL.1 to 1 SYNCDELAY; SYNCDELAY;
EP1OUTCFG = 0x00; //нас будет интересовать только точка 6 в режыме IN EP1INCFG = 0xb0; SYNCDELAY; EP2CFG = 0xA0; SYNCDELAY; EP4CFG = 0x00; SYNCDELAY; EP6CFG = 0xE0; SYNCDELAY; EP8CFG = 0x00; SYNCDELAY;
FIFOPINPOLAR = 0x04; //для записи - активный высокий, т.к. такие уж строчные SYNCDELAY;
for (i = 0; i < 4; i++) { //хм... хватилобы и один разок FIFORESET = 0x80; SYNCDELAY; FIFORESET = 0x02; SYNCDELAY; FIFORESET = 0x04; SYNCDELAY; FIFORESET = 0x06; SYNCDELAY; FIFORESET = 0x08; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; }
EP2FIFOCFG = 0x0; //эти точки нафиг пока не нужны SYNCDELAY; EP4FIFOCFG = 0x0; SYNCDELAY; EP8FIFOCFG = 0x0; SYNCDELAY;
EP6FIFOCFG = 0x04; //8 разрядов, пока не автаин, чтоб не леза дрянь SYNCDELAY; EP6AUTOINLENH = 0x02; //пакеты по 512 SYNCDELAY; EP6AUTOINLENL = 0x00; SYNCDELAY;
OED = 0xff; IOD = 0xff;
Rwuen = TRUE; // Enable remote-wakeup } Т.е. при включении хоть с камеры уже и идут данные, но мы их не принимаем, отключив внешние такты на ФИФО и точку сделав ручной. По прерываниям от кадрового импульса: Код void INT0_isr(void) interrupt INT0_VECT { PC0 = PC0 ^ 1; //это я так сморю нет ли пропусков кадровых импульсов (нету...)
if (nachalo == 1) { //флаг nachalo выставляется при нажатии кнопки, а сбрасывается при //приходе следующего кадрового импульса SYNCDELAY; FIFORESET = 0x80; //очистить ФИФО SYNCDELAY; FIFORESET = 0x06; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY;
IFCONFIG = 0x03; //вот тут делаем внешние такты (от камеры) и синхронный режим SYNCDELAY;
EP6FIFOCFG = 0x0c; //вот теперь точка стала автаин... пошел прием даных SYNCDELAY; EP6AUTOINLENH = 0x02; SYNCDELAY; EP6AUTOINLENL = 0x00; SYNCDELAY;
nachalo = 0; } else { //в следующем же кадре хватит принимать //чтобы у нас только один кадр был IFCONFIG = 0xcb; //нафиг внешние такты SYNCDELAY;
EP6FIFOCFG = 0x04; //на всякий случай точку в ручной режим SYNCDELAY; EP6AUTOINLENH = 0x02; SYNCDELAY; EP6AUTOINLENL = 0x00; SYNCDELAY;
SYNCDELAY; FIFORESET = 0x80; SYNCDELAY; FIFORESET = 0x06; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; } } Вот, т.е. нажали кнопку установив при этом флаг nachalo, и при приходе кадрового импульса разрешаем передачу данных в течении одного кадра. это 640*480 байт или 600 пакетов по 512 байт. Значицца, как же это принимаю на компе? А вот так (делаю не я, а програмист на компе, лучшеб конечно он объяснил ну да лана): Код dlg->CtrlEndPt->TimeOut = 1500; dlg->InEndPt->TimeOut = 1500; dlg->InEndPt->XferData(buffers[0], len); //вот собственно :) Делали и очередь по приему, как это написано в примере "Стриммер". Вывод на экран правильный, пробовал заменять принятый буфер buffers[0] на чото свое - все норм. И проблема осталась прежней  - картинка разбита на куски. Нет синхронизации ни строчной походу ни кадровой (т.к. разбивается и по вертикали и по горизонтали). Нажимаем кнопку "прием" и сразу же на плате кнопку, которая ставит флаг nachalo... и - пакет принимается не полностью, вроде не сначала. причом что интересно в разбиении картинки имеется повторяемость - примерно каждые 100 пикселей по вертикали разбиватет. Т.е. картинка состоит из 4,8 полосок по вертикали и по горизонтали похоже на то же самое. Что тут может быть не так? Прога для компа или для МК, как отличить???
--------------------
Быть. torizin-liteha@yandex.ru
|
|
|
|
|
Feb 15 2007, 23:08
|
Местный
  
Группа: Свой
Сообщений: 205
Регистрация: 16-10-05
Пользователь №: 9 704

|
Тяжело вот так, дистанционно, понять проблему... Думаю, что стоило бы разбить сложную задачу на более простые части. Например, нет-ли возможности организовать запись с камеры только 512 байт, а оставшуюся часть строки просто отбрасывать? Это позволило бы проверить и отладить синхронизацию. На этапе отладки, думаю, можно мириться с тем, что остаток кадра не виден. Т.е. организовать такой автомат, который пишет строку (указывая в первом байте маркер начала кадра) только до 512-го байта, а остаток отбрасывает. В этом случае можно было бы отработать все моменты системы. А потом, когда все заработает, продумать расширение строки до полных 640 пикселей.
--------------------
MPEG-4 - в массы!
|
|
|
|
|
Feb 16 2007, 15:34
|

Местный
  
Группа: Свой
Сообщений: 330
Регистрация: 10-06-05
Из: Россия, Москва
Пользователь №: 5 894

|
@torik Я тут чего-то не понял?? Вы пытаетесь с помощью микроконтроллера поймать начало кадра и засинхронизировать данные в FIFO???? Если так, то напрасно Вы это затеяли, скорости микроконтроллера НИКОГДА не хватит для этой задачи, тут если только в железе делать, на ПЛИС например... Тем более у Вас в обработчике прерываний SYNDELAY и сбросы FIFO, вообще непонятно, что Вы тогда принимаете, на эти процедуры уходит уйма времени.... Дейстивтельно, поставьте ПЛИС мжеду камерой и FIFO FX2, в ней и сделаете всё что надо
|
|
|
|
|
Feb 16 2007, 18:56
|
Местный
  
Группа: Свой
Сообщений: 205
Регистрация: 16-10-05
Пользователь №: 9 704

|
Цитата(torik @ Feb 16 2007, 14:05)  Как сделать на основе стримера высокий приоритет потоку? Это очень несложно. Вот как поступаю я: Код XferThread = CreateThread(NULL,0,XferLoop,0,CREATE_SUSPENDED,(LPDWORD )&lpThreadId); if(XferThread == NULL) { return false; } if(SetThreadPriority(XferThread,THREAD_PRIORITY_TIME_CRITICAL) == 0) { CloseHandle(XferThread); return false; } if(ResumeThread(XferThread) == -1) { CloseHandle(XferThread); return false; } return true; При этом я четко заметил, что флаг THREAD_PRIORITY_TIME_CRITICAL полностью решает проблему с пропаданием пакетов. Правда, зависит от всего остального. Если на компьютере выполняются другие важные задачи, то пакеты могут пропадать... Тогда нужно принимать более радикальные меры.
--------------------
MPEG-4 - в массы!
|
|
|
|
|
Feb 16 2007, 19:06
|

Местный
  
Группа: Свой
Сообщений: 330
Регистрация: 10-06-05
Из: Россия, Москва
Пользователь №: 5 894

|
Цитата(torik @ Feb 16 2007, 17:26)  А с помощью чего еще ловить начало кадра? По прерыванию от кадрового импульса сбрасываю ФИФО, как без этого...
Щас добились на компе четкого кадра, теперь надо засинхронизироваться с ним. Т.к. я не могу в начале каждой строки вставлять маркер, ведь пакеты то по 512 байт, то думаю передавать по отдельной точке пару байт...
А насчет того что не успевает - у меня же 6500 тактов камеры имеется в распоряжении... А ПЛИСа нету у меня, да и больно дорого станет. Во первых - абсолютно некорректно в обработчике прерывания трогать какие-либо регистры контроллера и, тем более, вводить такты ожидания (SYNCDELAY)! Там должно быть ТОЛЬКО изменения какого-либо флага, по которому в основном цикле уже надо начинать обработку. Во вторых - насколько помню, после сброса FIFO в FX2, надо выждать порядка 100мкс, прежде чем начинать писать туда что либо. В третьих - начало кадра лучше ловить с помощью ПЛИС да и проблема с пакетами исчазла бы сама собой, писали-бы всё в навал... Кстати, для передачи такого потока информации в реальном времени через Bulk EP без внешнего буфера не обойтись, иначе будут потери, внутреннего буфера FX2 просто будет недостаточно, так-что Вам, для нормальной работы Вашего устройства просто необходимо ставить ПЛИС. И что это за 6500 тактов камеры??? Цитата(jur @ Feb 16 2007, 18:56)  Цитата(torik @ Feb 16 2007, 14:05)  Как сделать на основе стримера высокий приоритет потоку? Это очень несложно. Вот как поступаю я: Код XferThread = CreateThread(NULL,0,XferLoop,0,CREATE_SUSPENDED,(LPDWORD )&lpThreadId); if(XferThread == NULL) { return false; } if(SetThreadPriority(XferThread,THREAD_PRIORITY_TIME_CRITICAL) == 0) { CloseHandle(XferThread); return false; } if(ResumeThread(XferThread) == -1) { CloseHandle(XferThread); return false; } return true; При этом я четко заметил, что флаг THREAD_PRIORITY_TIME_CRITICAL полностью решает проблему с пропаданием пакетов. Правда, зависит от всего остального. Если на компьютере выполняются другие важные задачи, то пакеты могут пропадать... Тогда нужно принимать более радикальные меры. Это имеет смысл только на скоростях близких к масимуму (~40МБ/сек) при меньших скоростях, тем более при скорости 10МБ/сек делать такое для того, чтобы не терялись пакеты - просто шаманство  Если пакеты теряются - надо перерабатывать аппаратную часть, вводить дополнительный буфер.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|