📄 audiostream.c
字号:
pDE=(PDEVICE_EXTENSION)SynchronizeContext;
pDespList = &pDE->AudioBufferList1;
//#if (USING_AUDIO_CHANNEL==1)
CurOffset=Ave2kReadRegister(pDE, PCI_ADP4) -
pDE->DataCommonBuffer1.DMAAddress;
//#else
// CurOffset=Ave2kReadRegister(pDE, PCI_ADP4) -
// pDE->DataCommonBuffer1.DMAAddress;
//#endif
LimitPointer = pDE->DataCommonBuffer1.BaseAddress +
pDE->DataCommonBuffer1.Length;
DMAPointer= pDE->DataCommonBuffer1.BaseAddress + CurOffset;
if(DMAPointer >= pDespList->pWritePointer->pData)
Distance = DMAPointer - pDespList->pWritePointer->pData;
else
Distance = CurOffset + LimitPointer - pDespList->pWritePointer->pData;
//ASSERT(Distance<2*sizeof(AUDIOSTREAMSECTOR));
while(Distance >= sizeof(AUDIOSTREAMSECTOR)){
if(pDespList->pWritePointer->Flags.ownbit == 1){
//the buffer ring is full, discard old data frame
ASSERT(pDespList->pWritePointer ==pDespList->pReadPointer);
pDE->Stat[0].PacketLost++;
pDespList->pReadPointer =
pDespList->pReadPointer->pNext;
}
pDespList->pWritePointer->Flags.ownbit = 1;
pDespList->pWritePointer->Flags.datalen = sizeof(AUDIOSTREAMSECTOR);
pDespList->pWritePointer =
pDespList->pWritePointer->pNext;
Distance-=sizeof(AUDIOSTREAMSECTOR);
}
return TRUE;
}
//This function is call in IsrDPC or OnDeviceRead to retrieve data from buffer list
BOOLEAN SyncAudioRead(PVOID SynchronizeContext)
{
PDEVICE_EXTENSION pDE;
PDEVICE_OBJECT pDeviceObject;
PIRP pIrp;
ULONG BufLen;
PIO_STACK_LOCATION IrpStack;
//KIRQL OldIrql;
//OldIrql=KeGetCurrentIrql();
pDE=(PDEVICE_EXTENSION)SynchronizeContext;
pDeviceObject = pDE->DeviceObject;
pIrp=pDeviceObject->CurrentIrp;
if(pIrp == NULL)
return FALSE;
IrpStack=IoGetCurrentIrpStackLocation( pIrp );
ASSERT(IrpStack!=NULL);
if(IrpStack==NULL)
return 0;
BufLen=IrpStack->Parameters.Read.Length;
//if(pDE->DataReceiving[0]==TRUE){
// if(!(Ave2kReadRegister(pDE, MC1)&0x04))
// KdPrint(("Ch1: Detected DMA off\n"));
// if(Ave2kReadRegister(pDE, RPS_ADDR0)!=pDE->RPS[0].PhysicalAddress+8*sizeof(ULONG))
// KdPrint(("Ch1: Detected active RPS\n"));
//}
return AudioDespListRead(pDE, BufLen, 0);
//&pDE->AudioBufferList1,
// pDE->ReadIrpDataBuffer, BufLen, pDE->DataFilter[0]);
}
#define A1_SWAP_YES 0x00200000
#define A2_SWAP_YES 0x00100000
#define A1_SWAP_NO 0x00000000
#define A2_SWAP_NO 0x00000000
#define WS_CTRL_INPUT 0l
#define WS_CTRL_3STATE 0l
#define WS_CTRL_OTSL1 1l
#define WS_CTRL_OTSL2 2l
#define WS_CTRL_OALOW 3l
#define WS_SYNC_I2S 0l
#define CLK_SRC_DIV8 7l
#define CLK_SRC_DIV6 6l
#define CLK_SRC_DIV4 5l
#define CLK_SRC1_BCLK1 0l
#define CLK_SRC1_BCLK2 1l
#define CLK_SRC2_BCLK1 1l
#define CLK_SRC2_BCLK2 0l
#define BCLK1_OE_YES 0
#define BCLK1_OE_NO (1l<<19)
#define BCLK2_OE_YES 0
#define BCLK2_OE_NO (1l<<18)
#define EOS 1
extern unsigned long lVideoBufferAddress;
//void ConfigAudio(int bThisPCB, int bTest);
void Turn1309On(void);
void DisableAudio(PDEVICE_EXTENSION pDE, ULONG Channel, BOOLEAN bForce)
{
PIO_STACK_LOCATION IrpStack;
KIRQL OldIrql;
PIRP Irp;
PDEVICE_OBJECT DeviceObject=pDE->DeviceObject;
if(Channel == 0){
Ave2kWriteRegister(pDE,MC1,0x00040000);//disable A2 input DMA
pDE->IERValue &=~0x8008L;
}
else{
Ave2kWriteRegister(pDE,MC1,0x00010000);//disable A1 input DMA
pDE->IERValue &=~0x2010L;
}
if(!pDE->Double)
DisableDataTSL(pDE);
KeSynchronizeExecution(
pDE->pInterrupt,
Ave2kSetInterrupts,
pDE);
pDE->DataReceiving[Channel] = FALSE;
if(bForce){
if(!Reset(pDE, Channel)){
ResetDSP(pDE, Channel);
LoadDSPCode(pDE, Channel);
}
else
KdPrint(("Stop: Reset DSP OK.\n"));
}
else
Ave2kStopDSP(pDE,Channel);
if(Channel==0){
KeAcquireSpinLock(&pDE->ReadLock, &OldIrql);
Irp = DeviceObject->CurrentIrp;
if(pDE->ReadIrpDataBuffer==NULL || Irp==NULL){
KeReleaseSpinLock(&pDE->ReadLock,OldIrql);
return;
}
IrpStack =IoGetCurrentIrpStackLocation( Irp );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = IrpStack->Parameters.Read.Length; //sizeof(AUDIOSTREAMSECTOR);
IoCompleteRequest(Irp,IO_NO_INCREMENT);
IoStartNextPacket(DeviceObject,TRUE);
pDE->ReadIrpDataBuffer=NULL;
KeReleaseSpinLock(&pDE->ReadLock,OldIrql);
}
else{
KeAcquireSpinLock(&pDE->ReadLock2, &OldIrql);
Irp = pDE->CurrentAlternateIrp;
if(pDE->CurrentAlternateIrpBuffer==NULL || Irp==NULL){
KeReleaseSpinLock(&pDE->ReadLock2,OldIrql);
return;
}
IrpStack =IoGetCurrentIrpStackLocation( Irp );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = IrpStack->Parameters.Read.Length; //sizeof(AUDIOSTREAMSECTOR);
IoCompleteRequest(Irp,IO_NO_INCREMENT);
Ave2kChannel2StartNextPacket(DeviceObject,TRUE);
pDE->CurrentAlternateIrpBuffer=NULL;
KeReleaseSpinLock(&pDE->ReadLock2,OldIrql);
}
}
void EnableAudio(PDEVICE_EXTENSION pDE, UCHAR Channel)
{
ULONG MC1Value =0;
KIRQL OldIrql;
// ULONG IER_Value;
//Set interrupt parameters
//Enable audio DMA interrupt
int i=0;
while(pDE->DataReceiving[Channel]){
ave2kDelay(100);
i++;
if(i>50)
break;
}
//Clear data currently in the list
pDE->Recovering[Channel]=FALSE;
//keep error flag
pDE->ExStat[Channel]&=(EXSTAT_STATFAIL|EXSTAT_LOADFAIL);
//pDE->nEat[Channel]=0;
pDE->nErrorRecover[Channel]=ERR_NONE;
pDE->nStillStuff[Channel]=0;
pDE->TestCount[Channel]=0;
pDE->nTotalCount[Channel]=0;
//46=2324*8/50
pDE->nStuffLimit[Channel]=(75-(pDE->VideoDataRate[Channel])/46)*(pDE->nOffFrame[Channel]+1);
pDE->bFirstVideo=TRUE;
SetCompressFrameRate(pDE, 1, 0);
if(Channel ==0){
RtlZeroMemory(&pDE->Stat[0],sizeof(AVE2K_STATISTICS));
InitAudioDespList(
&pDE->AudioBufferList1,
pDE->DataCommonBuffer1.BaseAddress,
pDE->DespBuffer1,
NUMOFAUDIODESCRIPTOR);
}
//Clear data currently in the list
if(Channel == 1){
RtlZeroMemory(&pDE->Stat[1],sizeof(AVE2K_STATISTICS));
InitAudioDespList(
&pDE->AudioBufferList2,
pDE->DataCommonBuffer2.BaseAddress,
pDE->DespBuffer2,
NUMOFAUDIODESCRIPTOR);
}
//Set GPIO to input state
#if 1
if(Channel == 0)
{
ULONG OldGpioValue= Ave2kReadRegister(pDE, GPIO_CTRL);
OldGpioValue &=0xffffff00;
OldGpioValue |= 0x10;
Ave2kWriteRegister(pDE, GPIO_CTRL, OldGpioValue);
//pDE->Stat[0].PacketLost=0;
}
if(Channel == 1)
{
ULONG OldGpioValue= Ave2kReadRegister(pDE, GPIO_CTRL);
OldGpioValue &=0xffff00ff;
OldGpioValue |= 0x1000;
Ave2kWriteRegister(pDE, GPIO_CTRL, OldGpioValue);
//pDE->Stat[1].PacketLost=0;
}
#endif
//if(Channel ==1)
Reset(pDE, Channel);
ConfigAudio(pDE);
//ShiftAudio(pDE, Channel);
if(Ave2kStartDSP(pDE, Channel)){
//KeAcquireSpinLock(&pDE->ReadLock, &OldIrql);
if(StartAudioRPS(pDE, Channel))
return;
KdPrint(("Hardware fault occured.\n"));
ResetDSP(pDE, Channel);
LoadDSPCode(pDE, Channel);
Reset(pDE, Channel);
if(Ave2kStartDSP(pDE, Channel)){
if(StartAudioRPS(pDE, Channel)){
KdPrint(("Restarted after code load.\n"));
return;
}
KdPrint(("Failed even code load.\n"));
Ave2kWriteRegister(pDE, MC1, 0x80008000); //master reset
if(StartAudioRPS(pDE, Channel)){
KdPrint(("Restarted after master reset.\n"));
return;
}
}
}
//KeReleaseSpinLock(&pDE->ReadLock, OldIrql);
}
static int WaitRPS(PDEVICE_EXTENSION pDE)
{
int i=0;
long t;
while(i<3){
t=Ave2kReadRegister(pDE, MC1);
t=Ave2kReadRegister(pDE, GPIO_CTRL);
if(!(Ave2kReadRegister(pDE, MC1)&0x1000))
return 1;
t=Ave2kReadRegister(pDE, RPS_ADDR0);
ave2kDelay(6000);
i++;
}
return 0;
}
BOOLEAN ErrorRecover(PDEVICE_EXTENSION pDE, int nChannel)
{
int nError=pDE->nErrorRecover[nChannel];
if( nError == ERR_NONE)
return 1;
if(pDE->Recovering[nChannel]){
KdPrint(("Error recover again!\n"));
return 1;
}
pDE->Recovering[nChannel]=TRUE;
if(nChannel==0)
InitAudioDespList(
&pDE->AudioBufferList1,
pDE->DataCommonBuffer1.BaseAddress,
pDE->DespBuffer1,
NUMOFAUDIODESCRIPTOR);
else
InitAudioDespList(
&pDE->AudioBufferList2,
pDE->DataCommonBuffer2.BaseAddress,
pDE->DespBuffer2,
NUMOFAUDIODESCRIPTOR);
KdPrint(("Device %d/%d: Error %d recovering...\n",pDE->NtDeviceNumber+1, nChannel, nError));
//if(pDE->DataFilter[nChannel]==AVE2K_STREAM_VIDEO ||
// pDE->DataFilter[nChannel]==AVE2K_STREAM_AUDIO)
// pDE->nEat[nChannel]=1;
//else
// pDE->nEat[nChannel]=2;
pDE->nErrorRecover[nChannel]=ERR_NONE;
switch(nError){
case ERR_RESYNC:
KdPrint(("Device %d/%d: Try to restart RPS...\n",pDE->NtDeviceNumber+1, nChannel));
if(StartAudioRPS(pDE, nChannel))
break;
//else continue to next section
case ERR_RELOAD:
KdPrint(("Device %d/%d: Reload DSP code and start it...\n",pDE->NtDeviceNumber+1, nChannel));
Reset(pDE, nChannel);//to avoid WB/PLD hang up
ResetDSP(pDE, nChannel);
Reset7113LLC(pDE, nChannel);
LoadDSPCode(pDE, nChannel);
Reset(pDE, nChannel);
pDE->bFirstVideo=TRUE;
SetCompressFrameRate(pDE, 1, 0);
if(!Ave2kStartDSP(pDE, nChannel))
goto FAIL;
if(StartAudioRPS(pDE, nChannel)){
KdPrint(("Restarted after code load.\n"));
break;
}
KdPrint(("Failed even code load.\n"));
goto FAIL;
case ERR_RESTART:
KdPrint(("Device %d/%d: Try to restart DSP...\n",pDE->NtDeviceNumber+1, nChannel));
pDE->nTotalCount[nChannel]=0;
ConfigAudio(pDE);
pDE->bFirstVideo=TRUE;
SetCompressFrameRate(pDE, 1, 0);
if(Ave2kReStartDSP(pDE, nChannel)){
if(StartAudioRPS(pDE, nChannel))
break;
KdPrint(("Hardware fault occured.\n"));
ResetDSP(pDE, nChannel);
LoadDSPCode(pDE, nChannel);
Reset(pDE, nChannel);
if(!Ave2kStartDSP(pDE, nChannel))
goto FAIL;
if(StartAudioRPS(pDE, nChannel)){
KdPrint(("Restarted after code load.\n"));
break;
}
KdPrint(("Failed even code load.\n"));
}
goto FAIL;
case ERR_SHIFT:
ShiftAudio(pDE, nChannel);
KdPrint(("Shift.\n"));
StartAudioRPS(pDE, nChannel);
break;
}
pDE->Recovering[nChannel]=FALSE;
return 1;
FAIL:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -