📄 dtv_ref5_audio.c
字号:
/*
* 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_ref5_audio.c 1.2
*
* Last update : 19:04:43 - 00/11/09
*
* Description :
*
*
*/
/* 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/tmSPDOmmio.h>
#include <tm1/tmIIC.h>
#include <tm1/tmProcessor.h>
#include <tm1/tmLibdevErr.h>
#include "uda13xx.h"
#include "philips_dtv_ref5.h"
#include "dtv_ref5_audio.h"
/***********************************************************/
/* flag to indicate that the 32-bit mode is enabled */
static Float dtvRef5CPUClock = 0.0;
static l3Param_t ao4UdaL3Param =
{
l3ModeGPIO, /* mode */
0, /* address */
0, /* l3Address unused , will be changed by uda13xx lib */
0x2000, /* l3Data is bit 13 */
0x4000, /* l3Mode is bit 14 */
0x200, /* l3Clock is bit 9 */
0, /* usrPin0 */
0, /* usrPin1 */
0, /* usrPin2 */
0, /* l3AddressAdd */
0x01, /* l3DataAdd */
0x01, /* l3ModeAdd */
0x03, /* l3ClockAdd */
0, /* usrPin0Add */
0, /* usrPin1Add */
0, /* usrPin2Add */
0, /* numberOfBytes */
Null /* data */
};
static uda13xxRegisters_t ao4UdaRegs;
static uda13xxParam_t ao4UdaParam =
{
uda13xxGPIOMode, /* mode */
(Pointer) &ao4UdaL3Param, /* modeParams */
&ao4UdaRegs /* regs */
};
static uda13xxOutputParam_t ao4UdaOutputParam =
{
False, /* muteOn */
&ao4UdaRegs /* regs */
};
static l3Param_t ao1UdaL3Param =
{
l3ModeGPIO, /* mode */
0, /* address */
0, /* l3Address, will be changed by uda13xx lib */
0x2000, /* l3Data is bit 13 */
0x4000, /* l3Mode is bit 14 */
0x400, /* l3Clock is bit 10 */
0, /* usrPin0 */
0, /* usrPin1 */
0, /* usrPin2 */
0, /* l3AddressAdd */
0x01, /* l3DataAdd */
0x01, /* l3ModeAdd */
0x03, /* l3ClockAdd */
0, /* usrPin0Add */
0, /* usrPin1Add */
0, /* usrPin2Add */
0, /* numberOfBytes */
Null /* data */
};
static uda13xxRegisters_t ao1UdaRegs;
static uda13xxParam_t ao1UdaParam =
{
uda13xxGPIOMode, /* mode */
(Pointer) &ao1UdaL3Param, /* modeParams */
&ao1UdaRegs /* regs */
};
static uda13xxOutputParam_t ao1UdaOutputParam =
{
False, /* muteOn */
&ao1UdaRegs /* regs */
};
/*******************************************************/
extern tmLibdevErr_t dtvRef5_AO_Init_1(boardAOParam_t * param)
{
Float val;
pprocCapabilities_t procCap;
Int err = TMLIBDEV_OK;
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
dtvRef5CPUClock = (Float) procCap->cpuClockFrequency;
/* reset the audio output peripheral */
aoRESETM(AO1_STATUS);
/* Set initial frequency to get AO into a stable state */
val = param->sRate * 256.0; /* 256 * sampleRate */
val = 0.5 + (477218588.0 * (val / dtvRef5CPUClock)); /* 2**32 / 9 */
aoSetFREQM(AO1_STATUS, ((UInt) val) | 0x80000000);
aoEnableSER_MASTERM(AO1_STATUS);
microsleep(10); /* wait until AO unit stabalized */
if (! (param->audioTypeFormat & DTV_REF5_SUPPORTED_AUDIO_OUT_TYPES_1) )
return AIO_ERR_UNSUPPORTED_FORMAT;
if (! (param->audioSubtypeFormat & DTV_REF5_SUPPORTED_AUDIO_OUT_SUBTYPES_1) )
return AIO_ERR_UNSUPPORTED_FORMAT;
/* initialize the AUD_LCLK4 DACs (UDA 1320) */
err = uda13xxInitOutput(&ao4UdaParam, &ao4UdaOutputParam);
/* initialize the AUD_LCLK1 DACs (UDA 1320) */
err = uda13xxInitOutput(&ao1UdaParam, &ao1UdaOutputParam);
if (err != TMLIBDEV_OK)
{
aoRESETM(AO1_STATUS);
return err;
}
#ifdef __LITTLE_ENDIAN__
aoEnableLITTLE_ENDIANM(AO1_STATUS);
#else
aoDisableLITTLE_ENDIANM(AO1_STATUS);
#endif
aoMsbFirstM(AO1_STATUS);
aoStartRisingEdgeWSM(AO1_STATUS);
aoSampleRisingCLOCK_EDGEM(AO1_STATUS); /* sample on rising edge */
aoSetSSPOSM(AO1_STATUS, 0); /* Left and right channel start at bit 0 */
aoDisableSIGN_CONVERTM(AO1_STATUS); /* Disable Sign Convert for MSB */
aoDisableWS_PULSEM(AO1_STATUS); /* word strobe in pulse mode */
aoDisableTRANS_ENABLEM(AO1_STATUS);
switch (param->audioSubtypeFormat) {
case apfStereo16: /* Two channel Audio */
{ /* 64 * 4 * 1 = 256fs */
DP(("stereo 16 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 3);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 0);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size);
break;
}
case apfStereo32: /* Two channel Audio, 32-bit */
{ /* 64 * 4 * 1 = 256 fs */
DP(("stereo 32 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 1);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 0);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size);
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 */
{
DP(("four channels 16 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 3);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 1);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size * 2);
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 */
{
DP(("four channels 32 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 1);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 1);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size * 2);
break;
}
case apfFiveDotOne16: /* Six Channel Audio */
{
DP(("six channels 16 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 3);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 2);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size * 3);
break;
}
case apfFiveDotOne32: /* Six Channel Audio, 32-bit */
{
DP(("six channels 32 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 1);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 2);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size * 3);
break;
}
case apfSevenDotOne16: /* Eight Channel Audio */
{
DP(("eight channels 16 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 3);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 3);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size * 4);
break;
}
case apfSevenDotOne32: /* Eight Channel Audio, 32-bit */
{
DP(("eight channels 32 bit\n"));
aoSetTRANS_MODEM(AO1_STATUS, 1);
aoSetWSDIVM(AO1_STATUS, 63);
aoSetSCKDIVM(AO1_STATUS, 3);
aoSetNR_CHANM(AO1_STATUS, 3);
aoSetLEFTPOSM(AO1_STATUS, 0);
aoSetRIGHTPOSM(AO1_STATUS, 32);
aoSetSIZEM(AO1_STATUS, param->size * 4);
break;
}
default:
/* unsupported subtype */
return(AIO_ERR_UNSUPPORTED_FORMAT);
}
/* set sample rate */
err = dtvRef5_AO_SetSRate_1(param->sRate);
if (err)
return err;
return TMLIBDEV_OK;
} /* end of dtvRef5_AO_Init() */
/*******************************************************/
extern tmLibdevErr_t dtvRef5_AO_Term_1(void)
{
Int err = TMLIBDEV_OK;
/* reset statics */
aoRESETM(AO1_STATUS);
return err;
}
/*******************************************************/
extern tmLibdevErr_t dtvRef5_AO_Start_1(void)
{
aoEnableTRANS_ENABLEM(AO1_STATUS);
return TMLIBDEV_OK;
}
/*******************************************************/
extern tmLibdevErr_t dtvRef5_AO_Stop_1(void)
{
aoDisableTRANS_ENABLEM(AO1_STATUS);
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 dtvRef5_AO_SetSRate_1(Float sRate)
{
UInt ao_serial;
Float sckdiv, wsdiv, val;
ao_serial = MMIO(AO1_SERIAL);
sckdiv = (Float) (aoExtractSCKDIV(ao_serial) + 1);
wsdiv = (Float) (aoExtractWSDIV(ao_serial) + 1);
sRate = sRate * sckdiv * wsdiv;
val = 0.5 + (477218588.0 * (sRate / dtvRef5CPUClock)); /* 2**32 / 9 */
aoSetFREQM(AO1_STATUS, ((UInt) val) | 0x80000000);
return TMLIBDEV_OK;
}
/*******************************************************/
extern tmLibdevErr_t dtvRef5_AO_GetSRate_1(Float * sRate)
{
UInt serial = MMIO(AO1_SERIAL);
UInt freq = MMIO(AO1_FREQ);
UInt sckdiv = 1 + aoExtractSCKDIV(serial);
UInt wsdiv = 1 + aoExtractWSDIV(serial);
Float rate;
rate = (Float) (freq & 0x7fffffff) * dtvRef5CPUClock / 477218588.0;
rate = rate / ((Float) sckdiv * (Float) wsdiv);
*sRate = rate;
return TMLIBDEV_OK;
}
/*******************************************************/
extern tmLibdevErr_t dtvRef5_AO_Config_1(UInt32 subaddr, Pointer value)
{
return AIO_ERR_COMMAND_NOT_SUPPORTED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -