⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtv_ttr_audio.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            aoSetSCKDIV(1);
            aoSetSFDIV(2);
#ifdef __LITTLE_ENDIAN__
            aoSetLEFTPOS(16);
            aoSetRIGHTPOS(0);
#else
            aoSetLEFTPOS(0);
            aoSetRIGHTPOS(16);
#endif
            aoSetSIZE(param->size * 6);
            break;
        }
        case apfSevenDotOne16:  /* Eight Channel Audio */
        {   /* 64 * 4 * 1 = 256 fs*/
            DP(("eight channels 16 bit\n"));
            iicd |= (_SET_OUTPUT_8_CHANS | _SET_OUTPUT_16_BITS);
            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 */
                dataFlag = True;
            }
            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"));
            iicd |= (_SET_OUTPUT_8_CHANS | _SET_OUTPUT_32_BITS);
            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 */
                dataFlag = True;
            }
            break;
        }
        default:
            /* unsupported subtype */
            return(AIO_ERR_UNSUPPORTED_FORMAT);
    }

    /* initialize the TDA 1315 for S/PDIF output */
    outputL3Params.data = & outputL3Regs[_CONTROL_REGISTER];
    err = tda1315InitOutput(&outputL3Params, param);
    
    /* set sample rate */    
    err = dtv_ttr_AO_SetSRate(param->sRate);
    if (err)
        return err;
    
    if (dataFlag)
    {
        /* set data mode for TDA1315 */
        err = dtv_ttr_AO_Config(AO_SPDIF_SET_DATA_MODE, Null);
        if (err)
            return err;
    }

    /* set mute bit */
    iicd |= _SET_MUTE_BIT;
    
    /* take FPGA out of reset in the proper mode */
    err  = iicWriteReg(TTR_IIC_EXPANDER_ADDRESS, -1, iicd);

    /* Reset Audio Out */
    err  |= iicReadReg(TTR_IIC_EXPANDER_ADDRESS, -1, &iicd);
    iicd &= ~_SET_RESET_BIT;
    err  |= iicWriteReg(TTR_IIC_EXPANDER_ADDRESS, -1, iicd);
    microsleep(300);
    err  |= iicReadReg(TTR_IIC_EXPANDER_ADDRESS, -1, &iicd);
    iicd |= _SET_RESET_BIT;
    err  |= iicWriteReg(TTR_IIC_EXPANDER_ADDRESS, -1, iicd);
    if (err) return err;

    return TMLIBDEV_OK;
}   /* end of dtv_ttr_AO_Init() */


/*******************************************************/
extern tmLibdevErr_t dtv_ttr_AO_Term(void)
{
    Int     err = TMLIBDEV_OK;

    /* reset statics */
    dtvTtrDoubleDDSEnable            = False;
    dtvTtrAoRunning                  = False;
    dtvTtrAoNeedToConfigureTDA1315   = False;
    
    aoRESET();
    err = iicWriteReg(TTR_IIC_EXPANDER_ADDRESS, -1, ~TTR_OUTPUT_IIC_AUDIOMODE_MASK);

    return err;
}

/*******************************************************/
extern tmLibdevErr_t dtv_ttr_AO_Start(void)
{
    Int     err = TMLIBDEV_OK;

    aoEnableTRANS_ENABLE();
    dtvTtrAoRunning = True;
    
    if (dtvTtrAoNeedToConfigureTDA1315)
    {
        outputL3Params.data = & outputL3Regs[_CHANNEL_STATUS_REGISTER];
        err = tda1315AccessL3(&outputL3Params, WRITE_CHANNEL_STATUS_REGISTER);
    }

    return err;
}

/*******************************************************/
extern tmLibdevErr_t dtv_ttr_AO_Stop(void)
{
    aoDisableTRANS_ENABLE();
    dtvTtrAoRunning = 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_ttr_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 (dtvTtrDoubleDDSEnable)
    {
        sRate *= 2;
    }
    
    if (dtvTtrCPUisTM1100)
    {
        val = 0.5 + (477218588.0 * (sRate / dtvTtrCPUClock));    /* 2**32 / 9 */
        aoSetFREQ(((UInt) val) | 0x80000000);
    }
    else
    {
        val = 0.5 + (1431655765.0 * (sRate / dtvTtrCPUClock));    /* 2**32 / 3 */
        aoSetFREQ((UInt) val);
    }
    
    if (old_val != outputL3Regs[_CHANNEL_STATUS_REGISTER]) 
    {
        if (dtvTtrAoRunning)
        {
            outputL3Params.data = & outputL3Regs[_CHANNEL_STATUS_REGISTER];
            err = tda1315AccessL3(&outputL3Params, WRITE_CHANNEL_STATUS_REGISTER);
        }
        else
        {
            dtvTtrAoNeedToConfigureTDA1315 = True;
        }
    }

    return err;
}

/*******************************************************/
extern tmLibdevErr_t dtv_ttr_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 (dtvTtrCPUisTM1100)
    {
        rate = (Float) (freq & 0x7fffffff) * dtvTtrCPUClock / 477218588.0;
    }
    else
    {
        rate = (Float) freq * dtvTtrCPUClock / 1431655765.0;
    }
    rate = rate / ((Float) sckdiv * (Float) wsdiv * (Float) sfdiv);

    *sRate = rate;

    return TMLIBDEV_OK;
}

/*******************************************************/
extern tmLibdevErr_t dtv_ttr_AO_Config(UInt32 subaddr, Pointer value)
{
	tmLibdevErr_t	rVal = TMLIBDEV_OK;
	Bool			setCopyright = False;
	UInt			categoryInfo = 0;
	
	switch (subaddr)
	{
	case AO_MUTE_SPDIF:
		/* mute S/PDIF output only */
		outputL3Regs[_CONTROL_REGISTER + 1] &= ~TDA1315_L3_CONTROL_MUTE_MASK;
		outputL3Regs[_CONTROL_REGISTER + 1] |= TDA1315_L3_CONTROL_MUTE;
		outputL3Params.data = & outputL3Regs[_CONTROL_REGISTER];
		rVal = tda1315AccessL3(&outputL3Params, WRITE_CONTROL_REGISTER);
		break;
	case AO_UNMUTE_SPDIF:
		/* unmute S/PDIF output only */
		outputL3Regs[_CONTROL_REGISTER + 1] &= ~TDA1315_L3_CONTROL_MUTE_MASK;
		outputL3Regs[_CONTROL_REGISTER + 1] |= TDA1315_L3_CONTROL_UNMUTE;
		outputL3Params.data = & outputL3Regs[_CONTROL_REGISTER];
		rVal = tda1315AccessL3(&outputL3Params, WRITE_CONTROL_REGISTER);
		break;
	case AO_MUTE_ANALOG_OUTPUTS:
		{
	    	UInt	iicd;
	    	
	    	rVal = iicReadReg(TTR_IIC_EXPANDER_ADDRESS, -1, &iicd);
		    iicd &= ~_SET_MUTE_BIT;
	    	rVal |= iicWriteReg(TTR_IIC_EXPANDER_ADDRESS, -1, iicd);
		}
		break;
	case AO_UNMUTE_ANALOG_OUTPUTS:
		{
	    	UInt	iicd;
	    	
	    	rVal = iicReadReg(TTR_IIC_EXPANDER_ADDRESS, -1, &iicd);
		    iicd |= _SET_MUTE_BIT;
	    	rVal |= iicWriteReg(TTR_IIC_EXPANDER_ADDRESS, -1, iicd);
		}
		break;
	case AO_SPDIF_SET_COPYRIGHT_INFO:
		/* get source information */
		switch ((UInt32) value & SPDIF_SOURCE_MASK)
		{
		case SPDIF_SOURCE_GENERAL:
		case SPDIF_SOURCE_CD:
		case SPDIF_SOURCE_OTHER_LASER_OPTICAL:
		case SPDIF_SOURCE_DAT:
		case SPDIF_SOURCE_MD:
			if ((UInt32) value & SPDIF_COPYRIGHT_MASK)
				setCopyright = True;
			categoryInfo = 0x00;
			break;
		case SPDIF_SOURCE_BROADCAST:
			if ((UInt32) value & SPDIF_COPYRIGHT_MASK)
				setCopyright = True;
			categoryInfo = 0x26;
			if (!((UInt32) value & SPDIF_PRERECORDED_SOFTWARE))
				categoryInfo |= 0x01;
			break;
		case SPDIF_SOURCE_DVD:
			if ((UInt32) value & SPDIF_COPYRIGHT_MASK)
				setCopyright = True;
			categoryInfo = 0x92;
			if (!((UInt32) value & SPDIF_PRERECORDED_SOFTWARE))
				categoryInfo |= 0x01;
			break;
		default:
			return AIO_ERR_MISC_ERROR;
		}
        outputL3Regs[_CHANNEL_STATUS_REGISTER + 1] &= ~TDA1315_L3_CHAN_STAT_CATEGORY_MASK;
        outputL3Regs[_CHANNEL_STATUS_REGISTER + 1] |= categoryInfo << 8;
        outputL3Regs[_CHANNEL_STATUS_REGISTER + 1] &= ~TDA1315_L3_CHAN_STAT_COPYRIGHT_MASK;
        if (!setCopyright)
            outputL3Regs[_CHANNEL_STATUS_REGISTER + 1] |= TDA1315_L3_CHAN_STAT_NO_COPYRIGHT;
        outputL3Params.data = & outputL3Regs[_CHANNEL_STATUS_REGISTER];
        rVal = tda1315AccessL3(&outputL3Params, WRITE_CHANNEL_STATUS_REGISTER);
		break;
	case AO_SPDIF_SET_DATA_MODE:
		outputL3Regs[_CHANNEL_STATUS_REGISTER] &= ~TDA1315_L3_CHAN_STAT_DATA_MASK;
		outputL3Regs[_CHANNEL_STATUS_REGISTER] |= TDA1315_L3_CHAN_STAT_DATA;
        outputL3Params.data = & outputL3Regs[_CHANNEL_STATUS_REGISTER];
        rVal = tda1315AccessL3(&outputL3Params, WRITE_CHANNEL_STATUS_REGISTER);
		break;
	case AO_SPDIF_PCM_MODE:
		outputL3Regs[_CHANNEL_STATUS_REGISTER] &= ~TDA1315_L3_CHAN_STAT_DATA_MASK;
		outputL3Regs[_CHANNEL_STATUS_REGISTER] |= TDA1315_L3_CHAN_STAT_AUDIO;
        outputL3Params.data = & outputL3Regs[_CHANNEL_STATUS_REGISTER];
        rVal = tda1315AccessL3(&outputL3Params, WRITE_CHANNEL_STATUS_REGISTER);
		break;
	default:
		/* unknown config parameter */
		return AIO_ERR_MISC_ERROR;
	}
    return rVal;
}


/************************** INPUT **********************************/

/* Input IIC expander, the interrupt pin of this iic expander (low active) is
   connected to the  user IRQ pin of the TriMedia. An interrupt is generated when
   the level changes on one of its inputs.
   
   address 0x72
   bit 0    unused
   bit 1    unused
   bit 2    copyprotection  input
   bit 3    powerdown       output

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -