📄 btdriverstreaminterrupt.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include "BTDriverStream.h"
///////////////////////////////////////////////////////////////////
// HandleInterrupts: Handle the interrupt
//////////////////////////////////////////////////////////////////
static void
AcknowledgeInterrupt (PWSSBTCLIENT_CONTEXT ptrcc, UCHAR mask)
{
__try
{
WRITE_PORT_UCHAR(ptrcc->ioBase + INTERRUPT_REGISTER_OFFSET,mask);
} __except (1)
{
}
}
static void
HandleInterrupts(PWSSBTCLIENT_CONTEXT ptrcc, BYTE reason)
{
if(reason & INTERRUPT_REASON_TX)
{
if(reason & FIRST_TX_BUFFER_EMPTY)
{
ptrcc->firstTxBufferFull = FALSE;
AcknowledgeInterrupt (ptrcc, FIRST_TX_BUFFER_EMPTY);
// DEBUGMSG(ZONE_INTERRUPT, (L"WCESTREAMBT:::::::::::::::::::TX1 EMPTY\n"));
}
if(reason & SECOND_TX_BUFFER_EMPTY)
{
ptrcc->secondTxBufferFull = FALSE;
AcknowledgeInterrupt (ptrcc, SECOND_TX_BUFFER_EMPTY);
// DEBUGMSG(ZONE_INTERRUPT, (L"WCESTREAMBT:::::::::::::::::::TX2 EMPTY\n"));
}
//New way
if(ptrcc->sendBuffer->DataAvailable() > 0)
{
BTWSSWriteFromSendBuffer(ptrcc);
}
}
if(reason & RX_BUFFER_OVERRUN)
{
AcknowledgeInterrupt (ptrcc, RX_BUFFER_OVERRUN);
// Die...
ptrcc->fOverflow = TRUE;
SetEvent (ptrcc->hWriteEvent);
SetEvent (ptrcc->hReadEvent);
DEBUGMSG(ZONE_ERROR, (L"WceStramBT: RX buffer overrun\r\n"));
}
}
/////////////////////////////////////////////////////////
// InterruptServiceRoutine: When an interrupt occur this function gets
// called by the system. We check if it is our interrupt, and
// queue our DPC if it is.
///////////////////////////////////////////////////////////
#if defined (DEBUG)
// Must be divisible by 5
#define IRQ_BUF_SIZE 20
static unsigned char irq_buff[IRQ_BUF_SIZE];
static int irq_count = 0;
#endif
BOOLEAN
InterruptServiceRoutine(
PVOID ServiceContext
)
{
PWSSBTCLIENT_CONTEXT extension = (PWSSBTCLIENT_CONTEXT)ServiceContext;
EnterCriticalSection (&g_CS);
if ((extension != g_pCC) || (! extension->fDriverStarted) || (extension->identifier != OURIDENTIFIER))
{
LeaveCriticalSection (&g_CS);
return FALSE;
}
//Disable interrupts
DisableInterrupts(extension);
for (int i = 0 ; i < 4 ; ++i)
{
BYTE reason = 0;
__try
{
reason = READ_PORT_UCHAR(extension->ioBase + INTERRUPT_REGISTER_OFFSET);
} __except (1)
{
reason = 0;
}
#if defined (DEBUG)
if (ZONE_INTERRUPTS)
{
PREFAST_ASSERT(irq_count < IRQ_BUF_SIZE);
irq_buff[irq_count++] = reason;
if (irq_count == IRQ_BUF_SIZE)
{
for (int j = 0 ; j < IRQ_BUF_SIZE ; j += 5)
{
DEBUGMSG(ZONE_INTERRUPTS, (L"WceStreamBT: IRQ: %02x %02x %02x %02x %02x\r\n",
irq_buff[j], irq_buff[j+1], irq_buff[j+2], irq_buff[j+3], irq_buff[j+4]));
}
irq_count = 0;
}
}
#endif
if ((reason & (RX_BUFFER_OVERRUN | INTERRUPT_REASON_TX | INTERRUPT_REASON_RX)) == 0)
break;
if(reason & INTERRUPT_REASON_RX)
{
BTWSSInterruptRead(extension, reason);
}
else
{
//Other interrupt reasons
HandleInterrupts (extension, reason);
}
}
//enable the interrupts
EnableInterrupts(extension);
LeaveCriticalSection (&g_CS);
if (i > 0)
BTWSSLedBlink ();
return TRUE;
}
///////////////////////////////////////////////////////////////////
// EnableInterrupts: Tell the PCCARD that we are interested in interrupts again
//////////////////////////////////////////////////////////////////
void
EnableInterrupts(PWSSBTCLIENT_CONTEXT ptrcc)
{
ptrcc->controlShadowRegister &= ~INTERRUPT_ENABLE_MASK;
ptrcc->controlShadowRegister |=( INT_ENABLE * INTERRUPT_ENABLE_MASK);
__try
{
WRITE_PORT_UCHAR(ptrcc->ioBase + CONTROL_REGISTER_OFFSET, ptrcc->controlShadowRegister);
} __except (1)
{
}
}
///////////////////////////////////////////////////////////////////
// DisableInterrupts: Tell the PCCARD that we are not currently interested in interrupts
//////////////////////////////////////////////////////////////////
void
DisableInterrupts(PWSSBTCLIENT_CONTEXT ptrcc)
{
ptrcc->controlShadowRegister &= ~INTERRUPT_ENABLE_MASK;
ptrcc->controlShadowRegister |=( INT_DISABLE * INTERRUPT_ENABLE_MASK);
__try
{
WRITE_PORT_UCHAR(ptrcc->ioBase + CONTROL_REGISTER_OFFSET, ptrcc->controlShadowRegister);
} __except (1)
{
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -