硬汉嵌入式论坛

 找回密码
 立即注册
查看: 961|回复: 6
收起左侧

[DMA2D] 寄存器方式DMA2D

[复制链接]

11

主题

28

回帖

61

积分

初级会员

积分
61
发表于 2022-7-11 08:36:24 | 显示全部楼层 |阅读模式
反客例程修改。硬解压800*600图像正常,超过800就异常。
怎么改才能在800*600屏幕上显示超过800的图片(缩小、剪裁都可以)?
//硬件解码使用这函数
void DMA2D_Copy_YCbCr_To_RGB_v(uint32_t pSrc,uint32_t *pDst,
                               uint16_t x, uint16_t y,uint16_t xsize, uint16_t ysize,
                               uint32_t PixelFormat, uint32_t ChromaSampling)
{
    uint32_t ss01; //转换c数
          uint32_t s24x;
       
        uint32_t cssMode = DMA2D_CSS_420;
    uint32_t inputLineOffset = 0;
    uint32_t destination = 0;
       
   JPEG_ConfTypeDef   JPEG_Info;
   HAL_JPEG_GetInfo(&hjpeg, &JPEG_Info);           // 获取JPG图片信息       
       
        x=0;   y=0;
        xsize=JPEG_Info.ImageWidth;            //目的区域的X轴大小,即每行像素数
  ysize=JPEG_Info.ImageHeight;             //目的区域的Y轴大小,即行数
        PixelFormat= LTDC_PIXEL_FORMAT_RGB565;                          //目标区颜色格式
        ChromaSampling= JPEG_Info.ChromaSubsampling;   //目标区颜色格式
       

    if(ChromaSampling == JPEG_420_SUBSAMPLING)
    {

            cssMode = DMA2D_CSS_420;
            s24x=24;  
            inputLineOffset = xsize % 16;
            if(inputLineOffset != 0)
            {
                    inputLineOffset = 16 - inputLineOffset;
            }   
    }
    else if(ChromaSampling == JPEG_444_SUBSAMPLING)
    {

            cssMode = DMA2D_NO_CSS;
            s24x=48;  
            inputLineOffset = xsize % 8;
            if(inputLineOffset != 0)
            {
                    inputLineOffset = 8 - inputLineOffset;
            }   
    }
    else if(ChromaSampling == JPEG_422_SUBSAMPLING)
    {

                              cssMode = DMA2D_CSS_422;
            s24x=32;  
            inputLineOffset = xsize % 16;
            if(inputLineOffset != 0)
            {
                    inputLineOffset = 16 - inputLineOffset;
            }      
    }  

                ss01=ysize/16;  //下次转换增加地址
       
         while(ss01--)       
   {
                  // 输出地址,乘以2的对RGB565,如果输出格式是ARGB8888,需要乘以4
    destination = (uint32_t)pDst + ((y * g_LcdWidth) + x) * 2 + g_LcdWidth*32*ss01;
                 
                 DMA2D->CR      = 0x00010000UL | (1 << 9);
    DMA2D->OOR     = g_LcdWidth - xsize;

    DMA2D->OPFCCR  = PixelFormat
                     | (DMA2D_REGULAR_ALPHA << 20)
                     | (DMA2D_RB_REGULAR << 21);  
    DMA2D->FGPFCCR = DMA2D_INPUT_YCBCR
                     | (DMA2D_REPLACE_ALPHA << 16)
                     | (DMA2D_REGULAR_ALPHA << 20)
                     | (DMA2D_RB_REGULAR << 21)   
                     | (0xFFU << 24)              
                     | (cssMode << 18);               
    DMA2D->FGOR    = inputLineOffset;
    DMA2D->NLR     = (uint32_t)(xsize << 16) | 16; //每次转换16行
       
    DMA2D->OMAR    = (uint32_t)destination;
                 
    DMA2D->FGMAR   = (uint32_t)pSrc+ (xsize+inputLineOffset)*s24x*ss01;
               
    DMA2D->CR   |= DMA2D_CR_START;   
    while (DMA2D->CR & DMA2D_CR_START) {}
         }

}

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2022-7-11 11:17:58 | 显示全部楼层
分享个你那边超过800不行的图片,我用我们的工程帮你看下
回复

使用道具 举报

11

主题

28

回帖

61

积分

初级会员

积分
61
 楼主| 发表于 2022-7-11 18:13:49 | 显示全部楼层
加一句就搞定了!
                 if(xsize>g_LcdWidth)
                         {inputLineOffset= inputLineOffset+(xsize-g_LcdWidth);
                                                  xsize= g_LcdWidth;}
回复

使用道具 举报

11

主题

28

回帖

61

积分

初级会员

积分
61
 楼主| 发表于 2022-7-11 18:16:30 | 显示全部楼层
eric2013 发表于 2022-7-11 11:17
分享个你那边超过800不行的图片,我用我们的工程帮你看下

不是图片不行,是这个转换写显示的程序问题
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2022-7-11 19:50:54 | 显示全部楼层
新洲罗远 发表于 2022-7-11 18:16
不是图片不行,是这个转换写显示的程序问题

好的,完全没有看你的程序,打算用我们的试试,直接用我们对应的程序即可。
回复

使用道具 举报

18

主题

212

回帖

266

积分

高级会员

积分
266
发表于 2022-7-12 10:16:30 | 显示全部楼层
HI 新洲大大
厲害!! 有空來試試.
回复

使用道具 举报

11

主题

28

回帖

61

积分

初级会员

积分
61
 楼主| 发表于 2022-7-15 09:04:11 | 显示全部楼层
DMA2D剪裁画面的理解:如果图片宽度小于显示宽度,当然不需要剪裁,
如果图片宽度大于显示宽度,就需要跳过大于部分,当然还要加上补齐(被16整除)
inputLineOffset=补齐(被16整除)
DMA2D->FGOR    =  inputLineOffset+(xsize-800);//补齐+跳过
//FGOR =前景层偏移  跳过多少像素
就这样,DMA2D就只会转换800像素(每行)了。

显示部分也有一个跳过设置,如果图片宽度小于显示宽度,就跳过小于部分,
如果如果图片宽度大于显示宽度,因为我们已经在原数据上作了剪裁,直接xsize=800;就成了跳过=0
DMA2D->OOR     = 800 - xsize;        //输出偏移寄存器
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-28 23:24 , Processed in 0.357152 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表