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

📄 scope_control.cpp

📁 一个简单示波器的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

//****************************************************************************
//
// 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 + -