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

Поведайде секрет работы от 8 мгц, ведь даже не учитывая front porch и back porch,экран 800х480 на 8 мгц клока будет работать на 20 Гц всего...

В реальности, когда я экспериментировал он работал нормально и на 15fps. Никаких бросающихся в глаза проблем не наблюдалось. Если сильно присматриваться, то на градиентах (а может и просто на определенных цветах) было заметно слабое мерцание, эффект минимизировался правильным выбором напряжения Vcom.

 

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

Не, с этим было все ок. Даже если отключить LTDC, то он "белеет" до пропадания изображения в течении нескольких секунд, начиная с 20fps изображение невозможно отличить от 30 или более fps. Остановился на 29fps по одной причине - при более низком анимации в интерфейсе выглядели хуже.

 

По поводу слоев - у вас ltdc настроен на rgb565. Есть промежуточный буфер argb8888, в котором вы собираете кадр из разных виджетов, графиков и прочего с помощью dma2d или как то еще. А потом весь кадр копируете через dma2d в видео буфер с конвертацией в rgb565?

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

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

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


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

Попробую на 29 Гц, покручу Vcom, подстроечник есть. Если скинете ваши тайминги экрана буду благодарен. По буферу, не совсем уловил мысль, как правильно и оптимально.

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


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

Попробую на 29 Гц, покручу Vcom, подстроечник есть. Если скинете ваши тайминги экрана буду благодарен.

 

#define TFT_HSW 40     //Horizontal Sync Width
#define TFT_HBL 46    //Horizontal Blanking Width 
#define TFT_AW  800   //Active Area Width
#define TFT_TW  863  //Total Width

#define TFT_VSH 20     //Vertical Sync Width
#define TFT_VBL 23     //Vertical Blanking Width 
#define TFT_AH  480   //Active Area Height
#define TFT_TH  649   //Total Height

 

Тайминги немного отличаются от общепринятых, но все в рамках допустимого (по датащиту). Сделано так, чтобы было больше времени между кадрами и меньше между строками (можно выиграть немного в производительности), но внешний вид не меняется если использовать стандартные 1056точек на горизонтальную линию и 525 строк на кадр.

 

По буферу, не совсем уловил мысль, как правильно и оптимально.

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

 

Оптимальный Vcom у меня был помнится в районе 3.4В. Если интересно могу померять точно.

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


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

Рассчетное выходит 16.2 Мгц... тайминги почти такие же, только ширина синхры у вас поболее и вертикальная задержка в конце кадра прямо таки гигантская - 146 строк. Vcom интересен, у себя подстроечник дает диапазон допустимых значений по ДШ, но можно выкрутить в самый минимум. 1056 и 525 - это на клок 33.3, что дает как раз таки 60фпс. Такой конфиг конечно меньше грузит sdram - на пиксель одно чтение sdram, клок всего 16 мгц, канал fmc даже на половину не загружен, всего 32МБ/с. Попробую.

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


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

Когда-то, втискивая 272*480 во внутреннюю память ST32F429, я пробовал для хранения использовать формат RRRGGGBB - который распаковывался LUT:

 

static void
fillLUT_L8(
    LTDC_Layer_TypeDef* LTDC_Layerx
    )
{
    unsigned color;

    for (color = 0; color < 256; ++ color)
    {
#define XRGB(zr,zg,zb) do { r = (zr), g = (zg), b = (zb); } while (0)
        uint_fast8_t r, g, b;

        switch (color)
        {
        case TFTRGB(0, 0, 0)            /*COLOR_BLACK*/:        XRGB(0, 0, 0);            break;    // 0x00 черный
        case TFTRGB(255, 0, 0)            /*COLOR_RED*/:            XRGB(255, 0, 0);        break;     // 0xE0 красный
        case TFTRGB(0, 255, 0)            /*COLOR_GREEN*/:        XRGB(0, 255, 0);        break;     // 0x1C зеленый
        case TFTRGB(0, 0, 255)            /*COLOR_BLUE*/:            XRGB(0, 0, 255);        break;     // 0x03 синий
        case TFTRGB(128, 0, 0)            /*COLOR_DARKRED*/:        XRGB(128, 0, 0);        break;     // 
        case TFTRGB(0, 128, 0)            /*COLOR_DARKGREEN*/:    XRGB(0, 128, 0);        break;     // 
        case TFTRGB(0, 0, 128)            /*COLOR_DARKBLUE*/:        XRGB(0, 0, 128);        break;     // 
        case TFTRGB(255, 255, 0)        /*COLOR_YELLOW*/:        XRGB(255, 255, 0);        break;     // 0xFC желтый
        case TFTRGB(255, 0, 255)        /*COLOR_MAGENTA*/:        XRGB(255, 0, 255);        break;     // 0x83 пурпурный
        case TFTRGB(0, 255, 255)        /*COLOR_CYAN*/:            XRGB(0, 255, 255);        break;     // 0x1F голубой
        case TFTRGB(255, 255, 255)        /*COLOR_WHITE*/:        XRGB(255, 255, 255);    break;  // 0xff    белый
        case TFTRGB(128, 128, 128)        /*COLOR_GRAY*/:            XRGB(128, 128, 128);    break;     // серый
        case TFTRGB(0xa5, 0x2a, 0x2a)    /*COLOR_BROWN*/:        XRGB(0xa5, 0x2a, 0x2a);    break;     // 0x64 коричневый
        case TFTRGB(0xff, 0xd7, 0x00)    /*COLOR_GOLD*/:            XRGB(0xff, 0xd7, 0x00);    break;     // 0xF4 золото
        case TFTRGB(0xd1, 0xe2, 0x31)    /*COLOR_PEAR*/:            XRGB(0xd1, 0xe2, 0x31);    break;     // 0xDC грушевый
#undef XRGB
        default:
            r = ((color & 0xe0) << 0) | ((color & 0x80) ? 0x1f : 0);    // red
            g = ((color & 0x1c) << 3) | ((color & 0x10) ? 0x1f : 0);    // green
            b = ((color & 0x03) << 6) | ((color & 0x02) ? 0x3f : 0);    // blue
            break;
        }
        /* запись значений в регистры палитры */
        LTDC_Layerx->CLUTWR = 
            ((color << 24) & LTDC_LxCLUTWR_CLUTADD) |
            ((r << 16) & LTDC_LxCLUTWR_RED) |
            ((g << 8) & LTDC_LxCLUTWR_GREEN) |
            ((b << 0) & LTDC_LxCLUTWR_BLUE);
    }

    LTDC_Layerx->CR |= LTDC_LxCR_CLUTEN;
}

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


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

Когда-то, втискивая 272*480 во внутреннюю память ST32F429, я пробовал для хранения использовать формат RRRGGGBB - который распаковывался LUT

Геннадий приветствую. Такой формат не позволит использовать DMA2D в полную силу. Ну и внутренняя память намного быстрее SDRAM, особенно при random write/read

 

Рассчетное выходит 16.2 Мгц..

Да, в реальности там 16.104МГц

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


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

Вбил ваши параметры, Vcom выкрученный в минус показывает 3.65. RGB565 запустился, но отчего-то цвет фона LTDC всегда синий. Надо разобраться. Но поверх рисует уже нужный цвет, прогнал каждый из 3-х.

UPD: насчет синего сам накосячил. При инициализации LTDC, чтобы не было мусора прогонял всю память через memset левым значением 0x11. На RGB было пофиг, просто серый цвет.

UPD2: решил глянуть производительность в Мпикс/с в штатном тесте STemWin. Поднялась в 4 с лишним раза, показывает 71мпикс/с на RGB565, против 13мпикс/с на ARGB8888, т.е. протягивает 142 МБайт/с.

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

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


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

Vcom выкрученный в минус показывает 3.65

Я вас немного дезинформировал про Vcom - померял у себя Vgh=16.49В, Vgl=-7.44В, Vcom=3.819В. Оптимальное значение Vcom зависит от Vgh/Vgl и от конкретной панели.

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


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

Нашел где косяк с отрисовкой шрифтов в STemWin.

Что-то не так с аппаратным смешением цветов у 1 пикселя в функции, которая используется при выводе сглаженного текста:

/**
  * @brief  Function for mixing up 2 colors with the given intensity.
  *         If the background color is completely transparent the
  *         foreground color should be used unchanged.
  * @param  Color
  * @param  BkColor
  * @param  Intens
  * @retval LCD_COLOR
  */
static LCD_COLOR DMA_MixColors(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens)
{
  uint32_t ColorFG, ColorBG, ColorDst;

  if ((BkColor & 0xFF000000) == 0xFF000000)
  {
    return Color;
  }
  ColorFG = Color   ^ 0xFF000000;
  ColorBG = BkColor ^ 0xFF000000;

  /* Set up mode */
  DMA2D->CR      = 0x00020000UL | (1 << 9);         /* Control Register (Memory to memory with blending of FG and BG and TCIE) */

  /* Set up pointers */
  DMA2D->FGMAR   = (uint32_t)&ColorFG;                   /* Foreground Memory Address Register */
  DMA2D->BGMAR   = (uint32_t)&ColorBG;                   /* Background Memory Address Register */
  DMA2D->OMAR    = (uint32_t)&ColorDst;                  /* Output Memory Address Register (Destination address) */

  /* Set up pixel format */
  DMA2D->FGPFCCR = LTDC_Pixelformat_ARGB8888
                 | (1UL << 16)
                 | ((uint32_t)Intens << 24);
  DMA2D->BGPFCCR = LTDC_Pixelformat_ARGB8888
                 | (0UL << 16)
                 | ((uint32_t)(255 - Intens) << 24);
  DMA2D->OPFCCR  = LTDC_Pixelformat_ARGB8888;

  /* Set up size */
  DMA2D->NLR     = (uint32_t)(1 << 16) | 1;              /* Number of Line Register (Size configuration of area to be transfered) */

  /* Execute operation */
  DMA2D->CR     |= DMA2D_CR_START;                       /* Control Register (Start operation) */

  /* Wait until transfer is done */
  while (DMA2D->CR & DMA2D_CR_START)
  {
  }

  return (ColorDst ^ 0xFF000000);
}

Криво работающее смешение:

4208a4160e32t.jpg

Если закоментить привязку этой функции к GUI, то GUI, видимо, начинает использовать софтовое смешение, и тогда все хорошо:

9794016508aft.jpg

 

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


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

Вопросик может не в тему (лень читать даташит ;) :

DMA2D может быть полезен не для вывода на LTDC, а для ускорения отрисовки картинки в обычном ОЗУ?

Причём картинки не в формате этого LTDC, а если пиксели хранятся скажем в формате - 1байт/пиксель или 1байт/2пикселя?

Думаю - можно-ли его использовать для ускорения программной отрисовки в ОЗУ?

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


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

DMA2D может быть полезен не для вывода на LTDC, а для ускорения отрисовки картинки в обычном ОЗУ?

Он так и работает - это абсолютно отдельный блок.

 

Причём картинки не в формате этого LTDC, а если пиксели хранятся скажем в формате - 1байт/пиксель или 1байт/2пикселя?

Формат обрабатываемых картинок можно выбрать из:

ARGB8888, ARGB4444, ARGB1555, RGB888, RGB565, L8, L4, A8, A4

 

Источник данных может быть в любом из этих форматов, приемник (выходной буфер) только в ARGB8888, ARGB4444, ARGB1555, RGB888, RGB565

 

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

 

Думаю - можно-ли его использовать для ускорения программной отрисовки в ОЗУ?

Он для этого и предназначен :)

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


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

Источник данных может быть в любом из этих форматов, приемник (выходной буфер) только в ARGB8888, ARGB4444, ARGB1555, RGB888, RGB565

Понятно. спасибо :)

У меня граф.библиотека формирует картинку в формате 2пиксела/байт. Каждый пиксел - это индекс в таблице цветов на 16 элементов.

Потом, перед передачей в LCD, эта картинка по частям перекодируется в RGB565. Похоже - можно хотя-бы эту операцию делать с помощью DMA2D.

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


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

Понятно. спасибо :)

У меня граф.библиотека формирует картинку в формате 2пиксела/байт. Каждый пиксел - это индекс в таблице цветов на 16 элементов.

Это формат L4 (с точки зрения STM ;))

Потом, перед передачей в LCD, эта картинка по частям перекодируется в RGB565. Похоже - можно хотя-бы эту операцию делать с помощью DMA2D.

Да это можно сделать без проблем.

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


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

Там можно было бы многое, но нет отрицательного смещения, нет дробного смещения. Иначе можно было бы выводить произвольные линии. А так только вертикальные и горизонтальные.

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


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

Там можно было бы многое, но нет отрицательного смещения, нет дробного смещения. Иначе можно было бы выводить произвольные линии. А так только вертикальные и горизонтальные.

Кроме любых линий (что зачастую не так уж и нужно), отсутствие отрицательного смещения делает невозможным скроллинг/копирование с перекрытием в одном из направлений, а также вывод всяких паттернов. Второй косяк - DMA2D блендер должен дополнительно работать с цветом фона, ибо в нынешнем виде background alpha фактически бесполезная штука. Короче инженеры STMа могли бы посмотреть мануал на какой-ить древний Epson, да на тот же S1D13A04 или что-то подобное, прежде чем ваять DMA2D. Хотя нужно отдать им должное - в нынешнем виде DMA2D весьма неплохо справляется с тем, что может.

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


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

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

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

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

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

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

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

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

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

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