⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 waveoutpdd.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*

  Copyright(c) 1998,1999 SIC/Hitachi,Ltd.

	Module Name:

		waveOutpdd.c

	Revision History:

		26th April		1999		Released
		30th June		1999		Modified audio out buffer address
									Added AudioOutInterrupt Flag
									suppress playback recording
		6th  July		1999		Fixed minor bug
		21th September	1999		Modified audio volume
									Added audio pause and Audio restart process
									Fixed L-R turn bug
									Added PCML(R) FIFO buffer clear in WaveOutStop & WaveOutEndOfData & WaveOutPause process
		8th  October	1999		Modified WaveData length extend
        29-Nov-1999 cea		Changed for SH3 (7709A) DMA control
*/

#include <windows.h>
#include <types.h>
#include <memory.h>
#include <excpt.h>
#include <waveddsi.h>
#include <wavedbg.h>
#include <mmsystem.h>
#include "waveOutpddMacros.h"
#include "wavepdd.h"
#include "waveOutpdd.h"

#include "cc.h"
#include "macros.h"
#include "wavecpud.h"
DmaObject * pDmaOutObject=NULL;
extern DWORD dwCCCodecRegBase;//CC_CODEC_REGBASE
extern DWORD dwCCSysSMCR;//CC_SYS_SMSCR
static PVUSHORT pCODEC_CR;						// virtual addrs of C.C. registers
static PVULONG  pCODEC_ACR, pCODEC_CAR, pCODEC_CDR;
static PVULONG  pCODEC_ATAGR;
static PVULONG  pCODEC_PCML;
static PVULONG  pSMSCR;
static PVUSHORT pCODEC_FSR;

extern "C" PUCHAR GetVirtualAddressOfUncachedMemory( PVOID base, ULONG sz, char* cID );
extern PWAVEFORMATEX g_pwfx[2];
extern PCM_TYPE g_pcmtype[2];

// Software Volume Control

#define scaleForVolume(sample) ((sample * multiplier) >> log2ofDivisor)

const struct {				// table facilitates multiplying by fraction:
   UINT16 multiplier;		//     multiply by "multiplier"
   UINT16 divisor;			//     then shift right by "log2ofDivisor"
} VOL[] = { {0, 0},			//  0/1
            {3, 5},			//  3/32
            {7, 6},			//  7/64
            {1, 3},			//  1/8
            {5, 5},			//  5/32
            {3, 4},			//  3/16
            {7, 5},			//  7/32
            {1, 2},			//  1/4
            {5, 4},			//   etc.
            {3, 3},
            {7, 4},
            {1, 1},
            {5, 3},
            {3, 2},
            {7, 3},
            {1, 0}
          };

// Double Buffer for Audio Playback

static ULONG v_nNextPage;

static  PBYTE   pCC_CODEC_RegBase;	// Companion chip  SERIAL CODEC register offsets
static  PBYTE   pCC_SYS_RegBase;	// Companion chip  SMSCR
static  PBYTE   pAudioBufferBase;	// Audio buffer

//PDRIVER_GLOBALS	pDriverGlobals;		// Drivers Globals

static ULONG v_nVolume;             // current volume setting
static volatile BOOL v_fMoreData[2];// TRUE iff MDD layer has called StopPlay
                                    //   v_fMoreData was volatile on D9000
                                    //   It could be involved in controlling
                                    //   multiple threads.

/*****************************************************************************
*   FUNCTION :  	private_AudioOutGetInterruptType
*   DESCRIPTION :   decodes type of audio interrupt
*   INPUTS :		None
*   OUTPUTS :     	interrupt type
*   DESIGN NOTES :
*   CAUTIONS :
*****************************************************************************/
AUDIO_STATE
private_AudioOutGetInterruptType(
   VOID
   )
{
	FUNC_WPDD("+PDD_AudioOutGetInterruptType");

	// An audio interrupt has occured. We need to tell the MDD who owns it
	// and what state that puts us in.


//	if ( pDriverGlobals->aud.outInt == (USHORT)NULL ) 
	if (pDmaOutObject==NULL || pDmaOutObject->GetGlobalOutInt()==NULL)
	{
		DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: ignore")));
		FUNC_WPDD("-PDD_AudioOutGetInterruptType");
		return AUDIO_STATE_IGNORE;	// assume audio-in generated interrupt
	}
	pDmaOutObject->ResetGlobalOutInt(TRUE); //decrement interrupt count.

	if (!v_fMoreData[WAPI_OUT]) 
	{
		DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: stopped")));
		FUNC_WPDD("-PDD_AudioOutGetInterruptType");
		return AUDIO_STATE_OUT_STOPPED;
	}
	else if (pDmaOutObject->GetGlobalPlayAddress()!=NULL)//(pDriverGlobals->aud.play_address != (ULONG)NULL)
	{
		DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: playing")));
		FUNC_WPDD("-PDD_AudioOutGetInterruptType");
		return AUDIO_STATE_OUT_PLAYING;
	}
	else
	{
		DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType:underflow")));
		FUNC_WPDD("-PDD_AudioOutGetInterruptType");
		return AUDIO_STATE_OUT_UNDERFLOW;
	}
}

/*****************************************************************************
*   FUNCTION :  	private_AudioOutInitialize
*   DESCRIPTION :   sets up register access for audio-out
*					sets DA, DMA, and CMT registers that remain constant
*					sets volume to maximum (default)
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :
*   CAUTIONS :
*****************************************************************************/
BOOL
private_AudioOutInitialize(
   VOID
   )
{
	ULONG	ACR_VALUE;
	USHORT	CR_VALUE;
	volatile DWORD dwIndex;

	//ULONG SizeOfBuffer;
	char here[] = "PDD_AudioOutInitialize";

	FUNC_WPDD("+PDD_AudioOutInitialize");
	RETAILMSG( 1, (TEXT("WaveOutpdd.c private_AudioOutInitialize: START\r\n")));

	// Set pointers to virtual addresses of playback registers
/*	
	pDMAC_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
		(PBYTE)DMAC_REGBASE,
		(DWORD)DMAC_REGSIZE,
		"PDD_AudioInitialize, pDMAC_RegBase");

	if (pDMAC_RegBase == NULL) return FALSE;

	pDMAOR   = (PVUSHORT)(pDMAC_RegBase + DMAC_DMAOR_OFFSET );
	pSAR1    = (PVULONG)(pDMAC_RegBase + DMAC_SAR1_OFFSET   );
	pDAR1    = (PVULONG)(pDMAC_RegBase + DMAC_DAR1_OFFSET   );
	pDMATCR1 = (PVULONG)(pDMAC_RegBase + DMAC_DMATCR1_OFFSET);
	pCHCR1   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR1_OFFSET  );

	pCHCR0   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR0_OFFSET  );
	pCHCR2   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR2_OFFSET  );
	pCHCR3   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR3_OFFSET  );

	pINTC_Area_1_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
		(PBYTE)INTC_AREA_1_REGBASE,
		(DWORD)INTC_AREA_1_REGSIZE,
		"PDD_AudioInitialize, pINTC_Area_1_RegBase");

	if (pINTC_Area_1_RegBase == NULL) return FALSE;

	pINTC_Area_7_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
		(PBYTE)INTC_AREA_7_REGBASE,
		(DWORD)INTC_AREA_7_REGSIZE,
		"PDD_AudioInitialize, pINTC_Area_7_RegBase");

	if (pINTC_Area_7_RegBase == NULL) return FALSE;
*/
	pCC_CODEC_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
		(PBYTE)dwCCCodecRegBase,//CC_CODEC_REGBASE,
		(DWORD)CC_CODEC_REGSIZE,
		"PDD_AudioInitialize, pCC_CODEC_RegBase");

	if (pCC_CODEC_RegBase == NULL) return FALSE;
	pCODEC_CR    = (PVUSHORT) (pCC_CODEC_RegBase + CC_CODEC_CR_OFFSET     );
	pCODEC_CAR   = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_CAR_OFFSET    );
	pCODEC_CDR   = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_CDR_OFFSET    );
	pCODEC_ACR   = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_ACR_OFFSET    );
	pCODEC_ATAGR = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_ATAGR_OFFSET  );
	pCODEC_PCML  = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_PCML_OFFSET   );
	pCODEC_FSR   = (PVUSHORT) (pCC_CODEC_RegBase + CC_CODEC_FSR_OFFSET    );

	pCC_SYS_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
		(PBYTE)dwCCSysSMCR,//CC_SYS_SMSCR,
		(DWORD)CC_SYS_REGSIZE,
		"PDD_AudioInitialize, pCC_SYS_RegBase");

	if (pCC_SYS_RegBase == NULL) return FALSE;
	pSMSCR       = (PVULONG ) (pCC_SYS_RegBase );

	// Set pointers to virtual addresses of audio buffers

/*	SizeOfBuffer = (AUDIO_DMA_PAGE_SIZE * 2);

	pAudioBufferBase = VirtualAlloc(
		NULL,
		SizeOfBuffer,
		MEM_RESERVE,
		PAGE_NOACCESS);

	if (pAudioBufferBase == NULL) return FALSE;

	if (!VirtualCopy((PVOID)pAudioBufferBase,
		(PVOID)dma_pagePhysicalAddress[0],
		(DWORD)SizeOfBuffer,
		PAGE_READWRITE | PAGE_NOCACHE))
	{
		VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
		return FALSE;
	}
*/
	if (pDmaOutObject==NULL) {
		pDmaOutObject= CreateDmaObject(FALSE); // false for play dma buffer
		ASSERT(pDmaOutObject);
	};
	pAudioBufferBase=(PBYTE)pDmaOutObject->GetDmaVirtualAddr();
	if (pAudioBufferBase == NULL)
	{
		RETAILMSG( 1, (TEXT("pAudioBufferBase ---error---\r\n")));
		return FALSE;
	}

	// Setup a Access to AudioPlayingAddress and AudioOutInterrupt
/*
	pDriverGlobals = VirtualAlloc(
		NULL,
		DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
		MEM_RESERVE,
		PAGE_NOACCESS);

	if (pDriverGlobals == NULL) return FALSE;

	if (!VirtualCopy((PVOID)pDriverGlobals,
		(PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
		(DWORD)DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
		PAGE_READWRITE | PAGE_NOCACHE))
	{
		VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
		return FALSE;
	}
*/
	//
	//	AC97 Setting
	//

	//Reset AC97
	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0a00 );
	Delay_AC();
	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
	Delay_AC();
	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0235 );
	Delay_AC();

	//Init_Codec
	ACR_VALUE = (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_ACR );
	ACR_VALUE &= 0x7fffffff;
	ACR_VALUE |= 0x001fffff;
	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
	Delay_AC();
	WRITE_REGISTER_ULONG((PULONG)pCODEC_ACR, ACR_VALUE );
	Delay_AC();

	//AC_Init
	CR_VALUE = (USHORT)READ_REGISTER_USHORT((PUSHORT)pCODEC_CR );
	CR_VALUE &= 0xf7ff;
	CR_VALUE |= 0x0035;
	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
	Delay_AC();
	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, CR_VALUE );
	Delay_AC();
	RETAILMSG( 1, (TEXT("Control register  =%08x\r\n"), (USHORT)READ_REGISTER_USHORT((PUSHORT)pCODEC_CR )));

	//Codec Ready?
	RETAILMSG( 1, (TEXT("ATAGR   =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_ATAGR )));
	RETAILMSG( 1, (TEXT("WAIT Condec Ready..............\r\n")));

	for (dwIndex=0;dwIndex<0x100;dwIndex++) {
		if (( (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_ATAGR ) & 0x80000000 )) 
			break;
		Delay_AC();
	};
	RETAILMSG( 1, (TEXT("codec ready with cound 0x%lx !! \r\n"),dwIndex));
	
	//RX TX Valid Slot
	WRITE_REGISTER_ULONG((PULONG)pCODEC_ATAGR, 0x00001ff8 );
	Delay_AC();

	WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x000a6000 );
	Delay_AC();

	RETAILMSG( 1, (TEXT("WAIT ADC DAC ANL Ready?..............\r\n")));

	while(( (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_CDR ) & 0x000000f0 ) != 0x000000f0)
	{
		WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x000a6000 );
		Delay_AC();
	}

	RETAILMSG( 1, (TEXT("111accept Data!!\r\n")));

	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
	Delay_AC();
	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0200 );
	Delay_AC();

	WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00002000 );  // Set Master Volume      address
	Delay_AC();
	WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00018000 );  // Set PCM Out Volume     address
	Delay_AC();
	WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00078000 );  // Set Sample rate        address
	Delay_AC();

	WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00015150 );// Set Master Volume        data
	Delay_AC();
	WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00008080 );// Set PCM Out Volume       data
	Delay_AC();
	WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR,  48000 << 4 );      // Set Sample rate          data
	Delay_AC();

	WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
	Delay_AC();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -