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

📄 aecdrv.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
字号:
//
// 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 OR INDEMNITIES.
//

/* Copyright 1999,2000,2001 Intel Corp.  */
/*
** 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.
*/

/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

  aecdrv.c

Abstract:

Functions:

Revision History:

--*/
//--------------------------------------------------------------------------------------
// Include Files
//--------------------------------------------------------------------------------------
#include  <windows.h>
#include  <types.h>
#include  <string.h>
#include  <nkintr.h>
#include  <bulverde.h>
#include  <ceddk.h>

#include "bulverde_base_regs.h"
#include "xllp_gpio.h"
#include "xllp_clkmgr.h"
#include "xllp_ssp.h"

#include "xllp_defs.h"
#include "xllp_serialization.h"
#include "xllp_ost.h"

#include "timer.h"

#include "aecdrv.h"

//========================
#define DEBUG_ZONE   0
#define DEBUG_ERROR  1
//========================

static void msWait(unsigned int);


//-----------------------------------------------------------------------------------------
// Global Variables.
//-----------------------------------------------------------------------------------------
static volatile XLLP_CLKMGR_T        * aec_pClkRegs                  = NULL;
static volatile XLLP_GPIO_T          * aec_pGPIORegs                 = NULL;
static volatile XLLP_SSPREGS_T       * aec_pSSPRegs                  = NULL;


//------------------------------------------------------------------------------------------------------------
// Function: ReadSSPLink
//
// Purpose:  Reads the data from the SSP's Rx FIFO with designated register address.
//
// Returns:  returns TRUE
//
//-------------------------------------------------------------------------------------------------------------
BOOL AEC_SSPLinkRead(unsigned char start,unsigned int *data)
{
    //16 bits mode
    unsigned int dest_data = 0;
    //Write Read address
    msWait(5);

    while((aec_pSSPRegs->sssr & SSP_TRANSMIT_FIFO_NOT_FULL) == 0);

    start = start | 0x80;
    dest_data = (start << 8) | dest_data;
    aec_pSSPRegs->ssdr = dest_data; //turn "read" on

    //Read return data
    while((aec_pSSPRegs->sssr & SSP_RECEIVE_FIFO_NOT_EMPTY)==0);
    //Read back 8 bits data
    *data=aec_pSSPRegs->ssdr & 0xFF;

    return(TRUE);    
}

//------------------------------------------------------------------------------------------------------------
// Function: WriteSSPLink
//
// Purpose:  Writes the data to the SSP's Tx FIFO. 8 bit address + 8 bit data
//
//
// Returns:  returns TRUE
//
//-------------------------------------------------------------------------------------------------------------


BOOL AEC_SSPLinkWrite(unsigned char start, unsigned int data)
{
    
    //16 bits mode
    unsigned int dest_data = 0;

    msWait(5);
    
    while((aec_pSSPRegs->sssr & SSP_TRANSMIT_FIFO_NOT_FULL) == 0);
    //Turn the "write" bit on (MSB active low)
    dest_data = (start<<8) & 0x7F00;
    dest_data = dest_data | (data & 0xFF);

    aec_pSSPRegs->ssdr =  dest_data; //turn "write" signal on

    return(TRUE);
}

//------------------------------------------------------------------------------------------------------------
// Function: AecAudioInit
//
// Purpose:  Initialises the SSP Controller of the XScale Processor.
// Returns:  returns void.
//
//-------------------------------------------------------------------------------------------------------------


BOOL AecAudioInit()
{
    unsigned int data;

    //Map registers
    if (!AllocateAECResources())
    {
        return FALSE;
    }

    // Initialize SSP Link
    if (!AEC_SSPLinkSetup())
    {
        return FALSE;
    }

    //Reset AEC chiipset with PDN/RST
    data= 0xFC; // turn off everything
    AEC_SSPLinkWrite(AEC_CR0,data);

    msWait(10);

    aec_pClkRegs->cken = (aec_pClkRegs->cken & XLLP_CLKEN_MASK) & ~CLK_SSP2;

    return (TRUE);
}



BOOL PowerUpAEC()
{
    unsigned int data;

    // Initialize SSP Link
    if (!AEC_SSPLinkSetup())
    {
        return FALSE;
    }

    //Power on
    data = 0x00;
    AEC_SSPLinkWrite(AEC_CR0,data);
    msWait(200);

    //CR11-B7 = 1
    do 
    {
        //CR11-B7 = 1?
        AEC_SSPLinkRead(AEC_CR11, &data);
    }while (!(data & 0x80));

    //Configure AEC to run Single echo canceler mode
    // (Acoustic Echo cancellation only)
    data = 0x1F;
    AEC_SSPLinkWrite(AEC_CR0,data);

    do {
        //CR11-B7 = 0?
        AEC_SSPLinkRead(AEC_CR11,&data);
    }while (data & 0x80);

    return (TRUE);
}


BOOL PowerDownAEC()
{
    unsigned int data;
    
    //Reset AEC chiipset with PDN/RST
    data= 0xFC; // turn off everything
    AEC_SSPLinkWrite(AEC_CR0,data);

    msWait(10);

    aec_pClkRegs->cken = (aec_pClkRegs->cken & XLLP_CLKEN_MASK) & ~CLK_SSP2;

    return TRUE;
}



//------------------------------------------------------------------------------------------------------------
// Function: AEC_SSPLinkInit
//
// Purpose:  Initialises the SSP Controller of the XScale Processor.
// Returns:  returns void.
//
//-------------------------------------------------------------------------------------------------------------
void AEC_SSPLinkInit()
{
    //Set to SPI mode
    
    // Sets up the SSP controller to Xmit 16 bit Data to the Renesas, frames are sent in the SPI format
    aec_pSSPRegs->sscr0 = 0x00000000;
    aec_pSSPRegs->sscr0 = SSCR0_TIM | SSCR0_RIM | SSCR0_SCR(0x10) | SSCR0_DSS(0x0F); //16 bits SPI mode

    aec_pSSPRegs->sscr1 = 0x00000000;
    aec_pSSPRegs->sscr1 = SSCR1_SPH  | SSCR1_SPO | SSCR1_TTE; //falling edge to drive transmit data, latch receiving data with rising edge, tristate enable for TXD
    aec_pSSPRegs->sscr0 |= SSCR0_SSE;
}




//----------------------------------------------------------------------------------------------------------------
//
// Function SSPGpioConfigure
//
// Purpose: This function must be called from the power handler of the respective drivers using this
// library. This function will configure the GPIO pins according to the functionality shown in the table below
//
//    Signals     GPIO    Direction   Alternate Function
//    SSPCLK      84      output        1
//    SSPSFRM     83      output        1
//    SSPRXD      82      input         1
//    SSPTXD      81      output        1
//
//----------------------------------------------------------------------------------------------------------------

BOOL AEC_SSPLinkGpioConfigure(volatile P_XLLP_GPIO_T v_pGPIORegs)
{
    if(v_pGPIORegs)
    {

        //Set GPIO pins: 36,37,38 as output, 40 as input (default is input??)
        v_pGPIORegs->GPDR1 |= 0x70;
        v_pGPIORegs->GPSR1 |= 0x70;  //Set to high level output
        //set pin 40 as input
        v_pGPIORegs->GPDR1 &= ~(0x00000100);

        v_pGPIORegs->GAFR1_L &= ~(0x00033F00);
        v_pGPIORegs->GAFR1_L |=   0x00012A00 ;

        return(TRUE);
    }

    return(FALSE);
}
//------------------------------------------------------------------------------------------------------------
// Function: SetupSSP
//
// Purpose:  Allocates the necessary registers, configures the necessary GPIO and initialises the SSP Link
// Returns:  returns TRUE if it could successfully do all this.
//
//-------------------------------------------------------------------------------------------------------------
BOOL AEC_SSPLinkSetup()
{
    // Turn on SSP2 clock
    aec_pClkRegs->cken = (aec_pClkRegs->cken & XLLP_CLKEN_MASK) | CLK_SSP2;

    if(aec_pSSPRegs)
    {
        if(AEC_SSPLinkGpioConfigure((XLLP_GPIO_T *)aec_pGPIORegs))
            AEC_SSPLinkInit(aec_pSSPRegs);
        else
            return(FALSE);
    }
    else
        return(FALSE);

    msWait(5);
    return(TRUE);
}



//Map register from Physical address to Virtual
static BOOL AllocateAECResources()
{

    PHYSICAL_ADDRESS RegPA;

    if (aec_pSSPRegs == NULL)
    {
        RegPA.QuadPart = BULVERDE_BASE_REG_PA_SSP2;
        aec_pSSPRegs = (volatile XLLP_SSPREGS_T *) MmMapIoSpace(RegPA, 0x400, FALSE);
    }

    if (aec_pClkRegs == NULL)
    {
        RegPA.QuadPart = BULVERDE_BASE_REG_PA_CLKMGR;
        aec_pClkRegs = (volatile BULVERDE_CLKMGR_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
    }

    if (aec_pGPIORegs == NULL)
    {
        RegPA.QuadPart = BULVERDE_BASE_REG_PA_GPIO;
        aec_pGPIORegs = (volatile BULVERDE_GPIO_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
    }

    if (!aec_pSSPRegs ||!aec_pClkRegs || !aec_pGPIORegs)
    {
        DEBUGMSG(TRUE, (TEXT("ERROR:  Failed to allocate AEC SSPLINK resources.\r\n")));
        //DeAllocateAECResources(DevId);
        return(FALSE);
    }

    return(TRUE);
}



BOOL DeAecAudioInit()
{
    if (aec_pSSPRegs)
    {
        VirtualFree((PVOID)aec_pSSPRegs,0,MEM_RELEASE);
        aec_pSSPRegs = NULL;
    }

    if (aec_pClkRegs)
    {
        VirtualFree((PVOID)aec_pClkRegs,0,MEM_RELEASE);
        aec_pClkRegs = NULL;
    }

    if (aec_pGPIORegs)
    {
        VirtualFree((PVOID)aec_pGPIORegs,0,MEM_RELEASE);
        aec_pGPIORegs = NULL;
    }

    return (TRUE);
}


extern PVOID VirtualAllocCopyPhysical(unsigned size,char *str,PVOID pPhysicalAddress);
static volatile BULVERDE_OST_REG *ost;

static void usWait(unsigned usVal)
{
    unsigned Start;
    static unsigned firstCall=1;

    if (firstCall)
    {
        ost = (volatile BULVERDE_OST_REG*)VirtualAllocCopyPhysical(0x80,"Wait OST",(PVOID)(BULVERDE_BASE_REG_PA_OST));
        if (!ost)
        {
            RETAILMSG(TRUE, (TEXT("usWait: Map OST register failed\r\n")));
            return;
        }
        firstCall=0;
    }

    if (usVal != 0)
    {
        Start = ost->oscr0;
        while ((ost->oscr0 - Start) < usVal * TIMERTICK)
        {
            // do nothing
        }
    }
}

static void msWait(unsigned msVal)
{
    usWait(msVal*1000);
}

static void sWait(unsigned sVal)
{
    msWait(sVal*1000);
}

⌨️ 快捷键说明

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