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

📄 usbddriver.c

📁 ATmel的AT91sam7SE芯片 USB固件开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting);
        }

        // Acknowledge the request
        USBD_Write(0, 0, 0, 0, 0);
    }
}

//------------------------------------------------------------------------------
/// Sends the currently active setting of the given interface to the USB
/// host. If alternate settings are not supported, this function STALLs the
/// control pipe.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param infnum  Interface number.
//------------------------------------------------------------------------------
static void GetInterface(
    const USBDDriver *pDriver,
    unsigned char infnum)
{
    // Make sure alternate settings are supported, or STALL the control pipe
    if (!pDriver->pInterfaces) {

        USBD_Stall(0);
    }
    else {

        // Sends the current interface setting to the host
        USBD_Write(0, &(pDriver->pInterfaces[infnum]), 1, 0, 0);
    }
}

#ifdef BOARD_USB_UDPHS
//------------------------------------------------------------------------------
// Performs the selected test on the USB device (high-speed only).
// \param test  Test selector value.
//------------------------------------------------------------------------------
static void USBDDriver_Test(unsigned char test)
{
    trace_LOG(trace_DEBUG, "UDPHS_Test\n\r");

    // the lower byte of wIndex must be zero
    // the most significant byte of wIndex is used to specify the specific test mode
    switch (test) {
        case USBFeatureRequest_TESTPACKET:
            //Test mode Test_Packet: 
            //Upon command, a port must repetitively transmit the following test packet until
            //the exit action is taken. This enables the testing of rise and fall times, eye 
            //patterns, jitter, and any other dynamic waveform specifications.
            //The test packet is made up by concatenating the following strings. 
            //(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one 
            //transmitted. 揝?indicates that a bit stuff occurs, which inserts an 揺xtra?NRZI data bit. 
            //? N?is used to indicate N occurrences of a string of bits or symbols.)
            //A port in Test_Packet mode must send this packet repetitively. The inter-packet timing 
            //must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and 
            //no greater than 125 us.
            // Send ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            // Tst PACKET
            USBD_Test(USBFeatureRequest_TESTPACKET);
            while (1);
            break;

        case USBFeatureRequest_TESTJ:
            //Test mode Test_J:
            //Upon command, a port抯 transceiver must enter the high-speed J state and remain in that
            //state until the exit action is taken. This enables the testing of the high output drive
            //level on the D+ line.
            // Send ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            // Tst J
            USBD_Test(USBFeatureRequest_TESTJ);
            while (1);
            break;

        case USBFeatureRequest_TESTK:
            //Test mode Test_K:
            //Upon command, a port抯 transceiver must enter the high-speed K state and remain in
            //that state until the exit action is taken. This enables the testing of the high output drive
            //level on the D- line.
            // Send a ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            USBD_Test(USBFeatureRequest_TESTK);
            while (1);
            break;

        case USBFeatureRequest_TESTSE0NAK:
            //Test mode Test_SE0_NAK:
            //Upon command, a port抯 transceiver must enter the high-speed receive mode
            //and remain in that mode until the exit action is taken. This enables the testing
            //of output impedance, low level output voltage, and loading characteristics.
            //In addition, while in this mode, upstream facing ports (and only upstream facing ports)
            //must respond to any IN token packet with a NAK handshake (only if the packet CRC is
            //determined to be correct) within the normal allowed device response time. This enables testing of
            //the device squelch level circuitry and, additionally, provides a general purpose stimulus/response
            //test for basic functional testing.
            USBD_Test(USBFeatureRequest_TESTSE0NAK);
            // Send a ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            while (1);
            break;

        default:
            USBD_Stall( 0 );
            break;

    }
    // The exit action is to power cycle the device.
    // The device must be disconnected from the host
}
#endif

//------------------------------------------------------------------------------
//      Exported functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Initializes a USBDDriver instance with a list of descriptors. If
/// interfaces can have multiple alternate settings, an array to store the
/// current setting for each interface must be provided.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param pDescriptors  Pointer to a USBDDriverDescriptors instance.
/// \param pInterfaces  Pointer to an array for storing the current alternate
///                     setting of each interface (optional).
//------------------------------------------------------------------------------
void USBDDriver_Initialize(
    USBDDriver *pDriver,
    const USBDDriverDescriptors *pDescriptors,
    unsigned char *pInterfaces)
{

    pDriver->cfgnum = 0;
#if (BOARD_USB_BMATTRIBUTES == USBConfigurationDescriptor_SELFPOWERED_RWAKEUP) \
    || (BOARD_USB_BMATTRIBUTES == USBConfigurationDescriptor_BUSPOWERED_RWAKEUP)
    pDriver->isRemoteWakeUpEnabled = 1;
#else
    pDriver->isRemoteWakeUpEnabled = 0;
#endif

    pDriver->pDescriptors = pDescriptors;
    pDriver->pInterfaces = pInterfaces;

    // Initialize interfaces array if not null
    if (pInterfaces != 0) {
    
        memset(pInterfaces, sizeof(pInterfaces), 0);
    }
}

//------------------------------------------------------------------------------
/// Handles the given request if it is standard, otherwise STALLs it.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param pRequest  Pointer to a USBGenericRequest instance.
//------------------------------------------------------------------------------
void USBDDriver_RequestHandler(
    USBDDriver *pDriver,
    const USBGenericRequest *pRequest)
{
    unsigned char cfgnum;
    unsigned char infnum;
    unsigned char eptnum;
    unsigned char setting;
    unsigned char type;
    unsigned char index;
    unsigned int length;
    unsigned int address;

    trace_LOG(trace_INFO, "Std ");
    
    // Check request code
    switch (USBGenericRequest_GetRequest(pRequest)) {

        case USBGenericRequest_GETDESCRIPTOR:
            trace_LOG(trace_INFO, "Get Descriptor\n");
            
            // Send the requested descriptor
            type = USBGetDescriptorRequest_GetDescriptorType(pRequest);
            index = USBGetDescriptorRequest_GetDescriptorIndex(pRequest);
            length = USBGenericRequest_GetLength(pRequest);
            GetDescriptor(pDriver, type, index, length);
            break;

        case USBGenericRequest_SETADDRESS:
            trace_LOG(trace_INFO, "set address\n");
            
            // Sends a zero-length packet and then set the device address
            address = USBSetAddressRequest_GetAddress(pRequest);

            if( USBD_IsHighSpeed() ) {

                USBD_SetAddress( address );
            }
            else {
                USBD_Write(0, 0, 0, (TransferCallback) USBD_SetAddress, (void *) address);
            }
            break;

        case USBGenericRequest_SETCONFIGURATION:
            trace_LOG(trace_INFO, "设置CONFIGURATION\n");
            
            // Set the requested configuration
            cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest);
            SetConfiguration(pDriver, cfgnum);
            break;

        case USBGenericRequest_GETCONFIGURATION:
            trace_LOG(trace_INFO, "获取CONFIGURATION\r\n");
            
            // Send the current configuration number
            GetConfiguration(pDriver);
            break;

        case USBGenericRequest_GETSTATUS:
            trace_LOG(trace_INFO, "获取STATUS\r\n");
    
            // Check who is the recipient
            switch (USBGenericRequest_GetRecipient(pRequest)) {
    
                case USBGenericRequest_DEVICE:
                    trace_LOG(trace_INFO, "    DEVICE\r\n");
    
                    // Send the device status
                    GetDeviceStatus(pDriver);
                    break;
    
                case USBGenericRequest_ENDPOINT:
                    trace_LOG(trace_INFO, "    ENDPOINT\r\n");
    
                    // Send the endpoint status
                    eptnum = USBGenericRequest_GetEndpointNumber(pRequest);
                    GetEndpointStatus(eptnum);
                    break;
    
                default:
                    trace_LOG(trace_WARNING,
                              "W: USBDDriver_RequestHandler: Unknown recipient (%d)\n\r",
                              USBGenericRequest_GetRecipient(pRequest));
                    USBD_Stall(0);
            }
            break;

        case USBGenericRequest_CLEARFEATURE:
            trace_LOG(trace_INFO, "清除FEATURE\r\n");

            // Check which is the requested feature
            switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {

                case USBFeatureRequest_ENDPOINTHALT:
                    trace_LOG(trace_INFO, "    端点halt\r\n");

                    // Unhalt endpoint and send a zero-length packet
                    USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest));
                    USBD_Write(0, 0, 0, 0, 0);
                    break;

                case USBFeatureRequest_DEVICEREMOTEWAKEUP:
                    trace_LOG(trace_INFO, "    设备remotewakeup");

                    // Disable remote wake-up and send a zero-length packet
                    pDriver->isRemoteWakeUpEnabled = 0;
                    USBD_Write(0, 0, 0, 0, 0);
                    break;

                default:
                    trace_LOG(trace_WARNING,
                              "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
                              USBFeatureRequest_GetFeatureSelector(pRequest));
                    USBD_Stall(0);
            }
            break;

    case USBGenericRequest_SETFEATURE:
        trace_LOG(trace_INFO, "设置FEATURE\r\n");

        // Check which is the selected feature
        switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {

            case USBFeatureRequest_DEVICEREMOTEWAKEUP:
                trace_LOG(trace_INFO, "    设备remotewakeup\r\n");

                // Enable remote wake-up and send a ZLP
                pDriver->isRemoteWakeUpEnabled = 1;
                USBD_Write(0, 0, 0, 0, 0);
                break;

            case USBFeatureRequest_ENDPOINTHALT:
                trace_LOG(trace_INFO, "    端点halt\r\n");

                // Halt endpoint
                USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
                USBD_Write(0, 0, 0, 0, 0);
                break;

            default:
                trace_LOG(trace_WARNING,
                          "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
                          USBFeatureRequest_GetFeatureSelector(pRequest));
                USBD_Stall(0);
        }
        break;

    case USBGenericRequest_SETINTERFACE:
        trace_LOG(trace_INFO, "设置接口\r\n");

        infnum = USBInterfaceRequest_GetInterface(pRequest);
        setting = USBInterfaceRequest_GetAlternateSetting(pRequest);
        SetInterface(pDriver, infnum, setting);
        break;

    case USBGenericRequest_GETINTERFACE:
        trace_LOG(trace_INFO, "获取接口\r\n");

        infnum = USBInterfaceRequest_GetInterface(pRequest);
        GetInterface(pDriver, infnum);
        break;

    default:
        trace_LOG(trace_WARNING,
                  "USBDDriver_RequestHandler: Unknown request code (%d)\n\r",
                  USBGenericRequest_GetRequest(pRequest));
        USBD_Stall(0);
    }
}


//------------------------------------------------------------------------------
/// Returns 1 if remote wake up has been enabled by the host; otherwise, returns
/// 0.
/// \param pDriver  Pointer to an USBDDriver instance.
//------------------------------------------------------------------------------
unsigned char USBDDriver_IsRemoteWakeUpEnabled(const USBDDriver *pDriver)
{
    return pDriver->isRemoteWakeUpEnabled;
}


⌨️ 快捷键说明

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