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

📄 hciuart.cxx

📁 老外的一个开源项目
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) David Vescovi.  All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
// 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.
//
//------------------------------------------------------------------------------
// 
//      Bluetooth HCI UART interface
// 
// 
// Module Name:
// 
//      hciuart.cxx
// 
// Abstract:
// 
//      This file implements Bluetooth HCI UART interface for Gumstix
//		After reset Ericsson (ROK104001) module will default to 57600 baud
//		The Infineon (PBA31307) will default to 115200 baud.
//		If the com port registry setting is set to COM5 (BTUART) the
//		Infineon module is assumed, if COM4 (HWUART) the Ericsson is assumed
// 
// 
//------------------------------------------------------------------------------
#include <windows.h>

#include <bt_buffer.h>
#include <bt_hcip.h>
#include <bt_os.h>
#include <bt_debug.h>
#include <bt_tdbg.h>
#include "bsp.h"

static HANDLE hFile = INVALID_HANDLE_VALUE;
static HANDLE hWriteEvent = NULL;
static HANDLE hReadEvent = NULL;
static HCI_TransportCallback gCallback = NULL;

#define PACKET_SIZE_R		(64 * 1024 + 128)
#define PACKET_SIZE_W		(255 + 3)

#define DEFAULT_COM_NAME	L"COM4:"		// ROK ERICSSON radio
#define ALT_COM_NAME	    L"COM5:"		// BPA INFINEON radio

#define DEBUG_READ_BUFFER_HEADER	4
#define DEBUG_WRITE_BUFFER_HEADER	8
#define DEBUG_READ_BUFFER_TRAILER	1
#define DEBUG_WRITE_BUFFER_TRAILER	3

DECLARE_DEBUG_VARS();

// specific code for Ericsson module
unsigned char HCC_RESET[] = {01, 03,  0x0c,  00};
unsigned char HCC_INFINEON_READ_VERSION[] = {01, 05,  0xfc,  00};
BOOL Ericsson = TRUE;
#define EricssonBaudRatePos 4
#define InfineonBaudRatePos 5
#define HEAD_LEN 7
unsigned char HCC_ERICSSON_SET_BAUD_RATE[] = {0x01, 0x09, 0xfc,  0x01, 0x02};
unsigned char HCC_INFINEON_SET_BAUD_RATE[] = {0x01, 0x06, 0xfc,  0x02, 0x00, 0x70};
unsigned char HCC_READ_BT_ADDR[] = {0x01, 0x09, 0x01, 0x00};
static BOOL WriteCommPort (unsigned char *pBuffer, unsigned int cSize);

BOOL SendHCC(HANDLE commPort, unsigned char* pHCC, DWORD size)
{
	DWORD nWritten = 0;
	if(WriteFile(commPort, pHCC, size,  &nWritten, 0))
			return TRUE;
	IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:SendHCC-WriteFile Fail. GetLastError = 0x%08x\n", GetLastError ()));
	return FALSE;
}

BOOL ReadHCE(HANDLE commPort)
{
	DWORD nRead = 0;
	unsigned char received[10];
	ZeroMemory(received, sizeof(received));
	if(ReadFile(commPort, received, HEAD_LEN, &nRead, 0) && nRead)
	{
		return TRUE;
	}
	IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:ReadHCE-ReadFile Fail. GetLastError = 0x%08x\n", GetLastError ()));
	return FALSE;
}

BOOL UART_SetBaudRate(HANDLE commPort, DWORD dwBaudRate)
{
	DCB dcb;
	Sleep(1000);
	ZeroMemory(&dcb, sizeof(dcb));
	if(!GetCommState(commPort, &dcb))
	{
		IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:UART_SetBaudRate-GetCommState Fail. GetLastError = 0x%08x\n", GetLastError ()));
	}
	if (Ericsson)
	{
		if(SendHCC(commPort, HCC_RESET, sizeof(HCC_RESET)))
		{
			Sleep(100);
			if(!ReadHCE(commPort))
			{
				return FALSE;
			}
			PurgeComm(commPort,  PURGE_TXCLEAR | PURGE_RXCLEAR);
		}
		Sleep(100);
		switch(dwBaudRate)
		{
			case 57600:
				HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 3;
				break;
			case 115200:
				HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 2;
				break;
			case 230400:
				HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 1;
				break;
			case 460800:
				HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 0;
				break;
			case 921600:
				HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 0x20;
				break;
			default:
			{
				IFDBG(DebugOut (DEBUG_ERROR, L"Invalid Baud Rate : %d\n", dwBaudRate));
				return FALSE;
			}
		}

		if(SendHCC(commPort, HCC_ERICSSON_SET_BAUD_RATE, sizeof(HCC_ERICSSON_SET_BAUD_RATE)))
		{
			Sleep(100);
			if(ReadHCE(commPort))
			{
				PurgeComm(commPort,  PURGE_TXCLEAR | PURGE_RXCLEAR);
				//GetCommState(commPort, &dcb);
				dcb.BaudRate = dwBaudRate;
				if(SetCommState(commPort, &dcb))
				{
					RETAILMSG(1, (L"ROK104001 Bluetooth module at 921600\r\n"));
					return TRUE;
				}
				else
					IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:Failed SetCommState in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
			}
			else
				IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:HCC_ERICSSON_SET_BAUD_RATE return event fail\n"));
		}
		else
			IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:Send HCC_ERICSSON_SET_BAUD_RATE fail\n"));
	}
	else // Infineon
	{
		// detect which Infineon module we are using start at 115200 then try 921600
		if(SendHCC(commPort, HCC_INFINEON_READ_VERSION, sizeof(HCC_INFINEON_READ_VERSION)))
		{
			Sleep(50);
			if(ReadHCE(commPort))
			{

			}
			else
			{	// try 921600
				PurgeComm(commPort,  PURGE_TXCLEAR | PURGE_RXCLEAR);
				dcb.BaudRate = dwBaudRate;
				if(SetCommState(commPort, &dcb))
				{
					if(SendHCC(commPort, HCC_INFINEON_READ_VERSION, sizeof(HCC_INFINEON_READ_VERSION)))
					{
						Sleep(50);
						if(ReadHCE(commPort))
						{ // if we can read it we don't need to change it
							RETAILMSG(1, (L"PBA31308 Bluetooth module at 921600\r\n"));
							return TRUE;
						}
					}
				}
			}
		}
		PurgeComm(commPort,  PURGE_TXCLEAR | PURGE_RXCLEAR);
		IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:Failed SetCommState in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
	}
	return FALSE;
}		











//		switch(dwBaudRate)
//		{
//			case 57600:
//				HCC_INFINEON_SET_BAUD_RATE[InfineonBaudRatePos] = 0x1e;
//				break;
//			case 115200:
//				HCC_INFINEON_SET_BAUD_RATE[InfineonBaudRatePos] = 0x70;
//				break;
//			case 230400:
//				HCC_INFINEON_SET_BAUD_RATE[InfineonBaudRatePos] = 0x37;
//				break;
//			case 460800:
//				HCC_INFINEON_SET_BAUD_RATE[InfineonBaudRatePos] = 0x1b;
//				break;
//			case 921600:
//				HCC_INFINEON_SET_BAUD_RATE[InfineonBaudRatePos] = 0x0d;
//				break;
//			default:
//			{
//				IFDBG(DebugOut (DEBUG_ERROR, L"Invalid Baud Rate : %d\n", dwBaudRate));
//				return FALSE;
//			}
//		}
//
//		if(SendHCC(commPort, HCC_INFINEON_SET_BAUD_RATE, sizeof(HCC_INFINEON_SET_BAUD_RATE)))
//		{
//			Sleep(50);
//			if(ReadHCE(commPort))
//			{
//				PurgeComm(commPort,  PURGE_TXCLEAR | PURGE_RXCLEAR);
//				//GetCommState(commPort, &dcb);
//				dcb.BaudRate = dwBaudRate;
//				if(SetCommState(commPort, &dcb))
//				{
//					Sleep(100);
//					if(ReadHCE(commPort))
//					{
//						PurgeComm(commPort,  PURGE_TXCLEAR | PURGE_RXCLEAR);
//						return TRUE;
//					}
//					else
//						IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:Failed SetCommState in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
//				}
//				else
//					IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:Failed SetCommState in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
//			}
//			else
//				IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:HCC_INFINEON_SET_BAUD_RATE return event fail\n"));
//		}
//		else
//			IFDBG(DebugOut (DEBUG_ERROR, L"BthGum:Send HCC_INFINEON_SET_BAUD_RATE fail\n"));
//	}
//
//	return FALSE;
//}

BOOL HardwareRadio(BOOL TurnOn)
{
	PHYSETAdrInfo phySetAddr;

	phySetAddr.subcode = PHY_SET_ADDR;
	if (TurnOn)
		phySetAddr.address = PXA255_BASE_REG_PA_GPIO + offsetof(GPIO_REG_T, GPSR0);	// set register
	else
		phySetAddr.address = PXA255_BASE_REG_PA_GPIO + offsetof(GPIO_REG_T, GPCR0);	// clear register
	phySetAddr.value = GPIO_7_nBTRESET;
	phySetAddr.mask = GPIO_7_nBTRESET;
    if (!KernelIoControl(IOCTL_HAL_PHYADR, &phySetAddr, sizeof(PHYSETAdrInfo), NULL, 0, NULL))
    {
        // invalid IOCTL call!
		IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:-HardwareRadio (bad IOCTL radio on/off call)\n"));
		return FALSE;
	}
	return TRUE;
}

int HCI_ReadHciParameters (HCI_PARAMETERS *pParms) {
	if (pParms->uiSize < sizeof (*pParms))
		return FALSE;

	memset (pParms, 0, sizeof(*pParms));

	pParms->uiSize             = sizeof(*pParms);
	pParms->fInterfaceVersion  = HCI_INTERFACE_VERSION_1_1;
	pParms->iMaxSizeRead       = PACKET_SIZE_R;
	pParms->iMaxSizeWrite      = PACKET_SIZE_W;
	pParms->iWriteBufferHeader = 4;
	pParms->iReadBufferHeader  = 4;
	pParms->fHardwareVersion   = HCI_HARDWARE_VERSION_V_1_0_B;
	pParms->uiWriteTimeout     = HCI_DEFAULT_WRITE_TIMEOUT;
	pParms->uiFlags            = HCI_FLAGS_NORESET | HCI_FLAGS_NOROLESWITCH;

#if defined (DEBUG) || defined (_DEBUG)
	pParms->iReadBufferHeader   = DEBUG_READ_BUFFER_HEADER;
	pParms->iReadBufferTrailer  = DEBUG_READ_BUFFER_TRAILER;
	pParms->iWriteBufferHeader  = DEBUG_WRITE_BUFFER_HEADER;
	pParms->iWriteBufferTrailer = DEBUG_WRITE_BUFFER_TRAILER;
#endif

	return TRUE;
}

int HCI_StartHardware (void) {

	IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:+HCI_StartHardware\n"));

	if (! HardwareRadio(TRUE))
	{
		IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:-HCI_StartHardware (can't turn on)\n"));
		return FALSE;
	}

	if (hFile != INVALID_HANDLE_VALUE) {
		IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:-HCI_StartHardware (already started)\n"));
		return TRUE;
	}

	if (! gCallback) 
	{
		IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:-HCI_StartHardware (not registered)\n"));
		return FALSE;
	}

	return ERROR_SUCCESS == gCallback (DEVICE_UP, NULL);
}

int HCI_StopHardware (void) {

	IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:+HCI_StopHardware\n"));

	if (! HardwareRadio(FALSE))
	{
		IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:-HCI_StopHardware (can't turn off)\n"));
		return FALSE;
	}

	if (hFile == INVALID_HANDLE_VALUE) {
		IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:-HCI_StopHardware (already stopped)\n"));
		return TRUE;
	}

	if (! gCallback) {
		IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:-HCI_StopHardware (not registered)\n"));
		return FALSE;
	}

	return ERROR_SUCCESS == gCallback (DEVICE_DOWN, NULL);
}

int HCI_SetCallback (HCI_TransportCallback pfCallback) {
	gCallback = pfCallback;

	if (! HardwareRadio(TRUE))
		DebugDeInit();
	
	if (gCallback)
		DebugInit();
	else
		DebugDeInit();

	return ERROR_SUCCESS;
}

int HCI_OpenConnection (void) {
	IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthGum:HCI_OpenConnection - Started\n"));
	DWORD dwHardwareConfig;
	DWORD dwBytesReturned;

	if (hFile != INVALID_HANDLE_VALUE)
		return FALSE;

	WCHAR szComPortName[_MAX_PATH];
	DWORD dwBaud = 0;
	DWORD dwStartBaud = 57600;

	HKEY hk;
	if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_BASE, L"software\\microsoft\\bluetooth\\hci", 0, KEY_READ, &hk)) {
		DWORD dwType;

⌨️ 快捷键说明

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