?? hssi.c
字號:
ch = globals->aud[i].REC_CH - CH_TX_HSSI_1;
pSSI_RegBase = (PBYTE)(pSSI0_RegBase + (SSI_CH_REGBASE_OFFSET * ch));
pSSI_CR_RX = (PVULONG) ( pSSI_RegBase + SSI_CR_OFFSET );
pSSI_SR_RX = (PVULONG) ( pSSI_RegBase + SSI_SR_OFFSET );
pSSI_RDR = (PVULONG) ( pSSI_RegBase + SSI_RDR_OFFSET );
DEBUGMSG(ZONE_TEST, (TEXT("SSI_CR_TX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_CR_TX )));
DEBUGMSG(ZONE_TEST, (TEXT("SSI_SR_TX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_SR_TX )));
DEBUGMSG(ZONE_TEST, (TEXT("SSI_CR_RX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_CR_RX )));
DEBUGMSG(ZONE_TEST, (TEXT("SSI_SR_RX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_SR_RX )));
// SSI Seting
WRITE_REGISTER_ULONG((PULONG)pSSI_CR_TX, (ULONG)0x00000000 ); // Disable module
DEBUGMSG( 1, (TEXT("SSI_TX Control Register (%08x) = %08x\r\n"), pSSI_CR_TX, 0x00000000));
WRITE_REGISTER_ULONG((PULONG)pSSI_SR_TX, (ULONG)0x00000000 ); // Clear 26,27 bits
DEBUGMSG( 1, (TEXT("SSI_TX Status Register (%08x) = %08x\r\n"), pSSI_SR_TX, 0x00000000));
WRITE_REGISTER_ULONG((PULONG)pSSI_CR_RX, (ULONG)0x00000000 ); // Disable module
DEBUGMSG( 1, (TEXT("SSI_RX Control Register (%08x) = %08x\r\n"), pSSI_CR_RX, 0x00000000));
WRITE_REGISTER_ULONG((PULONG)pSSI_SR_RX, (ULONG)0x00000000 ); // Clear 26,27 bits
DEBUGMSG( 1, (TEXT("SSI_RX Status Register (%08x) = %08x\r\n"), pSSI_SR_RX, 0x00000000));
if(globals->aud[i].PLAY_CH == CH_TX_HSSI_1){
SSI_PLAY_MODE = SSI1_PLAY_MODE;
SSI_REC_MODE = SSI1_REC_MODE;
CS4226_ReadADDR = SSI1_CS4226_ReadADDR;
CS4226_WriteADDR = SSI1_CS4226_WriteADDR;
CS4226_PLAY_CMB = SSI1_CS4226_PLAY_CMB;
CS4226_REC_CMB = SSI1_CS4226_REC_CMB;
CS4226_PLAY_DSP_PMB = SSI1_CS4226_PLAY_DSP_PMB;
CS4226_REC_DSP_PMB = SSI1_CS4226_REC_DSP_PMB;
CS4226_PLAY_DACCB = SSI1_CS4226_PLAY_DACCB;
CS4226_REC_DACCB = SSI1_CS4226_REC_DACCB;
CS4226_ADCCB = 0x03;
}
else{
SSI_PLAY_MODE = SSI2_PLAY_MODE;
SSI_REC_MODE = SSI2_REC_MODE;
CS4226_ReadADDR = SSI2_CS4226_ReadADDR;
CS4226_WriteADDR = SSI2_CS4226_WriteADDR;
CS4226_PLAY_CMB = SSI2_CS4226_PLAY_CMB;
CS4226_REC_CMB = SSI2_CS4226_REC_CMB;
CS4226_PLAY_DSP_PMB = SSI2_CS4226_PLAY_DSP_PMB;
CS4226_REC_DSP_PMB = SSI2_CS4226_REC_DSP_PMB;
CS4226_PLAY_DACCB = SSI2_CS4226_PLAY_DACCB;
CS4226_REC_DACCB = SSI2_CS4226_REC_DACCB;
CS4226_ADCCB = 0x04;
}
return ret;
}
/*****************************************************************************
* FUNCTION : module_deinit
* DESCRIPTION : HSSI Deinitialize
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
module_deinit(
VOID
)
{
VirtualFree((PVOID)pSSI0_RegBase, 0, MEM_RELEASE);
pSSI0_RegBase = NULL;
}
/*****************************************************************************
* FUNCTION : codec_init
* DESCRIPTION : CODEC Initialize
* INPUTS : None
* OUTPUTS : Return TRUE for success, FALSE for failure
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
codec_init(
VOID
)
{
DWORD a;
DWORD dwData;
DWORD dwRet;
HANDLE hI2C;
unsigned char I2Cdata[14][2] = {
//{Register Pointer, Value}
{CODEC_CMB, 0x00}, //*00:(01h)Clock Mode Byte(CO1乣CO0,CI1乣CI0)
// if 11.025kHz then ch0:0x52,ch1:0x50,ch2/3:0x40
{CODEC_DAC_CB, 0xc0}, //*01:(03h)DAC Control Byte(ZCD,MUTC)
{CODEC_OADB_1, 0x00}, // 02:(04h)Output Attenuator Data Byte(left ch)
{CODEC_OADB_2, 0x00}, // 03:(05h)Output Attenuator Data Byte(right ch)
{CODEC_OADB_3, 0x00}, // 04:(06h)Output Attenuator Data Byte(no use)
{CODEC_OADB_4, 0x00}, // 05:(07h)Output Attenuator Data Byte(no use)
{CODEC_OADB_5, 0x00}, // 06:(08h)Output Attenuator Data Byte(no use)
{CODEC_OADB_6, 0x00}, // 07:(09h)Output Attenuator Data Byte(no use)
{CODEC_ADC_CB, 0x00}, // 08:(0Bh)ADC Control Byte
{CODEC_ICB, 0x0f}, // 09:(0Ch)Input Control Byte(GNL1乣GNL0,GNR1乣GNR0)
{CODEC_DSP_PMB, 0xc8}, //*10:(0Eh)DSP Port Mode Byte(DCK1乣DCK0,DSCK)
// slave:0xc8,master:0xe8
{CODEC_APMB, 0x00}, //*11:(0Fh)Auxiliary Port Mode Byte(ACK1乣ACK0,ASCK)
// slave:0x00,master:0xe8
{CODEC_APCB, 0x58}, // 12:(10h)Auxilliary Port Control Byte(HPC,MOH,DEM24)
{CODEC_NONE, 0x00}}; // 13:delimiter
I2Cdata[0][1] = CS4226_PLAY_CMB;
I2Cdata[10][1] = CS4226_PLAY_DSP_PMB;
I2Cdata[11][1] = CS4226_PLAY_APMB;
I2Cdata[1][1] = CS4226_PLAY_DACCB;
I2Cdata[8][1] = CS4226_ADCCB;
ulDSPMode = I2Cdata[10][1];
ulDACControl = I2Cdata[1][1];
// Get I2C Channel for contol CS4226
hI2C = CreateFile( TEXT("I2C1:"),
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( hI2C == INVALID_HANDLE_VALUE ){
goto error_ret;
}
dwData = I2C_MASTER_MODE;
DeviceIoControl(hI2C, IOCTL_I2C_SET_MODE,
(PVOID)&dwData, sizeof(DWORD), NULL, 0, &dwRet, NULL);
// Set I2C to standard speed mode. (100kbps)
#ifdef I2C_STANDARD_SPEED
// 100kHz
dwData = 19<<2; // SCGD
dwData |= 2; // CDF
#else
// 400kHz
dwData = 3<<2; // SCGD
dwData |= 2; // CDF
#endif
DeviceIoControl(hI2C, IOCTL_I2C_SET_BAUDRATE,
(PVOID)&dwData, sizeof(DWORD), NULL, 0, &dwRet, NULL);
dwData = I2C_SINGLE_STAGE;
DeviceIoControl(hI2C, IOCTL_I2C_SET_BUFFER_MODE,
(PVOID)&dwData, sizeof(DWORD), NULL, 0, &dwRet, NULL);
// reset codec
I2C_ReadCODEC(hI2C, CODEC_CCB, FALSE);
do {
if ( I2C_WriteCODEC(hI2C, CODEC_CCB, CODEC_CCB_RS_RESET) == FALSE )
goto error_ret1;
}while( !(I2C_ReadCODEC(hI2C, CODEC_CCB, FALSE) & CODEC_CCB_RS_MASK) );
// configure codec
for(a=0;;a++){
if ( I2Cdata[a][0] == CODEC_NONE )
break;
do {
if ( I2C_WriteCODEC(hI2C, I2Cdata[a][0], I2Cdata[a][1]) == FALSE )
goto error_ret1;
}while( I2C_ReadCODEC(hI2C, I2Cdata[a][0], FALSE) != I2Cdata[a][1] );
I2C_ReadCODEC(hI2C, I2Cdata[a][0], TRUE);
}
// finish configure codec
do {
if ( I2C_WriteCODEC(hI2C, CODEC_CCB, CODEC_CCB_RS_NORESET) == FALSE )
goto error_ret1;
}while( (I2C_ReadCODEC(hI2C, CODEC_CCB, FALSE) & CODEC_CCB_RS_MASK) );
BusyWait(AdjustMicroSecondsToLoopCount( I2C_WAIT_COUNT )); // wait 10ms
// read codec status
I2C_ReadCODEC(hI2C, CODEC_DAC_SRB, TRUE); // DAC Status Report Byte(Read Only)(0Ah)
I2C_ReadCODEC(hI2C, CODEC_ADC_SRB, TRUE); // ADC Status Report Byte(Read Only)(0Dh)
I2C_ReadCODEC(hI2C, CODEC_RSB, TRUE); // Receiver Status Byte(Read Only)(11h)
CloseHandle( hI2C );
return TRUE;
error_ret1:
CloseHandle( hI2C );
error_ret:
RETAILMSG(1, (TEXT("HSSI codec_init: Error!\r\n")));
return FALSE;
}
/*****************************************************************************
* FUNCTION : module_txdmastart
* DESCRIPTION : HSSI Tx Start
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
module_txdmastart(
VOID
)
{
ULONG RegValue;
FUNC_WPDD("+hssi_txdmastart");
if(CS4226_ReadADDR == SSI1_CS4226_ReadADDR){
MuteSSI(FALSE);
}
if (RecOpenFlag == 0){
SSICR_TX.bits.DMEN = 1; // DMA Enable
SSICR_TX.bits.UIEN = 1; // Underflow IRQ enable
SSICR_TX.bits.OIEN = 1; // Overflow IRQ enable
SSICR_TX.bits.EN = 1; // SSI Enable
RegValue = SSICR_TX.AsDWORD;
WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
}
FUNC_WPDD("-hssi_txdmastart");
}
/*****************************************************************************
* FUNCTION : module_txstop
* DESCRIPTION : HSSI Tx Stop
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
module_txstop(
VOID
)
{
ULONG RegValue;
FUNC_WPDD("+hssi_txstop");
if (CS4226_ReadADDR == SSI2_CS4226_ReadADDR && RecOpenFlag == 1){
// on recording...
// clear play DMA buffer
memset(pAudioBufferBase, 0, AUDIO_DMA_PAGE_SIZE * 2);
// MuteSSI
if(CS4226_ReadADDR == SSI1_CS4226_ReadADDR){
MuteSSI(TRUE);
}
}
else{
if(SSICR_TX.bits.EN == 1){
// Stop SSI
SSICR_TX.bits.DMEN = 0; // DMA Disable
SSICR_TX.bits.UIEN = 0; // Underflow IRQ Disable
SSICR_TX.bits.OIEN = 0; // Overflow IRQ Disable
SSICR_TX.bits.EN = 0; // SSI Disable
RegValue = SSICR_TX.AsDWORD;
WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
waitSSIStatus(pSSI_SR_TX, SSI_SR_IIRQ_IDLE);
}
}
FUNC_WPDD("-hssi_txstop");
return;
}
/*****************************************************************************
* FUNCTION : module_rxdmastart
* DESCRIPTION : HSSI Rx Start
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
module_rxdmastart(
VOID
)
{
ULONG RegValue;
FUNC_WPDD("+hssi_rxdmastart");
// Set SSI Control Register
if(CS4226_ReadADDR == SSI2_CS4226_ReadADDR){
if(PlayOpenFlag == 0){
// not playing, dymmy playback start
// ch3 need ch2's clock
hssi2_dmastart();
SSICR_TX.bits.DMEN = 1; // DMA Enable
SSICR_TX.bits.UIEN = 1; // Underflow IRQ enable
SSICR_TX.bits.OIEN = 1; // Overflow IRQ enable
SSICR_TX.bits.EN = 1; // SSI Enable
RegValue = SSICR_TX.AsDWORD;
WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
}
}
SSICR_RX.bits.DMEN = 1; // DMA Enable
SSICR_RX.bits.UIEN = 1; // Underflow IRQ enable
SSICR_RX.bits.OIEN = 1; // Overflow IRQ enable
SSICR_RX.bits.EN = 1; // SSI Enable
RegValue = SSICR_RX.AsDWORD;
WRITE_REGISTER_ULONG(pSSI_CR_RX, RegValue);
FUNC_WPDD("-hssi_rxdmastart");
}
/*****************************************************************************
* FUNCTION : module_rxstop
* DESCRIPTION : HSSI Rx Stop
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
module_rxstop(
VOID
)
{
ULONG RegValue;
FUNC_WPDD("+hssi_rxstop");
if(SSICR_RX.bits.EN == 1){
SSICR_RX.bits.DMEN = 0; // DMA Disable
SSICR_RX.bits.UIEN = 0; // Underflow IRQ Disable
SSICR_RX.bits.OIEN = 0; // Overflow IRQ Disable
SSICR_RX.bits.EN = 0; // SSI Disable
RegValue = SSICR_RX.AsDWORD;
WRITE_REGISTER_ULONG(pSSI_CR_RX, RegValue);
waitSSIStatus(pSSI_SR_RX, SSI_SR_IIRQ_IDLE);
}
if(CS4226_ReadADDR == SSI2_CS4226_ReadADDR){
if(PlayOpenFlag == 0){
// not playing, stop dummy playback
// ch3 need ch2's clock
if(SSICR_TX.bits.EN == 1){
SSICR_TX.bits.DMEN = 0; // DMA Disable
SSICR_TX.bits.UIEN = 0; // Underflow IRQ Disable
SSICR_TX.bits.OIEN = 0; // Overflow IRQ Disable
SSICR_TX.bits.EN = 0; // SSI Disable
RegValue = SSICR_TX.AsDWORD;
WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
waitSSIStatus(pSSI_SR_TX, SSI_SR_IIRQ_IDLE);
hssi2_dmastop();
}
}
}
FUNC_WPDD("-hssi_rxstop");
}
/*****************************************************************************
* FUNCTION : module_txstart
* DESCRIPTION : HSSI Tx Start
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
module_txstart(
VOID
)
{
ULONG RegValue;
unsigned char DSPslave[5][2] = {
//{Register Pointer, Value}
{CODEC_CMB, 0x00}, //*0:(01h)Clock Mode Byte(CO1乣CO0,CI1乣CI0)
// if 11.025kHz then ch0:0x52,ch1:0x50,ch2/3:0x40
{CODEC_DSP_PMB, 0xc8}, //*1:(0Eh)DSP Port Mode Byte(DCK1乣DCK0,DSCK)
// slave:0xc8,master:0xe8
{CODEC_APMB, 0x00}, //*2:(0Fh)Auxiliary Port Mode Byte(ACK1乣ACK0,AMS1乣AMS0,ASCK)
// slave:0x00,master:0xe8
{CODEC_DAC_CB, 0xc0}, //*3:(03h)DAC Control Byte(ZCD,MUTC) not mute?
{CODEC_NONE, 0x00}}; // 4:delimiter
FUNC_WPDD("+hssi_txstart");
DSPslave[0][1] = CS4226_PLAY_CMB;
DSPslave[1][1] = CS4226_PLAY_DSP_PMB;
DSPslave[2][1] = CS4226_PLAY_APMB;
DSPslave[3][1] = CS4226_PLAY_DACCB;
if ( ulDSPMode != DSPslave[1][1] || ulDACControl != DSPslave[3][1] ){
if(I2C_SetCODEC(DSPslave)){
ulDSPMode = DSPslave[1][1];
ulDACControl = DSPslave[3][1];
}
}
if (RecOpenFlag == 0){
// Set SSI Control Register
SSICR_TX.bits.Reserved = 0;
SSICR_TX.bits.DMEN = 0; // DMA Disable
SSICR_TX.bits.UIEN = 0; // Underflow IRQ disable
SSICR_TX.bits.OIEN = 0; // Overflow IRQ disable
SSICR_TX.bits.IIEN = 0; // Idle Mode IRQ disable
SSICR_TX.bits.DIEN = 0; // Data IRQ disable
SSICR_TX.bits.CHNL = 0; // Channels
SSICR_TX.bits.DWL = 3; // Data Word Length 20 bit
SSICR_TX.bits.SWL = 3; // System Word Length 32 bit
SSICR_TX.bits.SCKD = SSI_PLAY_MODE; // Serial Clock Output(Master)
SSICR_TX.bits.SWSD = SSI_PLAY_MODE; // Serial WS Output(Master)
SSICR_TX.bits.SCKP = 1; // Serial Clock Polarity falling edge
SSICR_TX.bits.SWSP = 1; // Serial WS Polarity High for Left
SSICR_TX.bits.SPDP = 0; // Serial Padding Polarity Low
SSICR_TX.bits.SDTA = 1; // Serial Data Alignment Right
SSICR_TX.bits.PDTA = 1; // Parallel Data Alignment Right
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -