📄 philips_iref.c
字号:
__irefNeedToInitAD1847 = True;
__irefNeedAD1847Reset = False;
__irefSampleRate = 0.0;
__irefNeedToStartAi = False;
__irefAoInitialized = False;
__irefAoRunning = False;
__irefAoNeedToConfigureOutput = False;
__irefAoCurrentPcmFormat = apfNone;
__irefAoLGain = 0;
__irefAoRGain = 0;
__irefAiInitialized = False;
__irefAiRunning = False;
__irefAiNeedToConfigureInput = False;
__irefAiCurrentPcmFormat = apfNone;
__irefAiInput = aaaLineInput;
__irefAiAd1847Input = AD1847_SRC_LINE1;
__irefAiLGain = 0;
__irefAiRGain = 0;
aoRESET(); /* everything is done, so shut down */
aiRESET();
/* Set all frequencies to 0, Reset sets the frequency register to 0 but does not
stop the DDS */
MMIO(AO_FREQ) = MMIO(AI_FREQ) = 0;
rval = ad1847Term();
if (rval)
{
return rval;
}
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t iref_AO_start(void)
{
tmLibdevErr_t rval;
/* start audio out unit */
aoEnableTRANS_ENABLE();
/* the codec control register has to be set again because
otherwise the CC_BUSY flag will not be reset */
aoSetCC2(0x0F00);
if (__irefAoCurrentPcmFormat != apfFiveDotOne16)
{
if (__irefNeedAD1847Reset)
{
/*reset AD1847 */
rval = ad1847Reset(__irefSampleRate);
if (rval != TMLIBDEV_OK)
return rval;
__irefNeedAD1847Reset = False;
}
if (__irefNeedToStartAi)
{
aiEnableCAP_ENABLE();
__irefAiRunning = True;
}
if (__irefAoNeedToConfigureOutput)
{
rval = ad1847ConfigureOutput(__irefAoLGain, __irefAoRGain);
if (rval != TMLIBDEV_OK)
{
return rval;
}
__irefAoNeedToConfigureOutput = False;
}
if (__irefAiNeedToConfigureInput)
{
rval = ad1847ConfigureInput(__irefAiAd1847Input, __irefAiLGain, __irefAiRGain);
if (rval != TMLIBDEV_OK)
{
return rval;
}
__irefAiNeedToConfigureInput = False;
}
}
__irefAoRunning = True;
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t iref_AO_stop(void)
{
/* if audio in is running, we have to stop it because
the missing codec control will change settings in the
AD1847 */
if (__irefAiRunning)
{
__irefAiRunning = False;
__irefNeedToStartAi = True;
aiDisableCAP_ENABLE();
}
/* stop audio out unit */
aoDisableTRANS_ENABLE();
if (__irefAoCurrentPcmFormat != apfFiveDotOne16)
{
__irefNeedAD1847Reset = True;
}
__irefAoRunning = False;
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t iref_AO_SetVolume(Int lGain, Int rGain)
{
Int rval = TMLIBDEV_OK;
Int rvalConfig;
/* 6 channel mode: no action */
if (__irefAoCurrentPcmFormat == apfFiveDotOne16)
return AIO_ERR_COMMAND_NOT_SUPPORTED;
if (lGain < AD1847_OUTPUT_MIN_VOLUME)
{
lGain = AD1847_OUTPUT_MIN_VOLUME;
rval = AIO_ERR_VOLUME_TOO_LOW;
}
if (rGain < AD1847_OUTPUT_MIN_VOLUME)
{
rGain = AD1847_OUTPUT_MIN_VOLUME;
rval = AIO_ERR_VOLUME_TOO_LOW;
}
if (lGain > AD1847_OUTPUT_MAX_VOLUME)
{
lGain = AD1847_OUTPUT_MAX_VOLUME;
rval = AIO_ERR_VOLUME_TOO_HIGH;
}
if (rGain > AD1847_OUTPUT_MAX_VOLUME)
{
rGain = AD1847_OUTPUT_MAX_VOLUME;
rval = AIO_ERR_VOLUME_TOO_HIGH;
}
__irefAoLGain = lGain;
__irefAoRGain = rGain;
if (!__irefAoRunning)
{
__irefAoNeedToConfigureOutput = True;
return rval;
}
rvalConfig = ad1847ConfigureOutput(__irefAoLGain, __irefAoRGain);
if (rvalConfig)
{
return rvalConfig;
}
return rval;
}
/*******************************************************/
static tmLibdevErr_t iref_AO_GetVolume(Int *lGain, Int *rGain)
{
tmAssert(lGain, TMLIBDEV_ERR_NULL_PARAMETER);
tmAssert(rGain, TMLIBDEV_ERR_NULL_PARAMETER);
/* 6 channel mode: no action */
if (__irefAoCurrentPcmFormat == apfFiveDotOne16)
return AIO_ERR_COMMAND_NOT_SUPPORTED;
*lGain = __irefAoLGain;
*rGain = __irefAoRGain;
return TMLIBDEV_OK;
}
/***********************************************************************
* Convert a floating point sample rate value
* to a 32 bit frequency control value for the DDS.
*
* NOTE: YOU MUST SET THE sckdiv, wsdiv and sfdiv FIELDS FOR THIS TO WORK!
*
* Accurate to .5 ppm.
* The DDS can do better than this, but 64 bit math is
* required to use this interface.
*/
static tmLibdevErr_t iref_AO_SetSRate(Float sRate)
{
UInt aoSerial;
Float sckdiv, wsdiv, val, sfdiv;
tmLibdevErr_t rval;
if (__irefSampleRate == sRate)
return TMLIBDEV_OK;
__irefSampleRate = sRate;
if (__irefAoCurrentPcmFormat == apfFiveDotOne16)
{
/* audio out runs in master mode, therefore all those clock deviders are set */
aoSerial = MMIO(AO_SERIAL);
sckdiv = (Float) (aoExtractSCKDIV(aoSerial) + 1);
wsdiv = (Float) (aoExtractWSDIV(aoSerial) + 1);
sfdiv = (Float) (aoExtractSFDIV(aoSerial) + 1);
val = hertz2Control(sRate, sckdiv, wsdiv, sfdiv);
aoSetFREQ((UInt) val);
}
else
{
/* audio out runs in slave mode. The AD1847 uses 512 fs. */
val = hertz2Control(sRate, 512, 1, 1);
aoSetFREQ((UInt) val);
/* we have to reset the AD1847 after changing the audio clock */
if (__irefAoRunning)
{
/*reset AD1847 */
rval = ad1847Reset(sRate);
if (rval != TMLIBDEV_OK)
return rval;
}
else
{
__irefNeedAD1847Reset = True;
}
}
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t iref_AO_GetSRate(Float * sRate)
{
UInt serial = MMIO(AO_SERIAL);
UInt freq = MMIO(AO_FREQ);
UInt sckdiv = aoExtractSCKDIV(serial);
UInt wsdiv = 1 + aoExtractWSDIV(serial);
UInt sfdiv = 1 + aoExtractSFDIV(serial);
Float rate;
tmAssert(sRate, TMLIBDEV_ERR_NULL_PARAMETER);
if (__irefAoCurrentPcmFormat == apfFiveDotOne16)
{
if (__irefTMIsNot1S)
sckdiv -= 1; /* SCOPUS_BUG_ID_3013 */
else
sckdiv += 1;
rate = (Float) freq *(Float) __irefCPUClockFrequency / 1431655765.0;
rate = rate / ((Float) sckdiv * (Float) wsdiv * (Float) sfdiv);
}
else
{
rate = (Float) freq *(Float) __irefCPUClockFrequency / 1431655765.0;
rate = rate / 512.0; /* the AD1847 runs at 512 fs */
}
*sRate = rate;
return TMLIBDEV_OK;
}
/*******************************************************/
static tmLibdevErr_t iref_AI_init(pboardAIParam_t param)
{
Int rval;
tmAudioAnalogAdapter_t input;
tmAssert(param, TMLIBDEV_ERR_NULL_PARAMETER);
/* check if audio type is supported */
if (!(param->audioTypeFormat & IREF_SUPPORTED_STREAM_FORMATS))
{
return AIO_ERR_UNSUPPORTED_FORMAT;
}
/* check if audio subtype is supported */
if (!(param->audioSubtypeFormat & IREF_SUPPORTED_PCM_IN_FORMATS))
{
return AIO_ERR_UNSUPPORTED_FORMAT;
}
/* check settings for audio input adapter */
if (param->input & IREF_INPUT_AUDIO_ADAPTERS)
{
input = param->input;
if (param->input == aaaNone)
{
input = aaaLineInput;
}
}
else
{
return AIO_ERR_UNSUPPORTED_FORMAT;
}
/* If input and output are running at the same time their PCM formats must be the
* same. */
if (__irefAoInitialized && (param->audioSubtypeFormat != __irefAoCurrentPcmFormat))
{
return AIO_ERR_UNMATCHED_FORMATS;
}
if (__irefNeedToInitAD1847)
{
/* reset the audio I/O peripherals */
aoRESET();
aiRESET();
/* set frequency, The AD1847 uses the oversampling clock of the audio out
unit. Therefore we have to set the frequency register of the audio out
unit. */
MMIO(AO_FREQ) = hertz2Control(param->sRate, 4, 128, 1);
MMIO(AI_FREQ) = MMIO(AO_FREQ);
/* the AD 1847 has allready been initialized */
rval = ad1847MasterInit((tmAudioPcmFormat_t)param->audioSubtypeFormat,
param->sRate);
if (rval)
{
__irefAiCurrentPcmFormat = apfNone;
return rval;
}
__irefNeedToInitAD1847 = False;
}
/* set the requested input */
iref_AI_SetInput(input);
/* do format specific setup */
switch (param->audioSubtypeFormat)
{
case apfMono16:
aiSetCAP_MODE(2);
break;
case apfStereo16:
aiSetCAP_MODE(3);
break;
default:
return AIO_ERR_UNSUPPORTED_FORMAT;
/* no break ... statement unreachable */
}
#ifdef __LITTLE_ENDIAN__
aiEnableLITTLE_ENDIAN();
#else
aiDisableLITTLE_ENDIAN();
#endif
aiDisableSIGN_CONVERT();
aiDisableSER_MASTER();
aiMsbFirst();
aiSetFRAMEMODE(0);
aiSampleFallingCLOCK_EDGE();
aiStartRisingEdgeWS();
aiSetLEFTPOS(16);
aiSetRIGHTPOS(32);
aiSetSIZE(param->size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -