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

📄 hwctxt.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.
//
//------------------------------------------------------------------------------
//

#include "wavemain.h"
#include "nkintr.h"

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

HardwareContext *g_pHWContext=NULL;

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


static void CallInterruptThreadTx(HardwareContext *pHWContext);
static void CallInterruptThreadRx(HardwareContext *pHWContext);
static void CallTimeoutThread(HardwareContext *pHWContext);

//#undef DEBUGMSG
//#define DEBUGMSG(x, y) RETAILMSG(1,y)

//------------------------------------------------------------------------------
//
//  Function: HardwareContext::HardwareContext()
//  
//  HardwareContext constructor. 
//

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

    m_hParent = NULL;
    m_CurPowerState = PwrDeviceUnspecified ;

    m_hAudioInterruptThreadRx = NULL;
    m_hAudioInterruptThreadTx = NULL;
    m_hTimeoutThread = NULL;
    
    m_fRequestedSysIntr = FALSE;
    m_IntrAudioRx = m_IntrAudioTx = SYSINTR_UNDEFINED ;
    m_fRxInterruptIntialized = m_fTxInterruptIntialized = FALSE;

    m_hTimeoutEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
    m_hAudioInterruptTx = CreateEvent( NULL, FALSE, FALSE, NULL);
    m_hAudioInterruptRx = CreateEvent( NULL, FALSE, FALSE, NULL);
    
}

//------------------------------------------------------------------------------
//
//  Function: HardwareContext::~HardwareContext()
//  
//  destructor
//

HardwareContext::~HardwareContext()
{
    m_fTerminating = TRUE;

    if (m_hTimeoutEvent!=NULL)
        SetEvent(m_hTimeoutEvent);
    if (m_hAudioInterruptTx!=NULL)
        SetEvent(m_hAudioInterruptTx);
    if (m_hAudioInterruptRx)
        SetEvent(m_hAudioInterruptRx);
    
    Sleep(500); // Sleep 500 ticks to allow all thread terminated.
    TerminateCloseThread(m_hAudioInterruptThreadTx);
    TerminateCloseThread(m_hAudioInterruptThreadRx);
    TerminateCloseThread(m_hTimeoutThread);
    
    if (m_fRxInterruptIntialized)
        InterruptDisable(m_IntrAudioRx);  
    if (m_fTxInterruptIntialized)
        InterruptDisable(m_IntrAudioTx);   
    
    if (m_IntrAudioTx != SYSINTR_UNDEFINED && m_fRequestedSysIntr) {
        KernelIoControl( IOCTL_HAL_RELEASE_SYSINTR,&m_IntrAudioTx, sizeof( m_IntrAudioTx ), NULL,  0,  NULL );
    }
    if (m_IntrAudioRx != SYSINTR_UNDEFINED && m_fRequestedSysIntr) {
        KernelIoControl( IOCTL_HAL_RELEASE_SYSINTR,&m_IntrAudioRx, sizeof( m_IntrAudioRx ), NULL,  0,  NULL );
    }
    if (m_hTimeoutEvent)
        CloseHandle(m_hTimeoutEvent);

    if (m_hParent ) {
        SetDevicePowerState(m_hParent, D4 , NULL);
        CloseBusAccessHandle (m_hParent ) ;
    }
    DeleteCriticalSection(&m_Lock);
}
void HardwareContext::TerminateCloseThread(HANDLE hThread)
{
    if (hThread) {
        if( ::WaitForSingleObject( hThread, 0 ) != WAIT_OBJECT_0 ) // Can't terminate. Force it.
            ::TerminateThread( hThread, ( DWORD ) - 1 ) ;
        ::CloseHandle( hThread );
    }
}

//------------------------------------------------------------------------------
//
//  Function: Init
//  
//  map registers, allocate DMA buffers, set hardware to known state
//

BOOL 
HardwareContext::Init(DWORD Index)
{
    DEBUGMSG(ZONE_AC,(TEXT("WAVEDEV: HardwareContext::Init Index=0x%x\r\n"), Index));

    if (m_Initialized)
    {
        return FALSE;
    }

    m_hParent           = CreateBusAccessHandle((LPCTSTR) Index) ;

    m_DriverIndex       = Index;
    m_InPowerHandler    = FALSE;
    m_InputDMARunning   = FALSE;
    m_OutputDMARunning  = FALSE;
    m_NumForcedSpeaker  = 0;

    m_bDMARunning       = FALSE;
    m_bBtHeadsetSelected= FALSE;
    m_dwBtAudioRouting  = BT_AUDIO_MODEM;
    m_bHeadsetPluggedIn = FALSE;    
    m_bToggleLoadSpeaker= FALSE;   
    m_hRil              = NULL;                 
    
    // Map registers and the DMA buffers into driver's virtual address space
    if (!InitMemories())
    {
        goto Exit;
    }

    // Init codec.
    InitCodec();

    // Configure the DMA controller
    InitDMA();

    // Configure the controller
    InitController();

    if (!InitInterruptThread())
    {
        goto Exit;
    }

    m_Initialized=TRUE;

Exit:
    return m_Initialized;
}

//------------------------------------------------------------------------------
//
//  Function: InitMemories()
//  
//  Map DMA pages into the local address space
//

BOOL 
HardwareContext::InitMemories()
{
    PBYTE pbDMABufIn, pbDMABufOut;

    if (!HWMapControllerRegs ())
    {
        goto ErrExit;
    }

    if (HWMapDMAMemory(AUDIO_DMA_PAGE_SIZE*AUDIO_DMA_PAGES*2))
    {
        pbDMABufIn  = HWDMAMemoryIn(); 
        pbDMABufOut = HWDMAMemoryOut();

        // Save pointers to the virtual addresses so the driver can access them
        for (int i=0; i<AUDIO_DMA_PAGES; i++)
        {
            m_Output_pbDMA_PAGES[i] = pbDMABufOut + AUDIO_DMA_PAGE_SIZE*i;
            m_Input_pbDMA_PAGES[i]  = pbDMABufIn + ((AUDIO_DMA_PAGES+i)*AUDIO_DMA_PAGE_SIZE);
        }

        return TRUE;

    }

ErrExit:

    return FALSE;

}

//------------------------------------------------------------------------------
//
//  Function: InitDMA()
//  
//  set DMA registers to known state
//

void 
HardwareContext::InitDMA()
{
    HWInitInputDMA();
    HWInitOutputDMA();
}

//------------------------------------------------------------------------------
//
//  Function: InitController()
//  
//  
//

void 
HardwareContext::InitController()
{
    HWInitController();
    HWInitNetwork();
}

//------------------------------------------------------------------------------
//
//  Function: InitCodec()
//  
//
//

void 
HardwareContext::InitCodec()
{
    HWInitCodec();
}


//------------------------------------------------------------------------------
//
//  Function: StartOutputDMA()
//  
//  start output DMA on first call and transfer data to DMA buffers
//

void 
HardwareContext::StartOutputDMA()
{
    if (!m_OutputDMARunning)
    {
        // Set output dma to running state in case we get 
        // reentered during TransferOutputBuffer
        m_OutputDMARunning=TRUE;
        
        // Prime the output buffer and turn on DMA if anything got transferred
        ULONG OutputTransferred;
        OutputTransferred = TransferOutputBuffer(0)+TransferOutputBuffer(1);

        // If we didn't transfer any data to the DMA buffers, don't enable DMA
        if (OutputTransferred==0)
        {
            m_OutputDMARunning=FALSE;
            return;
        }

        m_bDMARunning = TRUE;
        
        HWUpdateAudioPRC ();
        HWStartOutputDMA();
    }
}

//------------------------------------------------------------------------------
//
//  Function: StopOutputDMA()
//  
//  stop output DMA and adjust power state
//

void 
HardwareContext::StopOutputDMA()
{
    if (m_OutputDMARunning)
    {
        m_OutputDMARunning=FALSE;
        HWStopOutputDMA();

        if (!m_InputDMARunning && !m_OutputDMARunning)
        {
            // Take care of power management.
            m_bDMARunning = FALSE;
            SetupDelayUpdate ();
        }
    }
}
//------------------------------------------------------------------------------
//
//  Function: StartInputDMA()
//  
//  start wave capture DMA, adjust power state and route audio to modem input
//

void 
HardwareContext::StartInputDMA()
{
    if (!m_InputDMARunning)
    {
#ifdef INPUT_CACHEDMEM
        InputBufferCacheDiscard( m_Input_pbDMA_PAGES[0],AUDIO_DMA_PAGE_SIZE*2);
#endif
        m_InputDMARunning=TRUE;

        m_bDMARunning = TRUE;
        HWUpdateAudioPRC ();
        
        // Turn on the recording path.
        SetRecordMemoPath (TRUE);

        HWStartInputDMA();
    }
}

//------------------------------------------------------------------------------
//
//  Function: StopInputDMA()
//  
//  stop capture DMA and switch off modem input
//

void 
HardwareContext::StopInputDMA()
{
    if (m_InputDMARunning)
    {
        m_InputDMARunning=FALSE;
        
        HWStopInputDMA();

        // Turn off the recording path.
        SetRecordMemoPath (FALSE);

        if (!m_InputDMARunning && !m_OutputDMARunning)
        {
            // Take care of power management.
            m_bDMARunning = FALSE;
            SetupDelayUpdate ();
        }
    }
}

void  HardwareContext::SetupDelayUpdate()
{
    SetEvent(m_hTimeoutEvent);
}
void  HardwareContext::DelayedUpdate()
{
    HWAudioPowerTimeout(TRUE); // Timeout.
}

//------------------------------------------------------------------------------
//
//  Function: GetInterruptThreadPriority()
//  
//  allow registry key to override priority of interrupt threads
//


void  
HardwareContext::GetRegistryValue()
{
    HKEY hDevKey;
    m_dwPriority256 = 210; // Default priority
    m_dwTimeoutTicks = 1000;    // 1 second.
    hDevKey = OpenDeviceKey((LPWSTR)m_DriverIndex);
    if (hDevKey)
    {
        DWORD dwValType;
        DWORD dwValLen;
        dwValLen = sizeof(DWORD);
        RegQueryValueEx(
                       hDevKey,
                       TEXT("Priority256"),
                       NULL,
                       &dwValType,
                       (PUCHAR)&m_dwPriority256,
                       &dwValLen);
        
        dwValLen = sizeof(DWORD);
        RegQueryValueEx(
                       hDevKey,
                       TEXT("SuspendDelayTicks"),
                       NULL,
                       &dwValType,
                       (PUCHAR)&m_dwTimeoutTicks,
                       &dwValLen);
        if (m_dwTimeoutTicks == 0 )
            m_dwTimeoutTicks = INFINITE;
        
        RegCloseKey(hDevKey);
    }

}

//------------------------------------------------------------------------------
//
//  Function: MapIrqToSysIntr()
//  
//  get dynamic mapping of hardware irq to software sysintr
//

DWORD 
HardwareContext::MapIrqToSysIntr(DWORD irq)
{
    DWORD dwSysIntr = SYSINTR_UNDEFINED;
    if (!KernelIoControl(
            IOCTL_HAL_REQUEST_SYSINTR, 
            &irq, 
            sizeof(irq), 
            &dwSysIntr,
            sizeof(dwSysIntr),
            NULL)) 
    {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("WaveDev: IRQ -> SYSINTR translation failed\r\n")));
        dwSysIntr = SYSINTR_UNDEFINED;
    }

    return dwSysIntr;
}

//------------------------------------------------------------------------------
//
//  Function: InitInterruptThread()
//  
//  start interrupt threads and map hardware interrupts to IST
//

BOOL 
HardwareContext::InitInterruptThread()
{
    DEBUGMSG(ZONE_AC, 
       (TEXT("WaveDev: HardwareContext::InitInterruptThread\r\n")));

    if ( !(m_hTimeoutEvent !=NULL &&  m_hAudioInterruptTx !=NULL &&  m_hAudioInterruptRx !=NULL))
        return FALSE;

    GetRegistryValue();

    m_fRequestedSysIntr    = TRUE;
    m_IntrAudioTx = MapIrqToSysIntr(AUDIO_OUTPUT_DMA_IRQ);
    m_IntrAudioRx = MapIrqToSysIntr(AUDIO_INPUT_DMA_IRQ);
    if (m_IntrAudioTx == SYSINTR_UNDEFINED ||
        m_IntrAudioRx == SYSINTR_UNDEFINED)
    {
        return FALSE;
    }

    m_fRxInterruptIntialized = InterruptInitialize(m_IntrAudioTx, m_hAudioInterruptTx, NULL, 0);
    m_fTxInterruptIntialized  = InterruptInitialize(m_IntrAudioRx, m_hAudioInterruptRx, NULL, 0);
    
    if (!m_fRxInterruptIntialized || !m_fTxInterruptIntialized)
        return FALSE ;


    m_hAudioInterruptThreadTx  = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
                                            0,
                                            (LPTHREAD_START_ROUTINE)CallInterruptThreadTx,
                                            this,
                                            0,

⌨️ 快捷键说明

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