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

📄 dtv_ref2_audio.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 1995,1996,1997 by TriMedia Technologies. 
 *
 * +------------------------------------------------------------------+
 * | This software is furnished under a license and may only be used  |
 * | and copied in accordance with the terms and conditions of  such  |
 * | a license and with the inclusion of this copyright notice. This  |
 * | software or any other copies of this software may not be provided|
 * | or otherwise made available to any other person.  The ownership  |
 * | and title of this software is not transferred.                   |
 * |                                                                  |
 * | The information in this software is subject  to change without   |
 * | any  prior notice and should not be construed as a commitment by |
 * | TriMedia Technologies.                                           |
 * |                                                                  |
 * | this code and information is provided "as is" without any        |
 * | warranty of any kind, either expressed or implied, including but |
 * | not limited to the implied warranties of merchantability and/or  |
 * | fitness for any particular purpose.                              |
 * +------------------------------------------------------------------+
 *
 *  Module name              : dtv_ref2_audio.c    1.8
 *
 *  Last update              : 18:53:23 - 00/11/09
 *
 *  Description              :
 *
 *  Initialize and control routines for TM1 DTV 8 channel audio DAC.
 *  Designed to be called from TM Device Library's board support package
 *
 *  This audio module supports:
 *      stereo 16 bit
 *      all Four channel 16 bit modes
 *      Six channel 16 bit
 *      Eight channel 16 bit
 *      Six channel analog plus 2 channel IEC1937, in 8 ch format.
 *          (atfLinearPCM | atf1937), apfSevenDotOne16
 *
 *  Other modes return resonable errors.
 *
 *  Revision                 :
 *      
 *
 *
 */


/* TriMedia standard shared includes */
#include <tm1/tmAssert.h>
#include <tmlib/dprintf.h>
#include <tmlib/tmtypes.h>
#include <tm1/tmAOmmio.h>
#include <tm1/tmAImmio.h>
#include <tm1/tmIIC.h>
#include <tm1/tmProcessor.h>
#include <tm1/tmLibdevErr.h>

#include "tda1315.h"

#include "philips_dtv_ref2.h"
#include "dtv_ref2_audio.h"

/***********************************************************/

    /* IIC "Legacy IREF" Expander (0x70)
    0: SReset
    1: AFE Reset
    2: ClkSel2
    3: ClkSel1
    4: unused
    5: unused
    6: unused
    7: unused
    */    
    
    /* IIC Audio Out Expander description on DTV Board (0x74)
    0:      L mode, DOut
    1:      L clock, DOut
    2:      L data, DOut
    3:      Audio Mode 5 -> reset (active low)
    4:      Audio Mode 4
    5:      Audio Mode 3 -> 16/32 bit mode
    6:      Audio Mode 2 -> channel mode1
    7:      Audio Mode 1 -> channel mode0
    
    Mode                IIC expander bits
                        7654 3210
    2 Channels          00xx xxxx
    4 Channels          10xx xxxx
    6 Channels          01xx xxxx
    8 Channels          11xx xxxx
    16 bit              xx1x xxxx
    32 bit              xx0x xxxx
    Reset               xxx0 xxxx
    unReset             xxx1 xxxx
    
    */
    
#define __SET_OUTPUT_8_CHANS    (REF2_OUTPUT_IIC_AUDIOMODE_1 | REF2_OUTPUT_IIC_AUDIOMODE_2)
#define __SET_OUTPUT_6_CHANS    REF2_OUTPUT_IIC_AUDIOMODE_2
#define __SET_OUTPUT_4_CHANS    REF2_OUTPUT_IIC_AUDIOMODE_1
#define __SET_OUTPUT_2_CHANS    0x00
#define __SET_OUTPUT_32_BITS    0x00 /* 0000 0000 */
#define __SET_OUTPUT_16_BITS    REF2_OUTPUT_IIC_AUDIOMODE_3
#define __SET_RESET_BIT         REF2_OUTPUT_IIC_AUDIOMODE_5
#define __DOUBLE_CLOCK_MODES    (apfFiveDotOne32 | apfSevenDotOne32) 
    
#define _CHANNEL_STATUS_REGISTER   0
#define _CONTROL_REGISTER          2

static Char outputL3Regs[4] = {0x0, 0x0, 0x0, 0x0};
static Char inputL3Regs[2]  = {0x0, 0x0};

static l3Param_t outputL3Params = 
{
    l3ModeIIC,                   /* mode          */
    L3_IIC_EXPANDER_ADDRESS,     /* address       */
    TDA1315_L3_ADDRESS,          /* l3Address     */
    REF2_OUTPUT_L3_DATA,         /* l3Data        */
    REF2_OUTPUT_L3_MODE,         /* l3Mode        */
    REF2_OUTPUT_L3_CLOCK,        /* l3Clock       */
    REF2_OUTPUT_L3_STROBE,       /* usrPin0       */
    0,                           /* usrPin1       */
    0,                           /* usrPin2       */
    0,                           /* l3AddressAdd  */
    0,                           /* l3DataAdd     */
    0,                           /* l3ModeAdd     */
    0,                           /* l3ClockAdd    */
    0,                           /* usrPin0Add    */
    0,                           /* usrPin2Add    */
    0,                           /* usrPin3Add    */
    2,                           /* numberOfBytes */
    Null                         /* data          */
};

static l3Param_t inputL3Params = 
{
    l3ModeIIC,                   /* mode          */
    L3_IIC_EXPANDER_ADDRESS,     /* address       */
    TDA1315_L3_ADDRESS,          /* l3Address     */
    REF2_INPUT_L3_DATA,          /* l3Data        */
    REF2_INPUT_L3_MODE,          /* l3Mode        */
    REF2_INPUT_L3_CLOCK,         /* l3Clock       */
    REF2_INPUT_L3_STROBE,        /* usrPin0       */
    0,                           /* usrPin1       */
    0,                           /* usrPin2       */
    0,                           /* l3AddressAdd  */
    0,                           /* l3DataAdd     */
    0,                           /* l3ModeAdd     */
    0,                           /* l3ClockAdd    */
    0,                           /* usrPin0Add    */
    0,                           /* usrPin2Add    */
    0,                           /* usrPin3Add    */
    2,                           /* numberOfBytes */
    Null                         /* data          */
};

/* flag to indicate that the 32-bit mode is enabled */
static Bool     dtvRef2DoubleDDSEnable            = False;
static Float    dtvRef2CPUClock                   = 0.0;
static Bool     dtvRef2CPUisTM1100                = False;

static Bool     dtvRef2AoRunning                  = False;
static Bool     dtvRef2AoNeedToConfigureTDA1315   = False;

static UInt     dtvRef2AiAudioTypeFormat;       
static UInt     dtvRef2AiAudioSubtypeFormat;    
static Float    dtvRef2AiSRate;
static Int      dtvRef2AiSize;
static UInt     dtvRef2AiInput;

/*******************************************************/
extern tmLibdevErr_t dtv_ref2_AO_Init(pboardAOParam_t param)
{
    UInt                iicd;
    Float               val;
    pprocCapabilities_t procCap;
    Int                 err = TMLIBDEV_OK;
#if 0
    param->maxSRate = 50000;    /* TDA 1305, 32KHz,44.1KHz,48KHz supported */
    param->minSRate = 20000;    
#endif       
    /* get the clock frequency of the TriMedia CPU */       
    err = procGetCapabilities(&procCap);
    if (err) return err;
    
    dtvRef2CPUClock = (Float) procCap->cpuClockFrequency;
    
    if (procCap->deviceID == PROC_DEVICE_TM1100)
    {
        dtvRef2CPUisTM1100 = True;
    }
    
    /* reset the audio output peripheral */
    aoRESET();

    /* Set initial frequency to get AO into a stable state */
    val = param->sRate * 256.0; /* 256 * sampleRate */
    if (dtvRef2CPUisTM1100)
    {
        val = 0.5 + (477218588.0 * (val / dtvRef2CPUClock));    /* 2**32 / 9 */
        aoSetFREQ(((UInt) val) | 0x80000000);
    }
    else
    {
        val = 0.5 + (1431655765.0 * (val / dtvRef2CPUClock));    /* 2**32 / 3 */
        aoSetFREQ((UInt) val);
    }
    
    aoEnableSER_MASTER();
    microsleep(10); /* wait until AO unit stabalized */

    if (! (param->audioTypeFormat & DTV_REF2_SUPPORTED_AUDIO_OUT_TYPES) )
        return AIO_ERR_UNSUPPORTED_FORMAT;
    if (! (param->audioSubtypeFormat & DTV_REF2_SUPPORTED_AUDIO_OUT_SUBTYPES) )
        return AIO_ERR_UNSUPPORTED_FORMAT;

    if (param->audioSubtypeFormat & __DOUBLE_CLOCK_MODES)
    {
        dtvRef2DoubleDDSEnable = True;
    }
    
#ifdef __LITTLE_ENDIAN__
    aoEnableLITTLE_ENDIAN();
#else
    aoDisableLITTLE_ENDIAN();
#endif
    aoMsbFirst();
    aoStartRisingEdgeWS();  
    aoSampleRisingCLOCK_EDGE();     /* sample on rising edge */
    aoSetTRANS_MODE(3);             /* Set Audio output to Stereo 16 bits per channel */
    aoSetSSPOS(0);                  /* Left and right channel start at bit 0 */
    aoDisableSIGN_CONVERT();        /* Disable Sign Convert for MSB */
    aoEnableWS_PULSE();             /* word strobe in pulse mode */
    aoDisableTRANS_ENABLE();

    /* err = iicReadReg(IIC_EXPANDER_ADDRESS, -1, &iicd); */
    iicd = 0xFF;
    err = 0;
    /* note: The audio code assumes that this latch is left in position FF. 
     * You would expect the audio code to read the latch, but there seems
     * to be a problem with that in this hardware.
     */

    iicd &= ~REF2_OUTPUT_IIC_AUDIOMODE_MASK;
    if (err) return err;

    switch (param->audioSubtypeFormat) {
        case apfStereo16:               /* Two channel Audio */
        {   /* 64 * 4 * 1 = 256fs */
            DP(("stereo 16 bit\n"));
            iicd |= (__SET_OUTPUT_2_CHANS | __SET_OUTPUT_16_BITS);
            aoSetWSDIV(63);
            aoSetSCKDIV(3);
            aoSetSFDIV(0);
            aoSetLEFTPOS(16);
            aoSetRIGHTPOS(48);
            aoSetSIZE(param->size);
            if (param->audioTypeFormat & atf1937)
            {
                /* set tda1315 to transmit non-PCM data */
            }
            break;
        }
        case apfStereo32:               /* Two channel Audio, 32-bit */
        {   /* 32 * 4 * 2 = 256 fs */
            DP(("stereo 32 bit\n"));
            iicd |= (__SET_OUTPUT_2_CHANS | __SET_OUTPUT_32_BITS);
            aoSetWSDIV(31);
            aoSetSCKDIV(3);
            aoSetSFDIV(1);
#ifdef __LITTLE_ENDIAN__
            aoSetLEFTPOS(16);
            aoSetRIGHTPOS(0);
#else
            aoSetLEFTPOS(0);
            aoSetRIGHTPOS(16);
#endif
            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"));
            iicd |= (__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"));
            iicd |= (__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"));
            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 */
            }
            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 */
            }
            break;
        }
        default:
            /* unsupported subtype */
            return(AIO_ERR_UNSUPPORTED_FORMAT);
    }

    /* set sample rate */    
    err = dtv_ref2_AO_SetSRate(param->sRate);
    if (err) return err;
    
    /* take FPGA out of reset in the proper mode */
    err  = iicWriteReg(IIC_EXPANDER_ADDRESS, -1, iicd);

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

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


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

    /* reset statics */
    dtvRef2DoubleDDSEnable            = False;
    dtvRef2AoRunning                  = False;
    dtvRef2AoNeedToConfigureTDA1315   = False;
    
    aoRESET();
    err = iicWriteReg(IIC_EXPANDER_ADDRESS, -1, ~REF2_OUTPUT_IIC_AUDIOMODE_MASK);

    return err;
}

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

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

    return err;
}

/*******************************************************/
extern tmLibdevErr_t dtv_ref2_AO_Stop(void)
{
    aoDisableTRANS_ENABLE();
    dtvRef2AoRunning = 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_ref2_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;

⌨️ 快捷键说明

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