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

📄 wavepdd.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++

$Workfile: WAVEPDD.C $

$Date: 2/03/04 10:11a $

Abstract:
      The PDD (Platform Dependent Driver) is responsible for
      communicating with the audio circuit to start and stop playback
      and/or recording and initialize and deinitialize the circuits. The
      API between the PDD and the MDD is called the DDSI (see "Key Routines"
      for more info).

Warning:
      This driver is specifically written for the UCB 1400 Audio Codec.  It is
      not a general AC 97 CODEC device driver.

Key Routines:

  PDD_AudioGetInterruptType -- This routine is part of the Interrupt Service Thread managed
    by the wave MDD.  Here interrupts are processed and DMA buffers are returned to the driver.
    That is, the DMA buffers are protected to keep the DMAC from reading or writing the buffers
    while the driver is processing them.  If the DMAC attempts to work on a buffer that is has
    not been posted by the driver an Interrupt will occur indicating write overflow or read
    under flow.  The DMAC engine will stall until the buffer is ready.  The status of reads or
    writes is returned to the MDD.

  private_WaveInStart, private_WaveOutStart -- These routines setup the DMAC for receive or
    transmit.  They copy data from application buffers (sent from or to the OS) to DMA buffers.
    The inital DMA buffers are then "posted" or setup for the DMAC engine to read or write.

  private_WaveInContinue, private_WaveOutContinue -- These routines continue processing
    input or output by moving data from or to application buffers from or to the DMAC buffers.
    Buffers are "posted" (marked for handling) by these routines.  If the DMAC engine attempts
    to read a buffer before it is posted, it will generate an interrupt and stall.  If the DMAC
    has stalled this routine will restart DMA.  (See also PDD_AudioGetInterruptType,
    private_AudioFillBuffer, and private_AudioGetBuffer).

  private_AudioFillBuffer,private_AudioGetBuffer -- These routines perform the actual copy and
    formatting of application sound data.  They copy the data from or to the DMAC buffers from
    or to the application buffers.  The data is also converted from the format of the audio
    Codec (stereo 16 bit) to the format requested by the application (such as monoral 8 bit).

  private_WaveInStop, private_WaveOutStop -- These routines stop the processing of audio buffers
    by indicating that no more data is available and setting the DMAC registers to stop xmit or
    recv of application data.

  PDD_WaveProc -- This routine actually processes the messages of the Device Driver Service
    Interface (DDSI).  The MDD sends these messages to the PDD for handling.

  PDD_AudioMessage -- This routine exposes a private interface to applications.

Key Structures:


Function Hierarchy:

     PDD_AudioGetInterruptType      xx
     PDD_AudioMessage               xx
     PDD_AudioInitialize            xx
         AudioPowerOn()             xx
         AudioOutMute();            xx
     PDD_AudioDeinitialize          xx
         PddpAudioDeallocateVm();   xx
     PDD_AudioPowerHandler          xx
     PDD_WaveProc                   xx
         WPDM_OPEN,                 xx
            private_WaveOpen        xx
         WPDM_CLOSE                 xx
         WPDM_START                 xx
             private_WaveInStart    xx
               private_AudioGetBuffer xx
             private_WaveOutStart   xx
               private_AudioFillBuffer !!
         WPDM_RESTART               xx
             private_WaveOutRestart xx
         WPDM_STOP                  xx
             private_WaveInStop     xx
             private_WaveOutStop    xx
         WPDM_CONTINUE              xx
             private_WaveInContinue xx
             private_WaveOutContinue xx
         WPDM_ENDOFDATA             xx
             private_WaveOutEndOfData xx
         WPDM_STANDBY                xx
             private_WaveStandby     --
         WPDM_PAUSE                  xx
             private_WaveOutPause    xx
         WPDM_GETDEVCAPS             xx
             private_WaveGetDevCaps  xx
         WPDM_GETVOLUME
         WPDM_SETVOLUME

Notes:



--*/

static const char __copyright[]= "Copyright 2000 Intel Corp."; //only for C/CPP files

/*++

** Copyright 2000-2001 Intel Corporation. All Rights Reserved.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.
** Title to the Material remains with Intel Corporation or its suppliers and licensors.
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise
** Some portion of the Materials may be copyrighted by Microsoft Corporation.

--*/

//-----------------------------------------------------------------
// INCLUDE FILES
//-----------------------------------------------------------------

#include <windows.h>
#include <types.h>
#include <memory.h>
#include <excpt.h>
#include <wavepdd.h>
#include <waveddsi.h>
#include <wavedbg.h>
#include <nkintr.h>
#include <ceddk.h>
#include <devload.h>
#include <bulverde.h>
#include "mmsystem.h"
#include <wavedbg.h>
#include "aclink.h"
#include "dmac.h"
#include "AC97.H"
#include "WAVE162.H"

//-----------------------------------------------------------------
// MACROS
//-----------------------------------------------------------------

#define BITS_8_TO_16(x)      (short) ( ( (LONG) ( (UINT8)(x) - 128) ) << 8 )
#define BITS_16_TO_8(x)       ( (UINT8) (( (x) >> 8 ) +128))

//-----------------------------------------------------------------
// DEFINES
//-----------------------------------------------------------------
#define NUM_DMA_AUDIO_BUFFERS    4

#define LOOPBACK_MASK 0x40
#define RESET_CODEC_MASK 0x04 //bit 2 0 origin

#define  MHZ11_980 11980000
#define  KHZ08_000 8000
#define  KHZ11_025 11025
#define  KHZ12_000 12000
#define  KHZ16_000 16000
#define  KHZ22_050 22050
#define  KHZ24_000 24000
#define  KHZ32_000 32000
#define  KHZ44_100 44100
#define  KHZ48_000 48000

#define   TIMERTICK   4  // 1 microsecond is 3.7 clock ticks

#define BULVERDE_REG_SYSINTR_VAL_NAME TEXT("Sysintr")
#define BULVERDE_REG_SYSINTR_VAL_LEN  sizeof( DWORD )

// TODO
#define DEV_TOUCH               1
#define DEV_AUDIO               2
#define DEV_BATTERY             3


//-----------------------------------------------------------------
// INTERNAL FUNCTIONS
//-----------------------------------------------------------------

// Local
static BOOL        MapDMADescriptors(void);
static BOOL        MapDeviceRegisters(void);
static void        FillDescriptors(void);


BOOL        AC97_SetVolume(ULONG uVolume);
short int   AC97SetSampleRate(unsigned short int SampleRate, WAPI_INOUT apidir );
BOOL        audio_out_buffer(ULONG);
BOOL        AudioInMute(   BOOL mute   );
BOOL        AudioOutMute(   BOOL mute   );
void        AudioPowerOff();
BOOL        AudioPowerOn();
void        ClearDmac( void );
void        dumpInterrupt(void);
BOOL        InitDMAC(int);
BOOL        IsMuted(BYTE Offset);
void        PowerDownUnit(unsigned short int Unit,BOOL ShutDown);
void        private_WaveStandby(WAPI_INOUT apidir);
short int   ShadowReadAC97(BYTE Offset, unsigned short int *Data, BYTE DevId);
short int   ShadowWriteAC97(BYTE Offset, unsigned short int Data, BYTE DevId);
BOOL        StopDmac(int);
BOOL        UnMapVirtual(void * v_pMapSpace);
VOID        private_WaveOutStop();
unsigned short int LastSampleRateIn=KHZ48_000;
unsigned short int LastSampleRateOut=KHZ48_000;

//-----------------------------------------------------------------
// EXTERNAL FUNCTIONS
//-----------------------------------------------------------------

extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);

//-----------------------------------------------------------------
// CONSTANTS AND VARIABLES
//-----------------------------------------------------------------
unsigned long  Ac97ShadowRegisters[64]; //shadow writes to the AC97 Codec
static  unsigned int ResetCaps; //HACK: If 0x2a0 it's rev 2a, if its 0x2a then its rev 1b
static  unsigned int CodecType=GENERIC_AC97;
static  BOOL PlayWave = 0;
static  unsigned int    i_buffer            = 0;  // Rcv buffer index
static  unsigned int    o_buffer            = 0;  // Xmt buffer index
static  BOOL    Expect_RcvRup_A;  // TRUE ==> Done_A interrupt expected; FALSE ==> Done_B
static  BOOL    Expect_XmtRup_A;  // TRUE ==> Done_A interrupt expected; FALSE ==> Done_B

InputSourceType gInputSrc=Line;  //Track the input source (microphone or line in)

const ULONG g_dma_buffer_size = AUDIO_BUFFER_SIZE;
DWORD g_capture_buffer_size;
const g_capture_latency = 20; // capture buffers will hold this much data (in milliseconds)

// This lets us know if we're in our power handler routine, so we know
// not to make any system calls (debug messages, etc).
BOOL g_fInPowerHandler;

// however, 44.1 will be about 1.1% off
static int sample_rate_out = KHZ44_100;        //define sample rate globally
static int sample_rate_in  = KHZ44_100;        //define sample rate globally


VOID (*g_pfnFillBuffer) (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples);
VOID (*g_pfnGetBuffer) (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples);

//point to the AC97 read/write functions based on
//the needs for the power handler
BOOL (*g_pfnReadAc97)  (BYTE Offset, UINT16 * Data, BYTE DevId);
BOOL (*g_pfnWriteAc97) (BYTE Offset, UINT16 Data, BYTE DevId);

VOID FillBufferM08 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples);
VOID FillBufferS08 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples);
VOID FillBufferM16 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples);
VOID FillBufferS16 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples);
VOID GetBufferM08 (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples);
VOID GetBufferS08 (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples);
VOID GetBufferM16 (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples);
VOID GetBufferS16 (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples);

static int in_counter;

static UINT16 g_VolMatrix[0x64];
volatile PBYTE   dma_page[NUM_DMA_AUDIO_BUFFERS];
volatile PBYTE   dma_page_physical[NUM_DMA_AUDIO_BUFFERS];

ULONG         v_nVolume=0xeeeeeeee; //default to volume

static int max_sample;
static int in_counter;

DWORD gIntrAudio = SYSINTR_UNDEFINED;

//
// These variables may be accessed by different processes or the hardware and
// are likely to change in a time critical fashion. Optimization may cause
// errors if not declared volatile.
//
volatile        BOOL    v_fMoreData[2];


// DMA descriptor buffers.
volatile DMADescriptorChannelType *v_pAudioRcvA_Virtual   = NULL;    // VA: Audio receive buffer A      128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioRcvA_Physical  = NULL;    // PA: Audio receive buffer A      128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioRcvB_Virtual   = NULL;    // VA: Audio receive buffer B      128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioRcvB_Physical  = NULL;    // PA: Audio receive buffer B      128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioXmitA_Virtual  = NULL;    // VA: Audio transmit buffer A     128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioXmitA_Physical = NULL;    // PA: Audio transmit buffer A     128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioXmitB_Virtual  = NULL;    // VA: Audio transmit buffer B     128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioXmitB_Physical = NULL;    // PA: Audio transmit buffer B     128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioMicA_Virtual   = NULL;    // VA: Audio Microphone buffer A   128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioMicA_Physical  = NULL;    // PA: Audio Microphone buffer A   128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioMicB_Virtual   = NULL;    // VA: Audio Microphone buffer B   128 bits (16 byte aligned)
volatile DMADescriptorChannelType *v_pAudioMicB_Physical  = NULL;    // PA: Audio Microphone buffer B   128 bits (16 byte aligned)

volatile BULVERDE_DMA_REG     *v_pDMARegs  = NULL;
volatile BULVERDE_AC97_REG    *v_pAC97Regs = NULL;

#define NUM_API_DIRS          2
BOOL g_fInUse[NUM_API_DIRS]; // is apidir in use? if so, fail Open calls
DWORD g_sample_size[NUM_API_DIRS];


void ResetAC97Controller(void)
{
    //reset the AC97 to workaround issue in sighting 46676
    ULONG ulTemp;

    // set GCR.ACOFF - turn controller off to flush FIFOs
    ulTemp = v_pAC97Regs->gcr;
    ulTemp |= 8;
    v_pAC97Regs->gcr = ulTemp; // do it.

    // wait for the ACOFFD (acoff "done") bit to assert.
    while(1)
    {
    ulTemp = v_pAC97Regs->gsr;
    if( ulTemp & 0x8 )
    break;
    }

    // clear GCR.ACOFF - turn controller back on
    ulTemp = v_pAC97Regs->gcr;
    ulTemp &= ~8;
    v_pAC97Regs->gcr = ulTemp;
}



//-----------------------------------------------------------------
// IMPLEMENTATIONS
//-----------------------------------------------------------------

void DumpDmacRegs()
{
    int i;

    DEBUGMSG(ZONE_ERROR, (TEXT( "%x, %x, %x, %x, %x\r\n" ),
        v_pAC97Regs->gsr,
        v_pAC97Regs->posr,
        v_pAC97Regs->pocr,
        v_pAC97Regs->pisr,
        v_pAC97Regs->picr
        ) );


    for (i=0; i< 16; i++)
        DEBUGMSG(ZONE_ERROR, (TEXT( "v_pDMARegs->dcsr[%d]       %x \r\n" ),i,v_pDMARegs->dcsr[i] ) );

    //skip rsvd section rsvd0[44];
    DEBUGMSG(ZONE_ERROR, (TEXT( "v_pDMARegs->dint       %x \r\n" ),v_pDMARegs->dint ) );

    //skip rsvd seciton rsvd1[3];

    for (i=0; i< 39; i++)
        DEBUGMSG(ZONE_ERROR, (TEXT( "v_pDMARegs->drcmr[%d]      %x \r\n" ),i,v_pDMARegs->drcmr[i] ) );

    for (i=0; i<16; i++)
    {

        DEBUGMSG(ZONE_ERROR, (TEXT( "v_pDMARegs->ddg[%d].ddadr  %x \r\n" ),i,v_pDMARegs->ddg[i].ddadr ) );
        DEBUGMSG(ZONE_ERROR, (TEXT( "v_pDMARegs->ddg[%d].dsadr  %x \r\n" ),i,v_pDMARegs->ddg[i].dsadr ) );
        DEBUGMSG(ZONE_ERROR, (TEXT( "v_pDMARegs->ddg[%d].dtadr  %x \r\n" ),i,v_pDMARegs->ddg[i].dtadr ) );
        DEBUGMSG(ZONE_ERROR, (TEXT( "v_pDMARegs->ddg[%d].dcmd   %x \r\n" ),i,v_pDMARegs->ddg[i].dcmd ) );


    }

}

⌨️ 快捷键说明

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