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

📄 audioctl.cpp

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
// Portions Copyright (c) Texas Instruments.  All rights reserved.
//
//------------------------------------------------------------------------------
//
//  EAC controller platform specific configuration.
//
//  Most settings depend on the codec, modem and bluetooth chip connected to
//  the OMAP2420 chipset.
//
#include <wavemain.h>
#include <omap3_defs.h>
#include <ceddk.h>
#include <spi.h>
#include <tsc2101.h>
#include "xhwctxt.h"

//------------------------------------------------------------------------------
//  Globals

const GUID DEVICE_IFC_CLK_GUID;
const GUID DEVICE_IFC_SPI_GUID;

//------------------------------------------------------------------------------
//
//  platform specific definition for codec port
//
//  on P2 Sample platform the codec port is configured as I2S
//

//------------------------------------------------------------------------------
//
// EAC BT auSPI pin muxing defines and function.
//

#define MODE1_INTERNAL_BTAUSPI_SOURCE_BITS  (BIT3|BIT2)  // Bits used to select BT EAC AuSPI source                                            
#define MODE1_V3U3V2T4_AS_BTAUSPI_SOURCE    (BIT2)       // use pins V3/U3/V2/T4 as source
#define MODE1_W6R9Y6Y5_AS_BTAUSPI_SOURCE    0            // use pins W6/R9/Y6/Y5 as source

// TSC2101 constants
#define TSC2101_PAGE2   0x1000


//------------------------------------------------------------------------------
//
//  TSC2101Write - uses SPI to write a value to one of the TSC2101 registers
//

static void TSC2101Write(HANDLE hSPI, WORD wReg, WORD wData)
{
    DWORD   dwCommand;

    dwCommand = ((DWORD)(TSC2101_PAGE2 | wReg) << 16) | wData;
    SPITransfer(hSPI, &dwCommand);
}

//------------------------------------------------------------------------------
//
//  TSC2101Read - uses SPI to read a value from one of the TSC2101 registers
//

static WORD TSC2101Read(HANDLE hSPI, WORD wReg)
{
    DWORD   dwCommand;

    dwCommand = (DWORD)(TSC2101_READ | TSC2101_PAGE2 | wReg) << 16;
    SPITransfer(hSPI, &dwCommand);
    return (WORD)dwCommand;
}

//------------------------------------------------------------------------------
//
//  test code to generate a tone without DMA
//

//#define TEST_TONE

#if defined(TEST_TONE)

#define TEST_SOUND  awSound     // awTone (below) or awSound (from sound.h)
#define TEST_READ_COUNT     44100
#if (TEST_SOUND == awSound)
#define TEST_WRITE_COUNT    1
#else
#define TEST_WRITE_COUNT    1000
#endif

#include "sound.h"  // awSound array

WORD awInput[TEST_READ_COUNT];
WORD awTone[] =
{
    0x0ce4, 0x0ce4, 0x1985, 0x1985, 0x25A1, 0x25A1, 0x30FD, 0x30FE,
    0x3B56, 0x3B55, 0x447A, 0x447A, 0x4C3B, 0x4C3C, 0x526D, 0x526C,
    0x56F1, 0x56F1, 0x59B1, 0x59B1, 0x5A9E, 0x5A9D, 0x59B1, 0x59B2,
    0x56F3, 0x56F2, 0x526D, 0x526D, 0x4C3B, 0x4C3B, 0x447C, 0x447C,
    0x3B5A, 0x3B59, 0x30FE, 0x30FE, 0x25A5, 0x25A6, 0x1989, 0x198A,
    0x0CE5, 0x0CE3, 0x0000, 0x0000, 0xF31C, 0xF31C, 0xE677, 0xE676,
    0xDA5B, 0xDA5B, 0xCF03, 0xCF03, 0xC4AA, 0xC4AA, 0xBB83, 0xBB83,
    0xB3C5, 0xB3C5, 0xAD94, 0xAD94, 0xA90D, 0xA90E, 0xA64F, 0xA64E,
    0xA562, 0xA563, 0xA64F, 0xA64F, 0xA910, 0xA90F, 0xAD93, 0xAD94,
    0xB3C4, 0xB3C4, 0xBB87, 0xBB86, 0xC4AB, 0xC4AB, 0xCF03, 0xCF03,
    0xDA5B, 0xDA5A, 0xE67B, 0xE67B, 0xF31B, 0xF3AC, 0x0000, 0x0000,
    0x0CE4, 0x0CE4, 0x1985, 0x1985, 0x25A1, 0x25A1, 0x30FD, 0x30FE,
    0x3B56, 0x3B55, 0x447A, 0x447A, 0x4C3B, 0x4C3C, 0x526D, 0x526C,
    0x56F1, 0x56F1, 0x59B1, 0x59B1, 0x5A9E, 0x5A9D, 0x59B1, 0x59B2,
    0x56F3, 0x56F2, 0x526D, 0x526D, 0x4C3B, 0x4C3B, 0x447C, 0x447C,
    0x3B5A, 0x3B59, 0x30FE, 0x30FE, 0x25A5, 0x25A6, 0x1989, 0x198A,
    0x0CE5, 0x0CE3, 0x0000, 0x0000, 0xF31C, 0xF31C, 0xE677, 0xE676,
    0xDA5B, 0xDA5B, 0xCF03, 0xCF03, 0xC4AA, 0xC4AA, 0xBB83, 0xBB83,
    0xB3C5, 0xB3C5, 0xAD94, 0xAD94, 0xA90D, 0xA90E, 0xA64F, 0xA64E,
    0xA562, 0xA563, 0xA64F, 0xA64F, 0xA910, 0xA90F, 0xAD93, 0xAD94,
    0xB3C4, 0xB3C4, 0xBB87, 0xBB86, 0xC4AB, 0xC4AB, 0xCF03, 0xCF03,
    0xDA5B, 0xDA5A, 0xE67B, 0xE67B, 0xF31B, 0xF3AC, 0x0000, 0x0000,
    0x0CE4, 0x0CE4, 0x1985, 0x1985, 0x25A1, 0x25A1, 0x30FD, 0x30FE,
    0x3B56, 0x3B55, 0x447A, 0x447A, 0x4C3B, 0x4C3C, 0x526D, 0x526C,
    0x56F1, 0x56F1, 0x59B1, 0x59B1, 0x5A9E, 0x5A9D, 0x59B1, 0x59B2,
    0x56F3, 0x56F2, 0x526D, 0x526D, 0x4C3B, 0x4C3B, 0x447C, 0x447C,
    0x3B5A, 0x3B59, 0x30FE, 0x30FE, 0x25A5, 0x25A6, 0x1989, 0x198A,
    0x0CE5, 0x0CE3, 0x0000, 0x0000, 0xF31C, 0xF31C, 0xE677, 0xE676,
    0xDA5B, 0xDA5B, 0xCF03, 0xCF03, 0xC4AA, 0xC4AA, 0xBB83, 0xBB83,
    0xB3C5, 0xB3C5, 0xAD94, 0xAD94, 0xA90D, 0xA90E, 0xA64F, 0xA64E,
    0xA562, 0xA563, 0xA64F, 0xA64F, 0xA910, 0xA90F, 0xAD93, 0xAD94,
    0xB3C4, 0xB3C4, 0xBB87, 0xBB86, 0xC4AB, 0xC4AB, 0xCF03, 0xCF03,
    0xDA5B, 0xDA5A, 0xE67B, 0xE67B, 0xF31B, 0xF3AC, 0x0000, 0x0000
};

static BOOL McBSPRead(OMAP2420_McBSP_REGS *pMcBSP, PWORD pwData)
{
    WORD    wReg, wAttempts;

    *pwData = INREG16(&pMcBSP->usMCBSP_DRR1);
    wReg = INREG16(&pMcBSP->usMCBSP_SPCR1);
    if (wReg & MCBSP_RSYNCERR)
    {
        OUTREG16(&pMcBSP->usMCBSP_SPCR1, wReg & (~MCBSP_RSYNCERR));
        DEBUGMSG(ZONE_AC, (L"AC: McBSPRead FAILED on RSYNC\r\n"));
    }
    else
    {
        for (wAttempts = 0; wAttempts < 1000; wAttempts++)
        {
            wReg = INREG16(&pMcBSP->usMCBSP_SPCR1);
            if (wReg & MCBSP_RRDY)
            {
                return TRUE;
            }
        }
        OUTREG16(&pMcBSP->usMCBSP_SPCR1, wReg & (~MCBSP_RRST));
        Sleep(1);
        OUTREG16(&pMcBSP->usMCBSP_SPCR1, wReg | MCBSP_RRST);
        Sleep(1);
        DEBUGMSG(ZONE_AC, (L"AC: McBSPRead FAILED on RRDY\r\n"));
    }

    return FALSE;
}

static BOOL McBSPWrite(OMAP2420_McBSP_REGS *pMcBSP, WORD wData)
{
    WORD    wReg, wAttempts;

    OUTREG16(&pMcBSP->usMCBSP_DXR1, wData);
    wReg = INREG16(&pMcBSP->usMCBSP_SPCR2);
    if (wReg & MCBSP_XSYNCERR)
    {
        OUTREG16(&pMcBSP->usMCBSP_SPCR2, wReg & (~MCBSP_XSYNCERR));
        DEBUGMSG(ZONE_AC, (L"AC: McBSPWrite FAILED on XSYNC\r\n"));
    }
    else
    {
        for (wAttempts = 0; wAttempts < 1000; wAttempts++)
        {
            wReg = INREG16(&pMcBSP->usMCBSP_SPCR2);
            if (wReg & MCBSP_XRDY)
            {
                return TRUE;
            }
        }
        OUTREG16(&pMcBSP->usMCBSP_SPCR2, wReg & (~MCBSP_XRST));
        Sleep(1);
        OUTREG16(&pMcBSP->usMCBSP_SPCR2, wReg | MCBSP_XRST);
        Sleep(1);
        DEBUGMSG(ZONE_AC, (L"AC: McBSPWrite FAILED on XRDY\r\n"));
    }

    return FALSE;
}

static void TestTone(OMAP2420_McBSP_REGS *pMcBSP)
{
    DWORD   i, j;

    DEBUGMSG(ZONE_AC, (L"AC: +TestTone\r\n"));
    Sleep(10);

    // write the test data
    for (i = 0; i < TEST_WRITE_COUNT; i++)
    {
        for (j = 0; j < sizeof(TEST_SOUND) / sizeof(WORD); j++)
        {
            if (!McBSPWrite(pMcBSP, TEST_SOUND[j]))
            {
                DEBUGMSG(ZONE_AC, (L"AC: -TestTone write %u %u\r\n", i, j));
                return;
            }
        }
    }

    // read some input data
    DEBUGMSG(ZONE_AC, (L"AC: start recording\r\n"));
    for (i = 0; i < TEST_READ_COUNT; i++)
    {
        if (!McBSPRead(pMcBSP, awInput + i))
        {
            DEBUGMSG(ZONE_AC, (L"AC: -TestTone read %u\r\n", i));
            return;
        }
    }
    DEBUGMSG(ZONE_AC, (L"AC: stop recording\r\n"));
    for (i = 0; i < TEST_READ_COUNT; i++)
    {
        if (!(i & 0xF))
        {
            DEBUGMSG(ZONE_AC, (L"\r\n\t"));
        }
        DEBUGMSG(ZONE_AC, (L"%04X, ", awInput[i]));
    }

    // write back what was read
    for (i = 0; i < TEST_READ_COUNT; i++)
    {
        if (!McBSPWrite(pMcBSP, awInput[i]))
        {
            DEBUGMSG(ZONE_AC, (L"AC: -TestTone writeback %u\r\n", i));
            return;
        }
    }

    Sleep(10);
    DEBUGMSG(ZONE_AC, (L"AC: -TestTone\r\n"));
}

#endif  // TEST_TONE

//------------------------------------------------------------------------------
//
//  Function:  HardwareContext::CreateHWContext
//  
//  This function creates a hardware context using a platform specific derived
//  class based on HardwareContext. In order to support different hardware 
//  configurations in one binary the approbriate class could be created here.
//
//

BOOL HardwareContext::CreateHWContext(DWORD Index)
{
    if (g_pHWContext)
    {
        return TRUE;
    }

    g_pHWContext = new ACAudioHWContext((LPTSTR)Index);

    if (!g_pHWContext)
    {
        return FALSE;
    }
    
    return g_pHWContext->Init(Index);
}

//------------------------------------------------------------------------------
//
//  Function: HWMapControllerRegs() 
//  
//  map hardware registers to device driver virtual addresses
//

BOOL 
ACAudioHWContext::HWMapControllerRegs()
{
    PHYSICAL_ADDRESS pa;

    DEBUGMSG(ZONE_AC, (L"+ACAudioHWContext::HWMapControllerRegs()\r\n"));

    // set the power state
    if (!m_hParent)
    {
        DEBUGMSG(ZONE_ERROR, (L"ACAudioHWContext::HWMapControllerRegs: "
            L"ERROR setting the power state.\r\n"
        ));
        goto ErrExit;
    }
    m_CurPowerState = D2; 
    SetDevicePowerState(m_hParent, D2 , NULL);

    // get the McBSP pointer
    pa.HighPart= 0;
    pa.LowPart = AUDIO_MCBSP_REGS_PA;
    m_pMCBSPRegisters = (OMAP2420_McBSP_REGS *)MmMapIoSpace(pa, N1KB, FALSE);
    if (!m_pMCBSPRegisters)
    {
        DEBUGMSG(ZONE_ERROR, (L"ACAudioHWContext::HWMapControllerRegs: "
            L"ERROR mapping MCBSP registers.\r\n"
        ));
        goto ErrExit;
    }

    // get the PRCM registers pointer
    pa.LowPart = OMAP2420_PRCM_REGS_PA;
    m_pPRCMRegs = (OMAP2420_PRCM_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_PRCM_REGS), FALSE);
    if (!m_pPRCMRegs)
    {
        DEBUGMSG(ZONE_ERROR, (L"ACAudioHWContext::HWMapControllerRegs: "
            L"Allocating PRCM register failed.\r\n"
        ));
        goto ErrExit;
    }

    // open the SPI device
    m_hSPI = SPIOpen();
    if (!m_hSPI)
    {
        DEBUGMSG(ZONE_ERROR, (L"ACAudioHWContext::HWMapControllerRegs: "
            L"Failed to open the SPI device driver.\r\n"
        ));
        goto ErrExit;
    }

    // configure the SPI device
    if (!SPISetSlaveAddress(m_hSPI, 0))
    {
        DEBUGMSG(ZONE_ERROR, (L"ACAudioHWContext::HWMapControllerRegs: "
            L"Failed to set the SPI slave address.\r\n"
        ));
        goto ErrExit;
    }

    return TRUE;

ErrExit:
    // reset all mappings in case of error
    m_pMCBSPRegisters = NULL;
    m_pPRCMRegs = NULL;
    m_hSPI = NULL; 
    return FALSE;
}

//------------------------------------------------------------------------------
//
//  Function: SetCodecPower 
// 
//  Set CODEC port power state.
//

VOID 
ACAudioHWContext::SetCodecPower(BOOL fPowerOn)
{
    DEBUGMSG(ZONE_AC, (L"+ACAudioHWContext::SetCodecPower(%x)\r\n", fPowerOn));

    // power on or off the BSP and CODEC
    if (fPowerOn)
    {
        CLRREG16(&m_pMCBSPRegisters->usMCBSP_PCR, MCBSP_IDLEEN);
        TSC2101Write(m_hSPI, TSC2101_AUDCTRL_POWER, CPC_SP1PWDN | CPC_SP2PWDN);
    }
    else
    {
        TSC2101Write(m_hSPI, TSC2101_AUDCTRL_POWER, CPC_MBIAS_HND | CPC_MBIAS_HED | CPC_ASTPWD |
                    CPC_SP1PWDN | CPC_SP2PWDN | CPC_DAPWDN | CPC_ADPWDN | CPC_VGPWDN |
                    CPC_COPWDN | CPC_LSPWDN);
        SETREG16(&m_pMCBSPRegisters->usMCBSP_PCR, MCBSP_IDLEEN);
    }
}

//------------------------------------------------------------------------------
//
//  Function: InitCodecPort() 
//  
//  Configures the codec port. 
//

void 
ACAudioHWContext::InitCodecPort()
{
    UINT16 uiTmp;

    DEBUGMSG(ZONE_AC, (L"+ACAudioHWContext::InitCodecPort()\r\n"));

    // power down everything
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_POWER, CPC_MBIAS_HND | CPC_MBIAS_HED | CPC_ASTPWD |
                    CPC_SP1PWDN | CPC_SP2PWDN | CPC_DAPWDN | CPC_ADPWDN | CPC_VGPWDN |
                    CPC_COPWDN | CPC_LSPWDN);

    // headset input not muted, AGC for Headset In off
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_HEADSET, HGC_ADPGA_HED(0x7F));

    // handset input not muted, AGC for Handset In off
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_HANDSET, HNGC_ADPGA_HND(0x7F));

    // mute analog sidetone, select MIC_INHED input for headset
    // Cell Phone In not connected
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_MIXER, MPC_ASTMU | MPC_ASTG(0x600) | MPC_MICADC |
                    MPC_MICSEL(1));

    // ADC, DAC, Analog Sidetone, cellphone, buzzer
    // softstepping enabled, 1dB AGC hysteresis, MICes bias 2V 
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_4, AC4_MB_HED(0));

    // Set codec output volume
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_DAC, DGC_DALVL(0) | DGC_DARVL(0));

    // DAC left and right routed to SPK2, SPK1/2 unmuted
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_5, AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
                    AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 | AC5_HDSCPTC);

    // OUT8P/N muted, CPOUT muted
//  TSC2101Write(m_hSPI, TSC2101_AUDCTRL_6, AC6_MUTSPK2 |
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_6, AC6_MUTSPK2 | AC6_SPL2LSK | AC6_AST2LSK |
                    AC6_LDSCPTC | AC6_VGNDSCPTC);

    // Headset/Hook switch detect disabled
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_7, 0);

    // set I2S, word length, and reference sampling rate (RFS) divisor
    if (BITSPERSAMPLE == 20) uiTmp = 1;
    else if (BITSPERSAMPLE == 24) uiTmp = 2;
    else if (BITSPERSAMPLE == 32) uiTmp = 3;
    else uiTmp = 0;
    TSC2101Write(m_hSPI, TSC2101_AUDCTRL_1, AC1_WLEN(uiTmp) | AC1_DACFS(0) | AC1_ADCFS(0));

    // make the TSC2101 the master vs. the McBSP, set the RFS to 44100 or 48000
    uiTmp = AC3_SLVMS | ((SAMPLERATE == 44100) ? AC3_REFFS : 0);

⌨️ 快捷键说明

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