📄 dvr_ref1.c
字号:
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
cpuClockRate = (Float) procCap->cpuClockFrequency;
if (procCap->deviceID == PROC_DEVICE_TM1000)
return AIO_ERR_AUDIO_OUT_NOT_SUPPORTED;
AO_shutdown = True;
DP(("AO_Init\n"));
dvr_ref1AttemptToggleAudioReset(AO_shutdown, AI_shutdown);
/* reset the audio output peripheral */
aoRESETM(AO_STATUS);
/* Set initial frequency to get AO into a stable state */
ddsVal = hertz2Control(param->sRate, 6, 64, 1, cpuClockRate);
aoSetFREQM(AO_STATUS, ddsVal | 0x80000000);
aoEnableSER_MASTERM(AO_STATUS);
microsleep(2); /* delay before further setup */
if (! (param->audioTypeFormat & DVR_REV1_SUPPORTED_DATA_TYPES) )
return AIO_ERR_UNSUPPORTED_FORMAT;
if (! (param->audioSubtypeFormat & DVR_REV1_SUPPORTED_DATA_SUBTYPES) )
return AIO_ERR_UNSUPPORTED_FORMAT;
#ifdef __LITTLE_ENDIAN__
aoEnableLITTLE_ENDIANM(AO_STATUS);
#else
aoDisableLITTLE_ENDIANM(AO_STATUS);
#endif
aoMsbFirstM(AO_STATUS);
aoStartRisingEdgeWSM(AO_STATUS);
aoSampleRisingCLOCK_EDGEM(AO_STATUS); /* sample on rising edge */
aoSetSSPOSM(AO_STATUS, 0); /* Left and right channel start at bit 0 */
aoDisableSIGN_CONVERTM(AO_STATUS); /* Disable Sign Convert for MSB */
aoDisableWS_PULSEM(AO_STATUS); /* word strobe not in pulse mode */
aoDisableTRANS_ENABLEM(AO_STATUS);
switch (param->audioSubtypeFormat) {
case apfStereo16: /* Two channel Audio, not IIS */
{ /* 64 * 6 * 1 = 384fs */
L1_DP(("stereo 16 bit\n"));
aoSetTRANS_MODEM(AO_STATUS, 3);
aoSetWSDIVM(AO_STATUS, 63);
aoSetSCKDIVM(AO_STATUS, 5);
aoSetSFDIVM(AO_STATUS, 0);
aoSetLEFTPOSM(AO_STATUS, 15);
aoSetRIGHTPOSM(AO_STATUS, 47);
aoStartRisingEdgeWSM(AO_STATUS);
aoSetSIZEM(AO_STATUS, param->size);
break;
}
default:
/* unsupported subtype */
return(AIO_ERR_UNSUPPORTED_FORMAT);
}
AO_shutdown = False;
dvr_ref1EnableAudio();
#ifdef USE_KARAOKE
yss903Init( DVR_REV1_KAR_DATA, DVR_REV1_KAR_CTRL, DVR_REV1_KAR_ADDR);
#endif
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_SetSRate(Float sRate)
{
UInt ddsVal;
Float cpuClockRate;
pprocCapabilities_t procCap;
tmLibdevErr_t err;
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
cpuClockRate = (Float) procCap->cpuClockFrequency;
ddsVal = hertz2Control(sRate, 6, 64, 1, cpuClockRate);
aoSetFREQM(AO_STATUS, ddsVal | 0x80000000);
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_GetSRate(Float * sRate)
{
Int err = TMLIBDEV_OK;
Float cpuClockRate;
UInt freq;
pprocCapabilities_t procCap;
Float rate;
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
cpuClockRate = (Float) procCap->cpuClockFrequency;
freq = MMIO(AO_FREQ);
rate = (Float) (freq & 0x7fffffff) * cpuClockRate / 477218588.0;
rate = rate / (384.0);
*sRate = rate;
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_term(void)
{
aoRESETM(AO_STATUS);
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_start(void)
{
aoEnableTRANS_ENABLEM(AO_STATUS);
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_stop(void)
{
aoDisableTRANS_ENABLEM(AO_STATUS);
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_Config(UInt32 subaddr, Pointer value)
{
return AIO_ERR_COMMAND_NOT_SUPPORTED;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_SetVolume(Int lGain, Int rGain)
{
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AO_GetVolume(Int *lGain, Int *rGain)
{
*rGain = *lGain = 0;
return TMLIBDEV_OK;
}
/*********************************************************************
***************** AI section **************************
*********************************************************************/
/***********************************************************************
* Convert a floating point sample rate value
* to a 32 bit frequency control value for the DDS.
*
* Accurate to .5 ppm.
* The DDS can do better than this, but 64 bit math is
* required to use this interface.
*/
static tmLibdevErr_t dvr_ref1_AI_SetSRate(Float sRate)
{
Float val;
pprocCapabilities_t procCap;
Float cpuClockRate;
Int err = TMLIBDEV_OK;
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
cpuClockRate = (Float) procCap->cpuClockFrequency;
val = 0.5 + (477218588.0 * (sRate * 384.0 / cpuClockRate));
aiSetFREQ(((UInt) val) | 0x80000000);
return TMLIBDEV_OK;
}
/***********************************************************************/
static tmLibdevErr_t dvr_ref1_AI_Init(pboardAIParam_t param)
{
Int err = TMLIBDEV_OK;
tmAssert(param, TMLIBDEV_ERR_NULL_PARAMETER);
/* check if audio type is supported */
if (!(param->audioTypeFormat & pcm1800_SUPPORTED_DATA_TYPE))
{
return AIO_ERR_UNSUPPORTED_FORMAT;
}
/* check if audio subtype is supported */
if (!(param->audioSubtypeFormat & pcm1800_SUPPORTED_DATA_SUBTYPES))
{
return AIO_ERR_UNSUPPORTED_FORMAT;
}
#if 0 // these are done in the reset function
/* hardware supports only stereo16 */
aiSetWSDIV(63);
aiSetSCKDIV(5);
aiSetCAP_MODE( 3); /* Stereo 16 bits per sample */
aiDisableSIGN_CONVERT();
aiMsbFirst(); /* MSB first */
aiSetFRAMEMODE(0); /* ignore valid bit */
aiSampleRisingCLOCK_EDGE(); /* sample on rising edge */
aiStartFallingEdgeWS();
aiSetSSPOS( 0);
aiSetLEFTPOS(0);
aiSetRIGHTPOS(32);
#endif
DP(("AI_Init\n"));
AI_shutdown = True;
dvr_ref1AttemptToggleAudioReset(AO_shutdown, AI_shutdown);
aiSetSIZE(param->size);
err = dvr_ref1_AI_SetSRate(param->sRate);
if (err)
return err;
AI_shutdown = False;
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AI_Term(void)
{
/* reset audio in */
aiRESET();
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AI_Start(void)
{
aiEnableCAP_ENABLE();
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AI_Stop(void)
{
aiDisableCAP_ENABLE();
return TMLIBDEV_OK;
}
/* audio in runs at the same clock as audio out */
static tmLibdevErr_t dvr_ref1_AI_GetSRate(Float * sRate)
{
UInt freq = MMIO(AI_FREQ);
Float rate;
pprocCapabilities_t procCap;
Float cpuClockRate;
Int err = TMLIBDEV_OK;
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
cpuClockRate = (Float) procCap->cpuClockFrequency;
tmAssert(sRate, TMLIBDEV_ERR_NULL_PARAMETER);
rate = (Float) (freq & 0x7fffffff) * cpuClockRate / 477218588.0;
rate = rate / 384;
*sRate = rate;
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AI_SetInput(tmAudioAnalogAdapter_t input)
{
if (input != aaaLineInput)
return AIO_ERR_UNSUPPORTED_INPUT;
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t dvr_ref1_AI_GetInput(tmAudioAnalogAdapter_t * input)
{
*input = aaaLineInput;
return TMLIBDEV_OK;
}
/* VO initialization */
static tmLibdevErr_t boardVOInit(pboardVOParam_t param)
{
tmLibdevErr_t rval = TMLIBDEV_OK;
DP(("reset video devices\n"));
/* this video encoder needs to be reset on standards
* changes, so reset it. Unfortunately on this board
* the video decoder is on the same reset line.....
*/
dvr_ref1ResetVideo();
microsleep(10);
dvr_ref1EnableVideo();
voSetFREQUENCY__CHECK(param->ddsFrequency);
voSetPLL_S__CHECK(1);
voSetPLL_T__CHECK(1);
voSetCLKOUT__CHECK(1);
voSetSYNC_MASTER__CHECK(1);
switch (param->videoStandard)
{
case vasNTSC:
voSupportNTSC();
break;
case vasPAL:
voSupportPAL();
break;
case vasNone:
break;
default:
return BOARD_ERR_UNSUPPORTED_STANDARD;
}
return rval;
}
/******************************************************************************/
static tmLibdevErr_t dvr_ref1_VI_Init (pboardVIParam_t param)
{
tmLibdevErr_t err;
if ((err = tw98Init(&dvr_ref1_vi.vDec, param)) != TMLIBDEV_OK)
return err;
return TMLIBDEV_OK;
}
/******************************************************************************/
static tmLibdevErr_t dvr_ref1_VI_SetAnalogInput(pboardVIDec_t pVD, tmVideoAnalogAdapter_t adapter, UInt adapterInstance)
{
int i;
Bool foundIt = False;
UInt num = 0;
for (i=0; i<NO_OF_VIDEO_ADAPTERS; i++)
{
if ( (dvr_ref1_vi_adapters[i].adapterType == adapter)
&& (dvr_ref1_vi_adapters[i].instNum == adapterInstance)
)
{
num = dvr_ref1_vi_adapters[i].decInput;
foundIt = True;
break;
}
}
if (!foundIt)
return VI_ERR_INVALID_DECODER_INIT;
return tw98SetAnalogInput(pVD, num);
}
/******************************************************************************/
static tmLibdevErr_t dvr_ref1_VI_GetAnalogInput(pboardVIDec_t pVD, tmVideoAnalogAdapter_t *adapter, UInt *adapterInstance)
{
int i;
tmLibdevErr_t rval;
UInt num;
rval = tw98GetAnalogInput(pVD, &num);
if (rval)
return rval;
for (i=0; i<NO_OF_VIDEO_ADAPTERS; i++)
{
if (num == dvr_ref1_vi_adapters[i].decInput)
{
*adapter = dvr_ref1_vi_adapters[i].adapterType;
*adapterInstance = dvr_ref1_vi_adapters[i].instNum;
return TMLIBDEV_OK;
}
}
return VI_ERR_INVALID_DECODER_INIT;
}
/******************************************************************************/
static tmLibdevErr_t dvr_ref1_VI_Configure(UInt32 subaddr, UInt32 value)
{
return tw98Configure(&dvr_ref1_vi.vDec, subaddr, value);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -