📄 drvvop.c
字号:
U8 regval;
#ifdef DBG_VOP
printf ( "[Drvvop.c::MDrv_VOP_EnableBlackBG()]\r\n" );
#endif
//set VOP test pattern to black
XBYTE[VOP_TST_IMG + 1] = 0x10;
XBYTE[VOP_U_PAT ] = 0x80;
XBYTE[VOP_U_PAT + 1] = 0x80;
regval = XBYTE[VOP_TST_IMG];
XBYTE[VOP_TST_IMG] = 0x02;
XBYTE[VOP_TST_IMG] = 0x00;
XBYTE[VOP_TST_IMG] = regval;
}
/******************************************************************************/
/// Set VOP output timing
/// @param ptiming \b IN VOP timing setting
/******************************************************************************/
void MDrv_VOP_SetOutputTiming ( MS_VOP_TIMING *ptiming )
{
U16 u16TF_VS, u16BF_VS;
U8 regval;
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_SetOutputTiming()]\r\n" );
#endif
XBYTE[VOP_FRAME_VCOUNT ] = LOWBYTE( ptiming->u16V_TotalCount );
XBYTE[VOP_FRAME_VCOUNT + 1] = HIGHBYTE( ptiming->u16V_TotalCount );
XBYTE[VOP_FRAME_HCOUNT ] = LOWBYTE( ptiming->u16H_TotalCount );
XBYTE[VOP_FRAME_HCOUNT + 1] = HIGHBYTE( ptiming->u16H_TotalCount );
XBYTE[VOP_VB0_STR ] = LOWBYTE( ptiming->u16VBlank0_Start );
XBYTE[VOP_VB0_STR + 1] = HIGHBYTE( ptiming->u16VBlank0_Start );
XBYTE[VOP_VB0_END ] = LOWBYTE( ptiming->u16VBlank0_End );
XBYTE[VOP_VB0_END + 1] = HIGHBYTE( ptiming->u16VBlank0_End );
XBYTE[VOP_VB1_STR ] = LOWBYTE( ptiming->u16VBlank1_Start );
XBYTE[VOP_VB1_STR + 1] = HIGHBYTE( ptiming->u16VBlank1_Start );
XBYTE[VOP_VB1_END ] = LOWBYTE( ptiming->u16VBlank1_End );
XBYTE[VOP_VB1_END + 1] = HIGHBYTE( ptiming->u16VBlank1_End );
XBYTE[VOP_TF_STR ] = LOWBYTE( ptiming->u16TopField_Start );
XBYTE[VOP_TF_STR + 1] = HIGHBYTE( ptiming->u16TopField_Start );
XBYTE[VOP_BF_STR ] = LOWBYTE( ptiming->u16BottomField_Start );
XBYTE[VOP_BF_STR + 1] = HIGHBYTE( ptiming->u16BottomField_Start );
XBYTE[VOP_HACT_STR ] = LOWBYTE( ptiming->u16HActive_Start );
XBYTE[VOP_HACT_STR + 1] = HIGHBYTE( ptiming->u16HActive_Start );
// Use VOP_VS_OFFSET in Saturn2.
// Instead, we use VOP_TF_VS & VOP_BF_VS directly to locate Vsync.
u16TF_VS = ptiming->u16VBlank0_Start + (U16)ptiming->u8VSync_Offset;
XBYTE[VOP_TF_VS ] = LOWBYTE( u16TF_VS );
XBYTE[VOP_TF_VS + 1] = HIGHBYTE( u16TF_VS );
u16BF_VS = ptiming->u16VBlank1_Start + (U16)ptiming->u8VSync_Offset;
if (ptiming->bInterlace) u16BF_VS -= 1;
XBYTE[VOP_BF_VS ] = LOWBYTE( u16BF_VS );
XBYTE[VOP_BF_VS + 1] = HIGHBYTE( u16BF_VS );
// + Saturn2, set default IMG_HSTR, IMG_VSTR0, IMG_VSTR1
XBYTE[VOP_IMG_HSTR ] = LOWBYTE( ptiming->u16HActive_Start );
XBYTE[VOP_IMG_HSTR + 1] = HIGHBYTE( ptiming->u16HActive_Start );
XBYTE[VOP_IMG_VSTR0 ] = LOWBYTE( ptiming->u16VBlank0_End );
XBYTE[VOP_IMG_VSTR0+ 1] = HIGHBYTE( ptiming->u16VBlank0_End );
XBYTE[VOP_IMG_VSTR1 ] = LOWBYTE( ptiming->u16VBlank1_End );
XBYTE[VOP_IMG_VSTR1+ 1] = HIGHBYTE( ptiming->u16VBlank1_End );
// select mvop output from frame color(black)
XBYTE[VOP_TST_IMG + 1] = 0x10;
XBYTE[VOP_U_PAT ] = 0x80;
XBYTE[VOP_U_PAT + 1] = 0x80;
// set mvop src to test pattern
regval = XBYTE[VOP_TST_IMG];
XBYTE[VOP_TST_IMG] = 0x02;
// make changed registers take effect
XBYTE[VOP_REG_WR] = 1;
XBYTE[VOP_REG_WR] = 0;
// reset mvop to avoid timing change cause mvop hang-up
XBYTE[VOP_CTRL0] &= ~0x1;
XBYTE[VOP_CTRL0] |= 0x1;
// select mvop output from mvd
XBYTE[VOP_TST_IMG] = 0x00;
XBYTE[VOP_TST_IMG] = regval;
#ifdef DBG_VOP
printf("VTot=%u\n",ptiming->u16V_TotalCount);
printf("HTot=%u\n",ptiming->u16H_TotalCount);
printf("VB0Str=%u\n",ptiming->u16VBlank0_Start);
printf("VB0End=%u\n",ptiming->u16VBlank0_End);
printf("VB1Str=%u\n",ptiming->u16VBlank1_Start);
printf("VB1End=%u\n",ptiming->u16VBlank1_End);
printf("TFStr=%u\n",ptiming->u16TopField_Start);
printf("BFStr=%u\n",ptiming->u16BottomField_Start);
printf("HAct=%u\n",ptiming->u16HActive_Start);
printf("TF_VS=%u\n",u16TF_VS);
printf("BF_VS=%u\n",u16BF_VS);
printf("I/P=%bu\n",ptiming->bInterlace);
printf("FRate=%bu\n",ptiming->u8Framerate);
printf("HFreq=%u\n",ptiming->u16H_Freq);
printf("Num=0x%x\n",ptiming->u16Num);
printf("Den=0x%x\n",ptiming->u16Den);
printf("W=%u\n",ptiming->u16Width);
printf("H=%u\n",ptiming->u16Height);
//printf("pixclk=0x%lx\n", ptiming->u32PixelClock);
printf("u16ExpFRate=0x%u\n", ptiming->u16ExpFrameRate);
#endif
}
/******************************************************************************/
// Set VOP clock enable
// @param bEnable \b IN
// - # TRUE Enable clock
// - # FALSE Close clock
/******************************************************************************/
void MDrv_VOP_SetVOPSynClkEable ( BOOLEAN bEnable )
{
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_SetVOPSynClkEable()]\r\n" );
#endif
MDrv_WriteByteMask(REG_CKG_DC0, ((bEnable==0)<<4), (1<<4)); // [4] 0:enable, 1:disable
}
/******************************************************************************/
/// Set VOP sync clock
/// @param ptiming \b IN VOP timing setting (pixel clock)
/******************************************************************************/
void MDrv_VOP_SetVOPSynClk ( MS_VOP_TIMING *ptiming )
{
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_SetVOPSynClk()]\r\n" );
#endif
#if 1
// select num/den
MDrv_WriteByteMask(REG_CKG_DC0, (0<<6), (3<<6)); // [7:6] set to 0
XBYTE[REG_DC0_NUM ] = LOWBYTE( ptiming->u16Num);
XBYTE[REG_DC0_NUM+1] = HIGHBYTE(ptiming->u16Num);
XBYTE[REG_DC0_DEN ] = LOWBYTE( ptiming->u16Den);
XBYTE[REG_DC0_DEN+1] = HIGHBYTE(ptiming->u16Den);
// set reg_update_dc0_sync_cw[14]=1
MDrv_WriteByteMask(REG_UPDATE_DC0_SYNC_CW+1, (1<<6), (1<<6));
MDrv_WriteByteMask(REG_UPDATE_DC0_SYNC_CW+1, (0<<6), (1<<6));
#ifdef DBG_VOP
printf("num=0x%x,den=0x%x\n", ptiming->u16Num, ptiming->u16Den);
#endif
#else
// select freerun_cw (for num/den hardware fail case)
MDrv_WriteByteMask(REG_CKG_DC0, (1<<6), (3<<6)); // [7:6] set to 1
u32tmp.u32Num = ptiming->u32PixelClock;
XBYTE[REG_DC0_FREERUN_CW_L ] = u32tmp.u8Num[3];
XBYTE[REG_DC0_FREERUN_CW_L+1] = u32tmp.u8Num[2];
XBYTE[REG_DC0_FREERUN_CW_H ] = u32tmp.u8Num[1];
XBYTE[REG_DC0_FREERUN_CW_H+1] = u32tmp.u8Num[0];
// set reg_update_dc0_sync_cw[11]=1
MDrv_WriteByteMask(REG_UPDATE_DC0_SYNC_CW+1, (1<<3), (1<<3));
#endif
#ifdef DBG_VOP
printf( "MDrv_VOP_SetVOPSynClk \r\n" );
printf( "u16V_TotalCount=%d \r\n", ptiming->u16V_TotalCount );
printf( "u16H_TotalCount=%d \r\n", ptiming->u16H_TotalCount );
printf( "u8Framerate=%bd \r\n", ptiming->u8Framerate );
#endif
}
#if 0
/******************************************************************************/
/// Set VOP for SD and MCU controlled mode
/******************************************************************************/
void MDrv_VOP_JPEGInit ( void )
{
U8 regval;
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_JPEGInit()] Ask if 422pack need to set\n" );
#endif
regval = XBYTE[VOP_MPG_JPG_SWITCH];
XBYTE[VOP_MPG_JPG_SWITCH] = (regval & 0xfc) | 0x2; // only set to MCU Ctrl mode
}
#endif
/******************************************************************************/
/// Move setting set by MDrv_VOP_SetJPEGBuffAddr and MDrv_VOP_SetJPEGSize
/// from internal register buffer to active registers
/******************************************************************************/
void MDrv_VOP_JPEGCmdFire ( void )
{
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_JPEGCmdFire()]\r\n" );
#endif
XBYTE[VOP_REG_WR] = 0x10;
XBYTE[VOP_REG_WR] = 0x0;
}
/******************************************************************************/
/// Set uncompressed image address
/// @param u32YAddr \b IN Address for Y
/// @param u32UVAddr \b IN Address for UV
/******************************************************************************/
void MDrv_VOP_SetJPEGBuffAddr ( U32 u32YAddr, U32 u32UVAddr )
{
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_SetJPEGBuffAddr()]\r\n" );
#endif
u32YAddr = u32YAddr >> 3;//8 Byte alignment
u32UVAddr = u32UVAddr >> 3;//8 Byte alignment
XBYTE[VOP_JPG_YSTR0_L ] = u32YAddr & 0xff;
XBYTE[VOP_JPG_YSTR0_L + 1] = ( u32YAddr >> 8 ) & 0xff;
XBYTE[VOP_JPG_YSTR0_H ] = ( u32YAddr >> 16 ) & 0xff;
XBYTE[VOP_JPG_UVSTR0_L ] = u32UVAddr & 0xff;
XBYTE[VOP_JPG_UVSTR0_L+ 1] = ( u32UVAddr >> 8 ) & 0xff;
XBYTE[VOP_JPG_UVSTR0_H ] = ( u32UVAddr >> 16 ) & 0xff;
}
#if 0
/******************************************************************************/
/// Set uncompressed image size
/// @param u16HSize \b IN Horizontal size
/// @param u16VSize \b IN Vertical size
/******************************************************************************/
void MDrv_VOP_SetJPEGSize ( U16 u16HSize, U16 u16VSize )
{
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_SetJPEGSize()]\r\n" );
#endif
XBYTE[VOP_JPG_HSIZE ] = u16HSize & 0xff;
XBYTE[VOP_JPG_HSIZE + 1] = ( u16HSize >> 8 ) & 0xff;
XBYTE[VOP_JPG_VSIZE ] = u16VSize & 0xff;
XBYTE[VOP_JPG_VSIZE + 1] = ( u16VSize >> 8 ) & 0xff;
}
/******************************************************************************/
/******************************************************************************/
void MDrv_VOP_TestSetting ()
{
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_TestSetting()]\r\n" );
#endif
XBYTE[VOP_TST_IMG + 1] = 0x51;
XBYTE[VOP_U_PAT ] = 0x5A;
XBYTE[VOP_U_PAT + 1] = 0xF0;
}
// ------------------------------------------------------------------------------------------------------------------
/// Set VOP Image Start Position
/// This Funtion can move your video showing to any other position.
/// You can also input "minus" value shift to "left" or "top", "plus" value shift to "right" or "bottom".
/// @param s16H_start \b IN: Horizontal Start Position
/// @param s16V_start \b IN: Vertical Start Position
// ------------------------------------------------------------------------------------------------------------------
void MDrv_VOP_SetImageStart(S16 s16H_start, S16 s16V_start)
{
U16 u16Reg_HACT_STR;
U16 u16Reg_VB_END0;
U16 u16Reg_VB_END1;
U16 u16tmp;
#ifdef DBG_VOP
printf( "[Drvvop.c:MDrv_VOP_SetImageStart()]\r\n" );
#endif
u16Reg_HACT_STR = (XBYTE[VOP_HACT_STR +1] <<8) | XBYTE[VOP_HACT_STR];
u16Reg_VB_END0 = (XBYTE[VOP_VB0_END +1]<<8) | XBYTE[VOP_VB0_END];
u16Reg_VB_END1 = (XBYTE[VOP_VB1_END +1]<<8) | XBYTE[VOP_VB1_END];
if (((int)u16Reg_HACT_STR + s16H_start) < 0)
u16tmp = 0;
else
u16tmp = u16Reg_HACT_STR + s16H_start;
XBYTE[VOP_IMG_HSTR ] = LOWBYTE( u16tmp );
XBYTE[VOP_IMG_HSTR + 1] = HIGHBYTE(u16tmp );
if (((int)u16Reg_VB_END0 + s16V_start) < 0)
u16tmp = 0;
else
u16tmp = u16Reg_VB_END0 + s16V_start;
XBYTE[VOP_IMG_VSTR0 ] = LOWBYTE( u16tmp );
XBYTE[VOP_IMG_VSTR0+ 1] = HIGHBYTE(u16tmp );
if (((int)u16Reg_VB_END1 + s16V_start) < 0)
u16tmp = 0;
else
u16tmp = u16Reg_VB_END1 + s16V_start;
XBYTE[VOP_IMG_VSTR1 ] = LOWBYTE( u16tmp );
XBYTE[VOP_IMG_VSTR1+ 1] = HIGHBYTE(u16tmp );
XBYTE[VOP_REG_WR] = 1;
XBYTE[VOP_REG_WR] = 0;
}
void MDrv_VOP_DumpReg()
{
U16 i, val;
printf("MDrv_VOP_DumpReg()\r\n");
for (i=0; i<34; i++) {
val = (U16)XBYTE[MVOP_REG_BASE+2*i+1];
val <<= 8;
val |= (U16)XBYTE[MVOP_REG_BASE+2*i];
printf("reg=0x%02x,val=0x%04x\n", i, val);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -