⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hw_screen.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
void Screen_CreatRGB(BACKGRND *Screen, DWDMALLP *LLPList, UINT32 SdramAddr, UINT16 XSize, UINT16 YSize)
{
    UINT32 ViewXSize, ViewYSize;
    LCDCCONFIG *Config;

    Config = &Screen->LCDCConfig;
    Screen->OffsetX = 0;
    Screen->OffsetY = 0;
    Screen->RawXSize = XSize;
    Screen->RawYSize = YSize;
    Screen->LLPList = LLPList;
    Screen->SdramAddr = SdramAddr;
    Screen->ScrFormat = (32==IMAGE_BMP_BITCOUNT) ? RGB888 : RGB565;
    Screen->ViewXSize = LCDCDev.XSize;
    Screen->ViewYSize = LCDCDev.YSize;
    ViewXSize = LCDCDev.XSize;
    ViewYSize = LCDCDev.YSize;
    Config->StartX = 0;
    Config->StartY = 0;
    Config->ScaleX = 0x200;
    Config->ScaleY = 0x200;
    if (RGB888==Screen->ScrFormat)
    {
    Config->LineYAddr[0] = 0x7fe;
    Config->LineYAddr[1] = ViewXSize - 2;
    if (ViewXSize > 448)
    {
        Config->LineYAddr[2] = Config->LineYAddr[0];
        Config->LineYAddr[3] = Config->LineYAddr[1];
    }
    else
    {
        Config->LineYAddr[2] = ViewXSize * 2 - 2;
        Config->LineYAddr[3] = ViewXSize * 3 - 2;
    }
        Config->Rgb565 = 0;
    }
    else
    {
        Config->LineYAddr[0] =0;
        Config->LineYAddr[1] =ViewXSize/2;
        if (ViewXSize>448*2)
        {
            Config->LineYAddr[2] =Config->LineYAddr[0];
            Config->LineYAddr[3] =Config->LineYAddr[1];
        }
        else
        {
            Config->LineYAddr[2] =(ViewXSize/2)*2;
            Config->LineYAddr[3] =(ViewXSize/2)*3;
        }
        Config->Rgb565 = 1;
    }
    Config->LineUVAddr[0] = Config->LineYAddr[0] + 1;
    Config->LineUVAddr[1] = Config->LineYAddr[1] + 1;
    Config->LineUVAddr[2] = Config->LineYAddr[2] + 1;
    Config->LineUVAddr[3] = Config->LineYAddr[3] + 1;
    Config->YMIX = 0;
    if (Screen_GetType() == MCULCD)
        Config->IntrMask = b_INTR_EVENLINE;
    else
        Config->IntrMask = b_VERT_INTR | b_INTR_EVENLINE;
    Screen_CreatLLPRGB(Screen);
}


/*---------------------------------------------------------
Name  :  Screen_CreatVideo
Dec   :  创建视频相关设置参数
Params:  Screen   -> MIX YUV背景的相关配置参数
         LLPList  -> LLP链条首地址
         SdramAddr-> 数据源首地址
         XSize    -> 数据源宽度
         YSize    -> 数据源高度
         Mode     -> 显示比例模式
Return:
Author:  nzy
Date  :
-----------------------------------------------------------*/
void Screen_CreatVideo(BACKGRND *Screen, DWDMALLP *LLPList, UINT32 SdramAddr, UINT16 XSize, UINT16 YSize, SCALEMODE Mode)
{
    UINT32 Scale, ScaleX, ScaleY, MaxXSize;
    LCDCCONFIG *Config;

    Config = &Screen->LCDCConfig;
    Screen->RawXSize = (XSize + 15) & 0xfff0;
    XSize &= 0xfffc;
    Screen->RawYSize = YSize;
    Screen->LLPList = LLPList;
    Screen->SdramAddr = SdramAddr;
    Screen->ScrFormat = MIX420;
    MaxXSize = ((0x800 - LCDCDev.XSize / 2) * 4 / 9) & 0xfffc;
    if (XSize > MaxXSize)
    {
        XSize = MaxXSize; //限制于720,留出空间以备ALPHA
    }
    ScaleX = ((UINT32)(XSize - 1) * 0x200) / (LCDCDev.XSize - 1);
    ScaleY = ((UINT32)(YSize - 1) * 0x200) / (LCDCDev.YSize - 1);
    ScaleX = (ScaleX > 0x3ff) ? 0x3ff : ScaleX;
    ScaleY = (ScaleY > 0x3ff) ? 0x3ff : ScaleY;
    if (Mode == LineArity)
    {
        if ((ScaleX > ScaleY) || (XSize == MaxXSize))
            ScaleY = ScaleX;
        else
            ScaleX = ScaleY;
    }
    else if (Mode == Zoom)
    {
        if ((ScaleX < ScaleY) || (XSize == MaxXSize))
            ScaleY = ScaleX;
        else
            ScaleX = ScaleY;
    }
    XSize = ((LCDCDev.XSize * ScaleX + 0x7ff) >> 9) & 0xfffc;//调整实际Xscale所需的X值的大小,填补到最小数值和满足4的倍数
    if (XSize > MaxXSize)
    {
        ScaleX = MaxXSize * 0x200 / LCDCDev.XSize;
        XSize = ((LCDCDev.XSize * ScaleX + 0x7ff) >> 9) & 0xfffc;
        ScaleY = (Mode == LineArity) ? ScaleX : ScaleY;
    }
    while ((((ScaleY*(LCDCDev.YSize - 1) >> 10) % 3) == 0x00) && (ScaleY < 0x3ff))
    {
        ScaleY++;   //避免最后一行使用LINE0导致的数据冲突
    }
    YSize = (LCDCDev.YSize * ScaleY + 0x1ff) >> 9; //调整实际Yscale所需的Y值的大小,填补到最小数值
    Screen->ViewXSize = XSize;
    Screen->ViewYSize = YSize;
    Screen->OffsetX = (Screen->RawXSize > Screen->ViewXSize) ? ((Screen->RawXSize - Screen->ViewXSize) / 2) : 0;
    Screen->OffsetY = (Screen->RawYSize > Screen->ViewYSize) ? ((Screen->RawYSize - Screen->ViewYSize) / 2) : 0;
    Config->StartX = 0;
    Config->StartY = 0;
    Config->ScaleX = ScaleX;
    Config->ScaleY = ScaleY;
    Config->LineYAddr[0] = 0x0 | b_YUV_SRC | b_SCALE_EN;
    Config->LineYAddr[1] = XSize * 1 / 2 | b_YUV_SRC | b_SCALE_EN;
    Config->LineYAddr[2] = XSize * 2 / 2 | b_YUV_SRC | b_SCALE_EN;
    Config->LineYAddr[3] = 0x0 | b_YUV_SRC | b_SCALE_EN;
    Config->LineUVAddr[0] = XSize * 3 / 2;
    Config->LineUVAddr[1] = XSize * 7 / 4;
    Config->LineUVAddr[2] = XSize * 8 / 4;
    Config->LineUVAddr[3] = XSize * 3 / 2;
    Config->YMIX = 1;
    Config->Rgb565 = 0;
    if (Screen_GetType() == MCULCD)
        Config->IntrMask = b_INTR_PERLINE;
    else
        Config->IntrMask = b_VERT_INTR | b_INTR_PERLINE;
    Screen_CreatLLPMIX(Screen);
}


/*---------------------------------------------------------
Name  :  Screen_CreatMPEG2
Dec   :  创建MPEG2相关设置参数
Params:  Screen     -> Camera背景的相关配置参数
         LLPList    -> LLP链条首地址
         SdramAddr  -> 数据源首地址
         XSize      -> 数据源宽度
         YSize      -> 数据源高度
Return:
Author:  nzy
Date  :
-----------------------------------------------------------*/
void Screen_CreatMPEG2(BACKGRND *Screen, DWDMALLP *LLPList, UINT32 SdramAddr, UINT32 SdramAddrUV, UINT16 XSize, UINT16 YSize, SCALEMODE Mode)
{
    UINT32 ScaleX,ScaleY,MaxXSize;
    LCDCCONFIG *Config;

    Config = &Screen->LCDCConfig;
    Screen->RawXSize = (XSize+15)&0xfff0;
    Screen->RawYSize = YSize;
    MaxXSize = ((0x800-LCDCDev.XSize/2)*4/8)&0xfffc;
    if (XSize>MaxXSize)
    {
        XSize = MaxXSize;  //留出空间以备ALPHA
    }
    ScaleX = (UINT32)(XSize-1)*0x200/(LCDCDev.XSize-1);
    ScaleY = (UINT32)(YSize-1)*0x200/(LCDCDev.YSize-1);
    ScaleX = (ScaleX>0x3ff) ? 0x3ff : ScaleX;
    ScaleY = (ScaleY>0x3ff) ? 0x3ff : ScaleY;
    if (Mode==LineArity)
    {
        if ( (ScaleX > ScaleY) || (XSize==MaxXSize) )
            ScaleY = ScaleX;
        else
            ScaleX = ScaleY;
    }

    XSize = ((LCDCDev.XSize*ScaleX+0x7ff)>>9) &0xfffc;   //调整实际scale所需的X值的大小,填补到最小数值和满足4的倍数
    if (XSize >MaxXSize)
    {
        ScaleX =MaxXSize*0x200/LCDCDev.XSize;
        XSize =((LCDCDev.XSize*ScaleX+0x7ff)>>9) &0xfffc;
        ScaleY = (Mode == LineArity) ? ScaleX : ScaleY;
    }
    while ((((ScaleY*(LCDCDev.YSize-1)>>10)&0x03)==0x00)&&(ScaleY<0x3ff))
    {
        ScaleY++;   //避免最后一行使用LINE0导致的数据冲突
    }
    YSize =(LCDCDev.YSize*ScaleY+0x1ff)>>9;     //调整实际scale所需的Y值的大小,填补到最小数值
    Screen->OffsetX = (XSize<Screen->RawXSize) ? (Screen->RawXSize-XSize)/2 : 0;
    Screen->OffsetY = 0;
    if (XSize < Screen->RawXSize)   XSize = Screen->RawXSize;
    Screen->ViewXSize = XSize;
    Screen->ViewYSize = YSize;
    Screen->LLPList =LLPList;
    Screen->SdramAddr = SdramAddr;
    Screen->SdramAddr2 = SdramAddrUV;
    Screen->ScrFormat =YUV420;
    Config->StartX =0;
    Config->StartY =0;
    Config->ScaleX =ScaleX;
    Config->ScaleY =ScaleY;
    Config->YMIX =0;
    Config->Rgb565 = 0;
    if (Screen_GetType()==MCULCD)
        Config->IntrMask =b_INTR_PERLINE;
    else
        Config->IntrMask =b_VERT_INTR|b_INTR_PERLINE;

    Config->LineYAddr[0] = (XSize*0/4) | b_YUV_SRC|b_SCALE_EN;
    Config->LineYAddr[1] = (XSize*1/4) | b_YUV_SRC|b_SCALE_EN;
    Config->LineYAddr[2] = (XSize*2/4) | b_YUV_SRC|b_SCALE_EN;
    Config->LineYAddr[3] = (XSize*3/4) | b_YUV_SRC|b_SCALE_EN;

    Config->LineUVAddr[0] = XSize*4/4;
    Config->LineUVAddr[1] = XSize*4/4;
    Config->LineUVAddr[2] = XSize*5/4;
    Config->LineUVAddr[3] = XSize*5/4;

    Screen_CreatLLPMPEG2(Screen);

}



/*---------------------------------------------------------
Name  :  Screen_CreatAlpha
Dec   :  创建Alpha相关设置参数
Params:  FrontGrnd -> RGB565前景的相关配置参数
         LLPList   -> LLP链条首地址
         SdramAddr -> 数据源首地址
         XSize     -> 数据源宽度
         YSize     -> 数据源高度
         StartX    -> Alpha区域的X方向启始点
         TopY      -> Alpha区域的Y方向启始点
         BottomY   -> Alpha区域的Y方向终止点
         AlphaLevel-> Alpha参数
Return:
Author:  nzy
Date  :
-----------------------------------------------------------*/
SCREENRESULT Screen_CreatAlpha(FRONTGRND *FrontGrnd, DWDMALLP *LLPList, UINT32 SdramAddr, UINT16 XSize, UINT16 YSize, UINT16 StartX, UINT16 TopY, UINT16 BottomY, UINT16 AlphaLevel)
{

    UINT32 EndX;
    UINT32 Width, Height;

    if (BottomY < TopY || BottomY > LCDCDev.YSize)
        return ScreenError;

    StartX = StartX & 0xfff0;   //align 16
    EndX = ((StartX + XSize) & 0xfff0) - 1;   //align 4
    if (EndX >= LCDCDev.XSize)
    {
        EndX = LCDCDev.XSize - 1;
    }
    BottomY++;           //remaind one line for fill dark;
    Width = EndX - StartX + 1;
    Height = BottomY - TopY + 1;
    FrontGrnd->LLPList = LLPList;
    FrontGrnd->ScrFormat = RGB565;
    FrontGrnd->SdramAddr = SdramAddr;
    FrontGrnd->OffsetX = 0x0;
    FrontGrnd->OffsetY = 0x0;
    FrontGrnd->ViewXSize = Width;
    FrontGrnd->ViewYSize = Height;
    FrontGrnd->RawXSize = XSize;
    FrontGrnd->RawYSize = YSize;

    FrontGrnd->AlphaConfig.AlphaLevel = AlphaLevel;
    FrontGrnd->AlphaConfig.ALX = StartX;
    FrontGrnd->AlphaConfig.ATY = TopY;
    FrontGrnd->AlphaConfig.ARX = EndX;
    FrontGrnd->AlphaConfig.ABY = BottomY;
    FrontGrnd->AlphaConfig.FifoAddr = 0x800 - Width / 2;
    FrontGrnd->AlphaConfig.BLX = 0x3ff;
    FrontGrnd->AlphaConfig.BTY = 0x3ff;
    FrontGrnd->AlphaConfig.BRX = 0x3ff;
    FrontGrnd->AlphaConfig.BBY = 0x3ff;
    Screen_CreatLLPAlpha(FrontGrnd);

    return ScreenOK;
}


/*---------------------------------------------------------
Name  :  Screen_CreatLLPMIX
Dec   :  设置MIX YUV的相关LLP链接
Params:  Screen -> MIX YUV背景的相关配置参数
Return:
Author:  nzy
Date  :
-----------------------------------------------------------*/
void Screen_CreatLLPMIX(BACKGRND *Screen)
{
    UINT32 Line, Bufoffset, Lineoffset, ScaleStep;
    UINT32 SYWidth, SUVWidth, DYWidth, DUVWidth, Datalen;
    UINT32 SourYAddr, SourUVAddr, DestYAddr, DestUVAddr;
    UINT32 OffsetX, OffsetY, Temp;
    UINT32 VirTolLine = 0, VirLine = 0, ActLine = 0;
    DWDMALLP *LLPList;

    SYWidth    = Screen->RawXSize / 2;
    SUVWidth   = Screen->RawXSize / 4;
    DYWidth    = Screen->ViewXSize / 2;
    DUVWidth   = Screen->ViewXSize / 4;
    Datalen    = Screen->RawXSize > Screen->ViewXSize ? DUVWidth : SUVWidth;
    Bufoffset  = Screen->RawXSize > Screen->ViewXSize ? 0 : ((Screen->ViewXSize - Screen->RawXSize) / 2) & 0xfffc;
    Lineoffset = Screen->RawYSize > Screen->ViewYSize ? 0 : ((Screen->ViewYSize - Screen->RawYSize) / 2) & 0xfffe;
    OffsetX    = Screen->OffsetX / 4;
    OffsetY    = Screen->OffsetY / 2;
    SourYAddr  = 8 * OffsetX + 4 * SYWidth * OffsetY + Screen->SdramAddr;
    SourUVAddr = 4 * OffsetX + 4 * SUVWidth * OffsetY + Screen->SdramAddr + Screen->RawXSize * ((Screen->RawYSize + 15) & 0xfff0);
    DestYAddr  = (UINT32)RegLCDC_BUF;
    DestUVAddr = DestYAddr + 12 * DYWidth;
    ScaleStep  = Screen->LCDCConfig.ScaleY;
    LLPList    = Screen->LLPList;
    Temp       = (Screen_GetType() == TVOUT) ? 3 : 0;

    DWDMA_LLPCfg((UINT32)SDRAM_DARK_Y, DestYAddr, LLPList, 3*DYWidth);
    DWDMA_LLPCfg((UINT32)SDRAM_DARK_UV, DestUVAddr, LLPList + 1, 3*DUVWidth);
    DWDMA_LLPChange(LLPList + 1, LLPList + 6);

    LLPList += 2;

    for (Line = 0; Line < LCDCDev.YSize; Line++, LLPList += 2)
    {
        if (Line > 1)
        {
            //LCD的第一行请求用来发送LCDC的LINE3
            VirTolLine += ScaleStep;
            VirLine = 4 + (VirTolLine >> 9);
        }

        //缩放和DWA的协调功能
        if ((VirLine / 2) >= ActLine)
        {
            if ((ActLine < Temp + Lineoffset / 2) || (ActLine >= (Screen->RawYSize + Lineoffset) / 2))
            {
                //当Y方向上无法满屏显示时,上下填充黑色
                DWDMA_LLPCfg((UINT32)SDRAM_DARK_Y, DestYAddr + (ActLine % 3)*4*DYWidth, LLPList, DYWidth);
                DWDMA_LLPCfg((UINT32)SDRAM_DARK_UV, DestUVAddr + (ActLine % 3)*4*DUVWidth, LLPList + 1, DUVWidth);
            }
            else
            {
                //填充有效的视频数据
                DWDMA_LLPCfg(SourYAddr + (ActLine - Temp - Lineoffset / 2)*4*SYWidth, DestYAddr + 2*Bufoffset + ((ActLine - Temp) % 3)*4*DYWidth, LLPList, 2*Datalen);
                DWDMA_LLPCfg(SourUVAddr + (ActLine - Temp - Lineoffset / 2)*4*SUVWidth, DestUVAddr + Bufoffset + ((ActLine - Temp) % 3)*4*DUVWidth, LLPList + 1, Datalen);
            }
            ActLine ++;
        }
        else
        {
            //等待LCDC当前行的Buffer数据发送完毕
            DWDMA_LLPCfg(SourYAddr, SourYAddr, LLPList, 1);
            DWDMA_LLPCfg(SourYAddr, SourYAddr, LLPList + 1, 1);
        }

        //先发送两行到LCDC buffer
        if (Line < 1)  VirLine += 2;
    }

    DWDMA_LLPChange(LLPList - 1, &LCDCDev.LLPTable);//上一屏的LLP的最后位置链接到当前屏的LLP的首位置

    if (Screen_GetType() != MCULCD)
    {
        DWDMA_LLPChange(Screen->LLPList + 5, LLPList);
        for (Line = 0; Line < 4; Line++, LLPList++)
            DWDMA_LLPCfg(SourYAddr, SourYAddr, LLPList, 1);
        DWDMA_LLPChange(LLPList - 1, Screen->LLPList + 6);
    }
    else
        DWDMA_LLPEnd(Screen->LLPList + 3);//传完LCD的前两行后停止LLP链接

}


/*---------------------------------------------------------
Name  :  Screen_CreatLLPRGB
Dec   :  设置RGB888的相关LLP链接
Params:  Screen -> RGB888背景的相关配置参数
Return:
Author:  nzy
Date  :
-----------------------------------------------------------*/
void Screen_CreatLLPRGB(BACKGRND *Screen)
{
    UINT32 Line, Bufoffset, Lineoffset;
    UINT32 SWidth, DWidth, Datalen, LineFactor;
    UINT32 SourRGBAddr, DestRGBAddr;
    UINT32 SourAddr, DestAddr;
    DWDMALLP *LLPList;

    SWidth      = Screen->RawXSize;
    DWidth      = Screen->ViewXSize;
    Bufoffset   = Screen->RawXSize>Screen->ViewXSize ? 0 : (Screen->ViewXSize -Screen->RawXSize)/2;
    Lineoffset  = Screen->RawYSize>Screen->ViewYSize ? 0 : (Screen->ViewYSize -Screen->RawYSize)/2;
    if (RGB565==Screen->ScrFormat)
    {
        SWidth      = SWidth/2;
        DWidth      = DWidth/2;
        Bufoffset   = Bufoffset/2;
        Lineoffset  = Lineoffset/2;
    }
    Datalen     = Screen->RawXSize > Screen->ViewXSize ? DWidth : SWidth;
    SourRGBAddr = Screen->SdramAddr;
    DestRGBAddr = (UINT32)RegLCDC_BUF;
    LLPList     = Screen->LLPList;
    LineFactor  = (DWidth > 448) ? 2 : 4;

    for (Line = 0; Line < LCDCDev.YSize; Line++, LLPList++)
    {
        if ((Line < Lineoffset) || (Line >= Screen->RawYSize + Lineoffset))
            SourAddr = (UINT32)SDRAM_DARK_RGB;//当Y方向上无法满屏显示时,上下填充黑色
        else
            SourAddr = SourRGBAddr + (Line - Lineoffset) * 4 * SWidth;//填充有效的系统UI数据

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -