📄 waveutil.c
字号:
/*++
Copyright (c) 2001,2002,2004 BSQUARE Corporation. All rights reserved.
Module Name:
waveutil.c
Module Description:
This module contains the implementation of various utility funtions for
the platform audio driver.
Author:
Benny Ng 25-June-2001
Revision History:
Yuqun Cao 16-Jan-2002
1. Turn on the DMA clock in InitiateDma().
2. Activate Rx and Tx DMA channel seperately.
Yuqun Cao 22-Mar-2002
1. MapTransfer() only call HalMapTransfer() if Start==TRUE.
Jason Browne Jan-2004
Fixed DMA buffering issue.
--*/
#include "chip.h"
#include "audio.h"
//TSAT* 27-Dec-2002 Turn on debug messages
//#undef DEBUGMSG
//#define DEBUGMSG(cond, msg) RETAILMSG(1, msg)
VOID
MapTransfer(
IN BOOLEAN Start,
IN PWAVE_RESOURCE WaveResource,
IN PULONG Buffer
)
{
#ifdef NOAUDIODMA
return;
#else
BOOLEAN UseBufferA;
ULONG BufferLength;
ULONG RequestedLength;
PHYSICAL_ADDRESS PhysAddr;
if(Start == FALSE) {
return;
}
if (Buffer == WaveResource->DmaBufferA) {
UseBufferA = TRUE;
}
else if (Buffer == WaveResource->DmaBufferB) {
UseBufferA = FALSE;
}
else {
DEBUGMSG(1, (TEXT("MapTransfer: Unexpected buffer.")));
goto ErrorReturn;
}
BufferLength = (UseBufferA == TRUE) ?
WaveResource->DmaBufferABytes :
WaveResource->DmaBufferBBytes;
//
// Map Dma buffer address
//
RequestedLength = BufferLength;
PhysAddr = HalMapTransfer(WaveResource->AdapterObject,
WaveResource->DmaBufferMdl,
WaveResource->MapRegsBase,
Buffer,
&RequestedLength,
TRUE);
if (RequestedLength != BufferLength) {
DEBUGMSG(1, (TEXT("MapTransfer: HalMapTransfer error\r\n")));
goto ErrorReturn;
}
// This DMA physical address will be written to DMA base register in StartDMA()
DEBUGMSG(1, (TEXT("MapTransfer: PhysAddr=0x%x BufferLength=0x%x\r\n"),
PhysAddr.LowPart, BufferLength));
if (UseBufferA == TRUE) {
WaveResource->BufferAPhysAddr.LowPart = PhysAddr.LowPart;
}
else {
WaveResource->BufferBPhysAddr.LowPart = PhysAddr.LowPart;
}
ErrorReturn:
return;
#endif
}
PULONG
GetNextDmaBuffer(
IN PWAVE_RESOURCE WaveResource
)
{
return ( (WaveResource->NextDMABuf & 1) ?
WaveResource->DmaBufferB :
WaveResource->DmaBufferA );
}
VOID
NextDmaBuffer(
IN PWAVE_RESOURCE WaveResource
)
{
WaveResource->NextDMABuf ^= 1;
}
VOID
SetBufferSize(
IN PWAVE_RESOURCE WaveResource,
IN PULONG Buffer,
IN ULONG NumBytes
)
{
if (Buffer == WaveResource->DmaBufferA) {
WaveResource->DmaBufferABytes = NumBytes;
}
else if (Buffer == WaveResource->DmaBufferB) {
WaveResource->DmaBufferBBytes = NumBytes;
}
else {
DEBUGMSG(1, (TEXT("SetBufferSize: Unknown buffer.\r\n")));
}
}
ULONG
GetBufferSize(
IN PWAVE_RESOURCE WaveResource,
IN PULONG Buffer,
IN ULONG NumBytes
)
{
ULONG BufferSize = 0;
if (Buffer == WaveResource->DmaBufferA) {
BufferSize = WaveResource->DmaBufferABytes;;
}
else if (Buffer == WaveResource->DmaBufferB) {
BufferSize = WaveResource->DmaBufferBBytes;;
}
else {
DEBUGMSG(1, (TEXT("GetBufferSize: Unknown buffer\r\n")));
}
return BufferSize;
}
VOID
InitiateDma(
IN PWAVE_RESOURCE WaveResource
)
{
ULONG tmp = 0;
#ifdef NOAUDIODMA
return;
#endif
DEBUGMSG(1, (TEXT("InitiateDma:\r\n")));
/*********************************************************************\
* *
* DMA clock must be turned on before DMA registers can be accessed! *
* There must be a delay before the clock become available. *
* *
\*********************************************************************/
//
// Enable DMA clock for AAC0_RX and AAC0_TX
//
tmp = READ_REGISTER_ULONG(&WaveResource->ABPClkCtrlRegPrt->PWRCNT);
if(WaveResource->WaveDirection == WAPI_IN) {
tmp |= CLK_DMA_AAC0_RX;
} else {
tmp |= CLK_DMA_AAC0_TX;
}
WRITE_REGISTER_ULONG(&WaveResource->ABPClkCtrlRegPrt->PWRCNT, tmp);
// delay for the clock
Drv_AHBBus_ExtraWrite();
//
// Enable DMA interrupt for AAC0_RX and AAC0_TX
//
WRITE_REGISTER_ULONG(&(WaveResource->DmaRegPtr->Control),
DMA_CTL_ICE |
DMA_CTL_ENABLE |
DMA_CTL_STALLINTEN |
DMA_CTL_CHERRINTEN |
DMA_CTL_NFBINTEN);
Drv_AHBBus_ExtraWrite();
}
VOID
ShutdownDma(
IN PWAVE_RESOURCE WaveResource
)
{
DEBUGMSG(1, (TEXT("ShutdownDma:\r\n")));
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->Control, 0);
return;
}
VOID
StartDmaIn(
IN PWAVE_RESOURCE WaveResource
)
{
DEBUGMSG(1, (TEXT("StartDma:\r\n")));
#ifdef NOAUDIODMA
SetEvent(hAudioInterrupt);
#else
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// RETAILMSG(1, (TEXT("\r\n")));
if(WaveResource->DmaBufferABytes) {
DEBUGMSG(1,(TEXT("StartDma=A\r\n")));
DEBUGMSG(1, (TEXT("StartDma-Base0: %d\r\n"), WaveResource->DmaBufferABytes));
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base0: MaxCnt0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->MaxCnt0));
// DEBUGMSG(1, (TEXT("StartDma-Base0: Base0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Base0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current0));
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->MaxCnt0, WaveResource->DmaBufferABytes);
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->Base0, WaveResource->BufferAPhysAddr.LowPart);
WaveResource->DmaBufferABytes = 0;
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base0: MaxCnt0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->MaxCnt0));
// DEBUGMSG(1, (TEXT("StartDma-Base0: Base0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Base0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current0));
}
if(WaveResource->DmaBufferBBytes) {
DEBUGMSG(1,(TEXT("StartDma=B\r\n")));
DEBUGMSG(1, (TEXT("StartDma-Base1: %d\r\n"), WaveResource->DmaBufferBBytes));
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base1: MaxCnt1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->MaxCnt1));
// DEBUGMSG(1, (TEXT("StartDma-Base1: Base1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Base1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current1));
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->MaxCnt1, WaveResource->DmaBufferBBytes);
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->Base1, WaveResource->BufferBPhysAddr.LowPart);
WaveResource->DmaBufferBBytes = 0;
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base1: MaxCnt1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->MaxCnt1));
// DEBUGMSG(1, (TEXT("StartDma-Base1: Base1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Base1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current1));
}
#endif
return;
}
VOID
StartDmaOut(
IN PWAVE_RESOURCE WaveResource
)
{
DEBUGMSG(1, (TEXT("StartDma:\r\n")));
#ifdef NOAUDIODMA
SetEvent(hAudioInterrupt);
#else
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// RETAILMSG(1, (TEXT("\r\n")));
if(GetNextDmaBuffer(WaveResource)==WaveResource->DmaBufferA) {
DEBUGMSG(1,(TEXT("StartDma=A\r\n")));
DEBUGMSG(1, (TEXT("StartDma-Base0: %d\r\n"), WaveResource->DmaBufferABytes));
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base0: MaxCnt0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->MaxCnt0));
// DEBUGMSG(1, (TEXT("StartDma-Base0: Base0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Base0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current0));
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->MaxCnt0, WaveResource->DmaBufferABytes);
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->Base0, WaveResource->BufferAPhysAddr.LowPart);
// WaveResource->DmaBufferABytes = 0;
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base0: MaxCnt0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->MaxCnt0));
// DEBUGMSG(1, (TEXT("StartDma-Base0: Base0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Base0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current0));
// RETAILMSG(1, (TEXT("StartDma-Base0: Current0: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current0));
}
if(GetNextDmaBuffer(WaveResource)==WaveResource->DmaBufferB) {
DEBUGMSG(1,(TEXT("StartDma=B\r\n")));
DEBUGMSG(1, (TEXT("StartDma-Base1: %d\r\n"), WaveResource->DmaBufferBBytes));
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base1: MaxCnt1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->MaxCnt1));
// DEBUGMSG(1, (TEXT("StartDma-Base1: Base1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Base1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X Before\r\n"), WaveResource->DmaRegPtr->Current1));
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->MaxCnt1, WaveResource->DmaBufferBBytes);
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->Base1, WaveResource->BufferBPhysAddr.LowPart);
// WaveResource->DmaBufferBBytes = 0;
//*TSAT* 22-Apr-2002 Test code to watch DMA ok/corrupted status as a file is passed to the codec.
// DEBUGMSG(1, (TEXT("StartDma-Base1: MaxCnt1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->MaxCnt1));
// DEBUGMSG(1, (TEXT("StartDma-Base1: Base1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Base1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current1));
// RETAILMSG(1, (TEXT("StartDma-Base1: Current1: 0x%8.8X After\r\n"), WaveResource->DmaRegPtr->Current1));
}
#endif
return;
}
VOID
ClearDmaStatus(
IN PWAVE_RESOURCE WaveResource
)
{
DEBUGMSG(1, (TEXT("ClearDmaStatus:\r\n")));
WRITE_REGISTER_ULONG(&WaveResource->DmaRegPtr->Interrupt,
(DMA_INT_STALLINT | DMA_INT_NFBINT | DMA_INT_CHERRINT));
Drv_AHBBus_ExtraWrite();
}
VOID
WaitForDmaComplete(
IN PWAVE_RESOURCE WaveResource
)
{
ULONG Status = 0;
ULONG CurrentState = 0;
DMA_CHANNEL_REG* DmaRegPtr;
DmaRegPtr = WaveResource->DmaRegPtr;
#ifdef NOAUDIODMA
return;
#endif
while (1) {
Status = READ_REGISTER_ULONG(&DmaRegPtr->Status);
CurrentState = Status & DMA_STATUS_CURRENTSTATE;
DEBUGMSG(1, (TEXT("WaitForDmaComplete: Status=0x%x\r\n"), Status));
//
// If the channel is in STALL or IDLE state, the DMA channel has stopped.
//
if (CurrentState == DMA_CURRENTSTATE_IDLE ||
CurrentState == DMA_CURRENTSTATE_STALL) {
break;
}
//
// Allow a reschedule to keep from burning processor time spinning
// in this loop.
//
Sleep(1);
DEBUGMSG(1, (TEXT("WaitForDmaComplete: Waiting for %s to complete.\r\n"),
DIR_STR(WaveResource->WaveDirection)));
} // end while (1)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -