📄 cem847x.c
字号:
return Q_OK; } return Q_FAIL;}/****f* HwLib/CQuasar__ReadMasterDramToHost * USAGE * NOT PRESENT in IDecoder interface * BOOL CQuasar__ReadMasterDramToHost(IDecoder* pIDecoder, IN DWORD addr, IN DWORD PhysAddr, IN DWORD nBytes, IN DWORD reverse) * DESCRIPTION * CQuasar__ReadMasterDramToHost writes "nBytes" from system memory "pData" to "addr" in DRAM * memory using PCI bus master. "pData" must point to a physical contiguous buffer of nBytes, * otherwise the system hangs. * "nBytes" can be any value between 1 and 0xFFFF (transfer size less than 64 kBytes). * It is not called in the actual implementation of library in order to not conflict with * microcode, that uses PCI bus master to transfer the compressed data. * PARAMETERS * IN IDecoder* pIDecoder - pointer to the decoder object * IN DWORD addr - DRAM address where to start writing * IN DWORD PhysAddr - physical address of the system buffer to write * IN DWORD nBytes - number of bytes to write * IN DWORD reverse - select order of bytes in DWORD * RETURN VALUE * The return value is FALSE if IDecoder_WriteDramSlave timeout. * SEE ALSO * IDecoder_WriteDramSlave/********************************************************************************************/BOOL CQuasar__ReadMasterDramToHost(IDecoder* pIDecoder, IN DWORD addr, IN DWORD PhysAddr, IN DWORD nBytes, IN DWORD reverse){ DWORD timeout; CheckTransferSize(nBytes, TEXT("ReadDramMaster")) CheckDramChannel(DRAM_HOST, TEXT("ReadDramMaster start timeout !")) // Set up PCI master to write in system memory and start CQuasar__WriteReg(pIDecoder, DRAM_portmux, (CQuasar__ReadReg(pIDecoder, DRAM_portmux) & ~DRAM_portmux_CHR0_Mask) | DRAM_portmux_CHR0_to_Port1); CQuasar__WriteReg(pIDecoder, QPM_master_xfer_enable, 1); CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_lo, PhysAddr & 0xFFFF); CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_hi, PhysAddr >> 16); CQuasar__WriteReg(pIDecoder, QPM_to_host_xfer_cnt, nBytes); // select Port1 for Master Write to Host CQuasar__WriteReg(pIDecoder, QPM_to_host_master_ena, Port1_to_MasterWriteToHost); ProgramDramChannel(DRAM_HOST, addr, nBytes) CheckDramChannel(DRAM_HOST, TEXT("ReadDramMaster end timeout !")) return TRUE;}/****f* HwLib/IDecoder_ReadDramSlave * USAGE * BOOL IDecoder_ReadDramSlave(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes) * BOOL CEM840X__ReadSlaveDramToHost(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes) * BOOL CEM847X__ReadSlaveDramToHost(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes) * DESCRIPTION * IDecoder_ReadDramSlave reads "nBytes" starting from "addr" in DRAM memory to system memory "pData". * "nBytes" can be any value between 1 and 0xFFFF (transfer size less than 64 kBytes). * The data is read in chunks of four bytes = one dword to increase the speed. * It is called by CQuasar__LoadMicroCode, CQuasar__GetOneLineRGB, CQuasar__CloseCaptionInterrupt, * IDecoder_TestDram, IDecoder_YannTestDRAM * PARAMETERS * IN IDecoder* pIDecoder - pointer to the decoder object * IN DWORD addr - DRAM address from where to start reading * OUT DWORD* pData - address of the system buffer where to put the read data * IN DWORD nBytes - number of bytes to read * RETURN VALUE * The return value is FALSE if IDecoder_ReadDramSlave timeout. * SEE ALSO * IDecoder_WriteDramSlave/********************************************************************************************/BOOL CEM847X__ReadSlaveDramToHost(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes){ UCHAR* pBytes = (UCHAR*)pData; DWORD i, timeout; CheckTransferSize(nBytes, TEXT("ReadDramSlave")) CheckDramChannel(DRAM_HOST, TEXT("ReadDramSlave start timeout !")) // select Port1 for Slave Write to Host CQuasar__WriteReg(pIDecoder, QPM_to_host_master_ena, Port1_to_SlaveWriteToHost); ProgramDramChannel(DRAM_HOST, addr, nBytes) for(i=0; i<nBytes/4; i++) { OSPutDword(CQuasar__ReadReg(pIDecoder, READ_3210), pBytes); pBytes += 4; } switch(nBytes % 4) { case 3: OSPutDword(CQuasar__ReadReg(pIDecoder, READ_210), pBytes); break; case 2: OSPutDword(CQuasar__ReadReg(pIDecoder, READ_10), pBytes); break; case 1: OSPutDword(CQuasar__ReadReg(pIDecoder, READ_0), pBytes); default: break; } CheckDramChannel(DRAM_HOST, TEXT("ReadDramSlave end timeout !")) return TRUE;}/////////////////////////////////////////////////////////////////////////// EM847x specific code for sigma TV encoder// EM8470 supports 8/16 bits, 601,656 TvMaster/Slave#include "ctvenc.h"void CSigmaTv__StartAccessReg(ITvEncoder* pITvEncoder);void CSigmaTv__EndAccessReg(ITvEncoder* pITvEncoder);void CEM847X__InitTvEncoder (ITvEncoder* pITvEncoder){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; DWORD SymbolTableSize; int i; IDecoder_GetSymbolTable(this->m_pIDecoder, &this->pQ, &SymbolTableSize); CSigmaTv__StartAccessReg(pITvEncoder); // clean all the registers ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG, 0x8000 | this->SigmaTvRegs[0] ); for (i=0;i<13; i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+3+i, 0 ); for (i=0;i<(sizeof(this->SigmaTvRegs35)/sizeof(WORD)); i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs35[i] ); ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG + 0xF, 0 );// test register this->SigmaTvRegs[0] = Q4_DACS_DISABLE; for (i=0;i<(sizeof(this->SigmaTvRegs)/sizeof(WORD)); i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs[i] ); CSigmaTv__EndAccessReg(pITvEncoder);}void CEM847X__SetCurrentYcYuvRgb(ITvEncoder* pITvEncoder, DWORD YcYuvRgb){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; this->YcYuvRgb = YcYuvRgb; this->SigmaTvRegs[0] &= ~0x300; // clear mask switch(this->YcYuvRgb) { case COMPONENT_YUV: this->SigmaTvRegs[0] |= 0x200; // select component output this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070) | 0x0070;// select YUV break; case COMPONENT_RGB: this->SigmaTvRegs[0] |= 0x200; // select component output this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070) | 0x0020;// select RGB sync-on-green break; case COMPONENT_RGB_SCART: this->SigmaTvRegs[0] |= 0x200; // select component output this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070) | 0x0010;// select RGB scart break; case OUTPUT_OFF: this->SigmaTvRegs[0] |= 0x000; // Dacs off break; case COMPOSITE: default: this->SigmaTvRegs[0] |= 0x100; // select YC output this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070); break; } // update to hardware CSigmaTv__StartAccessReg(pITvEncoder); ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG, this->SigmaTvRegs35[0] ); ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+1, this->SigmaTvRegs35[1] ); ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG, this->SigmaTvRegs[0] ); CSigmaTv__EndAccessReg(pITvEncoder);} void CEM847X__ProgramTV( ITvEncoder* pITvEncoder, DWORD TvMaster, DWORD nbits, DWORD ccir, DWORD TvStandard, DWORD DacsEnable){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ; DWORD Q3Ctrl3 = 0; int i; this->InvertField = (ccir & INVERT_FIELD_MASK)>>12; this->TvDacsEnable = DacsEnable; if(DacsEnable) this->SigmaTvRegs[0] = Q4_DACS_ENABLE; else this->SigmaTvRegs[0] = Q4_DACS_DISABLE; // update the values for TvStandard and take care of macrovision too ITvEncoder_SetTVStandard(pITvEncoder, TvStandard); if( TvStandard == SET_NTSC ) this->SigmaTvRegs35[1] = this->SigmaTvRegs35[1] & ~0x0800; else this->SigmaTvRegs35[1] = this->SigmaTvRegs35[1] | 0x0800; if( nbits >= 16 ) // HD { this->SigmaTvRegs[0] |= 0x8; // 16 bits - HD this->SigmaTvRegs[1] /= 2;// SIGMATV_HSYNC_PERIOD 0x1F31 this->SigmaTvRegs[2] /= 2;// SIGMATV_HSYNC_0 0x1F32 this->SigmaTvRegs[3] /= 2;// SIGMATV_HSYNC_1 0x1F33 this->SigmaTvRegs[6] /= 2;// SIGMATV_VSYNC_ODD_PIXEL_0 0x1F36 this->SigmaTvRegs[8] /= 2;// SIGMATV_VSYNC_ODD_PIXEL_1 0x1F38 this->SigmaTvRegs[10] /= 2;// SIGMATV_VSYNC_EVEN_PIXEL_0 0x1F3A this->SigmaTvRegs[12] /= 2;// SIGMATV_VSYNC_EVEN_PIXEL_1 0x1F3C } else // SD this->SigmaTvRegs[0] &= ~0x8; // 8 bits if(TvMaster) this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x0000; else { if((ccir & CCIR_MASK) == CCIR_601) this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x8; else this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0xC; } // update the output format to hardware ITvEncoder_SetCurrentYcYuvRgb(pITvEncoder, this->YcYuvRgb); // update the first set of registers to hardware CSigmaTv__StartAccessReg(pITvEncoder); for (i=0;i<(sizeof(this->SigmaTvRegs)/sizeof(WORD)); i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs[i] ); CSigmaTv__EndAccessReg(pITvEncoder); // programming correct VID_CTRL3 is resposability of CBoard... first Q/Tv Slave, second Tv/Q master Q3Ctrl3 = IDecoder_ReadDM(this->m_pIDecoder, pQ4->DICOM_Control3.addr) & ~Q3CTRL3_TVSYNCS_ENABLE; if(TvMaster) // Enable HSync & VSync from SigmaTV Q3Ctrl3 |= Q3CTRL3_TVSYNCS_ENABLE | Q3CTRL3_VS_ENABLE | Q3CTRL3_HS_ENABLE; IDecoder_WriteDM(this->m_pIDecoder, pQ4->DICOM_Control3.addr, Q3Ctrl3 );}// 480p/59.94Hz 720 480 5994 31469 858 40 54 44 525 5 11 28WORD SigmaTv_480Pslave656[]= {1716, 0, 0, 525, 0, 0, 0, 0, 0, 0, 0, 0};WORD SigmaTv_480Pmaster[]= {1716, 2,108, 525, 1, 2, 12, 2, 263, 108, 274, 108};// 720p/60Hz 1280 720 6000 45000 1650 0 80 0 750 0 0 0WORD SigmaTv_720Pslave656_G[]= {1650,1580,300, 750, 26, 1, 746, 0, 263, 826, 263, 825};//80,260WORD SigmaTv_720Pmaster[]= {1650, 1, 80, 750, 1, 1, 2, 0, 263, 826, 264, 825};//80,260// 1080i/59.94Hz 1920 1080 5994 33716 2199 0 88 116 1125 0 0 0WORD SigmaTv_1080Islave656_GI[]={2200,2156,236, 1125, 21, 1,1124, 0, 584,1101, 561,1100};//88,132WORD SigmaTv_1080Imaster[]= {2200, 1, 88, 1125, 1, 1, 2, 0, 563,1101, 564,1100};//88,132// the next 3 registers are used for the analog signal on HDTV#define SIGMATV_HSYNC_WIDTH 0x1F34#define SIGMATV_VSYNC_START 0x1F35#define SIGMATV_VSYNC_WIDTH 0x1F36#define SIGMATV_NTSC 0#define SIGMATV_PAL 1#define SIGMATV_PAL60 2#define SIGMATV_PALM 3#define SIGMATV_MASK 3QRESULT CEM847X__ProgramTVEx( ITvEncoder* pITvEncoder, DWORD TvMaster, DWORD nbits, DWORD CcirInvSE, DWORD TvStandard, DWORD DacsEnable, MASTERPARAMS* MP, DWORD Interlaced, DWORD Polarity){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ; DWORD Q3Ctrl3 = 0; WORD HSyncAnalogOffset = 0; WORD HSyncTotalPixels, HSyncActivePixels, VSyncTotalLines, VSyncActiveLines; WORD VSyncOddField0, VSyncOddField1, VSyncEvenField0, VSyncEvenField1; WORD HSyncOddField0, HSyncOddField1, HSyncEvenField0, HSyncEvenField1; int i; this->TvDacsEnable = DacsEnable; this->InvertField = (CcirInvSE & INVERT_FIELD_MASK)>>12; CSigmaTv__StartAccessReg(pITvEncoder); // change register set ITvEncoder_Write(pITvEncoder, SIGMATV_CONFIG, this->SigmaTvRegs[0] | 0x4000); if(TvStandard == evTvHdtvStandard_1080I)//if( MP->h == 1080 ) // 1080I { // HSyncAnalogOffset + PostHSync should be 192 to have a nice sync // for the analog signal HSyncAnalogOffset = 44; // PostHSync is 148 ITvEncoder_Write(pITvEncoder, SIGMATV_HSYNC_WIDTH, 88); ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_START, 132); ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_WIDTH, 880); } else if(TvStandard == evTvHdtvStandard_720P)//if( MP->h == 720 ) // 720P { // HSyncAnalogOffset + PostHSync should be 260 to have a nice sync // for the analog signal HSyncAnalogOffset = 40; // PostHSync is 220 ITvEncoder_Write(pITvEncoder, SIGMATV_HSYNC_WIDTH, 80); ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_START, 260); ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_WIDTH, 1280); } else { HSyncAnalogOffset = 0; ITvEncoder_Write(pITvEncoder, SIGMATV_HSYNC_WIDTH, MP->HSyncActive); } // update values for Hdtv mode this->SigmaTvRegs[0] = (DacsEnable ? Q4_DACS_ENABLE : Q4_DACS_DISABLE) | ( (nbits == 8) ? 0:8 ) | //*** high res ( (Interlaced == 0) ? 4:0 ); // progressive// | ( (MP->h == 576) ? 1:0 ); // Pal this->SigmaTvRegs[0] = (this->SigmaTvRegs[0] & ~SIGMATV_MASK); switch (TvStandard) { case evTvHdtvStandard_PAL: case evTvHdtvStandard_576P: this->SigmaTvRegs[0] |= SIGMATV_PAL; break; case evTvHdtvStandard_PAL60: this->SigmaTvRegs[0] |= SIGMATV_PAL60; break; case evTvHdtvStandard_PALM: this->SigmaTvRegs[0] |= SIGMATV_PALM; break; default://NTSC, 480P, Hdtv break; } this->CurrentTvStandard = TvStandard; if(TvMaster) this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x0000; else { if((CcirInvSE & CCIR_MASK) == CCIR_601) this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x8; else this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0xC; } HSyncTotalPixels = (WORD)MP->HSyncTotal*((nbits==8) ? 2:1); HSyncActivePixels = (WORD)MP->HSyncActive * ((nbits==8) ? 2:1); VSyncTotalLines = (WORD)MP->VSyncTotal/(Interlaced ? 2:1); VSyncActiveLines = (WORD)(Interlaced ? ((MP->VSyncActive + 1)/2) : MP->VSyncActive); // SIGMATV_HSYNC_PERIOD this->SigmaTvRegs[1] = HSyncTotalPixels; // SIGMATV_VSYNC_PERIOD - total lines per frame this->SigmaTvRegs[4] = (WORD)MP->VSyncTotal; if(Interlaced) { DWORD VSyncActIsOdd = MP->VSyncActive & 1; // for VSyncActive odd I will add a half line to every sync VSyncOddField0 = 1; VSyncOddField1 = (WORD)(VSyncOddField0 + MP->VSyncActive/2); VSyncEvenField0 = (WORD)(1 + MP->VSyncTotal/2); VSyncEvenField1 = (WORD)(VSyncEvenField0 + MP->VSyncActive/2 + VSyncActIsOdd); HSyncOddField0 = (WORD)(HSyncAnalogOffset + HSyncActivePixels/2); HSyncOddField1 = (WORD)(HSyncOddField0 + (VSyncActIsOdd * (HSyncTotalPixels/2))); HSyncEvenField0 = (WORD)(HSyncOddField0 + HSyncTotalPixels/2); HSyncEvenField1 = (WORD)(HSyncEvenField0 - (VSyncActIsOdd * (HSyncTotalPixels/2))); if( this->InvertField ) { // It starts with even field. Field even=bottom= nVSync goes low when nHSync is hi. VSyncOddField0 += (WORD)(MP->VSyncTotal/2 + 1); VSyncOddField1 += (WORD)(MP->VSyncTotal/2 + 1); VSyncEvenField0 -= (WORD)(MP->VSyncTotal/2); VSyncEven
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -