📄 hw_screen.c
字号:
/******************************************************************/
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*******************************************************************
File : hw_Screen.c
Desc : 逻辑屏物理屏控制
Author : nzy
Date : 2007
Notes :
$Log :
*********************************************************************/
#include "hw_include.h"
#include "hw_Dwdma.h"
#include "hw_Lcdctrl.h"
#include "hw_Screen.h"
#include "hwapi_Dwdma.h"
#include "hwapi_Mcupanel.h"
#include "hwapi_Rgbpanel.h"
#include "hwapi_Lcdctrl.h"
UINT32 SDRAM_DARK_Y[2056];
UINT32 SDRAM_DARK_UV[1280];
UINT32 SDRAM_DARK_RGB[1280];
LCDCDEV LCDCDev;
DWDMALLP AlphaDarkLLP;
UPDATESTA LCDUpDateStatus = UpDateIdle;
SCREENTYPE Screen_Type;
ALPHAEN AlphaEnable = FIFODisable;
/*---------------------------------------------------------
Name : Screen_SetType
Dec : 设置显示模块的类型
Params: ScreenType -> 显示模块的类型
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
void Screen_SetType(SCREENTYPE ScreenType)
{
Screen_Type = ScreenType;
}
/*---------------------------------------------------------
Name : Screen_GetType
Dec : 获取显示模块的类型
Params:
Return: ScreenType -> 显示模块的类型
Author: nzy
Date :
-----------------------------------------------------------*/
SCREENTYPE Screen_GetType(void)
{
return Screen_Type;
}
/*---------------------------------------------------------
Name : Screen_SetMCUUpDatStat
Dec : 设置显示模块的类型
Params: MCUUpDatStat -> MCU刷屏配置状态
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
void Screen_SetMCUUpDatStat(UPDATESTA MCUUpDatStat)
{
LCDUpDateStatus = MCUUpDatStat;
}
/*---------------------------------------------------------
Name : Screen_GetMCUUpDatStat
Dec : 获取显示模块的类型
Params:
Return: MCUUpDatStat -> MCU刷屏配置状态
Author: nzy
Date :
-----------------------------------------------------------*/
UPDATESTA Screen_GetMCUUpDatStat(void)
{
return LCDUpDateStatus;
}
/*---------------------------------------------------------
Name : Screen_SetAlphaEn
Dec : 设置Alpha使能转态
Params: AlphaEn -> Alpha使能转态
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
void Screen_SetAlphaEn(ALPHAEN AlphaEn)
{
AlphaEnable = AlphaEn;
}
/*---------------------------------------------------------
Name : Screen_GetAlphaEn
Dec : 获取Alpha使能转态
Params:
Return: AlphaEn -> Alpha使能转态
Author: nzy
Date :
-----------------------------------------------------------*/
ALPHAEN Screen_GetAlphaEn(void)
{
return AlphaEnable;
}
/*---------------------------------------------------------
Name : Screen_MCUUpDate
Dec : MCU接口物理刷屏
Params:
Return: UPDATESTATUS 值返回用于DMA及LCD状态检测判断,若DMA channel或LCD的状态为忙返回ERROR,尚未处理。
包括Screen和Alpha切换过程处理
Author: nzy
Date :
-----------------------------------------------------------*/
SCREENRESULT Screen_MCUUpDate(void)
{
UINT32 i;
if (Screen_GetType() != MCULCD)//防止电视输出时MCU接口刷屏
return ScreenOK;
if (Screen_GetMCUUpDatStat() == UpDating)//防止重入
return ScreenError;
Screen_SetMCUUpDatStat(UpDating);
if (Screen_GetMCUIFStatus() == BUSY)//防止交叉刷屏
{
Screen_SetMCUUpDatStat(UpDateIdle);
return ScreenError;
}
if (LCDCDev.Screen != 0x0)
{
DWDMA_DisChannel(CH0);
if (LCDCDev.ReConfig)
{
LcdCtrl_BackGroundSet(&LCDCDev.Screen->LCDCConfig); //config LCDC 的动态属性,不包括硬件属性
LCDCDev.ReConfig = 0;
if ((LCDCDev.Screen->ScrFormat == RGB565) || (LCDCDev.Screen->ScrFormat == RGB888))
{
for (i = 0; i < 4; i++)
memcpy((UINT32)RegLCDC_BUF + 4*i*LCDCDev.XSize, SDRAM_DARK_RGB, 4*LCDCDev.XSize);
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList);
DWDMA_Transmit(CH0, &LCDCDev.LLPTable, DWDMA_YUV_HS);
}
else
{
if (((LCDCDev.Screen->ScrFormat == YUV422)) || (LCDCDev.Screen->ScrFormat == YUV420))
DWDMA_DestScatter(CH0, LCDCDev.Screen->RawXSize / 4, (LCDCDev.Screen->ViewXSize - LCDCDev.Screen->RawXSize) / 4);
DWDMA_Transmit(CH0, LCDCDev.Screen->LLPList, DWDMA_YUV_HS);//开始刷上一屏
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList + 2);//将上一屏的最后指到当前屏开始位置
}
delay_nops(2000); //wait for DMA complete
}
else
{
if (LCDCDev.LLPTable.LLP != 0)
{
if ((LCDCDev.Screen->ScrFormat == RGB565) || (LCDCDev.Screen->ScrFormat == RGB888))
{
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList);
DWDMA_Transmit(CH0, &LCDCDev.LLPTable, DWDMA_YUV_HS);
}
else
{
if (((LCDCDev.Screen->ScrFormat == YUV422)) || (LCDCDev.Screen->ScrFormat == YUV420))
DWDMA_DestScatter(CH0, LCDCDev.Screen->RawXSize / 4, (LCDCDev.Screen->ViewXSize - LCDCDev.Screen->RawXSize) / 4);
DWDMA_Transmit(CH0, LCDCDev.LLPTable.LLP + 1, DWDMA_YUV_HS);
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList + 2);
}
}
}
}
if (LCDCDev.FrontGrnd != 0x0)
{
DWDMA_DisChannel(CH1);
WriteReg32(BUFF_CTRL, ReadReg32(BUFF_CTRL)&(~b_LCDC_FIFOEN)); //front data buffer address in LCDC
if (LCDCDev.ReConfigAlpha != 0)
{
LCDCDev.ReConfigAlpha = 0;
LcdCtrl_FrontGroundSet(&LCDCDev.FrontGrnd->AlphaConfig);
}
if (LCDCDev.FrontGrnd->AlphaConfig.AlphaLevel < 0x100)
{
DWDMA_Transmit(CH1, LCDCDev.FrontGrnd->LLPList, DWDMA_FIFO_HS);
WriteReg32(BUFF_CTRL, (ReadReg32(BUFF_CTRL) | b_LCDC_FIFOEN)); //front data buffer address in LCDC
}
}
else
{
if (Screen_GetAlphaEn() == FIFODisable)
WriteReg32(BUFF_CTRL, ReadReg32(BUFF_CTRL) &(~b_LCDC_FIFOEN));
else
{
DWDMA_DisChannel(CH1);
DWDMA_Transmit(CH1, &AlphaDarkLLP, DWDMA_FIFO_HS);
Screen_SetAlphaEn(FIFODisable);
}
}
delay_nops(2500); //wait for DMA complete
WriteReg32(BUFF_CTRL, ReadReg32(BUFF_CTRL) | b_BUFF_START | b_BUFF_WRITE | b_BUFF_LINE0 | b_RS_HIGH);
Screen_SetMCUUpDatStat(UpDateIdle);
return ScreenOK;
}
/*---------------------------------------------------------
Name : Screen_RGBUpDate
Dec : RGB接口物理刷屏
Params:
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
void Screen_RGBUpDate(void)
{
UINT32 i;
if (LCDCDev.Screen != 0x0)
{
DWDMA_DisChannel(CH0);
if (LCDCDev.ReConfig)
{
LcdCtrl_BackGroundSet(&LCDCDev.Screen->LCDCConfig); //config LCDC 的动态属性,不包括硬件属性
LCDCDev.ReConfig = 0;
if ((LCDCDev.Screen->ScrFormat == RGB565) || (LCDCDev.Screen->ScrFormat == RGB888))
{
for (i = 0; i < 4; i++)
memcpy((UINT32)RegLCDC_BUF + 4*i*LCDCDev.XSize, SDRAM_DARK_RGB, 4*LCDCDev.XSize);
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList);
DWDMA_Transmit(CH0, LCDCDev.LLPTable.LLP + 1, DWDMA_YUV_HS);
}
else
{
if ((LCDCDev.Screen->ScrFormat == YUV420) || (LCDCDev.Screen->ScrFormat == YUV422))
{
memcpy((UINT32)RegLCDC_BUF, SDRAM_DARK_UV, 2*LCDCDev.Screen->ViewXSize);
memcpy((UINT32)RegLCDC_BUF + 2*LCDCDev.Screen->ViewXSize, SDRAM_DARK_Y, 4*LCDCDev.Screen->ViewXSize);
DWDMA_DestScatter(CH0, LCDCDev.Screen->RawXSize / 4, (LCDCDev.Screen->ViewXSize - LCDCDev.Screen->RawXSize) / 4);
}
else
{
memcpy((UINT32)RegLCDC_BUF, SDRAM_DARK_Y, 4*LCDCDev.Screen->ViewXSize);
memcpy((UINT32)RegLCDC_BUF + 6*LCDCDev.Screen->ViewXSize, SDRAM_DARK_UV, 2*LCDCDev.Screen->ViewXSize);
}
DWDMA_Transmit(CH0, LCDCDev.Screen->LLPList, DWDMA_YUV_HS);//开始刷上一屏
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList + 2);//将上一屏的最后指到当前屏开始位置
}
}
else
{
if (LCDCDev.LLPTable.LLP != 0)
{
if ((LCDCDev.Screen->ScrFormat == RGB565) || (LCDCDev.Screen->ScrFormat == RGB888))
{
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList);
DWDMA_Transmit(CH0, LCDCDev.LLPTable.LLP + 1, DWDMA_YUV_HS);
}
else
{
if (((LCDCDev.Screen->ScrFormat == YUV422)) || (LCDCDev.Screen->ScrFormat == YUV420))
DWDMA_DestScatter(CH0, LCDCDev.Screen->RawXSize / 4, (LCDCDev.Screen->ViewXSize - LCDCDev.Screen->RawXSize) / 4);
DWDMA_Transmit(CH0, LCDCDev.LLPTable.LLP + 3, DWDMA_YUV_HS);
LCDCDev.LLPTable = *(LCDCDev.Screen->LLPList + 2);
}
}
}
}
if (LCDCDev.FrontGrnd != 0x0)
{
DWDMA_DisChannel(CH1);
WriteReg32(BUFF_CTRL, ReadReg32(BUFF_CTRL)&(~b_LCDC_FIFOEN)); //front data buffer address in LCDC
if (LCDCDev.ReConfigAlpha != 0)
{
LCDCDev.ReConfigAlpha = 0;
LcdCtrl_FrontGroundSet(&LCDCDev.FrontGrnd->AlphaConfig);
}
if (LCDCDev.FrontGrnd->AlphaConfig.AlphaLevel < 0x100)
{
DWDMA_Transmit(CH1, LCDCDev.FrontGrnd->LLPList, DWDMA_FIFO_HS);
WriteReg32(BUFF_CTRL, (ReadReg32(BUFF_CTRL) | b_LCDC_FIFOEN)); //front data buffer address in LCDC
}
}
else
{
if (Screen_GetAlphaEn() == FIFODisable)
WriteReg32(BUFF_CTRL, ReadReg32(BUFF_CTRL) &(~b_LCDC_FIFOEN));
else
{
DWDMA_DisChannel(CH1);
DWDMA_Transmit(CH1, &AlphaDarkLLP, DWDMA_FIFO_HS);
Screen_SetAlphaEn(FIFODisable);
}
}
}
/*---------------------------------------------------------
Name : Screen_RGBIFIsr
Dec : RGB接口中断函数
Params:
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
void Screen_RGBIFIsr(void)
{
UINT32 temp;
if (Screen_GetType() == MCULCD)//MCU式刷屏时关闭RGB式刷屏
return;
if (((temp = ReadReg32(LCDC_STA)) & b_VERT_ACTIVE) == 0x0)
{
Screen_RGBUpDate();
}
}
/*---------------------------------------------------------
Name : Screen_Configure
Dec : Screen上电初始化
Params: XSize -> 屏的物理宽度
YSize -> 屏的物理高度
ScreenType -> 显示模块的类型
TvoutType -> 视频或系统UI
TvoutSize -> TVOUT显示大小
TvoutMode -> TVOUT显示制式
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
void Screen_Configure(UINT16 XSize, UINT16 YSize, SCREENTYPE ScreenType, TVOUTPARA *pTVoutPara)
{
UINT32 frame;
while (Screen_GetMCUIFStatus() == BUSY);//mcu测试,是否获取得到
LCDCDev.XSize = XSize;
LCDCDev.YSize = YSize;
LCDCDev.ReConfig = 0;
LCDCDev.Screen = 0x0;
LCDCDev.FrontGrnd = 0x0;
LCDCDev.ReConfigAlpha = 0;
LCDCDev.LLPTable.LLP = 0;
Screen_SetType(ScreenType);
DWDMA_Init();
for (frame = 0; frame < 4; frame++)
memcpy((UINT32)RegLCDC_BUF + 4*frame*XSize, SDRAM_DARK_RGB, 4*XSize);
LcdCtrl_Configure(XSize, YSize, pTVoutPara);
if (Screen_GetType() == MCULCD)
Intr_Disable(INTC_LCDC);
else
Intr_Enable(INTC_LCDC);
}
/*---------------------------------------------------------
Name : Screen_PowerOnInit
Dec : Screen上电初始化,只调用一次
Params: XSize -> 屏的物理宽度
YSize -> 屏的物理高度
TvoutSize -> TVOUT显示大小
TvoutMode -> TVOUT显示制式
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
void Screen_PowerOnInit(UINT16 XSize, UINT16 YSize, TVOUTPARA *pTVoutPara)
{
UINT32 frame;
for (frame = 0; frame < 2560; frame++)
SDRAM_DARK_Y[frame] = 0x10101010;
for (frame = 0; frame < 1280; frame++)
SDRAM_DARK_UV[frame] = 0x80808080;
for (frame = 0; frame < 1280; frame++)
SDRAM_DARK_RGB[frame] = 0x00000000;
LcdCtrl_PowerOnInit();
#if 1
#ifdef MCU_PANEL
Screen_Configure(XSize, YSize, MCULCD, pTVoutPara);
#else
Screen_Configure(XSize, YSize, RGBLCD, pTVoutPara);
#endif
#else
Screen_Configure(XSize, YSize, TVOUT, pTVoutPara);
Tvout_Display(TV_ON, TV_PAL50);
#endif
Intr_SetType(INTC_LCDC, POSITIVE_EDGE);
Intr_RegISR(INTC_LCDC, Screen_RGBIFIsr);
}
/*---------------------------------------------------------
Name : Screen_CreatRGB
Dec : 创建背景为RGB888的相关设置参数
Params: Screen -> RGB888背景的相关配置参数
LLPList -> LLP链条首地址
SdramAddr-> 数据源首地址
XSize -> 数据源宽度
YSize -> 数据源高度
Return:
Author: nzy
Date :
-----------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -