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

📄 drvmvd.c

📁 mstar 776 开发的车载dvd
💻 C
📖 第 1 页 / 共 2 页
字号:

////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2007 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// (¨MStar Confidential Information〃) by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
///@file drvmvd.h
///@brief Driver interface for accessing the MPEG video decoder.
///
///@author MStarSemi Inc.
///
///- Providing MPEG video decoder command functions for controlling firmware.
///- MPEG video decoder can support Standard definition and High definition video
///
///@image html mvd.jpg MVD module
///
///@par Example
///@code
///  //Sample code for MVD Command
///  //Input: MVD command
///    void msAPI_VID_MVDCommand ( U8 u8MVDCommand )
///    {
///        /*Reset MVD command argument*/
///        memset(&stCmdArg,0x00,sizeof(MVD_CMD_ARG));
///        switch ( u8MVDCommand )
///        {
///            case MSAPI_VID_PLAY:
///                /*Send play command*/
///                MDrv_Mvd_MVDCommand( MVD_PLAY, &stCmdArg );
///                break;
///            case MSAPI_VID_RESET:
///                /*Reset MVD*/
///                MDrv_Mvd_MVDReset(  );
///                break;
///            case default:
///                break;
///        }
///  }
///@endcode
///////////////////////////////////////////////////////////////////////////////


#define DRV_MVD_C


#include <stdio.h>
#include <string.h>
#include "debug.h"
#include "drvuart.h"
#include "datatype.h"
#include "sysinfo.h"
#include "hwreg.h"
#include "board.h"
#include "drvmiu.h"
#include "drvtimer.h"
#include "drvmvd.h"
#include "drvgop.h"
#include "Analog_Reg.h"
#include "drvsys.h"
#include "drvGlobal.h"
#include "debug.h"

#define ASSERT(x)  __ASSERT(x)

#if (CHANNEL_SCAN_AUTO_TEST == 0)
#  define MVD_DEBUGINFO(x) //x
#  define MVD_DEBUGERROR(x) //x
#else
#  define MVD_DEBUGINFO(x)
#  define MVD_DEBUGERROR(x)
#endif

#define H_DWORD(x)   (U8)(((x)>>24)&0xff)
#define L_DWORD(x)   (U8)(((x)>>16)&0xff)
#define H_WORD(x)    (U8)(((x)>>8 )&0xff)
#define L_WORD(x)    (U8)((x)&0xff)
#define COMBWORD(hi,lo)     ((((U16)hi)<<8) | ((U16)lo))
#define COMBDWORD(hh,hl,lh,ll)  ((((U32)hi)<<24) | (((U32)hi)<<16) | (((U32)hi)<<8) | ((U32)lo))

/*************************************************************************************************/

#if VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_HD
        #include "Mvd_dm_var_HD.h"
        #define MVD_CODE_ID     BIN_ID_CODE_MVD_HD
#elif VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_SD
        #include "Mvd_dm_var_SD.h"
        #define MVD_CODE_ID     BIN_ID_CODE_MVD_SD
#elif VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_SD_REDUCE
        #include "Mvd_dm_var_SD_reduce.h"
        #define MVD_CODE_ID     BIN_ID_CODE_MVD_SD_REDUCE

#endif

#define MVD_PollingTimes    0x200000UL

static U8 u8MvdPlayMode = 0;
/*************************************************************************************************/
extern unsigned char get_bank ( void );

/********************************************************************************/
///Local functions (will not include in DDI document)
/********************************************************************************/
/********************************************************************************/
/// Wait MVD command ready or timeout
/// @return -MVD command ready or timeout
/********************************************************************************/
BOOLEAN MVD_TimeOut ()
{
    U32 i;

    for ( i = 0; i < MVD_PollingTimes; i++ )
    {
        ///- wait until MVD command ready or timeout
        if ( ( XBYTE[MVD_STATUS] & 0x2 ) == 0x2 )
        {
            return FALSE;
        }
    }
    MVD_DEBUGERROR( printf("MVD_TimeOut=%d\n", i) );
    return TRUE;
}

/********************************************************************************/
/// Initialize MVD
/// @param -u8cmd \b IN : MVD command
/// @param -pstCmdArg \b IN : pointer to command argument
/********************************************************************************/
BOOLEAN MDrv_Mvd_MVDCommand ( U8 u8cmd, MVD_CMD_ARG *pstCmdArg )
{
    if ( MVD_TimeOut() == TRUE )
        return FALSE;

    XBYTE[MVD_ARG0] = pstCmdArg->Arg0;
    XBYTE[MVD_ARG1] = pstCmdArg->Arg1;
    XBYTE[MVD_ARG2] = pstCmdArg->Arg2;
    XBYTE[MVD_ARG3] = pstCmdArg->Arg3;
    XBYTE[MVD_COMMAND] = u8cmd;
    MVD_DEBUGINFO(printf("%bx,%bx,%bx,%bx,%bx\n", u8cmd, pstCmdArg->Arg0, pstCmdArg->Arg1, pstCmdArg->Arg2, pstCmdArg->Arg3));

    if ( MVD_TimeOut() == TRUE )
        return FALSE;

    pstCmdArg->Arg0 = XBYTE[MVD_ARG0];
    pstCmdArg->Arg1 = XBYTE[MVD_ARG1];
    pstCmdArg->Arg2 = XBYTE[MVD_ARG2];
    pstCmdArg->Arg3 = XBYTE[MVD_ARG3];
    return TRUE;
}

static U16 MDrv_Mvd_FWChecksum(U32 addr, U32 len)
{
    U16 chksum = 0;
    U32 start, end;
    MVD_DEBUGINFO(printf("addrss=%08lx, len=%08lx\n",addr,len));
    while(len > 0) {
        MDrv_Sys_SetXdataWindow1Base( addr >> 12 );
        start = addr & 0xfffL;
        end = start+len;
        if (end > 0x1000L)
            end = 0x1000L;
        len-= (end - start);
        start += 0xf000L;
        end   += 0xf000L;
        MVD_DEBUGINFO(printf("[addr=0x%08lX,w1start=0x%08lX,w1end=0x%08lX]\r\n", addr, start, end));

        while(start < end) {
            chksum+= XBYTE[(U16)start];
            start++;
        }
        addr = ((addr + 0x1000L)>>12)<<12;
    }
    return chksum;
}

/********************************************************************************/
/// Load MVD firmware code to RISC
/// @return -Load firmware success or not
/********************************************************************************/
BOOLEAN MDrv_Mvd_LoadCode ( void )
{
#define TMP_ADR ((MVD_FRAMEBUFFER_ADR + 0x1FFFUL) & ~0x1FFFUL)  // 8k aligned
    U32 i;
    U16 CODE_SIZE;
    BINFORMAT BinInfo;

    /// mvd reset, clear interrupt, BIU reset
    XBYTE[MVD_CTRL] = 0x0D;
    for ( i = 0; i < MVD_PollingTimes; i++ ) {
        if (XBYTE[MVD_CTRL] == 0x0) {
            MVD_DEBUGINFO( printf( "MVD reset done\n" ) );
            break;
        }
    }

    ///-Get MVD binary information
    BinInfo.B_ID = MVD_CODE_ID;
    MVD_DEBUGINFO( printf("mvd_code_id=0x%04X\n", BinInfo.B_ID) );

    if (MDrv_MIU_Get_BinInfo(&BinInfo) != PASS)
    {
        MVD_DEBUGERROR( printf( "could not find MVD binary on flash.\r\n" ) );
        return FALSE;
    }

#if VIDEO_FIRMWARE_CODE == VIDEO_FIRMWARE_CODE_HD
    MVD_DEBUGINFO( printf("MVD-HD fw\n") );
#else
    MVD_DEBUGINFO( printf("MVD-SD fw\n") );
#endif

    CODE_SIZE = BinInfo.B_Len;

    MVD_DEBUGINFO( printf( "MVD code address:0x%8lx, length=0x%4x\n", TMP_ADR, CODE_SIZE) );

    ///-Copy firmware code from flash to SDRAM
    MDrv_MIU_XCopy( MCPY_LOADMVDFW, BinInfo.B_FAddr, TMP_ADR, CODE_SIZE );

    MVD_DEBUGINFO(printf("MVD Firmware checksum=0x%04x\n", MDrv_Mvd_FWChecksum(TMP_ADR, CODE_SIZE)));

    XBYTE[MVD_ARG0] = LOWBYTE( TMP_ADR >> 11 );
    XBYTE[MVD_ARG1] = HIGHBYTE( TMP_ADR >> 11 );

    CODE_SIZE = (CODE_SIZE + 7) >> 3;

    XBYTE[MVD_ARG2] = LOWBYTE( CODE_SIZE );
    XBYTE[MVD_ARG3] = HIGHBYTE( CODE_SIZE );

    ///-Enable booting, load firmware from SDRAM to MVD's program memory
    XBYTE[MVD_CTRL] = 2;
    for ( i = 0; i < MVD_PollingTimes; i++ )
    {
        if ( ( XBYTE[MVD_STATUS] & 0x3 ) == 0x3 ) // booting finished
        {
            MVD_DEBUGINFO( printf("MVD Booting done\n") );
            return TRUE;
        }
    }
    MVD_DEBUGERROR( printf("MVD BOOT TIMEOUT\n") );
    msWarning(ERR_MVD_BOOT_TIMEOUT);
    return FALSE;

#undef TMP_ADR
}

/********************************************************************************/
/// Initialize MVD
/********************************************************************************/

void MDrv_Mvd_MVDInit ( void )
{
    if ( ( XBYTE[MVD_STATUS] & 0x1 ) != 0x1 ) // booting not finished
    {
        ///-Load MVD firmware code
        if ( MDrv_Mvd_LoadCode() == FALSE )
        {
            MVD_DEBUGERROR( printf( "MVD load code fail\n!!" ) );
            return;
        }
    }

    XBYTE[REG_CKG_MVD]=0x44;    // set mvd_clk & mvd_boot_clk to 123MHz

    MVD_DEBUGINFO( printf( "MVD load code and start OK!\r\n" ) );

    MDrv_Mvd_MVDReset();

    ///-program bitstream address
    MDrv_Mvd_SetBitStreamAddr( MVD_BITSTREAM_ADR, MVD_BITSTREAM_ADR + MVD_BITSTREAM_LEN );
    ( printf("MVD_BITSTREAM_STARTADDR=0x%lx, MVD_BITSTREAM_ENDADDR=0x%lx\n",
                            MVD_BITSTREAM_ADR, MVD_BITSTREAM_ADR + MVD_BITSTREAM_LEN) );

    ///-program frambuffer start address
    MDrv_Mvd_SetFrameBufferAddr( MVD_FRAMEBUFFER_ADR );
    ( printf("MVD_FRAMEBUFFER_ADR=0x%lx\n", MVD_FRAMEBUFFER_ADR) );

}


void MDrv_Mvd_MVDResetBuffAddr ( void )
{
    ///-program bitstream address
    MDrv_Mvd_SetBitStreamAddr( MVD_BITSTREAM_ADR, MVD_BITSTREAM_ADR + MVD_BITSTREAM_LEN );

    ///-program frambuffer start address
    MDrv_Mvd_SetFrameBufferAddr( MVD_FRAMEBUFFER_ADR );
}

/********************************************************************************/
/// Reset MVD
/********************************************************************************/
void MDrv_Mvd_MVDReset ( void )
{
    XBYTE[MVD_CTRL] = 1;
    MDrv_Timer_Delayms(2); // Delay 2ms to make MVD reset complete
    u8MvdPlayMode = 0;
}

/********************************************************************************/
/// Play MVD
/********************************************************************************/
void MDrv_Mvd_Play()
{
    MVD_CMD_ARG mvdcmd;
    mvdcmd.Arg0 = u8MvdPlayMode;
    mvdcmd.Arg1 = 0;
    mvdcmd.Arg2 = 0;
    mvdcmd.Arg3 = 0;
    if (MDrv_Mvd_MVDCommand( MVD_PLAY, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_PLAY ) );
            return;
    }
}

/********************************************************************************/
/// Set bit stream buffer address to MVD
/// @param -u32start \b IN : start address
/// @param -u32end \b IN : end address
/********************************************************************************/
void MDrv_Mvd_SetBitStreamAddr ( U32 u32start, U32 u32end )
{
    MVD_CMD_ARG mvdcmd;
    ASSERT((u32start%8)==0);
    u32start >>= 3;
    mvdcmd.Arg0 = L_WORD(u32start);
    mvdcmd.Arg1 = H_WORD(u32start);
    mvdcmd.Arg2 = L_DWORD(u32start);
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_SET_BS_START, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_BS_START ) );
        return;
    }

    ASSERT((u32end%8)==0);
    u32end >>= 3;
    mvdcmd.Arg0 = L_WORD(u32end);
    mvdcmd.Arg1 = H_WORD(u32end);
    mvdcmd.Arg2 = L_DWORD(u32end);
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_SET_BS_END, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_BS_END ) );
        return;
    }
}

/********************************************************************************/
/// Set frame buffer address to MVD
/// @param -u32addr \b IN : start address
/********************************************************************************/
void MDrv_Mvd_SetFrameBufferAddr ( U32 u32addr )
{
    MVD_CMD_ARG mvdcmd;
    #if VIDEO_FIRMWARE_CODE >= VIDEO_FIRMWARE_CODE_HD
        ASSERT((u32addr%2048)==0);
        u32addr >>= ( 3 + 8 );
    #else
        ASSERT((u32addr%512)==0);
	    u32addr >>= ( 3 + 6 );
    #endif
    mvdcmd.Arg0 = L_WORD(u32addr);
    mvdcmd.Arg1 = H_WORD(u32addr);
    mvdcmd.Arg2 = 0;
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_SET_FB_START, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_FB_START ) );
        return;
    }
}

//#if ( KEEP_UNUSED_FUNC == 1 )
/********************************************************************************/
/// Set frame rate to MVD
/// @param -u8rate \b IN : frame rate
/********************************************************************************/
void MDrv_Mvd_SetFrameRate ( U8 u8rate )
{
    MVD_CMD_ARG mvdcmd;
    mvdcmd.Arg0 = u8rate;
    mvdcmd.Arg1 = 0;
    mvdcmd.Arg2 = 0;
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_SET_FRAMERATE, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_SET_FRAMERATE ) );
        return;
    }
}
//#endif

/********************************************************************************/
/// Check MVD decode status
/// @return -MVD decode ready or not
/********************************************************************************/
BOOLEAN MDrv_Mvd_CheckDecodeStatus ( void )
{
    MVD_CMD_ARG mvdcmd;
    U16 num;
    mvdcmd.Arg0 = 0;
    mvdcmd.Arg1 = 0;
    mvdcmd.Arg2 = 0;
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_GET_VALID_DATA_STATUS, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Command: 0x%bx fail!!\r\n", MVD_I_GET_VALID_DATA_STATUS ) );
        return FALSE;
    }
    num = COMBWORD(mvdcmd.Arg3, mvdcmd.Arg2);
    MVD_DEBUGERROR( printf( "mvd decode stall count=%u\n", num) );

    if (num <= 30)
        return TRUE;
    else
        return FALSE;
}



/********************************************************************************/
/// Get MVD decoded picture counter
/// @return -decoded picture counter
/********************************************************************************/
U8 MDrv_Mvd_GetPicCounter ( void )
{
    MVD_CMD_ARG mvdcmd;
    mvdcmd.Arg0 = PIC_COUNT;
    mvdcmd.Arg1 = 0;
    mvdcmd.Arg2 = 0;
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_COMMAND_CTRL, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Ctrl: PIC_COUNT fail!!\r\n" ) );
        return 0;
    }
    return mvdcmd.Arg2;
}


/********************************************************************************/
/// Get valid MVD stream detected flag
/// @return -decoded flag
/********************************************************************************/

BOOLEAN MDrv_Mvd_GetValidStreamFlag ( void )
{
    MVD_CMD_ARG mvdcmd;
    mvdcmd.Arg0 = INT_STAT;
    mvdcmd.Arg1 = 0;
    mvdcmd.Arg2 = 0;
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_COMMAND_CTRL, &mvdcmd ) == FALSE)
    {
        MVD_DEBUGERROR( printf( "Ctrl: INT_STAT fail!!\r\n" ) );
        return FALSE;
    }

    // 1 : New CC, 2: CC608 buffer overflow,3:CC708 overflow, 4: Valid MPEG , 0, 5: Invalid MPEG
    if (0x01 == mvdcmd.Arg2 || 0x02 == mvdcmd.Arg2 ||
        0x03 == mvdcmd.Arg2 || 0x04 == mvdcmd.Arg2)
        return TRUE;
    else
        return FALSE;
}

/********************************************************************************/
/// Get video frame information from MVD
/// @param -pinfo \b IN : pointer to video frame information
/********************************************************************************/

void MDrv_Mvd_GetFrameInfo ( MVD_FRAMEINFO *pinfo )
{
    MVD_CMD_ARG mvdcmd;
    mvdcmd.Arg0 = 0;
    mvdcmd.Arg1 = 0;
    mvdcmd.Arg2 = 0;
    mvdcmd.Arg3 = 0;

    if (MDrv_Mvd_MVDCommand( MVD_I_GET_PICTURE_SIZE, &mvdcmd ) == FALSE)
    {

⌨️ 快捷键说明

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