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

📄 btdriverstreaminterrupt.cpp

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 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 + -