📄 csm2288.c
字号:
/********************************************************************************************//* Csm2288.c : Implementation of mpeg encoder interface* REALmagic Quasar Hardware Library* Created by Aurelia Popa-Radu* Copyright Sigma Designs Inc* Sigma Designs Proprietary and confidential* Created on 8/5/01* Description:/********************************************************************************************//****h* HwLib/IMpegEncoder_implementation * NAME * IMpegEncoder_implementation * DESCRIPTION * Csm2288 implementation of the IMpegEncoder interface. * COPYRIGHT * Copyright Sigma Designs Inc * Sigma Designs Proprietary and confidential/********************************************************************************************/#include "pch.h"#if defined SM2288_OBJECT#include "csm2288.h"#include "regs840x.h"#include "regs847x.h"#include "em847x.h"WORD SM2288UCode[]={#include "sm2288/recorder.h"};#ifdef WITH_SM2288_DIAG WORD SM2288DiagnosisUCode[]={#include "sm2288/2288_diag.h"};#endif // WITH_SM2288_DIAG ////////////////////////////////////////////////////////////////////////////****f* HwLib/Csm2288__CreateInstance * USAGE * NOT PRESENT in IMpegEncoder interface * void Csm2288__CreateInstance(void **pv, DWORD dwInstance) * DESCRIPTION * Csm2288__CreateInstance allocates memory for MpegEncoder object, specific in * this code StreamMachine 2288 * PARAMETERS * IN DWORD dwInstance - instance passed down by CreateInstance. * OUT void** pv - Points to a 32-bit variable that receives the pointer to object *SEE ALSO * Csm2288__CreateInstance/********************************************************************************************/void Csm2288__CreateInstance(void **pv, DWORD dwInstance){ Csm2288__New((Csm2288**)pv, TEXT("Sm2288"), TRUE, dwInstance);}/****f* HwLib/Csm2288__New * USAGE * NOT PRESENT in IMpegEncoder interface * void Csm2288__New(Csm2288** ppCsm2288, TCHAR *pName, BOOL bAllocate, DWORD dwInstance) * DESCRIPTION * Csm2288__New - allocates memory for a new MpegEncoder object and plays the role of * the constructor in C++. * PARAMETERS * OUT Csm2288** ppCsm2288 - Points to a 32-bit variable that receives the pointer to object * IN TCHAR *pName - pointer to string containing the name of the object - debug purposes. * BOOL bAllocate - usually called with TRUE to allocate memory for object. * - if FALSE ppCsm2288 should point to an object already created. * IN DWORD dwInstance - instance passed down by CreateInstance. * SEE ALSO * IMpegEncoder_Delete/********************************************************************************************/void Csm2288__New (Csm2288** ppCsm2288, TCHAR *pName, BOOL bAllocate, DWORD dwInstance){ Csm2288* this = *ppCsm2288; if (bAllocate) { // Allocate Csm2288 *ppCsm2288 = OSmalloc(sizeof(Csm2288)); this = (Csm2288*) *ppCsm2288; if(this == NULL) return; OSmemset(this, 0, sizeof(Csm2288)); } // Call CObject constructor with bAllocate = FALSE CObject__New ((CObject**)ppCsm2288, pName, FALSE, dwInstance); // Initialize virtual table this->VTable.Delete = Csm2288__Delete; this->VTable.Init = Csm2288__Init; this->VTable.Write = Csm2288__Write; this->VTable.Read = Csm2288__Read; this->VTable.ReadTXFifo = Csm2288__ReadTXFifo; this->VTable.HwReset = Csm2288__HwReset; this->VTable.WriteCommand = Csm2288__WriteCommand; this->VTable.WriteEncodingParams = Csm2288__WriteEncodingParams; this->VTable.ReadData = Csm2288__ReadData; this->VTable.WriteData = Csm2288__WriteData; this->VTable.SetCurrentIrqMask = Csm2288__SetCurrentIrqMask; this->VTable.GetCurrentIrqMask = Csm2288__GetCurrentIrqMask; this->VTable.GetHwIrqMask = Csm2288__GetHwIrqMask; this->VTable.GetHwIrqStatus = Csm2288__GetHwIrqStatus; this->VTable.InitPropertySet = Csm2288__InitPropertySet; this->VTable.SetProperty = Csm2288__SetProperty; this->VTable.GetProperty = Csm2288__GetProperty; this->VTable.GetMicrocodeVersion = Csm2288__GetMicrocodeVersion; this->VTable.Test = Csm2288__Test; this->lpVtbl = &this->VTable;}/****f* HwLib/IMpegEncoder_Delete * USAGE * IMpegEncoder_Delete(IMpegEncoder* pIMpegEncoder, BOOL bDeleteObject) * Csm2288__Delete(IMpegEncoder* pIMpegEncoder, BOOL bDeleteObject) * DESCRIPTION * IMpegEncoder_Delete - frees memory for the specified MpegEncoder object. * IMpegEncoder_Delete plays the role of the destructor in C++. * PARAMETERS * IN IMpegEncoder* pIMpegEncoder - pointer to the object created by a previous * call to Csm2288__CreateInstance or Csm2288__New. * BOOL bDeleteObject - usually called with TRUE to free memory for object. * - if FALSE doesn't free any memory. * SEE ALSO * Csm2288__CreateInstance, Csm2288__New/********************************************************************************************/void Csm2288__Delete (IMpegEncoder* pIMpegEncoder, BOOL bDeleteObject){ Csm2288* this = (Csm2288*) pIMpegEncoder ; if (this == NULL) return; // Release what we were using // Call CObject Destructor CObject__Delete ((IObject*)this, FALSE); if (bDeleteObject) { // Delete Csm2288 OSfree(pIMpegEncoder); }}/****f* HwLib/IMpegEncoder_Init * USAGE * void IMpegEncoder_Init(IMpegEncoder* pIMpegEncoder) * void Csm2288__Init(IMpegEncoder* pIMpegEncoder) * DESCRIPTION * IMpegEncoder_Init - initialize the MpegEncoder object * It is called by CreateInstance. * PARAMETERS * IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object/********************************************************************************************/void Csm2288__Init(IMpegEncoder* pIMpegEncoder){ Csm2288* this = (Csm2288*) pIMpegEncoder; DWORD SymbolTableSize; QueryInterface(this->m_dwInstance, IID_IDECODER, (void**)&(this->m_pIDecoder)); IDecoder_GetSymbolTable(this->m_pIDecoder, &this->pQ, &SymbolTableSize); // invalid default value: this->CurrentMicrocodeVersion = 0xbeef;}/****f* HwLib/IMpegEncoder_Write * USAGE * void IMpegEncoder_Write(IMpegEncoder* pIMpegEncoder, DWORD Address, DWORD Data) * void Csm2288__Write(IMpegEncoder* pIMpegEncoder, DWORD Address, DWORD Data) * PARAMETERS * IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object * IN DWORD Address - address of the register to write * IN DWORD Data - data to write/********************************************************************************************/void Csm2288__Write(IMpegEncoder* pIMpegEncoder, DWORD Address, DWORD Data){ Csm2288* this = (Csm2288*) pIMpegEncoder; IDecoder_WriteLbcReg(this->m_pIDecoder, Address, Data);}/****f* HwLib/IMpegEncoder_Read * USAGE * DWORD IMpegEncoder_Read(IMpegEncoder* pIMpegEncoder, DWORD Address) * DWORD Csm2288__Read(IMpegEncoder* pIMpegEncoder, DWORD Address) * PARAMETERS * IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object/********************************************************************************************/DWORD Csm2288__Read(IMpegEncoder* pIMpegEncoder, DWORD Address){ Csm2288* this = (Csm2288*) pIMpegEncoder; DWORD Data = 0x1234; IDecoder_ReadLbcReg(this->m_pIDecoder, Address, &Data); return Data;}/// /** Loops on the TX_FIFO_NOT_EMPTY flag - if a message appears in [0,*pTimeLeft_ms[, *pTimeLeft_ms is diminished of the time elapsed, but is still >0, and the message is returned by the function or - if timeout expires, *pTimeLeft_ms=0 and the return value represents nothing Obviously, specifying a very large timeout freezes the machine until it expires. The semantic of this functions allows to write easily a while() loop to read a given number of answers within a certain delay. @param pIMpegEncoder @param pTimeLeft_ms @return <ReturnValue>*/DWORD Csm2288__ReadTXFifo(IMpegEncoder* pIMpegEncoder,DWORD *pTimeLeft_ms){ DWORD beginning=OSTimeGetTime(); while (1) { DWORD msSinceBeginning=OSTimeGetTime()-beginning; if (msSinceBeginning>=*pTimeLeft_ms) { *pTimeLeft_ms=0; return 0xbad00bad; } if (Csm2288__Read(pIMpegEncoder,SM2288_INT_INFO)&TX_FIFO_NOT_EMPTY) { *pTimeLeft_ms-=msSinceBeginning; return Csm2288__Read(pIMpegEncoder, SM2288_TX_FIFO); } }}BOOL CQuasar__ChannelWriteDramSlave(IDecoder* pIDecoder, DWORD Ch, IN DWORD addr, IN DWORD* pData, IN DWORD nBytes);/****f* HwLib/IMpegEncoder_HwReset * USAGE * QRESULT IMpegEncoder_HwReset(IMpegEncoder* pIMpegEncoder, void* pUCode, DWORD nBytesUCode, void* pParams, DWORD nBytesParams, DWORD Info) * QRESULT Csm2288__HwReset(IMpegEncoder* pIMpegEncoder, void* pUCode, DWORD nBytesUCode, void* pParams, DWORD nBytesParams, DWORD Info) * DESCRIPTION * IMpegEncoder_HwReset - reset the hardware * PARAMETERS * IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object/********************************************************************************************/QRESULT Csm2288__HwReset(IMpegEncoder* pIMpegEncoder, void* pUCodeIn, DWORD nBytesUCode, void* pParams, DWORD nBytesParams, DWORD Info){ Csm2288* this = (Csm2288*) pIMpegEncoder; WORD* pUCode = SM2288UCode; DWORD totalsize = sizeof(SM2288UCode); // sizeof() result is in bytes!!! DWORD t0; DWORD LBCInt = IDecoder_ReadReg(this->m_pIDecoder, LBC_interrupt_reg) & 0xFF; // VideoIn and encoding are dependend because VideoIn VSync interrupt is routed // through LBC_interrupt register. Try to separate the two functions by not reseting LBC internal IDecoder_WriteReg(this->m_pIDecoder, RISC_resets_1, 0x1010); // reset external LBC OSTimeDelay(100); IDecoder_WriteReg(this->m_pIDecoder, RISC_resets_1, 0x1000); // unreset external LBC OSTimeDelay(1000);// 100 not enough !!! // the new microcode enables by itself the VSync interrupt in VideoIn // and we should keep the value - need a better synchronization in the next // microcode. Also the polarity is cleared when the VideoIn VSync is coming IDecoder_WriteReg(this->m_pIDecoder, LBC_interrupt_reg, LBCInt | LBC_SM_INTR_ACTIVE_LO); // set mask and polarity { Q4SymbolTable* pQ = (Q4SymbolTable*)this->pQ; IDecoder_WriteDM(this->m_pIDecoder, pQ->LBCinterrupt.addr, 0x1100); } if( pUCodeIn == NULL ) { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(">>>Csm2288__HwReset internal ucode (%d bytes)"), totalsize)); } else { pUCode = (WORD *)pUCodeIn; totalsize = nBytesUCode; // sizeof() result is in bytes!!! QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(">>>Csm2288__HwReset external ucode (%d bytes)"), totalsize)); } if ( Info & INFO_SM_XFER_UCODE_IO ) { // for loop lasts about 650000 microseconds. DWORD i; QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(" Csm2288__HwReset XFER_UCODE_IO"))); for(i=0;i<totalsize/sizeof(WORD);i++) Csm2288__Write(pIMpegEncoder, SM2288_UCODE_DOWNLOAD, *(pUCode + i)); } else if(Info & INFO_SM_XFER_UCODE_BURST_SYS) { // intel burst lasts about ???? microseconds. DWORD maxxfer,offset=0; DWORD Mux1 = IDecoder_ReadReg(this->m_pIDecoder, 0x1fe5); DWORD Mux2 = IDecoder_ReadReg(this->m_pIDecoder, 0x1fe6); if ((this->XferUcodeParameters.SysPhysAddr == 0) || (this->XferUcodeParameters.SysLinAddr == 0) || (this->XferUcodeParameters.SysSizeInBytes == 0) ) { QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(" Csm2288__HwReset XFER_UCODE_BURST_SYS FAILED"))); return Q_FAIL; } QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT(" Csm2288__HwReset XFER_UCODE_BURST_SYS"))); while(1) { maxxfer = min(totalsize-offset,this->XferUcodeParameters.SysSizeInBytes); // use 32k of contiguos system memory (0x8000 bytes) at a harcoded address to // load the StreamMachine microcode directly in LBC through HostMaster_W4_LWCH0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -