📄 btdriverstreamioctl.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 + -