Jump to content

    
Sign in to follow this  
khach

STM32G4 QuadSPI + FT810 ftdi EVE LCD controller

Recommended Posts

Добрый день! Вопрос собственно, кто нибудь встречал подключение FTDI-шного LCD контроллера серии FT81x по QuadSPI шине к STM32G4 или подобным контроллерам?

Не хватает свободных ножек на управление LCD контроллером по параллельной шине а по SPI все получается медленно и печально.

В идеале ищу готовую библиотеку. Для FT800 с SPI была, но она по своей философии не позволяет использовать фичи QuadSPI контроллера STM32G c его ремапом на память итд.

Share this post


Link to post
Share on other sites

И как ее присобачить к FTDI FT81x? Если там только последовательные шины. А проблема возникла из за того, что надо перебираться на большой экрана 5 дюймовый с разрешением 800x480- в дешевых контроллера не хватает экранной памяти. И с параллельной шиной давно уже попадали на грабли с невозможностью читать экранный буфер- драйверы шины  LCD контроллера намного слабее драйверов шины FSMC STM32- с заданными таймингами писать в контроллер можно, а вот читать не получаетеся. А надо курсоры рисовать- нужна полная копия экранной памяти в памяти контроллера. А ее мало. А тут по QSPI убивается много зайцев стразу- и быстро, и ножек свободных много у контроллера остается, и шина нормально двунаправленная, и экран с большим разрешением.

Share this post


Link to post
Share on other sites
23 minutes ago, khach said:

драйверы шины  LCD контроллера намного слабее драйверов шины FSMC STM32- с заданными таймингами писать в контроллер можно, а вот читать не получаетеся

Не знаю, не знаю, вот с такими таймингами прекрасно работаю с винстар-модулями (SSD1963), 8-битная шина:

 

Spoiler

    Hardware::FSMC::Timings timings;
    timings.addressSetupTime = 10;
    timings.addressHoldTime = 0;
    timings.dataSetupTime = 10;
    timings.busTurnAroundDuration = 10;
    timings.clockDevider = 0;
    timings.dataLatency = 1;
    timings.accessMode = Hardware::FSMC::MODE_A;
    
    Hardware::FSMC::Settings settings;
    settings.dataWidth = 8;
    settings.waitSignalPolarity = 0;
    settings.isWriteOperationEnabled = true;
    settings.isDataAddressMultiplexed = false;
    settings.isBurstModeEnabled = false;
    settings.isWrappedBurstEnable = false;
    settings.isWaitSignalActiveDuringWaitState = false;
    settings.isExtendedModeEnabled = false;
    settings.isAsynchronousWaitEnabled = false;
    settings.isWriteBurstEnabled = false;
    settings.readWriteTimings = &timings;
    settings.writeTimings = &timings;
    memory.initialize(settings);

 

23 minutes ago, khach said:

А надо курсоры рисовать- нужна полная копия экранной памяти в памяти контроллера.

Ничего подобного, для курсора нужно совсем мало памяти, если курсор не размером с экран конечно )))

Share this post


Link to post
Share on other sites
1 minute ago, khach said:

C winstar иметь дела не пришлось, а вот с SSD1963 работал много, поэтому и хочу заменить на FT810.

Внутри winstar, которые я использую, стоит как раз SSD1963.

 

Share this post


Link to post
Share on other sites
1 hour ago, Vasily_ said:

Наверное уже  лучше менять на BT815-BT816.

Да нет смысла- мне тв картинку показывать на 10 дюймовом дисплее не надо, внешняя память тоже не нужна.  Задача- дисплей измерительного прибора, с весьма хитрыми сетками ( не только декартовыми) и развитой системой курсоров, возможно экранных кнопок на тачскрине.  FT81x младших  (810, 811) вполне достаточно. Вот был бы у BT815-BT816 HDMI выхлоп для внешнего дисплея в дополнение к LCD матрице- тогда возможно имело бы смысл.

1 hour ago, Forger said:

Внутри winstar, которые я использую, стоит как раз SSD1963.

И как вы читали экранный буфер при длине плоского кабеля к дисплею сантиметров 5-10? У нас одно из требований ТЗ - возможность делать полный скриншот.

Share this post


Link to post
Share on other sites
26 minutes ago, khach said:

И как вы читали экранный буфер при длине плоского кабеля к дисплею сантиметров 5-10?

Точно так же: сейчас стоит плоский шлейф 50мм, но на этих же таймингах точно также работал шлейф 100 мм. Даже не пришлось ставить согласующие резисторы. Камень STM32F4

 

Quote

У нас одно из требований ТЗ - возможность делать полный скриншот.

Полный скриншот все равно подразумевает буфер, который потом сохраняется на флэшку. Если буфера нет, то придется топтать и писать картинку куда-то наружу МК, одновременно вычитывая ее из экрана.

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

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

 

Share this post


Link to post
Share on other sites
1 час назад, Forger сказал:

Полный скриншот все равно подразумевает буфер, который потом сохраняется на флэшку. Если буфера нет, то придется топтать и писать картинку куда-то наружу МК, одновременно вычитывая ее из экрана.

Не обязательно. Всё зависит от процедур рисования. Проще говоря: например под виндой, при удалении какого-то объекта с экрана, совсем не обязательно сохранять содержимое экрана перед отрисовкой этого объекта и затем восстанавливать. Можно просто послать всем окнам, перекрывающим эту область, уведомление о необходимости перерисовать эту область. В порядке - от самого нижележащего окна, к самому верхнему поверх всех. И их обработчики WM_PAINT каждого окна отрисуют каждый своё содержимое в этой области. Собственно - так даже правильнее делать, если окна имеют динамически меняющееся содержимое, даже когда они на заднем плане.

Здесь можно поступить аналогично: Можно совсем не хранить копию экранного содержимого и не читать её не откуда. А послать всем процедурам сообщение о необходимости выполнить отрисовку. Перед этим установив область отсечения, которая нас интересует. Если графическое API поддерживает рисование в области отсечения и рисование в ОЗУ (внутреннее, в МК), то для захвата например всего экрана, при том что внутренней памяти хватает только на 1/8 содержимого экрана, можно сохранить экран (800x480) за 8 шагов:

1. установить область отсечения 0,0 - 99,479; выделить для неё буфер ОЗУ, нарисовать в эту область, сохранить её;

2. установить область отсечения 100,0 - 199,479; выделить для неё буфер ОЗУ, нарисовать в эту область, сохранить её;

...

8. установить область отсечения 700,0 - 799,479; выделить для неё буфер ОЗУ, нарисовать в эту область, сохранить её.

Потребует конечно больше времени, но зато меньше памяти.

Ничего при этом не замораживается, если API поддерживает рисование и в ОЗУ и в экран.

Share this post


Link to post
Share on other sites
48 minutes ago, jcxz said:

Не обязательно. Всё зависит от процедур рисования.

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

Share this post


Link to post
Share on other sites
9 часов назад, Forger сказал:

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

Ничуть. Представьте, что Вам нужно отображать некий объект, непрерывно перемещающийся, вращающийся и изменяющий размер. Например - звезду. В каждый момент времени её состояние определяется неким набором значений: координата центра (X,Y), угол поворота (A), размер (S). Вопрос - сколько (минимально) нужно данных, чтобы точно запомнить состояние экрана? Весь пиксельный массив экрана? Или достаточно только этих 4-х параметров: X,Y,A,S?

Конечно - второе. Ведь зная эти параметры, мы в любое время можем нарисовать звезду. Поэтому "скриншот" в нашем случае будет - просто захват этих 4-х параметров. И дальше, после того как они захвачены, мы можем в любой момент времени спокойно перевести их в пиксельный массив (если нам на SD-карту или ещё куда, нужно сохранить пиксельную картинку), рисуя в отдельную область в памяти (не основной видеобуфер!). Никак при этом не мешая основной процедуре рисования экрана. Чтобы для этого не требовался буфер в памяти размером с весь экран, необходимо чтобы API рисования поддерживало рисование с отсечением (прямоугольного отсечения достаточно) и могло выполнять линейный перенос координат (хотя это несложно сделать и внешне: X+X0,Y+Y0). И API должно быть реентерабельным. Тогда можно рисовать в отдельной низкоприоритетной задаче, вообще никак не влияя на работу остального кода. И насчёт того, что это будет как-то сильно тормозно: если рисовать примитивы (прямоугольники, прямые), то нормальное API отсечение для них делает по верхнему уровню (до начала рисования корректируя размеры), а значит - почти пропорционально уменьшается количество времени на рисование. Т.е. - нарисовать весь экран за 8 отдельных проходов, должно быть ненамного медленнее чем целиком за один. Но памяти потребуется в 8 раз меньше.

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

Также можно делать и для перемещения какого-то одного граф.объекта (курсор например) поверх другого: не сохранять/восстанавливать фон под ним, а просто - вызвать процедуры рисования для всех объектов на экране в порядке их Z-координаты (предварительно установив область отсечения по размерам стираемого перемещающегося объекта). Внутри этого же порядка Z-координат нарисовать и сам перемещающийся объект, но с новыми коорд. и без области отсечения.

Так что в общем случае - вполне можно обойтись вообще без чтения видеопамяти. Тем более, как уже заметили, QSPI МК ТС-а не поддерживает чтение в режиме отображения на память.

Share this post


Link to post
Share on other sites
4 hours ago, hd44780 said:

QSPI не позволяет записывать в память в memory-mapped режиме. Он read-only.

Плохо что так. Хотя в нескольких аппнотах встречается странное выражение- не read only, a not suitable for write operation. Надо будет попробовать и посмотреть что на шине творится. Тут еще вопрос назрел- если делать длинную шину QSPI, такую что могут понадобится буферы, каким сигналом можно  управлять направлением передачи буферов при переходе из фазы передачи данных с хоста к фазе приема? Не то что это сейчас требуется, но на будущее. Самый странный вариант был использовать аппаратный таймер и просчитывать количество клоков до начала приема

По поводу синтетического скриншота- в нашем случае так не получится- часть данных на экране динамически меняется, возможно с вариантом digital phosphor ( послесвечение) и еще пользователь может делать курсорные измерения задавая обьекты пальцем на тачскрине- кто его знает что он там наваяет. Поэтому или только копия экранного буфера в основной памяти, если видеопамять write only, или полноценное вычитывание видеопамяти. На старом дизайне на SSD1963  для этого приходилось выключать FSMC и заниматься дрыгоножеством медленно и печально. Возможно это была всего лишь ошибка в разводке шины, но по FSMC читалась зашумленная чушь с экрана. В любом случае 16 линий на шину данных жалко и хотелось бы перейти на QSPI.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this