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

AVR32: AP7000: Image Sensor Interface (ISI)

Пытаюсь подключить к STK1000 цифровую камеру с использованием имеющегося на борту AP7000 Image Sensor Interface (ISI). Не совсем понимаю, как переключать буферы, в которые будут писаться видеокадры.

Далее нужно вывести на LCD то, что в этих самых буферах находится с использованием встроенного LCD-контроллера (LCDC).

 

Может кто-нибудь подскажет, как вообще обрабатывается видеоинформация с использованием нескольких буферов.

Изменено пользователем Busel Roman

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может кто-нибудь подскажет, как вообще обрабатывается видеоинформация с использованием нескольких буферов.

Скажем, два буфера. Пока в первый пишутся данные с камеры, со второго выводится изображение на ЖКИ. При заполнении камерой первого буфера, она переключается на второй буфер, начиная его заполнять, а на ЖК выводится свежеснятое изображение из первого буфера... И так по циклу туда-сюда :)

Правда про AVR32 подсказать не могу - реализовано там это аппаратно или надо самому следить за переключением буферов...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скажем, два буфера. Пока в первый пишутся данные с камеры, со второго выводится изображение на ЖКИ. При заполнении камерой первого буфера, она переключается на второй буфер, начиная его заполнять, а на ЖК выводится свежеснятое изображение из первого буфера... И так по циклу туда-сюда :)
Я себе так все и представлял, но в AP7000 такой прикол:

 

В ISI есть регистр, хранящий адрес ячейки памяти, где находится адрес буфера. То есть, в этом регистре хранится указатель на буфер. При заполнении первого буфера, указатель инкрементируется на 32 бита и указывает уже на адрес второго буфера. Соответственно, адреса всех буферов нужно предварительно записать в соответствующие ячейки памяти. Интересно, что нигде не указывается, сколько всего используется буферов.

 

В LCDC есть только один регистр, в котором сразу указывается адрес единственного буфера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заглянул сейчас в даташит, вроде бы там все расписано под Вашу задачу :).

LCD: читаем стр. 735 - 35.9 Double buffer Technique

В общих чертах: изначально задаем в DMA-регистре адрес первого буфера, запускаем интерфейс LCD, по прерыванию End Of Frame меняем в DMA-регистрах адрес буфера на второй буфер. Следующий цикл DMA уже пойдет из второго буфера.

ISI: читаем стр. 783 - 36.4.4.4 FIFO and DMA Features (Prewiev Patch)

В общих чертах: создаем связанный список (linked list) описателей буферов (FBD - Frame Buffer Descriptors) - два, три, сколько угодно, указываем в DMA-регистре адрес первого FBD и запускам ISI. Все, он автоматически будет писать фреймы поочередно во все эти буфера.

 

При заполнении первого буфера, указатель инкрементируется на 32 бита

Нет, он не тупо инкрементируется, он берет адрес следующего буфера из описателя текущего буфера :).

Соответственно, адреса всех буферов нужно предварительно записать в соответствующие ячейки памяти.

Естественно, нужно сначала подготовить описатели всех буферов и зарезервировать соответственно память под сами буфера.

Интересно, что нигде не указывается, сколько всего используется буферов

Сколько Вашей душе пожелается :). И на сколько хватит памяти, естественно :).

 

В LCDC есть только один регистр, в котором сразу указывается адрес единственного буфера.

Вот его и меняем после каждого кадра по прерыванию...

Естественно, что частоту фреймов ISI и LCDC необходимо синхронизировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо тебе, добрый человек!

Когда первый раз читал datasheet на LCDC пару месяцев назад, как-то упустил из виду этот пункт - наверное, подумал, что это относится к "2D Memory Addressing". Теперь стало еще понятнее.

 

А как думаете, зачем проверять регистр DMAFRMPTх на наличие достаточного количества времени на изменение DMA Base Address Register, ведь можно просто изменять его по приходу прерывания End Of Frame?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как думаете, зачем проверять регистр DMAFRMPTх на наличие достаточного количества времени на изменение DMA Base Address Register, ведь можно просто изменять его по приходу прерывания End Of Frame?

Там просто описано два варианта: один без прерывания, проверяя достаточно ли времени для апдейта регистра, второй с использованием прерывания. И это в основном относится к панелям с двойным сканированием (Dual Scan Panels), когда надо апдейтить оба указателя буферов одновременно :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вот такой вопрос:

 

Как в С получить численное значение адреса, хранящегося в указателе. Дело в том, что в регистр ISI PPFBD (поле PREV_FBD_ADDR) необходимо записать фактический адрес первого дескриптора кадрового буфера в формате integer.

 

Как я понимаю, значение одного указателя можно присвоить другому указателю, если указатель-приемник указывает на тот же тип данных, что и указатель-источник.

Изменено пользователем Busel Roman

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

char *buf; // указатель

int adr=(unsigned int)buf; // получаем значение указателя

 

int *pInt=(int*)buf; // приводим указатель к типу int*

Изменено пользователем dimitryl

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как можно установить определенный диапазон адресов для значений указателя? То есть, чтобы определенный указатель мог указывать только на память, например, с адреса 0х10000000 по 0х20000000.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Указатель это просто переменная, если нужно чтоб он не выходил за определенные границы - его надо контролировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Указатель это просто переменная, если нужно чтоб он не выходил за определенные границы - его надо контролировать.
Я и спрашиваю, как сказать указателю, чтобы он адресовал только определенный участок памяти? Например, я хочу, чтобы кадровые буферы у меня находились во внешней SDRAM, а остальные переменные хранились во внутренней SRAM.

 

Не буду же я каждый раз создавать новый указатель, если только что созданный указатель адресует не ту область оперативной памяти. И так до тех пор, пока не будет создан "правильный" указатель.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Самый простой способ - статически выделить память под эти буфера.

 

в случае динамического выделения памяти из кучи (как у вас, если я правильно понял) нужно будет переписывать фукции работающие с памятью (malloc/calloc/new....).

 

Установить какие-либо определенные границы для указателя нельзя(.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Самый простой способ - статически выделить память под эти буфера.
Если не трудно - кусок кода приведите, в общих чертах.

 

А вообще, как в С организовать доступ к требуемому типу памяти - SRAM, SDRAM, FLASH, если они имеют каждая свой диапазон адресов? Например, как записать конкретное целое число в конкретную ячейку SDRAM?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У каждого типа памяти свое заранее известное адресное пространство.

Во-первых, Вы можете указать статической переменной (тому же буферу) абсолютный адрес, по которому она должна располагаться оператором @. Например:

__no_init unsigned int LCD_BUFFER1[1024] @ 0x20000000
__no_init unsigned int LCD_BUFFER2[1024] @ 0x20000400

Этот примр создаст две статических переменных - массивы по 1024 беззнаковых интовых значений.

А во-вторых можете указать не конкретный адрес, а только сегмент, внутри которого линкер уже сам выберет место размещения:

__no_init unsigned int LCD_BUFFER1[1024] @ "SDRAM_SEGMENT"
__no_init unsigned int LCD_BUFFER2[1024] @ "SDRAM_SEGMENT"

Это создаст две статические переменные - буфера - в сегменте SDRAM_SEGMENT по адресу, выбранному линкером.

 

Для ограничения адресного пространства Вы можете просто определить свой сегмент с заданными адресными границами и при создании переменных указывать его.

 

Это все справедливо для IAR ARM, но нечто подобное должно быть и в других средах. Смотрите хелп на компилятор, раздел наподобие "Controling data placement in memory" :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Программирую в среде AVR32Studio. Она использует GCC.

 

Кто знает, направьте, куда смотреть, какие файлы содержат описание "Controling data placement in memory"?

 

А также, где найти какие и как в GCC применяются директивы (может дополнительные знаки, типа @) при управлении распределением памяти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...