flybrain. передатчик + приемник + автопилот. powered by stm32

smalltim
Syberian:

На этом форуме заикнись про коммерцию - сразу банят. А Тимофей процветает почему-то.

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

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

serj

Олег, тебе ж никто не запрещает продавать свои изделия на стороне, а обсуждать подробности алгоритмов- здесь. Как и мне тоже, впрочем 😃

Syberian

[deleted]
Cообщения с №275 и далее надо стереть как офтоп.
Прошу прощения у топик-стартера за разведение свинарника в чужой теме 😁

smalltim

Я не делал каких-то специальных телодвижений для этого, просто слежу за своими словами и не лезу на рожон. Может быть, админы привыкли, я ж здесь с 2007 года железки программирую. А, может быть, реально просто не хотят убивать тему и убирать меня с форума - пользователи останутся без поддержки. В любом случае, админам за это спасибо.

Drinker

Тихо, тихо. Я по коммерческими образцами имел ввиду законченные работающие изделия. Которые не вдаваясь в подробности алгоритмов и без танцев с бубном можно подключать и летать.
Здесь не о торговле идет речь.
Некоторые проекты тут громко начинались, но со временем их ветки умирали.
Особенно те где много было “Я, у меня, не вижу проблем и т.п”

smalltim

Ок. Давайте тогда извинимся перед ТС и в качестве пряника и чтоб загладить вину предложим вариант решения проблемы с правильным временем старта ДМА для вывода видеостроки.
То, что ТС предлагает сейчас, выглядит жутковато.
Мне кажется, надо строчные синхроимпульсы завести на ногу, которая умеет работать как ICP и защелкнуть значение таймера в момент восходящего или нисходящего (по желанию) фронта.
Таймер завести на реально высокую частоту, 36 МГц, например.

Дальше, свалившись в прерывание строчного синхроимпульса, надо еще раз напрямую прочитать значение счетчика таймера и получить разницу. Эта разница, очевидно, будет переменной, ибо прерываний много и гарантии свалиться в прерывание ровно за Х клоков нет. Дальше от этой разницы добить пустым циклом ожидания до какой-то заранее заданной константы, физически означающей смещение накладываемых видеоданных по горизонтали, и уже запускать DMA.

Syberian
smalltim:

Дальше от этой разницы добить пустым циклом ожидания

Самая огромная засада в том, что в АРМ 3 памяти: флешка, срам и кэш. Если пустой цикл дергается внутри кэша, он крутится быстро. Если инструкции подаются из флешки - медленнее от 2 до 3 раз.
Оптимальным был бы аппаратный триггер запуска DMA-трансфера сразу по ССИ. Но синхропаузу и вспышку (8 мкс) придется пропускать путем передачи полезной части видеобуфера, забитой нулями.

Чтобы работало по вашей версии, нужно иметь всего одно прерывание в системе - по ССИ, а остальные хандлить программно уже после команды на ДМА-трансфер. Т.е. минимальное время между раздельными событиями будет фиксированно 64 мкс.

А кто-нибудь вообще мерял время входа в прерывание по таймеру на АРМ? Из собственного печального опыта, на TMS320С6728 с его 1.2 GFLOPS вход в таймерное прерывание занимает целых 7 мкс!

===
Появилась другая идея: вход “одноразового таймера” запараллелить с обычным прерыванием по фронту. Процесс: поступает ССИ, генерирует NMI по ноге и одновременно запускает таймер. Через какое-то неопределенное время включается обработчик NMI, в нем читаем таймер, делаем пропорциональную задержку циклом с чтением таймера и заряжаем DMA.
Профит.
И совершенно фиолетово на загруженность системы.
Таймер можно ставить на 8 МГц, квантование будет незаметным.

project_Ikar
Syberian:

Самая огромная засада в том, что в АРМ 3 памяти: флешка, срам и кэш. Если пустой цикл дергается внутри кэша, он крутится быстро. Если инструкции подаются из флешки - медленнее от 2 до 3 раз.
Оптимальным был бы аппаратный триггер запуска DMA-трансфера сразу по ССИ. Но синхропаузу и вспышку (8 мкс) придется пропускать путем передачи полезной части видеобуфера, забитой нулями.

Чтобы работало по вашей версии, нужно иметь всего одно прерывание в системе - по ССИ, а остальные хандлить программно уже после команды на ДМА-трансфер. Т.е. минимальное время между раздельными событиями будет фиксированно 64 мкс.

А кто-нибудь вообще мерял время входа в прерывание по таймеру на АРМ? Из собственного печального опыта, на TMS320С6728 с его 1.2 GFLOPS вход в таймерное прерывание занимает целых 7 мкс!

Как-то у АВР это дело обстоит проще, может автору часть связанную с осд нужно перевести на АВР и не городить аппаратную видеоразвертку, а сделать программную?..

AlexSneg:

Нет, не секрет. Все электрические схемы текущего рабочего прототипа опубликованы на первых двух страницах темы. Изменений практически никаких внесено не было. Как изначально было задумано в теории, так все на практике и заработало.

Вы уж извините, но не могу разобрать в таком качестве картинку, где там элементы отвечающие за видеомодулятор, может датите ссылку, не сочтите за труд на лучшую картинку, или саму часть осд системы.

project_Ikar
project_Ikar:

Вы уж извините, но не могу разобрать в таком качестве картинку, где там элементы отвечающие за видеомодулятор, может датите ссылку, не сочтите за труд на лучшую картинку, или саму часть осд системы.

удалось наконец-то скачать схему в лучшем качестве. Я так понимаю, видеомодулятор основан на так называемой “диодной схеме”. Вопрос такой, а как дело обстоит с тенями у этого видеомодулятора. Имеется ввиду, что для лучшей читабельности символов, по контуру последних, формируется темные пиксели…?

Syberian
project_Ikar:

видеомодулятор основан на так называемой “диодной схеме”.

как и во всех Е-ОСД-подобных штучках. Или символы на затененных знакоместах, или темный квадрат на все графическое поле, больше никак.
Для получения тени нужно или 1) городить grayscale-буфер, чтобы программно дорисовывать черные пиксели до, после, сверху и снизу, или 2) городить схему затенения, как делал MSV.

AlexSneg
Syberian:

Появилась другая идея: вход “одноразового таймера” запараллелить с обычным прерыванием по фронту.

Олег, я именно так изначально и задумывал. Посмотри на схему. Я завел специально на две ноги. Одна - вход таймера, друга прерывание по фронту. Таймер должен стартовать со своего канала всегда по положительному фронту, а потом спустя неопределенное время мы входим в прерывание. Дальше читаем таймер, который уже стартовал аппаратно и вычисляем паузу. Оно изначально так было задумано, и этот вариант я по прежнему держу в загашнике. Он 100% рабочий. Но я для начала хочу свой вариант на каскадных таймерах опробовать. Я хочу сначала попытаться уйти от софтовых прерываний в процессе развертки видимой части кадра вообще. Вчера я выяснил, что не получится два таймера соединить внутри кристалла штатно, так как получается мне нужно слейв-слейв, а без внешних перемычек получается только мастер-слейв. Пришлось еще один провод тащить внешний. Если бы не это, у меня уже вчера бы все заработало. Сейчас вот каскадная схема на таймерах абсолютно четко генерит окно от начала старта первого таймера с регулируемой задержкой и SPI стартует автоматом в промежутке окна. Я подобрал все тайминги, вывод SPI можно размером окна регулировать с точностью до пиксела, и DMA можно не перезаряжать на каждой строке, достаточно просто первый таймер стартовать и все, больше совсем ничего не надо. Единственный нюанс - последний пиксел в конце каждой строки должен быть обязательно погашен, но это приемлемый побочный эффект, с которым можно спокойно жить, если помнить, что он есть.

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

project_Ikar:

Вопрос такой, а как дело обстоит с тенями у этого видеомодулятора.

Никак, я не собирался в прототипе это городить. В чистовой версии можно завести еще один выход SPI3 до кучи и гнать оттуда тени с задержкой в 1 пиксел. Либо городить схему на дискретных элементах. Сейчас я по простому завел еще диод для уровня серого, чтобы при необходимости как-то воспользоваться.

Syberian:

Оптимальным был бы аппаратный триггер запуска DMA-трансфера сразу по ССИ.

Я уже писал страницу назад, что такая фича вообще сняла бы все проблемы. Но ее нет. DMA в STM работает слейвом. С таймеров DMA умеет только значения регистров брать. Поэтому управлять надо именно запуском SPI в слэйв режиме.

smalltim:

Ок. Давайте тогда извинимся перед ТС и в качестве пряника и чтоб загладить вину предложим вариант решения проблемы с правильным временем старта ДМА для вывода видеостроки. То, что ТС предлагает сейчас, выглядит жутковато.

Смотри мой ответ Олегу, я этот вариант с самого начала в голове держал.
Моя позиция такая - всегда софтово можно извернуться, но это крайний вариант и на него всегда можно перейти. Мне как раз “вставляют” аппаратные решения, разгружающие процессор от ненужной работы.

Syberian:

А кто-нибудь вообще мерял время входа в прерывание по таймеру на АРМ?

Я не мерял, но по косвенным признакам вижу, что документации оно не соответствует. Особенно для варианта, когда прерывание из прерывания отрабатывается. Ты вот еще только начал в STM погружаться, а я год назад начал осваивать. И за этот год сделал один неоспоримый вывод. Доку в STM пишут по остаточному принципу, типа и так сойдет, кто надо тот сам разберется. Что ты там про ноющие зубы писал при инициализации таймера? Ну так вот, как только ты например попытаешься ADC запустить с чтением через DMA и запуском от таймера, или например прерывания какие правильно обработать от периферии, у тебя не просто зубы ныть будут, у тебя появится желание взять молоток и треснуть этот STM посильнее и совсем забыть про него. Могу также предсказать какая истерика у тебя случиться, если ты попытаешься посмотреть в исходники STD Perif Lib, которую они предлагают использовать. АВР в этом отношении просто гладкая и пушистая лапочка.

rual

АлексСнег, у тебя i2c через DMA работает? Как запускаешь старт и передачу адреса?

AlexSneg
rual:

у тебя i2c через DMA работает

Я пробовал через DMA, но в результате остановился на прерываниях. Оно так более контролируемо и предсказуемо. Через ДМА все равно придется работать на прерываниях на фазах старт-адрес-регистр-рестарт. ДМА может работать только в фазах передачи данных или приема. Причем должно быть не менее, чем 2 байта. Короче, овчинка выделки не стоит.

Drinker

Блин, чуваки, не обижайтесь, но эт чет в радиолюбительский форум переростает.
Где полеты по камере и телеметрия?

Довайте обсуждать этапы создания девайса с каким-либо функционалом.

Или не?

rual
Drinker:

Блин, чуваки, не обижайтесь, но эт чет в радиолюбительский форум переростает. Где полеты по камере и телеметрия?

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

Drinker:

Где полеты по камере и телеметрия?

У меня до этого ещё далеко.

Drinker:

Довайте обсуждать этапы создания девайса с каким-либо функционалом

Дык вроде как и речь ведём о реализации некоего функционала.

Drinker
rual:

Дык вроде как и речь ведём о реализации некоего функционала.

Ну вот будет реализовано осд, можно будет обсудить его функционал. А так уже до старт-рестарт dma дошли.

rual:

Если в соседних ветках обсуждают инструмент и способ обработки профиля крыла, то это значит столярный форум?

Именно он.

Довайте результаты уже скорее.

AlexSneg
Drinker:

Ну вот будет реализовано осд, можно будет обсудить его функционал.

Согласен. Давайте подождем, пока я не покажу как OSD работает, потом обсудим, как и что на экране мне нарисовать. Все желающие спросить по узкоспециализированным моментам могут спросить в личку. Я в течение рабочего дня всегда отвечу.

serj
AlexSneg:

. Могу также предсказать какая истерика у тебя случиться, если ты попытаешься посмотреть в исходники STD Perif Lib,.

Туда следует смотреть с целью понять чего вскользь не упомянули в даташите. Хотя перенимать их не стоит- индусам что их писали платили очевидно за каждую строчку кода. инициализация регистров периферии - почти 6 килобайт кода 😃 например чтобы загрузить регистр битрейта usart там строчек 10 написано вместо одной операции деления. А в документации ваще опусы - много воды налито- дробная часть, целя часть- голову сломаешь, вместо того чтобы поделить частоту на битрейт…

Syberian
serj:

чтобы загрузить регистр битрейта usart там строчек 10 написано вместо одной операции деления.

холи щет 😃
Цитатка в тему:
bash.im/quote/416071
(изменено)

Как я обожаю даташиты для STM!
“Это винтик, это отвертка, винтик можно крутить отверткой. Это всякие железяки, их можно соединять винтиками, закрутив отверткой. Еще бывают гайки и шестеренки.
Задание:
Постройте синхрофазотрон.”

AlexSneg

Итак отчетец по борьбе за OSD.
Можно сказать, что теория подтвердилась полностью практикой.
Сейчас мне удалось добиться почти полностью аппаратной развертки всего поля. Работает это примерно так:

  1. Слушаем все прерывания ССИ до обнаружения начала кадра.
  2. Начало кадра обнаружено, пускаем таймер для пропуска 55 строк примерно. прерывания отключаем.
  3. приходит прерывание от таймера. Перезаряжаем таймер на 18 мс, чтобы гарантировано вывалится в новое прерывание и не пропустить кадровый импульс следующего кадра, если что-то пойдет не так. Здесь же заряжаем ДМА на начало видео буфера и запускаем: Таймер, который запускается по фронту следующео ССИ, он генерит точно подобранное окно с задержкой примерно 15мкс и скважностью в которую умещается 32 байта - одна строка; это окно разрешает каскадный таймер, который подает синхру на SPI, работающий слэйвом. SPI заряжен и подключен к DMA каналу, который заряжен на начало видеобуфера.
  4. Дале все происходит автоматом. Все прерывания от ССИ отключены, таймер автоматом ловит очередной фронт на каждой строке и SPI разворачивает одну строку за другой, так до конца ДМА буфера. При этом вмешательства софтового в этот процесс нет никакого. Оно само все происходит.
  5. По окончании ДМА генерит прерывание, в котором отключаем SPI и охранный таймер, заряженный в п.3. Он нам больше не нужен. Его мы перезаряжаем для пропуска примерно 50 строк. Подобрано так, чтобы попасть к началу ожидаемого кадрового импульса
  6. Срабатывает прерывание от таймера, разрешаем прерывания от ССИ и идем на пункт 1

Таким образом, практически все само разворачивается. Качество картинки превосходит все ожидания.
Сделал алгоритмы для засветки пиксела, линии, окружности, знакогенератор прикрутил, попробовал. Ну вообще все шоколадно. Просто в любой момент времени рисуем в видео буфере любые рисунки и даже не думаем ни о чем. Ну как в Spectrum’e в свое время практически было. Можно ради прикола пакмэна организовать. Проц практически полностью освобожден от OSD, я даже прерывания ССИ убрал с самого высокого приоритета на 3-е место. На первом оставил I2C шину.

Побочные эффекты:

  1. Первый пиксел в первом байте строки должен всегда быть нулевым, иначе в текущей схемотехнике это сорвет синхру.
  2. Есть странный сдвиг развертки самой первой линии на 1 знакоместо (8 бит), она получается 31 байт. Не понял почему так. Причем при старте сначала картинка стоит нормально около 3 сек, а затем смещается именно в такое положение и там уже стоит намертво. Пока я не понимаю почему это так. Но все остальные линии разворачиваются четко и без проблем. Фактически достаточно считать, что первая линия не рабочая и начинать рисовать со второй линии, а снизу добавить еще одну. Это совсем не есть проблема, просто первые 31 байт будут балластом. У меня есть подозрение, что первое знакоместо занято нулевыми данными, которые остаются в SPI после окончания предыдущего кадра. Их он как раз и вываливает в новом кадре, а дальше уже идет нормально все. Я еще поковыряюсь с этим делом, засечь причину достаточно сложно даже дебаггером, так как все надо смотреть в риалтайме. Но даже если я не найду почему так, можно с этим спокойно жить. Развертке этот эффект не мешает никак.

На этой неделе буду уже картинку рисовать и сделаю вам видео, на посмотреть как все получилось. Скачал разных видюх с OSD посмотрел в динамике. Пока остановился на на повторении варианта RVOSD. Если есть какие пожелания на тему удобства и недостатков текущих OSD, давайте выкладывайте. Будем думать, как сделать максимально удобно.