📄 scope_control.cpp
字号:
//****************************************************************************
//
// Request transmission of the last data captured by the oscilloscope.
//
//****************************************************************************
bool ScopeControlDataRequest(void)
{
bool bRetcode;
if(devInfo.bCommunicating)
{
//
// Tell the oscilloscope to send us the last data captured.
//
bRetcode = SendScopePacket(SCOPE_PKT_RETRANSMIT, 0, 0);
return(bRetcode);
}
else
{
return(false);
}
}
//****************************************************************************
//
// Perform a blocking read of a waveform data set from the USB device. This
// function must not be called if operating in asynchronous mode (where a
// valid window handle was passed on ScopeControlInit()).
//
//****************************************************************************
bool ScopeControlReadData(tScopeDataStart *pStartInfo,
unsigned long *pulNumElements, void **ppvData)
{
unsigned char ucPacketCount;
unsigned char ucPacketType;
unsigned char ucParam;
unsigned long ulParam;
unsigned long ulDataLength;
unsigned long ulBlockSize;
unsigned long ulWritePos;
unsigned char *pcSamples;
bool bRetcode;
bool bErrorInSequence;
//
// Don't allow this operation if we are running in asynchronous mode
//
if(devInfo.hwndNotify)
{
return(false);
}
//
// Wait for a SCOPE_PKT_DATA_START packet. We throw away anything else
// we see while waiting.
//
while(1)
{
//
// Read a packet.
//
bRetcode = ScopeWaitPacket(&ucPacketType, &ucParam, &ulParam, &ulDataLength,
ppvData);
if(bRetcode)
{
//
// Was this a data start packet?
//
if(ucPacketType == SCOPE_PKT_DATA_START)
{
//
// Yes - copy the payload into the passed structure.
//
*pStartInfo = *(tScopeDataStart *)(*ppvData);
LocalFree(*ppvData);
//
// Allocate a buffer large enough for the data we are going to receive.
//
ulBlockSize = ulParam * (pStartInfo->bDualChannel ?
sizeof(tScopeDualDataElement) : sizeof(tScopeDataElement));
*ppvData = LocalAlloc(LMEM_FIXED, ulBlockSize);
*pulNumElements = ulParam;
//
// Did we get the buffer successfully?
//
if(!ppvData)
{
//
// Out of memory
//
return(false);
}
//
// Now read SCOPE_PKT_DATA packets and copy their payloads into our
// data buffer.
//
ulWritePos = 0;
ucPacketCount = 1;
bErrorInSequence = false;
while(ucPacketType != SCOPE_PKT_DATA_END)
{
//
// Read a packet.
//
bRetcode = ScopeWaitPacket(&ucPacketType, &ucParam,
&ulParam, &ulDataLength,
(void **)&pcSamples);
if(bRetcode)
{
//
// Is this a data packet? If it is, and we have not seen an error in the
// sequence already, go ahead and process it.
//
if((ucPacketType == SCOPE_PKT_DATA) && !bErrorInSequence)
{
//
// Check that the packet number is as expected.
//
if(ucPacketCount == ucParam)
{
//
// Copy the payload into our sample buffer.
//
memcpy((unsigned char *)(*ppvData) + ulWritePos, pcSamples,
ulDataLength);
ulWritePos += ulDataLength;
ucPacketCount++;
}
else
{
//
// Packet continuity counter showed an error. Read and
// discard everything to the end of the sequence.
//
bErrorInSequence = true;
}
}
//
// Free the data block if there was one in the last packet read.
//
if(pcSamples)
{
LocalFree(pcSamples);
}
}
}
//
// We got to the end of the data sequence. Did we see any errors?
//
if(bErrorInSequence)
{
//
// Yes - discard the data and report an error to the caller.
//
LocalFree(*ppvData);
return(false);
}
else
{
//
// The sequence was captured properly. Return the good news to
// the caller.
//
return(true);
}
}
else
{
//
// This wasn't a data start packet so free any payload we were passed and wait
// for the next packet.
//
if(*ppvData)
{
LocalFree(*ppvData);
*ppvData = NULL;
}
}
}
else
{
//
// We experienced an error reading a packet. Return to the caller.
//
return(false);
}
}
}
//****************************************************************************
//
// Request that the oscilloscope rescale and reposition one channel's
// waveform to ensure that it is visible on the display.
//
// \param ucChannel indicates the channel that is to be found, either
// SCOPE_CHANNEL_1 or SCOPE_CHANNEL_2.
//
//****************************************************************************
bool ScopeControlFind(unsigned char ucChannel)
{
bool bRetcode;
if(devInfo.bCommunicating)
{
//
// Tell the oscilloscope to send us the last data captured.
//
bRetcode = SendScopePacket(SCOPE_PKT_FIND, ucChannel, 0);
return(bRetcode);
}
else
{
return(false);
}
}
//****************************************************************************
//
// Returns the device path associated with a provided interface GUID.
//
// \param InterfaceGuid is a pointer to the GUID for the interface that
// we are looking for. Assuming you installed the device using the sample
// INF file, this will be the GUID provided in the Dev_AddReg section.
// \param pcDevicePath is a pointer to a buffer into which will be written
// the path to the device if the function is successful.
// \param BufLen is the size of the buffer pointed to by \f pcDevicePath.
//
// Given an interface GUID, this function determines the path that is
// necessary to open a file handle on the USB device we are interested in
// talking to. It returns the path to the first device which is present in
// the system and which offers the required interface.
//
// \return Returns one of the following Windows system error codes.
// ERROR_SUCCESS if the operation completed successfully
// ERROR_DEV_NOT_EXIST if the interface is not found on the system. This
// implies that the driver for the USB device has not been installed.
// ERROR_DEVICE_NOT_CONNECTED if the interface has been installed but no
// device offering it is presently available. This typically indicates
// that the USB device is not currently connected.
// ERROR_NOT_ENOUGH_MEMORY if the function fails to allocate any required
// buffers.
// ERROR_INSUFFICIENT_BUFFER if the buffer passed is too small to hold
// the device path.
//****************************************************************************
static DWORD GetDevicePath(LPGUID InterfaceGuid,
PCHAR pcDevicePath,
size_t BufLen)
{
BOOL bResult = FALSE;
HDEVINFO deviceInfo;
SP_DEVICE_INTERFACE_DATA interfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
ULONG length;
ULONG requiredLength=0;
HRESULT hr;
//
// Get a handle to the device information set containing information on
// the interface GUID supplied on this PC.
//
deviceInfo = SetupDiGetClassDevs(InterfaceGuid,
NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if(deviceInfo == INVALID_HANDLE_VALUE)
{
//
// No device offering the required interface is present. Has the
// interface been installed? Ask for the information set for all
// devices and not just those that are presently installed.
//
deviceInfo = SetupDiGetClassDevs(InterfaceGuid,
NULL, NULL,
DIGCF_DEVICEINTERFACE);
if(deviceInfo == INVALID_HANDLE_VALUE)
{
return(ERROR_DEV_NOT_EXIST);
}
else
{
SetupDiDestroyDeviceInfoList(deviceInfo);
return(ERROR_DEVICE_NOT_CONNECTED);
}
}
interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
//
// SetupDiGetClassDevs returned us a valid information set handle so we
// now query this set to find the find the first device offering the
// interface whose GUID was supplied.
//
bResult = SetupDiEnumDeviceInterfaces(deviceInfo,
NULL,
InterfaceGuid,
0,
&interfaceData);
if(bResult == FALSE)
{
//
// We failed to find the first matching device so tell the caller
// that no suitable device is connected.
//
return(ERROR_DEVICE_NOT_CONNECTED);
}
//
// Now that we have the interface information, we need to query details
// to retrieve the device path. First determine how much space we need to
// hold the detail information.
//
SetupDiGetDeviceInterfaceDetail(deviceInfo,
&interfaceData,
NULL, 0,
&requiredLength,
NULL);
//
// Allocate a buffer to hold the interface details.
//
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED,
requiredLength);
if(NULL == detailData)
{
SetupDiDestroyDeviceInfoList(deviceInfo);
return(ERROR_NOT_ENOUGH_MEMORY);
}
detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
length = requiredLength;
//
// Now call once again to retrieve the actual interface detail information.
//
bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo,
&interfaceData,
detailData,
length,
&requiredLength,
NULL);
if(FALSE == bResult)
{
SetupDiDestroyDeviceInfoList(deviceInfo);
LocalFree(detailData);
return(GetLastError());
}
//
// Copy the device path string from the interface details structure into
// the caller's buffer.
//
hr = StringCchCopy((LPTSTR)pcDevicePath,
BufLen,
(LPCTSTR)detailData->DevicePath);
if(FAILED(hr))
{
//
// We failed to copy the device path string!
//
SetupDiDestroyDeviceInfoList(deviceInfo);
LocalFree(detailData);
return(ERROR_INSUFFICIENT_BUFFER);
}
//
// Clean up and free locally allocated resources.
//
SetupDiDestroyDeviceInfoList(deviceInfo);
LocalFree(detailData);
return(ERROR_SUCCESS);
}
//****************************************************************************
//
// Opens the USB device and returns a file handle.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -