реклама на сайте
подробности

 
 
8 страниц V  « < 5 6 7 8 >  
Reply to this topicStart new topic
> LTDC + ChromART в STM, Проконсультируйте, кто работал.
Rash
сообщение Aug 22 2016, 19:40
Сообщение #91


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



без SDRAM или SRAM нужного размера под видео буфер не имеет практического смысла запускать
Go to the top of the page
 
+Quote Post
adrvyho
сообщение Aug 22 2016, 20:51
Сообщение #92


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 21-08-16
Из: Москва
Пользователь №: 93 041



Цитата
без SDRAM или SRAM нужного размера под видео буфер не имеет практического смысла запускать

Необходимо выводить только примитивы в виде кнопок и текст. Хотя убийственная мысль, что на каждый пиксель экрана необходимо минимум два байта постоянно перезаписываемой памяти, всё больше проникает в мозг. Может есть какие-то уловки с FLASH или SD картой, или ещё какие-то заклинания?!

Цитата
Ищите где производится инициализация LTDC и смотрите где находится видеобуфер


Единственное указание на видеобуфер находится в инициализации слоя 1, пока что-то делать с ним боюсь, только расширил массив до 45000,но это - мёртвому припарки.
Код
   displayLayer1.WindowX0 = 10;
   displayLayer1.WindowX1 = 790;
   displayLayer1.WindowY0 = 10;
   displayLayer1.WindowY1 = 470;
   displayLayer1.PixelFormat = LTDC_PIXEL_FORMAT_ARGB4444;
   displayLayer1.Alpha = 255;
   displayLayer1.Alpha0 = 250;
   displayLayer1.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
   displayLayer1.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
   displayLayer1.FBStartAdress = (uint32_t)&aBufferResult;
   displayLayer1.ImageWidth = 0;
   displayLayer1.ImageHeight = 0;
   displayLayer1.Backcolor.Blue = 250;
   displayLayer1.Backcolor.Green = 0;
   displayLayer1.Backcolor.Red = 200;

   HAL_LTDC_ConfigLayer(&displayTypeDef, &displayLayer1, 0);


Go to the top of the page
 
+Quote Post
Rash
сообщение Aug 23 2016, 05:41
Сообщение #93


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



под ваш LCD нужен видео буфер 800*480*2 иначе просто нет смысла возится (ИМХО). Или переходите на маленький экран, что бы разместить видео буфер во внутреннем ОЗУ. Самый менее затратный вариант взять 429Disco, отпаять родной LCD и сделать переходную плату под нужный LCD, а потом уже разводить свою, при рабочем программе (или готовый DevKit).
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Aug 23 2016, 06:54
Сообщение #94


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(adrvyho @ Aug 22 2016, 23:51) *
Необходимо выводить только примитивы в виде кнопок и текст. Хотя убийственная мысль, что на каждый пиксель экрана необходимо минимум два байта постоянно перезаписываемой памяти, всё больше проникает в мозг. Может есть какие-то уловки с FLASH или SD картой, или ещё какие-то заклинания?!

Вы бы почитали мой пост предварительно. Тогда бы поняли что DMA2D целесообразен только в режиме 16 или 24-битного цвета.
...
Давайте поясню на пальцах. В МК есть 2 совершенно независимых узла: LTDC (контроллер дисплея) и DMA2D (ускоритель, но фактически контроллер прямого доступа к памяти позволяющий работать с прямоугольными областями памяти).
LTDC фактически отображает область памяти (видеобуфер) на экран. А с помощью DMA2D вы можете модифицировать ваш видеобуфер. То есть сам DMA2D к дисплею никакого отношения не имеет. Поскольку в экране у вас ничего не хранится, то видеобуфер должен быть обязательно. Там находится то, что отображается на дисплее.
Самый экономный режим для вашего МК - 8 бит (L8 - 256 цветов из палитры 16 бит или аналогичный AL44 - палитра 16 цветов с 16 градациями яркости). Для реализации потребуется 800*480 = 384 кб. У Вашего контроллера лишь 256.
Выхода 3.
1) Добавить память внешнюю. Но на проводах не запаяешь. Работать не будет. Придётся переразводить плату.
2) Применить дисплей с меньшим разрешением. Например 4.3" 480*272 = 130кб. Качество картинки будет описанное выше. DMA2D будет использоваться ограниченно (только копирование и заливка).
3) Применить дисплей с собственным контроллером типа 1963 или другим. Там память находится на самом дисплее. DMA2D в этом случае теряет смысл.
Go to the top of the page
 
+Quote Post
adrvyho
сообщение Aug 24 2016, 16:43
Сообщение #95


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 21-08-16
Из: Москва
Пользователь №: 93 041



Всем спасибо большое за ответ!!!
Понял всю фатальность ситуации, что запуск моей платы снова отодвинут на этап создания паттернов в PCAD.
Для себя на пальцах представил ОЗУ, как участок земли определённой площади, которым я обладаю (в моём случае - 256 кв. м).
Видеобуфер - это полотно, которое я могу расстелить в пределах моего участка. Полотно, зараза, большое.
Пиксели - это кубики с площадью основания >= 2 кв.м.
И чтобы мне расстелить полотно, нужно купить участок побольше, можно и в другом районе, дабы курьерская служба DMA2D может доставить кубики-пиксели куда угодно)
Уважаемый SasaVitebsk, я ведь в случае варианта 2 могу не брать другой экран, а на своём задать область размером, допустим 400х300 на слое 1? Или нужно вначале инициализировать экран конкретно под это разрешение?
Пока не выходит, хотя создал uint16_t aBufferResult[95000] (больше не создаётся). Может нужно как-то по-другому задавать видеобуфер? Тут мои знания уже конкретно плывут(

Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Aug 25 2016, 08:34
Сообщение #96


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



В доке на МК имеется достаточно детальное описание как программируется дисплей.
Вы сможете слегка уменьшить отображаемое поле. Но в целом, TFT дисплей это всё же не телевизор и поля с краёв будут небольшими.
То есть я думаю вас это не спасёт. Хотя я не пробовал, честно скажу.
Go to the top of the page
 
+Quote Post
adnega
сообщение Aug 25 2016, 09:27
Сообщение #97


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(adrvyho @ Aug 24 2016, 19:43) *
а на своём задать область размером, допустим 400х300 на слое 1? Или нужно вначале инициализировать экран конкретно под это разрешение?

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

PS. Я так делал - работает, но при определенных соотношениях размеров.
Go to the top of the page
 
+Quote Post
adrvyho
сообщение Aug 25 2016, 15:00
Сообщение #98


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 21-08-16
Из: Москва
Пользователь №: 93 041



Цитата(adnega @ Aug 25 2016, 09:27) *
Нужно проинициализировать экран со всеми таймингами под полное разрешение,
но при инициализации слоев (а именно они используют видеопамять) можно указать буфера меньшего размера.
Границы будут залиты цветом фона, который можно выбрать.


Именно так и сделал - задал массив aBufferResult при инициализации слоя 1, сделал заполнение 2х областей. Дык, всё равно заливаются линии, а не области!


Видимо, прокладка между рулём и сиденьем износилась)
Подскажите, пожалуйста, как корректно задать видеобуфер - видимо я это совсем через пень-колоду делаю.

Go to the top of the page
 
+Quote Post
adnega
сообщение Aug 25 2016, 15:27
Сообщение #99


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(adrvyho @ Aug 25 2016, 18:00) *
Именно так и сделал

Кусок кода покажете?
Go to the top of the page
 
+Quote Post
adrvyho
сообщение Aug 25 2016, 15:38
Сообщение #100


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 21-08-16
Из: Москва
Пользователь №: 93 041



Цитата(adnega @ Aug 25 2016, 15:27) *
Кусок кода покажете?

CODE
#define PIXELWIDHT 2

#define LCD_WIDTH 800
#define LCD_HEIGHT 480

#define HFP 40
#define HSYNC 48
#define HBP 40

#define VFP 13
#define VSYNC 3
#define VBP 29



#define ACTIVE_W (HSYNC + LCD_WIDTH + HBP - 1)
#define ACTIVE_H (VSYNC + LCD_HEIGHT + VBP - 1)
#define DISP_ACCUM_HORIZ_BACKPORCH (HSYNC + HBP - 1)
#define DISP_ACCUM_VERT_BACKPORCH (VSYNC + VBP - 1)
#define TOTAL_WIDTH (HSYNC + HBP + LCD_WIDTH + HFP - 1)
#define TOTAL_HEIGHT (VSYNC + VBP + LCD_HEIGHT + VFP - 1)

uint16_t aBufferResult[95000];

void Screen_Init(void)
{
LTDC_HandleTypeDef displayTypeDef;
LTDC_LayerCfgTypeDef displayLayer1;
LTDC_LayerCfgTypeDef displayLayer2;

GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5| GPIO_PIN_6|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = 14;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_10| GPIO_PIN_11;

HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1| GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_10;

HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3| GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_1
4|GPIO_PIN_15;

HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, 1);

__LTDC_CLK_ENABLE();

// PLL

/* LCD clock configuration */
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 MHz */
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 MHz */
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/5 = 38.4 MHz */
/* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_4 = 38.4/4 = 9.6MHz */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
PeriphClkInitStruct.PLLSAI.PLLSAIR = 5;
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);

// enable clock for LTDC
RCC->APB2ENR |= RCC_APB2ENR_LTDCEN;

// LTDC
HAL_LTDC_Init(&displayTypeDef);
displayTypeDef.Instance = LTDC;
displayTypeDef.Init.HSPolarity = LTDC_HSPOLARITY_AL;
displayTypeDef.Init.VSPolarity = LTDC_VSPOLARITY_AL;
displayTypeDef.Init.DEPolarity = LTDC_DEPOLARITY_AL;
displayTypeDef.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
displayTypeDef.Init.HorizontalSync = HSYNC-1;
displayTypeDef.Init.VerticalSync = VSYNC-1;
displayTypeDef.Init.AccumulatedHBP = DISP_ACCUM_HORIZ_BACKPORCH;
displayTypeDef.Init.AccumulatedVBP = DISP_ACCUM_VERT_BACKPORCH;
displayTypeDef.Init.AccumulatedActiveW = ACTIVE_W;
displayTypeDef.Init.AccumulatedActiveH = ACTIVE_H;
displayTypeDef.Init.TotalWidth = TOTAL_WIDTH;
displayTypeDef.Init.TotalHeigh = TOTAL_HEIGHT;
displayTypeDef.Init.Backcolor.Blue = 200;
displayTypeDef.Init.Backcolor.Green = 0;
displayTypeDef.Init.Backcolor.Red = 200;

HAL_LTDC_Init(&displayTypeDef);

// Layer 1
displayLayer1.WindowX0 = 210;
displayLayer1.WindowX1 = 590;
displayLayer1.WindowY0 = 100;
displayLayer1.WindowY1 = 380;
displayLayer1.PixelFormat = LTDC_PIXEL_FORMAT_ARGB4444;
displayLayer1.Alpha = 255;
displayLayer1.Alpha0 = 250;
displayLayer1.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
displayLayer1.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
displayLayer1.FBStartAdress = (uint32_t)&aBufferResult;
displayLayer1.ImageWidth = 0;
displayLayer1.ImageHeight = 0;
displayLayer1.Backcolor.Blue = 250;
displayLayer1.Backcolor.Green = 0;
displayLayer1.Backcolor.Red = 200;

HAL_LTDC_ConfigLayer(&displayTypeDef, &displayLayer1, 0);

}

static void DMA2D_Config(void)
{
__HAL_RCC_DMA2D_CLK_ENABLE();
/* Register to memory mode with ARGB4444 as colorMode */
Dma2dHandle.Init.Mode = DMA2D_R2M;
Dma2dHandle.Init.ColorMode = DMA2D_ARGB4444;
Dma2dHandle.Init.OutputOffset = 0x0;

Dma2dHandle.XferCpltCallback = TransferComplete;
Dma2dHandle.XferErrorCallback = TransferError;
Dma2dHandle.Instance = DMA2D;

/* DMA2D Initialization */
if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
{

}
}

static void _DMA_Fill(void * pDst, int xSize, int ySize, int OffLine, uint32_t ColorIndex) {

DMA2D->CR = 0x00030000UL | (1 << 9); // Register to memory and TCIE
DMA2D->OCOLR = ColorIndex; // Color to be used
DMA2D->OMAR = (uint32_t)pDst; // Destination address
DMA2D->OOR = OffLine; // Destination line offset
DMA2D->OPFCCR = 4; // Defines the number of pixels to be transfered
DMA2D->NLR = ((uint32_t)xSize << 16) | ySize; // Size configuration of area to be transfered
DMA2D->CR |= 1; // Start operation
//
// Wait until transfer is done
//
while (DMA2D->CR & DMA2D_CR_START) {
//__WFI(); // Sleep until next interrupt
}


Код
_DMA_Fill(aBufferResult+10, 10, 10, 0, 0x1F0A);
_DMA_Fill(aBufferResult+200, 20, 2, 0, 0x1C01);
_DMA_Fill(aBufferResult+300, 50, 20, 0, 0xF0F0);


Сообщение отредактировал IgorKossak - Aug 25 2016, 17:20
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
adnega
сообщение Aug 25 2016, 15:56
Сообщение #101


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Я не спец по HAL, но
Код
  displayLayer1.ImageWidth = 0;
   displayLayer1.ImageHeight = 0;

по-моему, не должны быть нулевыми.
Go to the top of the page
 
+Quote Post
adrvyho
сообщение Aug 25 2016, 16:56
Сообщение #102


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 21-08-16
Из: Москва
Пользователь №: 93 041



Цитата(adnega @ Aug 25 2016, 15:56) *
Я не спец по HAL, но
Код
  displayLayer1.ImageWidth = 0;
   displayLayer1.ImageHeight = 0;

по-моему, не должны быть нулевыми.

почему-то, когда они не нулевые, картинка вообще безобразная
Пытался выставлять 380х280


Go to the top of the page
 
+Quote Post
adnega
сообщение Aug 25 2016, 18:45
Сообщение #103


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Попробуйте 400x240.
Попробуйте записать в видеопамять напрямую, без DMA2D.
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Aug 25 2016, 20:20
Сообщение #104


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



Когда требуется сложить два слоя с разным форматом и разной площадью - то смещение считается не в пикселах, а в байтах!!! Точно так-же как и в простом dma.
Сам модуль DMA2D достаточно тупой для таких подсчётов, он просто гонит поток данных через свою матрицу, заниматься расчётами приходится пользователю. Перед смешиванием оба потока преобразуются в ARGB 32бита, и выхлоп уже считается в пикселах.

Для того чтобы юзать DMA2D в полном масштабе - придётся написать собственную функцию, с прямым обращением в регистры. При этом глубина изменений (количество меняемых регистров) - напрямую зависит от разнообразности режимов. Универсальный модуль есно меняет всё, но и запускается медленнее всех, хал - это универсальный способ!!! Посему выбирается некий компромисс, с отбрасыванием неиспользуемых режимов - вот тогда будет всё летать.
Go to the top of the page
 
+Quote Post
pvo125
сообщение Sep 1 2016, 07:13
Сообщение #105


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 9-04-14
Из: Черногорск Хакасия
Пользователь №: 81 299



Такая запись конечно же ошибка.
displayLayer1.ImageWidth = 0;
displayLayer1.ImageHeight = 0;
Если смотреть функцию LTDC_SetConfig() то она записывает в регистр LTDC_LxCFBLR

CFBP[17:0]=displayLayer1.ImageWidth*2 (для ARGB4444 ) Сolor frame buffer pitch (по смыслу длина строки в байтах смысл pitch не смог перевести )
CFBLL[12:0]= (displayLayer1.WindowX1- displayLayer1.WindowX0)*2 (для ARGB4444) Color Frame Buffer Line Length которые задают длину строки в байтах плюс 3.
Короче одно другое повторяет но на 3 больше если по крестьянски сказать.

А в регистр LTDC_LxCFBLNR = displayLayer1.ImageHeight который определяет количество линий в color frame buffer.
Так что .ImageWidth ImageHeight не могут быть 0 и даже больше они должны четко соответствовать и тому что задано в
displayLayer1.WindowX1
displayLayer1.WindowX0
displayLayer1.WindowY1
displayLayer1.WindowY0

Делал для 480*272 экрана и эти параметры задавал такие
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 480;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 272;
pLayerCfg.ImageWidth = 480;
pLayerCfg.ImageHeight = 272;

Go to the top of the page
 
+Quote Post

8 страниц V  « < 5 6 7 8 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 21:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01529 секунд с 7
ELECTRONIX ©2004-2016