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

📄 scope_control.cpp

📁 一个简单示波器的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// \param None.
//
// This function determines whether or not the required USB device is
// available and, if so, creates a file allowing access to it. The file
// handle is returned on success.
//
// \return Returns a valid file handle on success of INVALID_HANDLE_VALUE
// on failure. In cases of failure, GetLastError() can be called to determine
// the cause.
//
//****************************************************************************
static HANDLE OpenDevice(void)
{
    HANDLE hDev = NULL;
    char devicePath[MAX_DEVPATH_LENGTH];
    BOOL retVal;

    //
    // Get the path needed to open a file handle on our USB device.
    //
    retVal = GetDevicePath((LPGUID)&GUID_DEVINTERFACE_LUMINARY_SCOPE,
                           devicePath,
                           sizeof(devicePath));
    if(retVal != ERROR_SUCCESS)
    {
        SetLastError(retVal);
        return(INVALID_HANDLE_VALUE);
    }

    //
    // Open the file we will use to communicate with the device.
    //
    hDev = CreateFile((LPCTSTR)devicePath,
                      GENERIC_WRITE | GENERIC_READ,
                      FILE_SHARE_WRITE | FILE_SHARE_READ,
                      NULL,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                      NULL);

    return(hDev);
}

//****************************************************************************
//
// Determines that the required USB device is present, opens it and gathers
// required information to allow us to read and write it.
//
// \param pbDriverInstalled points to a variable which will be written with
// \b true if the driver for the device is found (even if the device itself
// is not connected or \b false if the driver is not installed.
//
// This function is called to initialize the USB device and perform one-off
// setup required to allocate handles allowing the application to read and
// write the device endpoints.
//
// \return Returns \e TRUE on success or \e FALSE on failure. In failing
// cases, GetLastError() can be called to determine the cause.
//
//****************************************************************************
static bool InitializeDevice(bool *pbDriverInstalled)
{
    BOOL bResult;
    WINUSB_INTERFACE_HANDLE usbHandle;
    USB_INTERFACE_DESCRIPTOR ifaceDescriptor;
    WINUSB_PIPE_INFORMATION pipeInfo;
    UCHAR speed;
    ULONG length;
    int i;

    //
    // Determine whether the USB device is present and, if so, generate a
    // file handle to allow access to it.
    //
    devInfo.deviceHandle = OpenDevice();
    if(devInfo.deviceHandle == INVALID_HANDLE_VALUE)
    {
        //
        // We were unable to access the device - return a failure.
        //
        devInfo.bInterfaceFound = (GetLastError() == ERROR_DEV_NOT_EXIST) ?
                                  false : true;
        *pbDriverInstalled = devInfo.bInterfaceFound ? true : false;
        return(FALSE);
    }
    else
    {
        //
        // If OpenDevice returns a handle then the interface is present
        // (driver is installed) and the device is connected.
        //
        *pbDriverInstalled = true;
        devInfo.bInterfaceFound = true;
    }

    //
    // The device is opened so we now initialize the WinUSB layer passing it
    // the device handle.
    //
    bResult = WinUsb_Initialize(devInfo.deviceHandle, &usbHandle);

    if(bResult)
    {
        //
        // If we managed to initialize the WinUSB layer, we now query the
        // device descriptor to determine the speed of the device.
        //
        devInfo.winUSBHandle = usbHandle;
        length = sizeof(UCHAR);
        bResult = WinUsb_QueryDeviceInformation(devInfo.winUSBHandle,
                                                DEVICE_SPEED,
                                                &length,
                                                &speed);
    }

    if(bResult)
    {
        //
        // If all is well, now query the interface descriptor. We ask for the
        // first interface only since, in the case of the generic bulk device,
        // this is all that is available.
        //
        devInfo.deviceSpeed = speed;
        bResult = WinUsb_QueryInterfaceSettings(devInfo.winUSBHandle,
                                                0,
                                                &ifaceDescriptor);
    }

    if(bResult)
    {
        //
        // We got the interface descriptor so now we enumerate the endpoints
        // to find the two we require - one bulk IN endpoint and one bulk OUT
        // endpoint.
        //
        for(i=0;i<ifaceDescriptor.bNumEndpoints;i++)
        {
            bResult = WinUsb_QueryPipe(devInfo.winUSBHandle, 0, (UCHAR) i,
                                      &pipeInfo);

            if((pipeInfo.PipeType == UsbdPipeTypeBulk) &&
                  USB_ENDPOINT_DIRECTION_IN(pipeInfo.PipeId))
            {
                devInfo.bulkInPipe = pipeInfo.PipeId;
            }
            else if((pipeInfo.PipeType == UsbdPipeTypeBulk) &&
                  USB_ENDPOINT_DIRECTION_OUT(pipeInfo.PipeId))
            {
                devInfo.bulkOutPipe = pipeInfo.PipeId;
            }
            else
            {
                //
                // Hmm... we found and endpoint that we didn't expect to see
                // on this interface. This tends to imply that there is a
                // mismatch between the device configuration and this
                // application so we will fail the call after setting an
                // appropriate error code for the caller to query.
                //
                SetLastError(ERROR_NOT_SAME_DEVICE);
                bResult = FALSE;
                break;
            }
        }
    }

    //
    // If we see an error reported, free any resources allocated prior to
    // returning.
    //
    if(bResult == FALSE)
    {
        TerminateDevice(&devInfo);
        return(false);
    }
    else
    {
        //
        // All is well.
        //
        return(true);
    }
}

//****************************************************************************
//
// Cleans up and free resources associated with the USB device communication
// prior to exiting the application.
//
// \param pDevice is a pointer to the device instance data whose resources
// are to be freed.
//
// This function should be called prior to exiting the application to free
// the resources allocated during InitializeDevice().
//
// \return Returns \e TRUE on success or \e FALSE on failure.
//
//****************************************************************************
static bool TerminateDevice(tDeviceInfo *pDevice)
{
    BOOL bRetcode = TRUE;
    BOOL bRetcode2 = TRUE;

    if(pDevice->winUSBHandle)
    {
        bRetcode = WinUsb_Free(pDevice->winUSBHandle);
    }

    if(pDevice->deviceHandle)
    {
        bRetcode2 = CloseHandle(pDevice->deviceHandle);
    }

    pDevice->bDeviceConnected = false;
    pDevice->winUSBHandle = 0;
    pDevice->deviceHandle = 0;

    if(bRetcode && bRetcode2)
    {
        return(true);
    }
    else
    {
        return(false);
    }
}

//****************************************************************************
//
// Sends a single packet and optional additional data to the oscilloscope
// device if it is connected.
//
// \param ucPacketType is the type of packet to send.
// \param ucParam is the packet-specific byte parameter.
// \param ulParam is the packet-specific word parameter.
// \param ulDataLength is the length of the optional packet payload in bytes.
// \param pvData is a pointer to the optional packet payload data.
//
// This function sends a single packet to the oscilloscope of it is currently
// connected. A packet comprises a tScopePacket header structure followed,
// optionally, by a block of data.
//
// \return Returns \e TRUE on success or \e FALSE on failure.
//
//****************************************************************************
static bool SendScopePacket(unsigned char ucPacketType,
                            unsigned char ucParam,
                            unsigned long ulParam,
                            unsigned long ulDataLength,
                            void *pData)
{
    BOOL bResult;
    ULONG ulWritten;
    tScopePacket sPacket;

    //
    // We only try to send the packet if we are currently communicating with the
    // device.
    //
    if(devInfo.bDeviceConnected)
    {
        //
        // Populate the packet header.
        //
        sPacket.ucVersion = SCOPE_PROTOCOL_VERSION_1;
        sPacket.ucHdrLength = sizeof(tScopePacket);
        sPacket.ucPacketType = ucPacketType;
        sPacket.ucParam = ucParam;
        sPacket.ulParam = ulParam;
        sPacket.ulDataLength = ulDataLength;

        //
        // Write the user's string to the device.
        //
        bResult = WinUsb_WritePipe(devInfo.winUSBHandle,
                                   devInfo.bulkOutPipe,
                                   (PUCHAR)&sPacket,
                                   sizeof(tScopePacket),
                                   &ulWritten,
                                   NULL);
        if((!bResult) || (ulWritten != sizeof(tScopePacket)))
        {
            return(FALSE);
        }
        else
        {
            //
            // If we have optional data to send, append it to the packet.
            //
            if(ulDataLength != 0)
            {
                bResult = WinUsb_WritePipe(devInfo.winUSBHandle,
                                           devInfo.bulkOutPipe,
                                           (PUCHAR)pData,
                                           ulDataLength,
                                           &ulWritten,
                                           NULL);
                if((!bResult) || (ulWritten != ulDataLength))
                {
                    return(FALSE);
                }
            }
        }

        //
        // We sent all the data successfully
        //
        return(TRUE);
    }

    //
    // The device is not connected so there is no point trying to send
    // the packet.
    //
    return(FALSE);
}

//****************************************************************************
//
// Reads a single packet and optional additional data from the oscilloscope,
// blocking until the packet is available.
//
// \param pucPacketType is storage for the type of packet read.
// \param pucParam is storage for the packet-specific byte parameter.
// \param pulParam is storage the packet-specific word parameter.
// \param pulDataLength is storage for the length of the optional packet
//        payload in bytes.
// \param ppData is storage for a pointer to the optional packet payload
//        data.
//
// This function blocks until a packet is received from the oscilloscope
// then returns information on the packet to the caller. If the packet
// contains an optional data block, this is copied into a buffer whose
// pointer is passed back to the caller.
//
// \note The caller is responsible for freeing the packet whose pointer is
// returned in *ppData in cases where this is not NULL. The pointer must be
// freed using a call to LocalFree().
//
// \return Returns \e TRUE on success or \e FALSE on failure.
//
//****************************************************************************
static bool ScopeWaitPacket(unsigned char *pucPacketType,
                            unsigned char *pucParam,
                            unsigned long *pulParam,
                            unsigned long *pulDataLength,
                            void **ppData)
{
    BOOL bResult;
    ULONG ulRead;
    tScopePacket sPacket;

    //
    // Only try to read if the device is connected.
    //
    if(devInfo.bDeviceConnected)
    {
        bResult = WinUsb_ReadPipe(devInfo.winUSBHandle,
                                  devInfo.bulkInPipe,
                                  (PUCHAR)&sPacket,
                                  sizeof(tScopePacket),
                                  &ulRead,
                                  NULL);
        if((!bResult) || (ulRead != sizeof(tScopePacket)))
        {
            //
            // An error occurred trying to read the packet.
            //
            return(FALSE);
        }
        else
        {
            //
            // We got the scope packet header. Make sure that the
            // protocol and size fields are as expected.
            //
            if((sPacket.ucVersion == SCOPE_PROTOCOL_VERSION_1) &&
                (sPacket.ucHdrLength == sizeof(tScopePacket)))
            {
                //
                // Packet header seems fine. Do we have any optional data to read?
                //
                if(sPacket.ulDataLength != 0)
                

⌨️ 快捷键说明

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