📄 dtv_ref3_audio.c
字号:
aoSetSIZE(param->size * 2);
if (param->audioTypeFormat & atf1937)
{
/* set tda1315 to transmit non-PCM data */
}
break;
}
case apfFourCh_3_1_0_16: /* Four channel Audio */
case apfFourCh_2_2_0_16: /* Four channel Audio */
case apfFourCh_2_1_1_16: /* Four channel Audio */
case apfFourCh_3_0_1_16: /* Four channel Audio */
{ /* 63 * 2 * 2 = 256fs */
DP(("four channels 16 bit\n"));
fpgaAudioMode |= (__SET_OUTPUT_4_CHANS | __SET_OUTPUT_16_BITS);
aoSetWSDIV(63);
aoSetSCKDIV(1);
aoSetSFDIV(1);
aoSetLEFTPOS(16);
aoSetRIGHTPOS(48);
aoSetSIZE(param->size * 2);
if ((param->audioTypeFormat & atf1937) && (param->audioSubtypeFormat == apfFourCh_2_2_0_16))
{
/* set second pair's tda1315 to transmit non-PCM data */
}
break;
}
case apfFourCh_3_1_0_32: /* Four channel Audio, 32-bit */
case apfFourCh_2_2_0_32: /* Four channel Audio, 32-bit */
case apfFourCh_2_1_1_32: /* Four channel Audio, 32-bit */
case apfFourCh_3_0_1_32: /* Four channel Audio, 32-bit */
{ /* 32 * 2 * 4 = 256 fs */
DP(("four channels 32 bit\n"));
fpgaAudioMode |= (__SET_OUTPUT_4_CHANS | __SET_OUTPUT_32_BITS);
aoSetWSDIV(31);
aoSetSCKDIV(1);
aoSetSFDIV(3);
#ifdef __LITTLE_ENDIAN__
aoSetLEFTPOS(16);
aoSetRIGHTPOS(0);
#else
aoSetLEFTPOS(0);
aoSetRIGHTPOS(16);
#endif
aoSetSIZE(param->size * 4);
if ((param->audioTypeFormat & atf1937) && (param->audioSubtypeFormat == apfFourCh_2_2_0_32))
{
/* set second pair's tda1315 to transmit non-PCM data */
}
break;
}
case apfSevenDotOne16: /* Eight Channel Audio */
{ /* 64 * 4 * 1 = 256 fs*/
DP(("eight channels 16 bit\n"));
fpgaAudioMode |= (__SET_OUTPUT_8_CHANS | __SET_OUTPUT_16_BITS);
DP(("Fpga : %08x\n", fpgaAudioMode ));
aoSetWSDIV(63);
aoSetSCKDIV(0);
aoSetSFDIV(3);
aoSetLEFTPOS(16);
aoSetRIGHTPOS(48);
aoSetSIZE(param->size * 4);
if (param->audioTypeFormat & atf1937)
{
/* set fourth pair's tda1315 to transmit non-PCM data */
}
break;
}
case apfSevenDotOne32: /* Eight Channel Audio, 32-bit */
{ /* 32 * 4 * 1 = 128fs -> In 32-bit mode the audio out hardware runs at
the double speed. Therefore the resulting oversampling clock is 256 fs.*/
DP(("eight channels 32 bit\n"));
fpgaAudioMode |= (__SET_OUTPUT_8_CHANS | __SET_OUTPUT_32_BITS);
DP(("Fpga : %08x\n", fpgaAudioMode ));
aoSetWSDIV(31);
aoSetSCKDIV(0);
aoSetSFDIV(3);
#ifdef __LITTLE_ENDIAN__
aoSetLEFTPOS(16);
aoSetRIGHTPOS(0);
#else
aoSetLEFTPOS(0);
aoSetRIGHTPOS(16);
#endif
aoSetSIZE(param->size * 8);
if (param->audioTypeFormat & atf1937)
{
/* set fourth pair's tda1315 to transmit non-PCM data */
}
break;
}
default:
/* unsupported subtype */
return(AIO_ERR_UNSUPPORTED_FORMAT);
}
/* set sample rate */
err = dtv_ref3_AO_SetSRate(param->sRate);
if (err) return err;
/* take FPGA out of reset in the proper mode */
fpgaAudioMode |= __SET_MUTE_BIT;
/* Reset Audio Out */
fpgaAudioMode |= __SET_RESET_BIT;
*pAudioRegAddr = fpgaAudioMode;
microsleep(300);
fpgaAudioMode &= ~__SET_RESET_BIT;
*pAudioRegAddr = fpgaAudioMode;
microsleep(300);
fpgaAudioMode |= __SET_RESET_BIT;
*pAudioRegAddr = fpgaAudioMode;
return TMLIBDEV_OK;
} /* end of dtv_ref3_AO_Init() */
/*******************************************************/
extern tmLibdevErr_t dtv_ref3_AO_Term(void)
{
Int err = TMLIBDEV_OK;
unsigned char *pAudioRegAddr = (unsigned char *) FPGA_AUDIO_REG_ADDRESS;
/* reset statics */
dtvRef3DoubleDDSEnable = False;
dtvRef3AoRunning = False;
dtvRef3AoNeedToConfigureTDA1315 = False;
aoRESET();
fpgaAudioMode = ~REF3_OUTPUT_FPGA_AUDIOMODE_MASK;
*pAudioRegAddr = fpgaAudioMode;
return err;
}
/*******************************************************/
extern tmLibdevErr_t dtv_ref3_AO_Start(void)
{
Int err = TMLIBDEV_OK;
aoEnableTRANS_ENABLE();
dtvRef3AoRunning = True;
if (dtvRef3AoNeedToConfigureTDA1315)
{
outputL3Params.data = & outputL3Regs[_CHANNEL_STATUS_REGISTER];
err = tda1315AccessL3(&outputL3Params, WRITE_CHANNEL_STATUS_REGISTER);
}
return err;
}
/*******************************************************/
extern tmLibdevErr_t dtv_ref3_AO_Stop(void)
{
aoDisableTRANS_ENABLE();
dtvRef3AoRunning = False;
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.
*/
extern tmLibdevErr_t dtv_ref3_AO_SetSRate(Float sRate)
{
UInt ao_serial;
Float sckdiv, wsdiv, val, sfdiv;
tmLibdevErr_t err = TMLIBDEV_OK;
Char old_val = outputL3Regs[_CHANNEL_STATUS_REGISTER];
ao_serial = MMIO(AO_SERIAL);
sckdiv = (Float) (aoExtractSCKDIV(ao_serial) + 1);
wsdiv = (Float) (aoExtractWSDIV(ao_serial) + 1);
sfdiv = (Float) (aoExtractSFDIV(ao_serial) + 1);
/* set the right value to the channel status register of the TDA1315 */
outputL3Regs[_CHANNEL_STATUS_REGISTER] &= ~TDA1315_L3_CHAN_STAT_FREQUENCY_MASK;
if (sRate < 38050.0)
{
outputL3Regs[_CHANNEL_STATUS_REGISTER] |= TDA1315_L3_CHAN_STAT_32000_HZ;
}
else if (sRate < 46050.0)
{
outputL3Regs[_CHANNEL_STATUS_REGISTER] |= TDA1315_L3_CHAN_STAT_44100_HZ;
}
else
{
outputL3Regs[_CHANNEL_STATUS_REGISTER] |= TDA1315_L3_CHAN_STAT_48000_HZ;
}
sRate = sRate * sckdiv * wsdiv * sfdiv;
/* double output clock for modes that require it (e.g. 8-channel 32-bits) */
if (dtvRef3DoubleDDSEnable)
{
sRate *= 2;
}
if (dtvRef3CPUisTM1100)
{
val = 0.5 + (477218588.0 * (sRate / dtvRef3CPUClock)); /* 2**32 / 9 */
aoSetFREQ(((UInt) val) | 0x80000000);
}
else
{
val = 0.5 + (1431655765.0 * (sRate / dtvRef3CPUClock)); /* 2**32 / 3 */
aoSetFREQ((UInt) val);
}
if (old_val != outputL3Regs[_CHANNEL_STATUS_REGISTER])
{
if (dtvRef3AoRunning)
{
outputL3Params.data = & outputL3Regs[_CHANNEL_STATUS_REGISTER];
err = tda1315AccessL3(&outputL3Params, WRITE_CHANNEL_STATUS_REGISTER);
}
else
{
dtvRef3AoNeedToConfigureTDA1315 = True;
}
}
return err;
}
/*******************************************************/
extern tmLibdevErr_t dtv_ref3_AO_GetSRate(Float * sRate)
{
UInt serial = MMIO(AO_SERIAL);
UInt freq = MMIO(AO_FREQ);
UInt sckdiv = 1 + aoExtractSCKDIV(serial);
UInt wsdiv = 1 + aoExtractWSDIV(serial);
UInt sfdiv = 1 + aoExtractSFDIV(serial);
Float rate;
if (dtvRef3CPUisTM1100)
{
rate = (Float) (freq & 0x7fffffff) * dtvRef3CPUClock / 477218588.0;
}
else
{
rate = (Float) freq * dtvRef3CPUClock / 1431655765.0;
}
rate = rate / ((Float) sckdiv * (Float) wsdiv * (Float) sfdiv);
*sRate = rate;
return TMLIBDEV_OK;
}
/*******************************************************/
extern tmLibdevErr_t dtv_ref3_AO_Config(UInt32 subaddr, Pointer value)
{
return AIO_ERR_COMMAND_NOT_SUPPORTED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -