📄 btdriverstreamwrite.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"
//////////////////////////////////////////////////////////////////////
// BTWSSWrite: Write to TxFIFO until there's no more to write.
// Before writing data, we check how much space there are left in TxFIFO
//////////////////////////////////////////////////////////////////////
static DWORD
BTWSSWrite(PWSSBTCLIENT_CONTEXT ptrcc, PVOID buf,DWORD length)
{
DWORD amountWritten = 0;
PWSSBTCLIENT_CONTEXT extension = (PWSSBTCLIENT_CONTEXT)ptrcc;
for (int i = 0 ; i < 2 ; ++i) {
if((extension->currentTxBuffer == FIRST_TX_BUFFER && extension->firstTxBufferFull)
|| (extension->currentTxBuffer == SECOND_TX_BUFFER && extension->secondTxBufferFull)
|| (length == 0))
{
break;
}
DWORD thisWrite=0;
if(length > TXBUFFERSIZE) thisWrite = TXBUFFERSIZE;
else thisWrite = length;
//Write the first buffer
if(extension->currentTxBuffer == FIRST_TX_BUFFER)
{
WRITE_PORT_UCHAR(extension->ioBase + FIRST_TX_BUFFER_LENGTH_OFFSET,(BYTE)thisWrite);
for(DWORD j=0;j<thisWrite;j++)
{
WRITE_PORT_UCHAR(extension->ioBase + FIRST_TX_BUFFER_DATA_OFFSET + j,*((BYTE *)buf + j));
}
extension->currentTxBuffer = SECOND_TX_BUFFER;
extension->firstTxBufferFull = TRUE;
//Give the buffer to the FPGA
WRITE_PORT_UCHAR(extension->ioBase + CMD_REGISTER_OFFSET,START_FIRST_TX_BUFFER);
// DEBUGMSG(ZONE_INTERRUPT, (L"WCESTREAMBT:::::::::::::::::::TX1 %d bytes\n", thisWrite));
}
else
{
WRITE_PORT_UCHAR(extension->ioBase + SECOND_TX_BUFFER_LENGTH_OFFSET,(BYTE)thisWrite);
for(DWORD j=0;j<thisWrite;j++)
{
WRITE_PORT_UCHAR(extension->ioBase + SECOND_TX_BUFFER_DATA_OFFSET + j,*((BYTE *)buf + j));
}
extension->currentTxBuffer = FIRST_TX_BUFFER;
extension->secondTxBufferFull = TRUE;
//Give the buffer to the FPGA
WRITE_PORT_UCHAR(extension->ioBase + CMD_REGISTER_OFFSET,START_SECOND_TX_BUFFER);
// DEBUGMSG(ZONE_INTERRUPT, (L"WCESTREAMBT:::::::::::::::::::TX2 %d bytes\n", thisWrite));
}
buf = (BYTE *)buf + thisWrite;
length -= thisWrite;
amountWritten += thisWrite;
}
return amountWritten;
}
////////////////////////////////////////////////////////////
// BTWSSWrite: A user application wants to write data to us.
// Check if we can complete the request immediately, queue
// it otherwise
///////////////////////////////////////////////////////////
DWORD WBT_Write(DWORD dwOpenContext, LPCVOID pBuffer, DWORD dwNumBytes)
{
DEBUGMSG(ZONE_TRACE, (L"WceStreamBT: WBT_Write %d bytes\r\n", dwNumBytes));
PWSSBTCLIENT_CONTEXT pcc = (PWSSBTCLIENT_CONTEXT)dwOpenContext;
DWORD written = 0;
EnterCriticalSection (&g_CS);
int iTimeout = 0;
if ((pcc == g_pCC) && pcc->fDriverStarted)
{
if (pcc->fWriting)
{
DEBUGMSG(ZONE_ERROR, (L"WceStreamBT: another thread already writing\r\n"));
LeaveCriticalSection (&g_CS);
return 0xffffffff;
}
pcc->fWriting = TRUE;
iTimeout = pcc->CommTimeOuts.WriteTotalTimeoutConstant;
if (pcc->CommTimeOuts.WriteTotalTimeoutMultiplier != MAXDWORD)
iTimeout += pcc->CommTimeOuts.WriteTotalTimeoutMultiplier * dwNumBytes;
ASSERT (pcc->sendBuffer->DataAvailable() == 0);
DWORD empty = pcc->sendBuffer->GetEmptySpace();
if (empty < dwNumBytes)
{
// Overflow...
DEBUGMSG(ZONE_ERROR, (L"WceStreamBT: packet too big for TX buffer\r\n"));
LeaveCriticalSection (&g_CS);
return 0xffffffff;
}
pcc->sendBuffer->WriteData((BYTE *)pBuffer, dwNumBytes);
DEBUGMSG(ZONE_WRITE, (L"WceStreamBT: Write iteration: initiating content transfer\r\n"));
BTWSSWriteFromSendBuffer (pcc);
}
DWORD dwRes = WAIT_OBJECT_0;
for ( ; ; )
{
if ((pcc != g_pCC) || pcc->fOverflow || (! pcc->fDriverStarted))
{
DEBUGMSG(ZONE_ERROR, (L"WceStreamBT: Overflow detected or card removed. Failing the write.\r\n"));
dwNumBytes = 0xffffffff;
break;
}
if (pcc->sendBuffer->DataAvailable() == 0)
break;
if (dwRes == WAIT_TIMEOUT)
{
dwNumBytes -= pcc->sendBuffer->DataAvailable();
pcc->sendBuffer->Flush ();
break;
}
DEBUGMSG(ZONE_WRITE, (L"WceStreamBT: Write blocking for %d ms...\r\n", iTimeout));
HANDLE h = pcc->hWriteEvent;
pcc->iRefCnt++;
LeaveCriticalSection (&g_CS);
dwRes = WaitForSingleObject (h, iTimeout);
EnterCriticalSection (&g_CS);
if (pcc == g_pCC)
--pcc->iRefCnt;
}
if (pcc == g_pCC)
{
pcc->fWriting = FALSE;
}
LeaveCriticalSection (&g_CS);
DEBUGMSG(ZONE_WRITE, (L"WceStreamBT: Completing a write with %d bytes\r\n", dwNumBytes));
return dwNumBytes;
}
//////////////////////////////////////////////////////////////////////
// BTWSSWriteFromSendBuffer: Try writing from our sendBuffer
///////////////////////////////////////////////////////////////////////
void
BTWSSWriteFromSendBuffer(PWSSBTCLIENT_CONTEXT ptrcc)
{
DWORD dataLeft = ptrcc->sendBuffer->DataAvailable();
if (! dataLeft)
{
ptrcc->sendBuffer->Flush();
SetEvent (ptrcc->hWriteEvent);
return;
}
BYTE *data = ptrcc->sendBuffer->c_ptr(0,dataLeft);
if(data == NULL)
{
// Error...
ptrcc->fOverflow = TRUE;
SetEvent (ptrcc->hWriteEvent);
SetEvent (ptrcc->hReadEvent);
return;
}
DWORD written = BTWSSWrite(ptrcc,data,dataLeft);
ptrcc->sendBuffer->DropData(written);
dataLeft = ptrcc->sendBuffer->DataAvailable();
if(dataLeft == 0)
{
ptrcc->sendBuffer->Flush();
SetEvent (ptrcc->hWriteEvent);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -