📄 cve2000.c
字号:
/********************************************************************************************//* cve2000.c : specific code for VE2000 board* REALmagic Quasar Hardware Library* Created by Aurelia Popa-Radu* Copyright Sigma Designs Inc* Sigma Designs Proprietary and confidential* Created on 8/7/01* Description:/********************************************************************************************//****h* HwLib/CVE2000_Implementation * DESCRIPTION * CVE2000 implementation of the IDecoderBoard interface. * VE2000 uses EM840X, EM9038 components to implement digital overlay output, * TV output, 480P output. * NetStream Console is also a VE2000. * Identified by HwLib reading MD5,MD4,MD3,MD2 pins = 0001, 0011 (MDCFG_VE2000, MDCFG_VE200024). * PIO0 - IIC Clock for EM9038, Eeprom * PIO1 - IIC Data for EM9038, Eeprom * PIO2 - AUDIOSEL0 = audio frequency selection - just for Coreea * PIO3 - AUDIOSEL1 = audio frequency selection - just for Coreea * PIO4 - nDIGENABLE_PIO = 1/0 disable/enable digital Vga header * PIO5 - * PIO6 - * PIO7 - * Specific implementation: * QRESULT CVE2000__HwReset(IDecoderBoard* pIDecoderBoard) * QRESULT CVE2000__UpdateOverlay(IDecoderBoard* pIDecoderBoard) * QRESULT CVE2000__SetCustomTvHdtv(IDecoderBoard* pIDecoderBoard, void* pTvHdtv, DWORD TvHdtvSize) * QRESULT CVE2000__VidSetVGATV(IDecoderBoard* pIDecoderBoard, DWORD VideoRunning, DWORD TvOut) * QRESULT CVE2000__AudioSetSampleRate(IDecoderBoard* pIDecoderBoard, DWORD Rate)/******************************************************************************/#include "pch.h"#ifdef DIGITAL_OVERLAY#include "cqsrbrd.h"#include "em847x.h"#ifndef AUDIOSEL0_32#define AUDIOSEL0_32 0 /* PIO2 value for 32K audio */#define AUDIOSEL1_32 0 /* PIO3 value for 32K audio */#define AUDIOSEL0_441 1 /* PIO2 value for 44.1K audio */#define AUDIOSEL1_441 0 /* PIO3 value for 44.1K audio */#define AUDIOSEL0_48 0 /* PIO2 value for 48K audio */#define AUDIOSEL1_48 1 /* PIO3 value for 48K audio */#endif#undef NEW_4TVQRESULT CVE2000__HwReset(IDecoderBoard* pIDecoderBoard){ CQuasarBoard *this = (CQuasarBoard*) pIDecoderBoard; CommonSymbolTable* pQ = (CommonSymbolTable*)this->pQ; QRESULT qr = Q_OK; int i = 0; DWORD temp; this->m_bEnableSync = TRUE; this->FirstSystemSCR = TRUE; this->VideoState = VideoStoppedAfterReset; if( !this->pRegistry->DoHwReset ) return CQuasarBoard__DontDoHwReset(pIDecoderBoard); // program TV with Dacs disable before HwReset to minimize flashing on TV if(this->m_pIExtTv) ITvEncoder_InitTvEncoder(this->m_pIExtTv); if( QFAILED(qr = IDecoder_HwReset(this->m_pIDecoder)) ) return qr; // Restore the PIO state for (i = 0; i < 16 ; i++) { if( (this->PioAccessedByUser>>i) && 1 ) // PIO accessed by user { if( (this->PioDirState>>i) && 1) // PIO is Output IDecoder_WritePIO(this->m_pIDecoder, i, (this->PioDataState>>i) & 1 ); else // PIO is input IDecoder_ReadPIO(this->m_pIDecoder, i, &temp ); } } if( this->BoardVersion == GALAXY2000 ) { if( !((this->PioAccessedByUser>>7) && 1) ) // PIO7 not accessed by user => default to: // PIO7 = 1 -> enable mux for IGS to show IGS + EM8400 window on TV IDecoder_WritePIO(this->m_pIDecoder, PIO7, 1); } ITvEncoder_InitTvEncoder(this->m_pISigmaTv); IDecoder_InitCloseCaption(this->m_pIDecoder); if(this->m_pINovaLite) IAnalogOverlay_InitAnalogMux(this->m_pINovaLite, 0); this->ReqYcYuvRgb = OUTPUT_OFF;// analog Tv dacs are off IDecoderBoard_VidSetVGATV(pIDecoderBoard, 0, this->TvOut); // force the hardware to set the sample rate IDecoderBoard_AudioSetSampleRate(pIDecoderBoard, this->BoardAudioRate | FORCED_HW_UPDATE); if(this->PixelClockPolarity == 1) { IDecoder_WriteDM(this->m_pIDecoder, pQ->DICOM_Control2.addr, IDecoder_ReadDM(this->m_pIDecoder, pQ->DICOM_Control2.addr) | Q3CTRL2_PIXCLK_POLARITY); } if(this->VideoClipEnable == 1) { IDecoder_WriteDM(this->m_pIDecoder, pQ->DICOM_Control2.addr, IDecoder_ReadDM(this->m_pIDecoder, pQ->DICOM_Control2.addr) | Q3CTRL2_VIDEO_CLIP_ENABLE); } IDecoder_WriteDM(this->m_pIDecoder, pQ->Force_PanScanDefHorSize.addr, this->Force_PanScanDefHorSize); if( QFAILED(qr = IDecoder_HwStart(this->m_pIDecoder)) ) return qr; // Risc Start and BlackFrame IDecoder_SetCurrentIrqMask( this->m_pIDecoder, 0 ); if( this->BoardCapabilities & MPEG_CAPABILITY_AUDIO_VCXO ) { // reset the VCXO and the PPM filter if ( (this->HwVcxo >= eHwVcxoPio0) && (this->HwVcxo <= eHwVcxoPio15) ) { DWORD temp; IDecoder_ReadPIO(this->m_pIDecoder, PIO0 + (this->HwVcxo-eHwVcxoPio0), &temp); // tristate } OSmemset(this->iPpmCoef, 0, sizeof(this->iPpmCoef)); this->iPpmIndex = 0; this->iPpmAvg = 0; this->iDeltaSCR_APTS = 0; } return Q_OK;}QRESULT CVE2000__UpdateOverlay(IDecoderBoard* pIDecoderBoard){ CQuasarBoard *this = (CQuasarBoard*) pIDecoderBoard; if ( (this->TvOut == SET_HDTV) || (this->TvOut == evOutputDevice_DigOvOnly) ) CQuasarBoard__HdtvUpdateVideoWindow(pIDecoderBoard); else // SET_TV, SET_VGA CQuasarBoard__TVVMIUpdateVideoWindow(pIDecoderBoard); return Q_OK;}QRESULT CVE2000__SetCustomTvHdtv(IDecoderBoard* pIDecoderBoard, void* pTvHdtv, DWORD TvHdtvSize){ CQuasarBoard *this = (CQuasarBoard*) pIDecoderBoard; QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("VE2000_SetCustomTvHdtv %d %d"), ((HDTV_MODE*)pTvHdtv)->VideoWidth, ((HDTV_MODE*)pTvHdtv)->VideoHeight )); // don't check the unused fields if( !OSmemcmp (pTvHdtv, &(this->HdtvMode), sizeof(HDTV_MODE) - 8) ) { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("SetCustomTvHdtv no change") )); return Q_OK; } OSmemcpy ((void*)&this->HdtvMode, pTvHdtv, sizeof (HDTV_MODE)); if (this->HdtvMode.PixelFreq == 0x49475331) // "IGS1" this->OverlayFlags |= SPECIAL_IGS_STANDARD; else if (this->HdtvMode.PixelFreq == 0x49475330) // "IGS0" this->OverlayFlags &= ~SPECIAL_IGS_STANDARD; if ( (this->TvOut == SET_HDTV) || (this->TvOut == SET_HDTV_SUBD) || ((this->OverlayFlags & SPECIAL_IGS_STANDARD) && // special Igs hack ((this->TvOut == SET_TV) || ((this->BoardVersion == GALAXY2000) && (this->TvOut == SET_VGA))))) { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("SetCustomTvHdtv apply") )); IDecoderBoard_VidSetVGATV(pIDecoderBoard, RST_DC | this->TvDacsState, this->TvOut); } return Q_OK;}void CVE2000__SetSpecialStandard(IDecoderBoard* pIDecoderBoard){ CQuasarBoard *this = (CQuasarBoard*) pIDecoderBoard; HDTV_MODE LocalHdtvIgs; OSmemcpy ((void*)&LocalHdtvIgs,(void*)&this->HdtvMode, sizeof (HDTV_MODE)); if( this->Standard_TvOut == SET_PAL ) { LocalHdtvIgs.VFreq = 5000; // cHz LocalHdtvIgs.HFreq = 15625; // Hz if( LocalHdtvIgs.VideoHeight == 0 ) LocalHdtvIgs.VideoHeight = 576; if( (LocalHdtvIgs.VideoHeight > 576) && (LocalHdtvIgs.VideoHeight <= 602) ) { LocalHdtvIgs.VideoHeight = 576; this->OverlayFlags |= VISIBLE_VIDEO_INDEPENDENT; LocalHdtvIgs.PostVSync = 33;// 33+1=34=2*17 } else { this->OverlayFlags &= ~VISIBLE_VIDEO_INDEPENDENT; LocalHdtvIgs.PostVSync = 45;// 45+1=46=2*23 = close caption line } LocalHdtvIgs.VSyncTotal = 625; if(LocalHdtvIgs.VideoWidth == 0 ) { LocalHdtvIgs.VideoWidth = 720; LocalHdtvIgs.HSyncTotal = 864; } if( LocalHdtvIgs.HSyncTotal == 0 ) { if( LocalHdtvIgs.VideoWidth > 720 ) { LocalHdtvIgs.HSyncTotal = 1080;#ifdef FUJITSU_RISC_CLK // 72M LocalHdtvIgs.HSyncTotal = 1152;// 864 * 36/27#endif } else LocalHdtvIgs.HSyncTotal = 864; } } else //SET_NTSC { // default values for Ntsc LocalHdtvIgs.VFreq = 5994; // cHz LocalHdtvIgs.HFreq = 15734; // Hz LocalHdtvIgs.VSyncTotal = 525; // lines LocalHdtvIgs.PostVSync = 41; // 41+1=42=2*21 = close caption line this->OverlayFlags &= ~VISIBLE_VIDEO_INDEPENDENT;// don't center the video if( LocalHdtvIgs.VideoHeight == 0 ) LocalHdtvIgs.VideoHeight = 480; else if( LocalHdtvIgs.VideoHeight <= 500 )//480 ; // don't do anything else if( LocalHdtvIgs.VideoHeight <= 602 ) { LocalHdtvIgs.VSyncTotal = 625; // lines/* LocalHdtvIgs.PostVSync = 65; LocalHdtvIgs.VideoHeight = 480; // don't scale the video*/ LocalHdtvIgs.PostVSync = 21; LocalHdtvIgs.VideoHeight = 600; // scale the video for aspect ratio this->OverlayFlags |= VISIBLE_VIDEO_INDEPENDENT; // center the video LocalHdtvIgs.HFreq = 18731; // 18731.25Hz to keep 59.94 Hz for VSync LocalHdtvIgs.HSyncTotal = 901; // 900.9 pixels at 33.75MHz pixel clock } else { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("Ntsc >602 lines not supported - Is the video is very distorted?") )); } if(LocalHdtvIgs.VideoWidth == 0 ) { LocalHdtvIgs.VideoWidth = 720; LocalHdtvIgs.HSyncTotal = 858; } if( LocalHdtvIgs.HSyncTotal == 0 ) { if( LocalHdtvIgs.VideoWidth > 720 ) { LocalHdtvIgs.HSyncTotal = 1072;// 858 * 33.75/27#ifdef FUJITSU_RISC_CLK // 72M LocalHdtvIgs.HSyncTotal = 1144;// 858 * 36/27#endif } else LocalHdtvIgs.HSyncTotal = 858; } } if( LocalHdtvIgs.HSyncActive == 0 ) { LocalHdtvIgs.PostHSync = LocalHdtvIgs.HSyncTotal - LocalHdtvIgs.VideoWidth - 2; LocalHdtvIgs.HSyncActive = 2; } LocalHdtvIgs.VSyncActive = 1;// LocalHdtvIgs.PreVSync, LocalHdtvIgs.PreHSync, LocalHdtvIgs.Interlaced not used this->MasterParams.x = LocalHdtvIgs.HSyncActive + LocalHdtvIgs.PostHSync;// pixels this->MasterParams.y = LocalHdtvIgs.VSyncActive + LocalHdtvIgs.PostVSync;// lines this->MasterParams.w = LocalHdtvIgs.VideoWidth; // pixels this->MasterParams.h = LocalHdtvIgs.VideoHeight; // lines this->MasterParams.VSyncTotal = LocalHdtvIgs.VSyncTotal; // lines this->MasterParams.VSyncActive = LocalHdtvIgs.VSyncActive; // lines this->MasterParams.HSyncTotal = LocalHdtvIgs.HSyncTotal; // pixels this->MasterParams.HSyncActive = LocalHdtvIgs.HSyncActive; // pixels this->MasterParams.HFrequency = LocalHdtvIgs.HFreq / 100; // HFrequency unit is 100Hz LocalHdtvIgs.PixelFreq = LocalHdtvIgs.HSyncTotal * LocalHdtvIgs.HFreq; QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("%dx%d VF=%dcHz HF=%dHz PixF=%dKHz HSTot=%d %d_%d VSTot=%d %d_%d"), this->MasterParams.w, this->MasterParams.h, LocalHdtvIgs.VFreq, LocalHdtvIgs.HFreq, LocalHdtvIgs.PixelFreq/1000, this->MasterParams.HSyncTotal, this->MasterParams.HSyncActive, LocalHdtvIgs.PostHSync, this->MasterParams.VSyncTotal, this->MasterParams.VSyncActive, LocalHdtvIgs.PostVSync )); this->HFrequency = LocalHdtvIgs.HFreq/100; this->HdtvMode.PixelFreq = LocalHdtvIgs.PixelFreq;}QRESULT C840xBrd__DigOvOnly(IDecoderBoard* pIDecoderBoard, DWORD VideoRunning){ CQuasarBoard *this = (CQuasarBoard*) pIDecoderBoard; DWORD CcirInvSE = this->DigOvOnlyParams.Ccir | (this->DigOvOnlyParams.InvertField << 12) | (this->DigOvOnlyParams.SyncEnable << 4); DWORD nInternBitsPerClock = this->DigOvOnlyParams.BitsPerClock; // all the results are in pixels, updates this->HFrequency CQuasarBoard__HdtvCalc(pIDecoderBoard, this->DigOvOnlyParams.BitsPerClock, (HDTV_MODE*)&this->DigOvOnlyParams, &this->MasterParams, &this->HFrequency); // I don't have many choices: DVCLK source is Gclk/2 = 33.75MHz or extern 27MHz if ((26900000 < this->DigOvOnlyParams.PixelFreq) && (this->DigOvOnlyParams.PixelFreq < 27100000)) { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(" C840xBrd__DigOvOnly PixFreq= %dHz"), this->DigOvOnlyParams.PixelFreq )); this->DigOvOnlyParams.PixelFreq = 27000000; } else if ((33650000 < this->DigOvOnlyParams.PixelFreq) && (this->DigOvOnlyParams.PixelFreq < 33850000)) { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(" C840xBrd__DigOvOnly PixFreq= %dHz"), this->DigOvOnlyParams.PixelFreq )); this->DigOvOnlyParams.PixelFreq = 33750000; } else { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(" C840xBrd__DigOvOnly failed PixFreq= %dHz"), this->DigOvOnlyParams.PixelFreq )); CQuasarBoard__HdtvUpdateVideoWindow(pIDecoderBoard); return Q_FAIL; } if(this->DigOvOnlyParams.SyncGen == evSyncGen_em8xxx_Master) { if(VideoRunning & RST_DC) IDecoder_StopDisplayController(this->m_pIDecoder); // Quasar is slave // Tv is master - both 601 & 656 are OK ITvEncoder_ProgramTVEx(this->m_pISigmaTv, TVMASTER, nInternBitsPerClock, CcirInvSE, this->DigOvOnlyParams.TvHdtvStandard, VideoRunning & ~RST_DC, &this->MasterParams, this->DigOvOnlyParams.Interlaced, (this->DigOvOnlyParams.HSyncPolarity ? HS_ACTIVE_HI:HS_ACTIVE_LOW) | (this->DigOvOnlyParams.VSyncPolarity ? VS_ACTIVE_HI:VS_ACTIVE_LOW) ); IDecoder_QuasarSlave( this->m_pIDecoder, this->DigOvOnlyParams.BitsPerClock, CcirInvSE, &this->MasterParams, (this->DigOvOnlyParams.HSyncPolarity ? HS_ACTIVE_HI:HS_ACTIVE_LOW) | (this->DigOvOnlyParams.VSyncPolarity ? VS_ACTIVE_HI:VS_ACTIVE_LOW), Q3CTRL2_NOINTERLACED | DIGITAL_DATA_ENABLE | ((this->DigOvOnlyParams.PixelFreq == 33750000)? USE_GCLK_DIVIDED2:0) ); } else if(this->DigOvOnlyParams.SyncGen == evSyncGen_em8xxx_SlaveTo_Vsync_HSync_Vclk) { if(VideoRunning & RST_DC) IDecoder_StopDisplayController(this->m_pIDecoder); // Quasar is slave // Tv is slave and doesn't work - the analog output will be disabled ITvEncoder_ProgramTVEx(this->m_pISigmaTv, TVSLAVE, nInternBitsPerClock, CcirInvSE & ~CCIR_656, this->DigOvOnlyParams.TvHdtvStandard, VideoRunning & ~RST_DC,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -