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

📄 aaci_audio_ok.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// Release Status:OS005-SW-70002-r0p0-00REL0
// $Copyright: 
// ----------------------------------------------------------------
// This confidential and proprietary software may be used only as
// authorised by a licensing agreement from ARM Limited
//   (C) COPYRIGHT 2004 ARM Limited
//       ALL RIGHTS RESERVED
// The entire notice above must be reproduced on all authorised
// copies and copies may only be made to the extent permitted
// by a licensing agreement from ARM Limited.
// ----------------------------------------------------------------
// File:     aaci_audio.c,v
// Revision: 1.2
// ----------------------------------------------------------------
// $

//--------------------------------------------------------------------------------
//
//                    PL041 AACI & LM4549A - Audio functions
//
//     This is a group of hardware specific functions that define a general
//  interface to be portable to other Operating systems and to run on the
//  National Semiconductor LM4549A CODEC and ARM PL041 AACI.
//
//     These functions include interfaces to an AC'97 Codec, Hardware
//  Initialization and currently run on the Intergrator/CP platforms.
//
//     This driver is set-up to use the dedicated AACI h/w registers to send 
//  and receive configuration data on slots 1 & 2, of the CODEC frame, to and 
//  from the LM4549A CODEC.
//  The AACI FIFOs are only used for sending and receiving wave channel data 
//  on slots 3 & 4, of the CODEC frame, left and right channels respectively.
//  Please read the ARM PrimeCell AACI (PL041) Technical Reference Manual for 
//  more information.
//--------------------------------------------------------------------------------

#include <windows.h>
#include <pkfuncs.h>
#include <ceddk.h>
#include <types.h>
#include <waveddsi.h>
#include <wavedbg.h>
#include <oalfuncs.h>

#include "wavmsg.h"
#include "pdd_audio.h"
#include <dma.h>
#include "oalintr.h"
#include "wavemdd.h"

#define DBG_AACI 0
//add whs
DWORD WINAPI DeviceThreadProc(PVOID pvParam);
   int  Volume = 0xd0d;
   BOOL  playflags=FALSE;//当前是否在播放
   BOOL  headphone=FALSE;//耳机输出
   BOOL  lout=FALSE;//喇叭输出
   BOOL  pauseflags=FALSE;//当前是否在播放
//add whs

int OnInit();
int OnDeinit();
int OnPlayOpen();
int OnPlayStart();
int OnPlayStop();
int OnPlayClose();

int OnRecordOpen();
int OnRecordStart();
int OnRecordStop();
int OnRecordClose();
CRITICAL_SECTION Criticalthread;

//---------------------------
// AACI Control
//---------------------------
VOID AACI_RegWrite32(USHORT reg, ULONG val);
ULONG AACI_RegRead32(USHORT reg);

//---------------------------
// CODEC Control
//---------------------------
VOID AACI_CodecWrite16( USHORT codec_reg, USHORT codec_data );
USHORT AACI_CodecRead16( USHORT codec_reg );

//---------------------------
// FIFO operations
//---------------------------
VOID FillFIFO_M8(PWAVEHDR pwh){};
VOID FillFIFO_M16(PWAVEHDR pwh){};
VOID FillFIFO_S8(PWAVEHDR pwh){};
VOID FillFIFO_S16(PWAVEHDR pwh){};
VOID GetFIFO_M8(PWAVEHDR pwh){};
VOID GetFIFO_M16(PWAVEHDR pwh){};
VOID GetFIFO_S8(PWAVEHDR pwh){};
VOID GetFIFO_S16(PWAVEHDR pwh){};

// Internal functions
static void DumpCurrentSettings();
static VOID CodecSend( ULONG raw_codec_reg, ULONG raw_codec_data );
static BOOL ResetDevice();
static void PowerUp();
static void PowerDown();
static BOOL ClearTransmitFIFO();
static BOOL ClearReceiveFIFO(DWORD *);

#ifdef TEST_API
// Internal test functions
static DWORD TestTransmit_FIFOSize(BOOL);
static DWORD TestTransmit_Complete(BOOL);
static DWORD TestTransmit_HalfEmpty(BOOL);
static DWORD TestReceive_Overrun(BOOL);
static DWORD TestReceive_HalfFull(BOOL);
static DWORD TestReceive_Runaway(BOOL);
#endif

// Keep this uncommented to enable transmit compact mode (recommended)
//#define TX_COMPACT_MODE
// Keep this uncommented to enable receive compact mode (recommended)
//#define RX_COMPACT_MODE

// Test and wait for flags to clear
#define _TWMAX 10
#define TESTWAIT(test,dbgmsg)                       \
    {                                               \
        int _testwait = 0;                          \
        while( (test) && _testwait < _TWMAX )       \
        {                                           \
            Sleep(1);                               \
            _testwait++;                            \
        }                                           \
        if( _testwait == _TWMAX )                   \
            ERRMSG1("AACI: Failed to wait for %s", TEXT(dbgmsg) ); \
    }
        
// FIFO Sizes for testing and use in filling/clearing the FIFOs
#define TX_FIFOSIZE_NOTCOMPACT 512
#define TX_FIFOSIZE_COMPACT    (TX_FIFOSIZE_NOTCOMPACT/2)
#define RX_FIFOSIZE_NOTCOMPACT 512
#define RX_FIFOSIZE_COMPACT    (RX_FIFOSIZE_NOTCOMPACT/2)

#ifdef TX_COMPACT_MODE
#define TX_FIFOSIZE     TX_FIFOSIZE_COMPACT
#else
#define TX_FIFOSIZE     TX_FIFOSIZE_NOTCOMPACT
#endif
#ifdef RX_COMPACT_MODE
#define RX_FIFOSIZE     RX_FIFOSIZE_COMPACT
#else
#define RX_FIFOSIZE     RX_FIFOSIZE_NOTCOMPACT
#endif


//junxz
//#define SET_SLOT12_FALSE 	AACI_RegWrite32( AACIReg_Slot12Tx, 0x00000);
//#define SET_SLOT12_TRUE 	AACI_RegWrite32( AACIReg_Slot12Tx, 0xfffff);

#define SET_SLOT12_FALSE 	AACI_RegWrite32( AACIReg_Slot12Tx, (AACI_CodecRead16(0x54)&(~0x06))<<4);
#define SET_SLOT12_TRUE 	AACI_RegWrite32( AACIReg_Slot12Tx, (AACI_CodecRead16(0x54)|(0x06))<<4);

USHORT MakeTest();


//--------------------------------------------------------------------------------
// Variables - local and globally global
//--------------------------------------------------------------------------------

// The event handler (from MDD layer)
extern HANDLE hAudioInterrupt;

#ifdef DEBUG
// To get access to the debug zones (from MDD layer)
extern DBGPARAM dpCurSettings;
#endif

// System Interrupt - used by MDD layer
ULONG gIntrAudio;

static BOOL g_fPowerOn;             // Current Power setting
static ULONG g_nVolume;             // Current master volume setting (MSFT format)
static UCHAR *g_AudioRegBase = NULL;// Pointer to memory mapped AACI regs.

#ifdef TEST_API
// When we are performing tests
static BOOL g_fTesting = FALSE;     // Specifies whether testing or not
static BOOL g_fTestIntDisable;      // AACI Interrupts disabled on AACI interrupt?
static HANDLE g_hTestInterrupt;     // Test interrupt event - set on AACI interrupt
static DWORD g_dwTestIntStatus;     // AACI status flags on interrupt
#endif

// The following arrays contains 2 entries, One for input, one for output
static BOOL g_fInUse[2];            // Channel in use?
static DWORD g_dwRunMode[2];        // Channel receiving/transmitting data?
static BOOL g_fTxEndOfData;         // Channel transmit end of data?
static PWAVEFORMATEX g_pwfx[2];     // Current channel format

#define RUNMODE_STOPPED  0
#define RUNMODE_STOPPING 1
#define RUNMODE_RUNNING  2

// This variable may be accessed by different processes (i.e. via interrupts) 
// and is likely to change in a time critical fashion. Optimization may cause 
// errors if not declared volatile.
static volatile BOOL gv_fMoreData[2];   // Any more data to transmit/receive?

// Current shortcuts to FIFO fill/get functions - dependent on wave format
static VOID (*pfnFillFIFO)(PWAVEHDR);
static VOID (*pfnGetFIFO)(PWAVEHDR);


//add junxz
BOOL leftout = TRUE;


// Volume control translation array - from MSFT format to CODEC format

/*
const USHORT VolumeLUT[] = {
    0x20, 0x20, 0x1d, 0x1d, 0x1a, 0x1a, 0x17, 0x17,
    0x13, 0x13, 0x0f, 0x0f, 0x0d, 0x0d, 0x0a, 0x0a,
    0x08, 0x08, 0x06, 0x06, 0x05, 0x05, 0x04, 0x04,
    0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00 };
*/

/*
const USHORT VolumeLUT[] = {
    0x20, 0x20, 0x1d, 0x1d, 0x1b, 0x1b, 0x19, 0x19,
    0x17, 0x17, 0x15, 0x15, 0x13, 0x13, 0x11, 0x11,
    0x0f, 0x0f, 0x0d, 0x0d, 0x0b, 0x0b, 0x09, 0x09,
    0x07, 0x07, 0x05, 0x05, 0x03, 0x03, 0x01, 0x01 };
*/
///
/*
const USHORT VolumeLUT[] = {
    0x1d, 0x1d, 0x1d, 0x1d, 0x1b, 0x1b, 0x1b, 0x19,
    0x19, 0x19, 0x17, 0x17, 0x17, 0x15, 0x15, 0x15,
    0x13, 0x13, 0x13, 0x11, 0x11 0x11, 0x0f, 0x0f,
    0x0f, 0x0d, 0x0d, 0x0d, 0x0b, 0x0b, 0x0b, 0x0b };
*/

// junxz
const USHORT VolumeLUT[] = {
    0x1f, 0x1f, 0x1c, 0x1c, 0x1a, 0x1a, 0x17, 0x17,
    0x14, 0x14, 0x12, 0x12, 0x10, 0x10, 0x0e, 0x0e,
    0x0c, 0x0c, 0x0b, 0x0b, 0x0a, 0x0a, 0x09, 0x09,
    0x08, 0x08, 0x07, 0x07, 0x06, 0x06, 0x05, 0x05 };


/*
	const USHORT VolumeLUT[] = {
    0x20, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
    0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
    0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
    0x07, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02 };

*/
//add by whs  for ---- power amplifier 
/*
const SHORT PowerAmplifier[] = {

    -22, -22, -19, -19, -16, -16, -13, -13,
    -10, -10, -7, -7, -4, -4, 0, 0,
    0, 2, 2, 2, 5, 5, 5, 8,
    8, 8, 11, 11, 14, 14, 20,20,
    };
*/
/*
const SHORT PowerAmplifier[] = {
    -4, -4,-4, -4, 0, 0, 0, 0,
    2, 2,2, 2, 5, 5, 5, 5,
    8, 8,8, 8, 11, 11, 11, 11, 
    14, 14, 14, 14, 20,20, 20,20,
    };
*/


    

// Keep a record of all the bytes played and recorded in a 
//  wavestart-wavestop session
#ifdef AACI_STATS
static DWORD g_dwBytesRecorded[2];
#endif

//-----------------------------------------------------------------------------
//
//  UCHAR AACI_Initialize (UINT Irq, UINT SysIntr, UINT IoBase)
//
//  Initializes the AACI and LM4549 hardware.
//  It has to be called with the resources that were assigned by the OS
//
//  This function:
//
//  - Maps the Irq to a system interrupt number
//  - Maps in the AACI hardware register addresses
//  - Reset and initialize the CODEC
//
//  Resources assigned by the system:
//
//  unsigned int    Irq,
//  unsigned int    SysIntr,
//  unsigned int    IoBase
//
//--------------------------------------------------------------------------------
BOOL AACI_Initialize (UINT Irq, UINT SysIntr, UINT IoBase)
{
    BOOL bRet = FALSE;
    PHYSICAL_ADDRESS PhysicalAddress;
    //add whs
    HANDLE hWaveThread;
    //add whs

    
    // Turn on various DEBUG messages - (see public\common\oak\inc\wavedbg.h)
#ifdef DEBUG
    // All INIT messages
    dpCurSettings.ulZoneMask |= (1<<10);
    // PDD Function debug 
    //dpCurSettings.ulZoneMask |= (1<<6) | (1<<13);
    // All debug messages (even MDD layer)
    //dpCurSettings.ulZoneMask = 0xFFFF;
#endif

	FUNC_WPDD("+AACI_Initialize");

	RETAILMSG(DBG_AACI,(TEXT("AACI PDD 1.5\r\n")));

    PRINTMSG(ZONE_INIT, (TEXT("AACI Initialising - version %d.%d"),
            WAVEDEV_VERSION_MAJOR,WAVEDEV_VERSION_MINOR) );
    
    // Set up system interrupt for MDD layer
    gIntrAudio = SysIntr;

    // Setup global variables for input and output buffers
    gv_fMoreData[WAPI_OUT]  = FALSE;
    gv_fMoreData[WAPI_IN]   = FALSE;
    g_fInUse[WAPI_OUT]      = FALSE;
    g_fInUse[WAPI_IN]       = FALSE;
    g_dwRunMode[WAPI_OUT]   = RUNMODE_STOPPED;
    g_dwRunMode[WAPI_IN]    = RUNMODE_STOPPED;
    g_fTxEndOfData          = FALSE;
    g_pwfx[WAPI_OUT]        = NULL;
    g_pwfx[WAPI_IN]         = NULL;

    // NOTE: g_nVolume should get properly set on boot up by a WPDM_SETVOLOUME
    //  message (from the WAVAPI.DLL). We set it here to 0 to reflect the 
    //  default CODEC setting (mute)
    g_nVolume = 0;

    // Map in address space for AACI hardware registers
    PhysicalAddress.HighPart = 0;
    PhysicalAddress.LowPart = IoBase;
    g_AudioRegBase = (UCHAR *)MmMapIoSpace (PhysicalAddress, AACI_HWREGS_SIZE,//物理地址影射到虚拟地址
                                            FALSE);
    if( !g_AudioRegBase )//如果影射失败
    {
        ERRMSG("PDD_AudioInitialize: Map audio registers failed");
    }
    else
    {
    // Set up the device
    
        if( ResetDevice() )
        {
            g_fPowerOn = TRUE;

#if 0
            // Show what the initialised settings are
            DumpCurrentSettings();
#endif
            // All is well, AACI is up and working
            bRet = TRUE;
        }
    }


	OnInit();
	
	AACI_RegWrite32( AACIReg_Channel1TxControl, 
		AACI_RegRead32(AACIReg_Channel1TxControl) & 
		(~AACIBit_EnableFIFO) );
	
	//Disable Tx Interrupt	
	AACI_RegWrite32( AACIReg_Channel1IntEnable, 
		AACI_RegRead32( AACIReg_Channel1IntEnable ) & 
		~(AACIBit_TxCIE | AACIBit_TxIE /*| AACIBit_TxUIE*/) );

⌨️ 快捷键说明

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