📄 aecdrv.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 + -