Easyelectronics.ru

Электроника для всех
Текущее время: 19 сен 2019, 07:35

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
 Заголовок сообщения: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 15:19 
Заглядывает иногда

Зарегистрирован: 05 дек 2017, 18:17
Сообщения: 160
Добрый день.
А есть ли возможность при копировании через DMA2D отключить инкремент памяти?
Контроллер F429.
Я делаю отображение bmp файла на экране. В bmp данные лежат в XRGB888, т.е. 24 бита + "пустой" альфа канал. Экран подключен по FSMC, 16 бит, RGB565.
Сделал пробный вариант - читаю кусками по 8кб из файла, при помощи DMA2D перегоняю прочитанный буфер из 32-битного формата в другой буфер в 16-битный RGB565 и потом через обычный dma mem2mem вывожу на экран. С обычным DMA проблем нет, у памяти инкремент включен, у адреса экрана выключен.
Было бы здорово, избавиться от второго копирования. Т.е. взять буфер 32-битных данных и при помощи DMA2D преобразовать и вывести прямо в экран. Но не нашел как отключить инкремент "получателя".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 15:33 
Старожил
Аватара пользователя

Зарегистрирован: 12 июн 2018, 15:04
Сообщения: 350
Если адресную ногу LCD повешать на старший бит адресной шины, то инкремент адреса приемника мешать не будет.

разрешение дисплея какое?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 15:35 
Заглядывает иногда

Зарегистрирован: 05 дек 2017, 18:17
Сообщения: 160
800*480, ssd1963
Ногу перевесить не очень удобно, уже плата сделана :) Дальнейшее развитие планирую в виде перехода к LTDC и SDRAM, поэтому переделывать уже не хочется.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 15:35 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1009
Sergey_spb писал(а):
Было бы здорово, избавиться от второго копирования.

Что мешает сразу хранить графику в нужном формате?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 15:40 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 6139
Перед обменом переключить выходы FSMC_A* на порт, выставив нужное значение; выдать нужное по DMA2D; вернуть выходы в FSMC. (если возможно)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 15:44 
Заглядывает иногда

Зарегистрирован: 05 дек 2017, 18:17
Сообщения: 160
Reflector писал(а):
Sergey_spb писал(а):
Было бы здорово, избавиться от второго копирования.

Что мешает сразу хранить графику в нужном формате?

Да вообщем ничего :) Вопрос не про это просто был :)
Да, можно и сразу в массив rgb565 сложить, но это требует чуть больше действий, чем просто в bmp на карту кинуть.
Интерес академический скорее, чтоб с DMA2D разобраться.
Я изначально вообще сделал ручное преобразование, потом прикрутил DMA2D, потом решил еще ускорить, отказавшись от второго буфера и второго копирования через dma.

Ну нет такого режима, да и ладно. Сейчас сделаю с двойным копированием, потом надеюсь перейти к LTDC и внешней памяти и вопрос решится сам собой.

u37 писал(а):
Перед обменом переключить выходы FSMC_A* на порт, выставив нужное значение; выдать нужное по DMA2D; вернуть выходы в FSMC. (если возможно)


Спасибо, попробую, если получится, расскажу.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 16:44 
Старожил
Аватара пользователя

Зарегистрирован: 12 июн 2018, 15:04
Сообщения: 350
Sergey_spb писал(а):
800*480, ssd1963
Ногу перевесить не очень удобно, уже плата сделана :) Дальнейшее развитие планирую в виде перехода к LTDC и SDRAM, поэтому переделывать уже не хочется.


тогда актуальность вопроса падает. И зачем конверсия 8:8:8:8 в 5:6:5 ? С дизерингом дружите?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 17:09 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 3618
DMA2D- это инструмент для конвертирования и наложения слоев. Выход у него - такой же массив данных, строго равный по размеру входным массивам. То есть ответ - "нет, нельзя"
А что касается bmp - подготовьте bmp именно в нужном формате, чтобы избежать конвертации в самом МК. Конвертация возможна в любом текстовом редакторе. Я делал в фотошопе. И еще че делал - менял порядок следования строк. Известно, что bmp-формат имеет обратный порядок следования строк - снизу вверх. Картинка отзеркалена по вертикали. В микроконтроллерном применении это неудобно. Потому я в фотошопе при сохранении картинки менял порядок следования строк, таким образом, что строки шли сверху вниз. Поэтому картинка очень удобно выводилась на дисплей за один раз.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA2D, mem2mem, инкремент
СообщениеДобавлено: 14 авг 2019, 17:48 
Старожил
Аватара пользователя

Зарегистрирован: 12 июн 2018, 15:04
Сообщения: 350
BusMaster писал(а):
И еще че делал - менял порядок следования строк. Известно, что bmp-формат имеет обратный порядок следования строк - снизу вверх. Картинка отзеркалена по вертикали. В микроконтроллерном применении это неудобно. Потому я в фотошопе при сохранении картинки менял порядок следования строк, таким образом, что строки шли сверху вниз. Поэтому картинка очень удобно выводилась на дисплей за один раз.


В свое время была проблема найти конвертер, который работал 100% правильно во всех случаях. То с шириной не кратной 4 не дружит, то цвета уродует, то ещё много чего. Пришлось вникнуть в BMP формат и написать свою конвертилку. Сорец ниже (если дизеринг не нужен, то его закомментировать и раскомментировать закомментированное). Надёжно работает и опробовал в играх(там где надо 5:6:5). Вдовесок к "задо-наперёдности" ещё добавлю, что в BMP ширина дополняется до кратной 4 байтам (пустые байты). И ещё бывают сжатые BMP (их не рассматриваю).

Код:
#include <vector>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "Type.h"

#define BYTE u8

inline BYTE Clamp(int n)
{
    n = n>255 ? 255 : n;
    return n<0 ? 0 : n;
}

struct RGBTriplet
{
    int r;
    int g;
    int b;
    RGBTriplet(int _r = 0, int _g = 0, int _b = 0) : r(_r), g(_g), b(_b) {};
};

void RGB565Dithered(const BYTE * pIn, int width, int height, int strideIn, BYTE * pOut, int strideOut)
{
    std::vector<RGBTriplet> oldErrors(width + 2);
    for (int y = 0;  y < height;  ++y)
    {
        std::vector<RGBTriplet> newErrors(width + 2);
        RGBTriplet errorAhead;
        for (int x = 0;  x < width;  ++x)
        {
            int b = (int)(unsigned int)pIn[3*x] + (errorAhead.b + oldErrors[x+1].b) / 16;
            int g = (int)(unsigned int)pIn[3*x + 1] + (errorAhead.g + oldErrors[x+1].g) / 16;
            int r = (int)(unsigned int)pIn[3*x + 2] + (errorAhead.r + oldErrors[x+1].r) / 16;
            int bAfter = Clamp(b) >> 3;
            int gAfter = Clamp(g) >> 2;
            int rAfter = Clamp(r) >> 3;
            int pixel16 = (rAfter << 11) | (gAfter << 5) | bAfter;
            pOut[2*x] = (BYTE) pixel16;
            pOut[2*x + 1] = (BYTE) (pixel16 >> 8);
            int error = r - ((rAfter * 255) / 31);
            errorAhead.r = error * 7;
            newErrors[x].r += error * 3;
            newErrors[x+1].r += error * 5;
            newErrors[x+2].r = error * 1;
            error = g - ((gAfter * 255) / 63);
            errorAhead.g = error * 7;
            newErrors[x].g += error * 3;
            newErrors[x+1].g += error * 5;
            newErrors[x+2].g = error * 1;
            error = b - ((bAfter * 255) / 31);
            errorAhead.b = error * 7;
            newErrors[x].b += error * 3;
            newErrors[x+1].b += error * 5;
            newErrors[x+2].b = error * 1;
        }
        pIn += strideIn;
        pOut += strideOut;
        oldErrors.swap(newErrors);
    }
}

int main(int argc, char *argv[])
{
if(argc<2)
{
  printf("\nUse: BMP24toBIN16.exe bmp_file\n");
  return -1;
}

u16 BitmapPosition,BitmapWidth,BitmapHeight;
u8 Garbage[4];

FILE *f=fopen(argv[1],"rb");
if(!f)return -1;

fseek(f,10,SEEK_SET);
fread(&BitmapPosition,2,1,f);

fseek(f,18,SEEK_SET);
fread(&BitmapWidth,2,1,f);

fseek(f,22,SEEK_SET);
fread(&BitmapHeight,2,1,f);

fseek(f,BitmapPosition,SEEK_SET);

u8 *BufferIN=(u8*)malloc(BitmapWidth*BitmapHeight*3);

for(s32 i=BitmapHeight-1;i>=0;i--)
{
  fread(&BufferIN[BitmapWidth*3*i],1,BitmapWidth*3,f);
  if((BitmapWidth&3)!=0)fread(Garbage,1,BitmapWidth&3,f);
}

fclose(f);

u8 *BufferOUT=(u8*)malloc(BitmapWidth*BitmapHeight*2);

RGB565Dithered((const u8*)BufferIN,BitmapWidth,BitmapHeight,BitmapWidth*3,(u8*)BufferOUT,BitmapWidth*2);

/*
for(u32 i=0;i<BitmapWidth*BitmapHeight;i++)
{
  u32 O=(u32)&BufferIN[3*i];
  *((u16*)&BufferOUT[i<<1])=((((u16)(*(u8*)(O+2)))>>3)<<11)|((((u16)(*(u8*)(O+1)))>>2)<<5)|(((u16)(*(u8*)O))>>3);
}
*/

char name[64];
memset(name,0,sizeof(name));
memcpy(name,argv[1],strlen(argv[1])-4);                         //truncate ".bmp"
sprintf(name,"%s_%d_%d.bin",name,BitmapWidth/8,BitmapHeight/8); //size in tiles

f=fopen(name,"wb");

fwrite(BufferOUT,1,BitmapWidth*BitmapHeight*2,f);
fclose(f);

free(BufferIN);
free(BufferOUT);

return 0;
}


Здесь алгоритм дизеринга 5:6:5 лучше, чем у GIMP-овского плагина :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB