📄 ad1847.c
字号:
Int rval;
UInt bID;
UInt iicd;
/* Use I2C control register to place 1847 in reset */
boardGetID(&bID);
rval = iicReadReg(TM_IREF_IIC_EXPANDER_ADDRESS, -1, &iicd);
if (rval)
{
return rval;
}
iicd &= 0x7; /* video signals high, the rest low */
if (bID == BOARD_VERSION_PHILIPS_TM1_IREF)
iicd |= 0x80; /* standby for 6ch DAC */
rval = iicWriteReg(TM_IREF_IIC_EXPANDER_ADDRESS, -1, iicd);
if (rval)
{
return rval;
}
MMIO(AO_FREQ) = MMIO(AI_FREQ) = 0;
microsleep(1000);
MMIO(AO_FREQ) = MMIO(AI_FREQ) = ddsFrequency;
/* codec out of reset */
iicd |= 0x70; /* codec master, TM slave mode */
rval = iicWriteReg(TM_IREF_IIC_EXPANDER_ADDRESS, -1, iicd);
if (rval)
{
return rval;
}
/* Wait 8200 samples, this is the time that the AD1847 needs to get
into a stable mode. The data book says that it needs amx. 170 ms but this works only
for the proposed external clocks (24.576 MHz and 16.9344 MHz)*/
microsleep((UInt32)(1.0/sRate * 8200.0 * 1000000.0));
/* copy init values to local */
for (i = 0; i < 16; i++)
Reg1847[i] = InitReg1847M[i];
/* Setup dummy buffers. We need those buffers to keep audio out running
while we are doing the initialization of the AD1847 */
ob1 = (Int*) (((Int) dummyBuffer + 63) & 0xffffffc0);
ob2 = &ob1[64];
memset(ob1, 0, _TEMP_BUFSIZE * sizeof(Int));
memset(ob2, 0, _TEMP_BUFSIZE * sizeof(Int));
_cache_copyback(ob1, _TEMP_BUFSIZE * sizeof(Int));
_cache_copyback(ob2, _TEMP_BUFSIZE * sizeof(Int));
/******* Handle Format dependent stuff *******/
/* See 1847 datasheet p15 for more info */
if (pcmFormat == apfStereo16)
{
Reg1847[8] = (Reg1847[8] & 0xF) | 0x50;
}
else /* apfMono16 */
{
Reg1847[8] = (Reg1847[8] & 0xF) | 0x40;
}
aoDisableSER_MASTER();
aoSetTRANS_MODE(3);
aoSampleFallingCLOCK_EDGE(); /* sample on falling edge */
aoStartRisingEdgeWS(); /* frame starts on rising edge */
aoSetLEFTPOS(16);
aoSetRIGHTPOS(32);
/* setup codec control, we are using only codec control word 2 */
aoSetCC2_POS(0);
aoSetCC1_POS(64);
aoDisableCC1_EN();
aoEnableCC2_EN();
MMIO(AO_BASE1) = (unsigned int) ob1; /* point to dummy buffers for init */
MMIO(AO_BASE2) = (unsigned int) ob2;
MMIO(AO_SIZE) = _TEMP_BUFSIZE;
/* AIO out of reset */
microsleep(2); /* delay for 2usec coming out of reset */
aoEnableTRANS_ENABLE();
/* write default values to all internal registers */
rval = ad1847WriteRegisters();
if (rval)
{
return rval;
}
__ad1847Initialized = True; /* Configure requires Inititalized flag */
/* reset audio out and restore frequency register */
aoRESET();
MMIO(AO_FREQ) = MMIO(AI_FREQ) = ddsFrequency;
/* make sure that the codec control allways sends a defined value that does not
change the configuration of the AD1847 (register 0xf is not used by the AD1847)*/
aoSetCC2(0x0F00);
aoSetCC2_POS(0);
aoSetCC1_POS(64);
aoDisableCC1_EN();
aoEnableCC2_EN();
/*
* at this point, the codec should be ready to play or record data
*/
return TMLIBDEV_OK;
} /* end of ad1847MasterInit() */
extern tmLibdevErr_t ad1847MuteOutput(void)
{
Int timeout;
/* mute left and rigth DAC */
aoSetCC2(0x0680);
timeout = 0;
while (aoCC_BUSY(MMIO(AO_STATUS))) { /* cc_busy */
aoAckACK1();
aoAckACK2();
microsleep(40);
timeout++;
if (timeout++ > 30000) {
return AIO_ERR_TIMEOUT5;
}
}
aoSetCC2(0x0780);
timeout = 0;
while (aoCC_BUSY(MMIO(AO_STATUS))) { /* cc_busy */
aoAckACK1();
aoAckACK2();
microsleep(40);
timeout++;
if (timeout++ > 30000) {
return AIO_ERR_TIMEOUT5;
}
}
return TMLIBDEV_OK;
}
/*******************************************************************/
extern tmLibdevErr_t ad1847Reset(Float sRate)
{
UInt bID;
UInt iicd;
Int rval;
/* Use I2C control register to place 1847 in reset */
boardGetID(&bID);
rval = iicReadReg(TM_IREF_IIC_EXPANDER_ADDRESS, -1, &iicd);
if (rval)
{
return rval;
}
iicd &= 0x7; /* video signals high, the rest low */
if (bID == BOARD_VERSION_PHILIPS_TM1_IREF)
iicd |= 0x80; /* standby for 6ch DAC */
rval = iicWriteReg(TM_IREF_IIC_EXPANDER_ADDRESS, -1, iicd);
if (rval)
{
return rval;
}
/* codec out of reset */
iicd |= 0x70; /* codec master, TM slave mode */
rval = iicWriteReg(TM_IREF_IIC_EXPANDER_ADDRESS, -1, iicd);
if (rval)
{
return rval;
}
/* Wait 8200 samples, this is the time that the AD1847 needs to get
into a stable mode. The data book says that it needs amx. 170 ms but this works only
for the proposed external clocks (24.576 MHz and 16.9344 MHz)*/
microsleep((UInt32)(1.0/sRate * 8200.0 * 1000000.0));
rval = ad1847WriteRegisters();
if (rval)
{
return rval;
}
return TMLIBDEV_OK;
}
/*******************************************************************/
static tmLibdevErr_t ad1847WriteRegisters(void)
{
Int timeout = 0;
Int i;
Int count;
while (aoCC_BUSY(MMIO(AO_STATUS))) { /* cc_busy */
if (AO_BUF1_EMPTY | AO_BUF2_EMPTY)
{
aoAckACK1();
aoAckACK2();
}
microsleep(40);
timeout++;
if (timeout++ > 30000)
{
/* reset the audio I/O peripherals */
aoRESET();
aiRESET();
return AIO_ERR_TIMEOUT5;
}
}
/*** setup the 16 internal registers ***/
for (i = 0; i < 16; i++) {
for (count = 0; count < 4; count++) {
timeout = 0;
/* writing to the CC register triggers the busy bit */
aoSetCC2(0xC000 + (i << 8) + Reg1847[i]);
while (aoCC_BUSY(MMIO(AO_STATUS))) { /* cc_busy */
if (AO_BUF1_EMPTY | AO_BUF2_EMPTY)
{
aoAckACK1();
aoAckACK2();
}
microsleep(40);
timeout++;
if (timeout++ > 30000)
{
/* reset the audio I/O peripherals */
aoRESET();
aiRESET();
return AIO_ERR_TIMEOUT5;
}
} /* end of while */
/* printf("1847 Register %d, 0x%x\n", i, MMIO(AO_CC)); */
} /* end of for count */
} /* end of for registers */
/* come out reset in calibration mode */
/* set register 0 again. for some reason it does not get set or it
gets overwritten, fix for bug#502014 */
aoSetCC2(0xC000 + Reg1847[0]);
timeout = 0;
while (aoCC_BUSY(MMIO(AO_STATUS))) { /* cc_busy */
if (AO_BUF1_EMPTY | AO_BUF2_EMPTY)
{
aoAckACK1();
aoAckACK2();
}
microsleep(40);
timeout++;
if (timeout++ > 30000)
{
/* reset the audio I/O peripherals */
aoRESET();
aiRESET();
return AIO_ERR_TIMEOUT5;
}
}
aoSetCC2(0x0f00);
timeout = 0;
while (aoCC_BUSY(MMIO(AO_STATUS))) { /* cc_busy */
if (AO_BUF1_EMPTY | AO_BUF2_EMPTY)
{
aoAckACK1();
aoAckACK2();
}
microsleep(40);
if (timeout++ > 30000)
{
/* reset the audio I/O peripherals */
aoRESET();
aiRESET();
return AIO_ERR_TIMEOUT6;
}
} /* end of while */
return TMLIBDEV_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -