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

📄 btdriverstreamioctl.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"
#include <windev.h>
#include <pegdser.h>

///////////////////////////////////////////////////////////////
// BTWSSSetBaudRate: Tell the PCCARD to change the baud rate
// for the serial communication
///////////////////////////////////////////////////////////////

static int BTWSSSetBaudRate(PWSSBTCLIENT_CONTEXT ptrcc, DWORD rate)
{
	DEBUGMSG(ZONE_TRACE, (L"WceStreamBT: BTWSSSetBaudRate (%d)\r\n", rate));

	// Disable RX

	BTWSSSetRTSState (ptrcc, FALSE);

	// Do the software part...
	unsigned char HCC_ERICSSON_SET_BAUD_RATE[] = {0x01, 0x09, 0xfc,  0x01, 0x00};
	
	switch(rate)
	{
	case 57600:
		HCC_ERICSSON_SET_BAUD_RATE[4] = 3;
		break;

	case 115200:
		HCC_ERICSSON_SET_BAUD_RATE[4] = 2;
		break;

	case 230400:
		HCC_ERICSSON_SET_BAUD_RATE[4] = 1;
		break;

	case 460800:
		HCC_ERICSSON_SET_BAUD_RATE[4] = 0;
		break;

	default:
		return FALSE;
	}

	LeaveCriticalSection (&g_CS);

	WBT_Write ((DWORD)ptrcc, HCC_ERICSSON_SET_BAUD_RATE, sizeof(HCC_ERICSSON_SET_BAUD_RATE));

	Sleep (500);

	EnterCriticalSection (&g_CS);

	if ((g_pCC != ptrcc) || (! g_pCC->fDriverStarted) || (g_pCC->fOverflow))
	{
		return FALSE;
	}

	// Now do the hardware part
	ptrcc->controlShadowRegister &= ~BAUD_RATE_BITMASK;//Zero out baudrate bits
	
	switch(rate)
	{
	case 57600:
		ptrcc->controlShadowRegister |= BAUD_RATE_57600_BITMASK;
		break;

	case 115200:
		ptrcc->controlShadowRegister |= BAUD_RATE_115200_BITMASK;
		break;

	case 230400:
		ptrcc->controlShadowRegister |= BAUD_RATE_230400_BITMASK;
		break;

	case 460800:
		ptrcc->controlShadowRegister |= BAUD_RATE_460800_BITMASK;
		break;

	default:
		return FALSE;
	}

	__try
	{
		WRITE_PORT_UCHAR(ptrcc->ioBase + CONTROL_REGISTER_OFFSET, ptrcc->controlShadowRegister  );
	} __except (1)
	{
		return FALSE;
	}

	// reenable RX
	BTWSSSetRTSState (ptrcc, TRUE);

	// Let the command soak in...
	LeaveCriticalSection (&g_CS);

	Sleep (500);

	EnterCriticalSection (&g_CS);

	if ((g_pCC != ptrcc) || (! g_pCC->fDriverStarted) || (g_pCC->fOverflow))
	{
		return FALSE;
	}

	// Clear the buffers
	ptrcc->sendBuffer->Flush ();
	ptrcc->receiveBuffer->Flush ();

	return TRUE;
}

////////////////////////////////////////////////////////////
// BTWSSDispatchIoctl: A user application sends ioctls to us.
///////////////////////////////////////////////////////////


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

BOOL WBT_IOControl(DWORD dwOpenContext, DWORD dwIoControlCode, PBYTE pInBuf, 
		 DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, 
		 PDWORD pBytesReturned)
{
	PWSSBTCLIENT_CONTEXT pcc = (PWSSBTCLIENT_CONTEXT)dwOpenContext;
	BOOL		retval = FALSE;

	DEBUGMSG(ZONE_TRACE, (L"WceStreamBT: WBT_IOControl code 0x%08x\r\n", dwIoControlCode));

	if (pOutBuf || nOutBufSize || (! pBytesReturned))
	{
		SetLastError (ERROR_INVALID_PARAMETER);
		return FALSE;
	}

	EnterCriticalSection (&g_CS);
	if ((pcc != g_pCC) || (! pcc->fDriverStarted))
	{
		LeaveCriticalSection (&g_CS);
		SetLastError (ERROR_DEVICE_NOT_CONNECTED);
		return FALSE;
	}

	// Switch on IO control code.
	switch (dwIoControlCode) 
	{
	case IOCTL_SERIAL_SET_QUEUE_SIZE:
		retval = TRUE;
		break;

	case IOCTL_SERIAL_SET_TIMEOUTS:
		if (nInBufSize != sizeof (COMMTIMEOUTS))
		{
			SetLastError (ERROR_INVALID_PARAMETER);
			break;
		}

		memcpy (&pcc->CommTimeOuts, pInBuf, sizeof (COMMTIMEOUTS));
		retval = TRUE;
		break;

	case IOCTL_SERIAL_SET_DCB: 
		{
			if (nInBufSize != sizeof(DCB))
			{
				SetLastError (ERROR_INVALID_PARAMETER);
				break;
			}

			DCB *pDCB = (DCB *)pInBuf;
			DWORD dwBaud = pDCB->BaudRate;

			retval = BTWSSSetBaudRate(pcc, dwBaud);

			if (! retval)
			{
				SetLastError (ERROR_INVALID_PARAMETER);
				break;
			}
		}
		break;

	case IOCTL_SERIAL_PURGE:
		{
			if (nInBufSize != sizeof(DWORD)) 
			{
				SetLastError (ERROR_INVALID_PARAMETER);
				break;
			}

			DWORD dwAction = *(DWORD *)pInBuf;

			if (dwAction & PURGE_RXABORT)
			{
				if (pcc->fReading)
				{
					pcc->fReading = FALSE;
					SetEvent (pcc->hReadEvent);
				}
			}

			if (dwAction & PURGE_TXABORT)
			{
				if (pcc->fWriting)
				{
					pcc->fWriting = FALSE;
					SetEvent (pcc->hWriteEvent);
				}
			}

			if (dwAction & PURGE_RXCLEAR)
			{
				pcc->receiveBuffer->Flush ();
			}

			if (dwAction & PURGE_TXCLEAR)
			{
				pcc->sendBuffer->Flush ();
			}

			retval = TRUE;
		}
		break;

	default: 
		SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
		break;
	}

	LeaveCriticalSection (&g_CS);

	*pBytesReturned = 0;
	return retval;
}

///////////////////////////////////////////////////////////////
// BTWSSResetCard: Perform a hardware reset
///////////////////////////////////////////////////////////////

int BTWSSResetCard(PWSSBTCLIENT_CONTEXT ptrcc)
{
	DEBUGMSG(ZONE_TRACE, (L"WceStreamBT: BTWSSResetCard\r\n"));

	__try
	{
		PWSSBTCLIENT_CONTEXT ext = (PWSSBTCLIENT_CONTEXT)ptrcc;

		//Turn off BT, disable interrupts
		ext->controlShadowRegister = (BT_ON_MASK * BT_OFF_FLAG) | (BT_RESET_MASK * BT_RESET_FLAG) |
						 (INTERRUPT_ENABLE_MASK * INT_DISABLE)
						| (CARD_RESET_MASK * CARD_RESET);
		
		WRITE_PORT_UCHAR(ext->ioBase + CONTROL_REGISTER_OFFSET,ext->controlShadowRegister);
		
		//Reset FPGA
		WRITE_PORT_UCHAR(ext->ioBase + CARD_RESET_OFFSET,CARD_RESET_MASK * CARD_RESET);

		//Reset all status flags and counters
		ext->currentRxBuffer = FIRST_RX_BUFFER;
		ext->currentTxBuffer = FIRST_TX_BUFFER;
		ext->firstTxBufferFull = FALSE;
		ext->secondTxBufferFull = FALSE;
		

		//Turn on FPGA
		WRITE_PORT_UCHAR(ext->ioBase + CARD_RESET_OFFSET,CARD_RESET_MASK * CARD_ON);

		//Turn on Rx
		RxInit(ext);
		
		//Turn on the BT, keep BT in reset, keep RTS off, keep interrupts disabled, set baudrate to 57600
		ext->controlShadowRegister = (BT_ON_MASK * BT_ON_FLAG) | (RTS_BIT_MASK * RTS_OFF_FLAG) | (BT_RESET_MASK * BT_RESET_FLAG) |
						(BT_RES_PU_MASK * BT_RES_PU_ON)| (INTERRUPT_ENABLE_MASK * INT_DISABLE)
						| (CARD_RESET_MASK * CARD_ON) | BAUD_RATE_57600_BITMASK;
		
		WRITE_PORT_UCHAR(ext->ioBase + CONTROL_REGISTER_OFFSET,ext->controlShadowRegister);

		Sleep(300);

		//Turn on the BT, drop BT reset, set RTS on, set interrupts enabled, set baudrate to 57600
		ext->controlShadowRegister = (BT_ON_MASK * BT_ON_FLAG) | (RTS_BIT_MASK * RTS_ON_FLAG) | (BT_RESET_MASK * BT_START_FLAG) |
						(BT_RES_PU_MASK * BT_RES_PU_ON)| (INTERRUPT_ENABLE_MASK * INT_ENABLE)
						| (CARD_RESET_MASK * CARD_ON) | BAUD_RATE_57600_BITMASK;
		
		WRITE_PORT_UCHAR(ext->ioBase + CONTROL_REGISTER_OFFSET,ext->controlShadowRegister);

		//Flush buffers
		ext->receiveBuffer->Flush();
		ext->sendBuffer->Flush();

		//Set the level when RTS should be enabled (15 bytes of seconf rx buffer) and number of stop bits to use
		WRITE_PORT_UCHAR(ext->ioBase + RX_CTRL_REGISTER_OFFSET,(15 << RTS_LEVEL_SHIFT_BITS) | 0); // 0 = stop bits
	} __except (1)
	{
		return FALSE;
	}

	return TRUE;
}

⌨️ 快捷键说明

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