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

📄 hwctxt.cpp

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// 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.
//
/*++
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:    HWCTXT.CPP

Abstract:               Platform dependent code for the mixing audio driver.

Notes:                  The following file contains all the hardware specific code
                                for the mixing audio driver.  This code's primary responsibilities
                                are:

                                        * Initialize audio hardware (including codec chip)
                                        * Schedule DMA operations (move data from/to buffers)
                                        * Handle audio interrupts

                                All other tasks (mixing, volume control, etc.) are handled by the "upper"
                                layers of this driver.

                                ****** IMPORTANT ******
                                For the SC2410 CPU, DMA channel 2 can be used for both input and output.  In this,
                                configuration, however, only one type operation (input or output) can execute.  In
                                order to implement simultaneous playback and recording, two things must be done:

                                        1) Input DMA should be moved to DMA Channel 1; Output DMA still uses DMA Channel 2.
                                        2) Step #3 in InterruptThread() needs to be implemented so that the DMA interrupt
                                           source (input DMA or output DMA?) can be determined.  The interrupt source needs
                                           to be determined so that the appropriate buffers can be copied (Steps #4,#5...etc.).

-*/

#include "wavemain.h"
#include <s3c2410x.h>
#include "s3c2410x_dmatransfer.h"
#include "I2S.h"
#include "hwctxt.h"
#include <ceddk.h>

#define DMA_CH_MIC 2
#define DMA_CH_OUT 1

#define L3M (0x04)      // TOUT2
#define L3C (0x10)      // TCLK0
#define L3D (0x08)      // TOUT3

// UDA1341 Register definitions
// The codec has three "addressing modes", which could also be thought of as registers
#define UDA1341_ADDR_DATA0  0x14    // 00010100 | 00  (ID | data0)
#define UDA1341_ADDR_DATA1  0x15    // 00010100 | 01  (ID | data1)
#define UDA1341_ADDR_STATUS     0x16    // 00010100 | 10  (ID | status)

// Status register bits
// Think of the status register as two separate 7-bit register (StatusA and StatusB)
// with bit 7 selecting between the two.

#define UDA1341_STATUS_A            0x00
#define UDA1341_STATUS_B            0x80
#define UDA1341_STATUS_DCFILTER     0x01 // bit 0: DC Filter on
#define UDA1341_STATUS_FMTIIS       0x00 // bit 1-3: format status
#define UDA1341_STATUS_FMT_LSB16    0x02
#define UDA1341_STATUS_FMT_LSB18    0x04
#define UDA1341_STATUS_FMT_LSB20    0x06
#define UDA1341_STATUS_FMT_MSB      0x08
#define UDA1341_STATUS_FMT_MSB16    0x0A
#define UDA1341_STATUS_FMT_MSB18    0x0C
#define UDA1341_STATUS_FMT_MSB20    0x0E
#define UDA1341_STATUS_CLK512       0x00 // bits 4,5: system clock
#define UDA1341_STATUS_CLK384       0x10 //
#define UDA1341_STATUS_CLK256       0x20 //
#define UDA1341_STATUS_RESET        0x40 // bit 6: reset

#define UDA1341_STATUS_PWR_DAC      0x01 // bit 0: DAC power on
#define UDA1341_STATUS_PWR_ADC      0x02 // bit 1: ADC power on
#define UDA1341_STATUS_IGS          0x20 // bit 5: IGS - ADC 6dB Boost
#define UDA1341_STATUS_OGS          0x40 // bit 6: OGS - DAC 6dB Boost


int rec_mode=0;
//-------------------------------- Global Variables --------------------------------------
volatile S3C2410X_IISBUS_REG *g_pIISregs                = NULL;         // I2S control registers
volatile S3C2410X_IOPORT_REG *g_pIOPregs                = NULL;         // GPIO registers (needed to enable I2S and SPI)
volatile S3C2410X_SPI_REG    *g_pSPIregs        = NULL;         // SPI control registers

volatile S3C2410X_DMA_REG    *g_pDMAregs                = NULL;         // DMA registers (needed for I/O on I2S bus)
volatile S3C2410X_CLKPWR_REG *g_pCLKPWRreg      = NULL;         // Clock power registers (needed to enable I2S and SPI clocks)
volatile S3C2410X_INTR_REG *s2410INT            = NULL;

HardwareContext *g_pHWContext           = NULL;

PHYSICAL_ADDRESS g_PhysDMABufferAddr;

//----------------------------------------------------------------------------------------

#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("WaveDriver"), {
        TEXT("Test")           //  0   ZONE_TEST
        ,TEXT("Params")         //  1   ZONE_PARAMS
        ,TEXT("Verbose")        //  2   ZONE_VERBOSE
        ,TEXT("Interrupt")      //  3   ZONE_INTERRUPT
        ,TEXT("WODM")           //  4   ZONE_WODM
        ,TEXT("WIDM")           //  5   ZONE_WIDM
        ,TEXT("PDD")            //  6   ZONE_PDD
        ,TEXT("MDD")            //  7   ZONE_MDD
        ,TEXT("Regs")           //  8   ZONE_REGS
        ,TEXT("Misc")           //  9   ZONE_MISC
        ,TEXT("Init")           // 10   ZONE_INIT
        ,TEXT("IOcontrol")      // 11   ZONE_IOCTL
        ,TEXT("Alloc")          // 12   ZONE_ALLOC
        ,TEXT("Function")       // 13   ZONE_FUNCTION
        ,TEXT("Warning")        // 14   ZONE_WARN
        ,TEXT("Error")          // 15   ZONE_ERROR
    },
    (1 << 15)   // Errors
    |   (1 << 14)   // Warnings
};
#endif


void WriteL3Addr(unsigned char data)
{
    int i,j;

    g_pIOPregs->GPBDAT &= ~(L3D|L3M|L3C);               //L3D=L/L3M=L(in address mode)/L3C=L
    g_pIOPregs->GPBDAT |= L3C;                  //L3C=H

    for (j=0;j<10;j++);                              //tsu(L3) > 190ns

    //PD[8:6]=L3D:L3C:L3M
    for (i=0;i<8;i++)                            //LSB first
    {
        if (data&0x1)                                //if data's LSB is 'H'
        {
            g_pIOPregs->GPBDAT &= ~L3C;             //L3C=L
            g_pIOPregs->GPBDAT |= L3D;              //L3D=H
            for (j=0;j<10;j++);                      //tcy(L3) > 500ns
            g_pIOPregs->GPBDAT |= L3C;              //L3C=H
            g_pIOPregs->GPBDAT |= L3D;              //L3D=H
            for (j=0;j<10;j++);                      //tcy(L3) > 500ns
        }
        else                                            //if data's LSB is 'L'
        {
            g_pIOPregs->GPBDAT &= ~L3C;             //L3C=L
            g_pIOPregs->GPBDAT &= ~L3D;             //L3D=L
            for (j=0;j<10;j++);                      //tcy(L3) > 500ns
            g_pIOPregs->GPBDAT |= L3C;              //L3C=H
            g_pIOPregs->GPBDAT &= ~L3D;             //L3D=L
            for (j=0;j<10;j++);                      //tcy(L3) > 500ns
        }
        data >>=1;
    }
    g_pIOPregs->GPBDAT|=L3C|L3M;                    //L3M=H,L3C=H
}


void WriteL3Data(unsigned char data,int halt)
{
    int i,j;

    if (halt)
    {
        g_pIOPregs->GPBDAT|=L3C;                    //L3C=H(while tstp, L3 interface halt condition)
        for (j=0;j<10;j++);                       //tstp(L3) > 190ns
    }

    g_pIOPregs->GPBDAT|=L3C|L3M;                    //L3M=H(in data transfer mode)
    for (j=0;j<10;j++);                          //tsu(L3)D > 190ns

    //PD[8:6]=L3D:L3C:L3M
    for (i=0;i<8;i++)
    {
        if (data&0x1)                            //if data's LSB is 'H'
        {
            g_pIOPregs->GPBDAT &= ~L3C;             //L3C=L
            g_pIOPregs->GPBDAT |= L3D;          //L3D=H
            for (j=0;j<10;j++);                  //tcy(L3) > 500ns
            g_pIOPregs->GPBDAT |= (L3C|L3D);    //L3C=H,L3D=H
            for (j=0;j<10;j++);                  //tcy(L3) > 500ns
        }
        else            //if data's LSB is 'L'
        {
            g_pIOPregs->GPBDAT &= ~L3C;             //L3C=L
            g_pIOPregs->GPBDAT &= ~L3D;             //L3D=L
            for (j=0;j<10;j++);                  //tcy(L3) > 500ns
            g_pIOPregs->GPBDAT |= L3C;          //L3C=H
            g_pIOPregs->GPBDAT &= ~L3D;             //L3D=L
            for (j=0;j<10;j++);                  //tcy(L3) > 500ns
        }
        data>>=1;       //for check next bit
    }

    g_pIOPregs->GPBDAT|=L3C|L3M;                    //L3M=H,L3C=H
}

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

    g_pHWContext = new HardwareContext;
    if (!g_pHWContext)
    {
        return(FALSE);
    }

    return(g_pHWContext->Init(Index));
}

HardwareContext::HardwareContext()
: m_InputDeviceContext(), m_OutputDeviceContext()
{
    InitializeCriticalSection(&m_Lock);
    m_Initialized=FALSE;
}

HardwareContext::~HardwareContext()
{
    DeleteCriticalSection(&m_Lock);
}

BOOL HardwareContext::Init(DWORD Index)
{
    UINT32 Irq;

    if (m_Initialized)
    {
        return(FALSE);
    }

    // Call the OAL to translate the audio IRQ into a SYSINTR value.
    //
    Irq = IRQ_DMA2;  // audio output DMA interrupt.
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(UINT32), &m_dwSysintrOutput, sizeof(UINT32), NULL))
    {
        RETAILMSG(TRUE, (TEXT("ERROR: HardwareContext::Init: Failed to obtain sysintr value for output interrupt.\r\n")));
        return FALSE;
    }

    Irq = IRQ_DMA1;  // audio input DMA interrupt.
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(UINT32), &m_dwSysintrInput, sizeof(UINT32), NULL))
    {
        RETAILMSG(TRUE, (TEXT("ERROR: HardwareContext::Init: Failed to obtain sysintr value for input interrupt.\r\n")));
        return FALSE;
    }

    //----- 1. Initialize the state/status variables -----
    m_DriverIndex       = Index;
    m_InPowerHandler    = FALSE;
    m_InputDMARunning   = FALSE;
    m_OutputDMARunning  = FALSE;
    m_InputDMABuffer    = 0;
    m_OutputDMABuffer   = 0;

    //----- 2. Map the necessary descriptory channel and control registers into the driver's virtual address space -----
    if (!MapRegisters())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::Init() - Failed to map config registers.\r\n")));
        goto Exit;
    }

    //----- 3. Map the DMA buffers into driver's virtual address space -----
    if (!MapDMABuffers())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::Init() - Failed to map DMA buffers.\r\n")));
        goto Exit;
    }

    //----- 4. Configure the Codec -----
    m_dwOutputGain = 0xFFFFFFFF;
    m_dwInputGain  = 0xFFFFFFFF;
    m_fInputMute  = FALSE;
    m_fOutputMute = FALSE;

    PowerUp();

    //----- 5. Initialize the interrupt thread -----
    if (!InitInterruptThread())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::Init() - Failed to initialize interrupt thread.\r\n")));
        goto Exit;
    }

    m_Initialized=TRUE;

    Exit:
    return(m_Initialized);
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:               MapRegisters()

Description:    Maps the config registers used by both the SPI and
                                I2S controllers.

Notes:                  The SPI and I2S controllers both use the GPIO config
                                registers, so these MUST be initialized FIRST.

Returns:                Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::MapRegisters()
{

    // IIS registers.
    //
    g_pIISregs = (volatile S3C2410X_IISBUS_REG*)VirtualAlloc(0, sizeof(S3C2410X_IISBUS_REG), MEM_RESERVE, PAGE_NOACCESS);
    if (!g_pIISregs)
    {
        DEBUGMSG(1, (TEXT("IISreg: VirtualAlloc failed!\r\n")));
        return(FALSE);
    }
    if (!VirtualCopy((PVOID)g_pIISregs, (PVOID)(S3C2410X_BASE_REG_PA_IISBUS >> 8), sizeof(S3C2410X_IISBUS_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
    {
        DEBUGMSG(1, (TEXT("IISreg: VirtualCopy failed!\r\n")));
        return(FALSE);
    }

    // SPI registers.
    //
    g_pSPIregs = (volatile S3C2410X_SPI_REG*)VirtualAlloc(0, sizeof(S3C2410X_SPI_REG), MEM_RESERVE, PAGE_NOACCESS);
    if (!g_pSPIregs)
    {
        DEBUGMSG(1, (TEXT("SPIreg: VirtualAlloc failed!\r\n")));
        return(FALSE);
    }
    if (!VirtualCopy((PVOID)g_pSPIregs, (PVOID)(S3C2410X_BASE_REG_PA_SPI >> 8), sizeof(S3C2410X_SPI_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
    {
        DEBUGMSG(1, (TEXT("SPIreg: VirtualCopy failed!\r\n")));
        return(FALSE);
    }

    g_pIOPregs = (volatile S3C2410X_IOPORT_REG*)VirtualAlloc(0, sizeof(S3C2410X_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
    if (!g_pIOPregs)
    {
        DEBUGMSG(1, (TEXT("IOPreg: VirtualAlloc failed!\r\n")));
        return(FALSE);

⌨️ 快捷键说明

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