亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? usbddriver.c

?? useful when developer using ARM7 to interface HID devices like USB Keyboard
?? C
字號:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * ----------------------------------------------------------------------------
 * Copyright (c) 2008, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 */

//------------------------------------------------------------------------------
//      Headers
//------------------------------------------------------------------------------

#include "USBDDriver.h"
#include "USBDDriverCallbacks.h"
#include "USBD.h"
#include <board.h>
#include <utility/trace.h>
#include <usb/common/core/USBGenericDescriptor.h>
#include <usb/common/core/USBDeviceDescriptor.h>
#include <usb/common/core/USBConfigurationDescriptor.h>
#include <usb/common/core/USBDeviceQualifierDescriptor.h>
#include <usb/common/core/USBEndpointDescriptor.h>
#include <usb/common/core/USBFeatureRequest.h>
#include <usb/common/core/USBSetAddressRequest.h>
#include <usb/common/core/USBGetDescriptorRequest.h>
#include <usb/common/core/USBSetConfigurationRequest.h>
#include <usb/common/core/USBInterfaceRequest.h>

#include <string.h>

//------------------------------------------------------------------------------
//      Local functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Configures the device by setting it into the Configured state and
/// initializing all endpoints.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param cfgnum  Configuration number to set.
//------------------------------------------------------------------------------
static void SetConfiguration(USBDDriver *pDriver, unsigned char cfgnum)
{
    USBEndpointDescriptor *pEndpoints[BOARD_USB_NUMENDPOINTS+1];
    const USBConfigurationDescriptor *pConfiguration;

    // Use different descriptor depending on device speed
    if (USBD_IsHighSpeed()) {

        pConfiguration = pDriver->pDescriptors->pHsConfiguration;
    }
    else {

        pConfiguration = pDriver->pDescriptors->pFsConfiguration;
    }

    // Set & save the desired configuration
    USBD_SetConfiguration(cfgnum);
    pDriver->cfgnum = cfgnum;

    // If the configuration is not 0, configure endpoints
    if (cfgnum != 0) {
    
        // Parse configuration to get endpoint descriptors
        USBConfigurationDescriptor_Parse(pConfiguration, 0, pEndpoints, 0);
    
        // Configure endpoints
        int i = 0;
        while (pEndpoints[i] != 0) {
    
            USBD_ConfigureEndpoint(pEndpoints[i]);
            i++;
        }
    }
    // Should be done before send the ZLP
    USBDDriverCallbacks_ConfigurationChanged(cfgnum);

    // Acknowledge the request
    USBD_Write(0, // Endpoint #0
               0, // No data buffer
               0, // No data buffer
               (TransferCallback) 0,
               (void *)  0);
}

//------------------------------------------------------------------------------
/// Sends the current configuration number to the host.
/// \param pDriver  Pointer to a USBDDriver instance.
//------------------------------------------------------------------------------
static void GetConfiguration(const USBDDriver *pDriver)
{
    USBD_Write(0, &(pDriver->cfgnum), 1, 0, 0);
}

//------------------------------------------------------------------------------
/// Sends the current status of the device to the host.
/// \param pDriver  Pointer to a USBDDriver instance.
//------------------------------------------------------------------------------
static void GetDeviceStatus(const USBDDriver *pDriver)
{
    unsigned short data = 0;
    const USBConfigurationDescriptor *pConfiguration;

    // Use different configuration depending on device speed
    if (USBD_IsHighSpeed()) {

        pConfiguration = pDriver->pDescriptors->pHsConfiguration;
    }
    else {

        pConfiguration = pDriver->pDescriptors->pFsConfiguration;
    }

    // Check current configuration for power mode (if device is configured)
    if (pDriver->cfgnum != 0) {

        if (USBConfigurationDescriptor_IsSelfPowered(pConfiguration)) {

            data |= 1;
        }
    }

    // Check if remote wake-up is enabled
    if (pDriver->isRemoteWakeUpEnabled) {

        data |= 2;
    }

    // Send the device status
    USBD_Write(0, &data, 2, 0, 0);
}

//------------------------------------------------------------------------------
/// Sends the current status of an endpoints to the USB host.
/// \param bEndpoint  Endpoint number.
//------------------------------------------------------------------------------
static void GetEndpointStatus(unsigned char bEndpoint)
{
    unsigned short data = 0;

    // Check if the endpoint exists
    if (bEndpoint > BOARD_USB_NUMENDPOINTS) {

        USBD_Stall(0);
    }
    else {

        // Check if the endpoint if currently halted
        if (USBD_IsHalted(bEndpoint)) {

            data = 1;
        }
        
        // Send the endpoint status
        USBD_Write(0, &data, 2, 0, 0);
    }
}

//------------------------------------------------------------------------------
/// Sends the requested USB descriptor to the host if available, or STALLs  the
/// request.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param type  Type of the requested descriptor
/// \param index  Index of the requested descriptor.
/// \param length  Maximum number of bytes to return.
//------------------------------------------------------------------------------
static void GetDescriptor(
    const USBDDriver *pDriver,
    unsigned char type,
    unsigned char index,
    unsigned int length)
{
    const USBDeviceDescriptor *pDevice;
    const USBConfigurationDescriptor *pConfiguration;
    const USBDeviceQualifierDescriptor *pQualifier;
    const USBConfigurationDescriptor *pOtherSpeed;
    const USBGenericDescriptor **pStrings =
        (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings;
    unsigned char numStrings = pDriver->pDescriptors->numStrings;
    const USBGenericDescriptor *pString;

    // Use different set of descriptors depending on device speed
    if (USBD_IsHighSpeed()) {

        TRACE_DEBUG("HS ");
        pDevice = pDriver->pDescriptors->pHsDevice;
        pConfiguration = pDriver->pDescriptors->pHsConfiguration;
        pQualifier = pDriver->pDescriptors->pHsQualifier;
        pOtherSpeed = pDriver->pDescriptors->pHsOtherSpeed;
    }
    else {

        TRACE_DEBUG("FS ");
        pDevice = pDriver->pDescriptors->pFsDevice;
        pConfiguration = pDriver->pDescriptors->pFsConfiguration;
        pQualifier = pDriver->pDescriptors->pFsQualifier;
        pOtherSpeed = pDriver->pDescriptors->pFsOtherSpeed;
    }

    // Check the descriptor type
    switch (type) {
        
        case USBGenericDescriptor_DEVICE:
            TRACE_INFO_WP("Dev ");

            // Adjust length and send descriptor
            if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) {

                length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice);
            }
            USBD_Write(0, pDevice, length, 0, 0);
            break;

        case USBGenericDescriptor_CONFIGURATION:
            TRACE_INFO_WP("Cfg ");

            // Adjust length and send descriptor
            if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) {

                length = USBConfigurationDescriptor_GetTotalLength(pConfiguration);
            }
            USBD_Write(0, pConfiguration, length, 0, 0);
            break;

        case USBGenericDescriptor_DEVICEQUALIFIER:
            TRACE_INFO_WP("Qua ");

            // Check if descriptor exists
            if (!pQualifier) {

                USBD_Stall(0);
            }
            else {

                // Adjust length and send descriptor
                if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier)) {

                    length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier);
                }
                USBD_Write(0, pQualifier, length, 0, 0);
            }
            break;

        case USBGenericDescriptor_OTHERSPEEDCONFIGURATION:
            TRACE_INFO_WP("OSC ");

            // Check if descriptor exists
            if (!pOtherSpeed) {

                USBD_Stall(0);
            }
            else {

                // Adjust length and send descriptor
                if (length > USBConfigurationDescriptor_GetTotalLength(pOtherSpeed)) {

                    length = USBConfigurationDescriptor_GetTotalLength(pOtherSpeed);
                }
                USBD_Write(0, pOtherSpeed, length, 0, 0);
            }
            break;

        case USBGenericDescriptor_STRING:
            TRACE_INFO_WP("Str%d ", index);

            // Check if descriptor exists
            if (index > numStrings) {

                USBD_Stall(0);
            }
            else {

                pString = pStrings[index];

                // Adjust length and send descriptor
                if (length > USBGenericDescriptor_GetLength(pString)) {

                    length = USBGenericDescriptor_GetLength(pString);
                }
                USBD_Write(0, pString, length, 0, 0);
            }
            break;

        default:
            TRACE_WARNING(
                      "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r",
                      type);
            USBD_Stall(0);
    }
}

//------------------------------------------------------------------------------
/// Sets the active setting of the given interface if the configuration supports
/// it; otherwise, the control pipe is STALLed. If the setting of an interface
/// changes.
/// \parma pDriver  Pointer to a USBDDriver instance.
/// \parma infnum  Interface number.
/// \parma setting  New active setting for the interface.
//------------------------------------------------------------------------------
static void SetInterface(
    USBDDriver *pDriver,
    unsigned char infnum,
    unsigned char setting)
{
    // Make sure alternate settings are supported
    if (!pDriver->pInterfaces) {

        USBD_Stall(0);
    }
    else {

        // Change the current setting of the interface and trigger the callback 
        // if necessary
        if (pDriver->pInterfaces[infnum] != setting) {

            pDriver->pInterfaces[infnum] = setting;
            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_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. 揝

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产欧美精品区一区二区三区 | 在线这里只有精品| 国产精品白丝jk黑袜喷水| 日本aⅴ精品一区二区三区| 五月天精品一区二区三区| 亚洲一级电影视频| 亚洲图片欧美视频| 午夜成人免费电影| 蜜臀av一区二区| 国内精品嫩模私拍在线| 国产99久久久国产精品潘金| 国产成人aaaa| 色综合咪咪久久| 欧美日韩中字一区| 日韩欧美的一区| 中文字幕不卡在线观看| 亚洲欧美一区二区三区国产精品 | 欧美精三区欧美精三区| 欧美喷潮久久久xxxxx| 日韩精品一区二区三区中文不卡 | 日韩一区二区三区电影在线观看 | 国产另类ts人妖一区二区| 粉嫩av一区二区三区粉嫩| 91丨九色丨蝌蚪富婆spa| 欧美日韩视频在线观看一区二区三区 | 日韩电影在线一区二区| 精品一区二区三区蜜桃| 成人自拍视频在线| 欧美女孩性生活视频| 久久综合九色综合97婷婷女人| 国产精品三级在线观看| 午夜视黄欧洲亚洲| 国产成人免费视频精品含羞草妖精 | 91精品国产91久久综合桃花| 国产午夜精品在线观看| 一区二区三区蜜桃网| 精品一区二区三区不卡| 91麻豆文化传媒在线观看| 欧美日韩不卡视频| 国产精品福利一区二区三区| 青青国产91久久久久久| 色综合天天狠狠| 精品福利二区三区| 亚洲mv在线观看| 粉嫩欧美一区二区三区高清影视| 欧美精品第1页| 一区二区在线看| 国产乱国产乱300精品| 欧美日韩国产精品成人| 国产精品美女久久久久高潮| 美女视频一区二区| 欧美亚洲国产一区二区三区| 久久久99久久| 美女在线视频一区| 亚洲精品国产一区二区三区四区在线| 亚洲午夜精品17c| 国产成人av电影免费在线观看| 欧美二区三区91| 一区二区三区加勒比av| 成人国产视频在线观看| 久久综合色婷婷| 蜜乳av一区二区三区| 欧美最新大片在线看| 国产精品第13页| 粉嫩久久99精品久久久久久夜| 欧美精品一区二区三区在线| 日本特黄久久久高潮| 欧美日韩成人综合天天影院| 亚洲影院在线观看| 色丁香久综合在线久综合在线观看| 中文字幕国产一区| 99re成人在线| 亚洲色图第一区| 在线欧美一区二区| 亚洲欧美自拍偷拍色图| 成人丝袜高跟foot| 国产日韩欧美不卡| 国产成人免费在线观看不卡| 久久九九全国免费| 粉嫩在线一区二区三区视频| 中文子幕无线码一区tr| 99久久久免费精品国产一区二区| 久久精品亚洲一区二区三区浴池 | 午夜精品免费在线观看| 欧美色窝79yyyycom| 视频一区中文字幕国产| 欧美精品123区| 久久精品国产在热久久| 国产拍欧美日韩视频二区| 91视频一区二区三区| 亚洲一区中文日韩| 6080午夜不卡| 国产一区二区伦理| 亚洲欧美电影院| 欧美日韩激情一区二区三区| 日本亚洲电影天堂| 国产亚洲精久久久久久| 色婷婷av一区二区三区gif | 国产校园另类小说区| 91免费小视频| 秋霞av亚洲一区二区三| 国产精品情趣视频| 欧美日韩一级黄| 国产成人欧美日韩在线电影| 夜夜嗨av一区二区三区中文字幕| 欧美一区二区国产| 成人美女视频在线观看18| 亚洲综合色在线| 久久精品欧美一区二区三区麻豆 | 美美哒免费高清在线观看视频一区二区 | 欧美精品一级二级三级| 国产一区二区三区视频在线播放| 中文字幕亚洲在| 日韩精品一区二区三区三区免费 | 成人性生交大片免费看中文网站| 亚洲女女做受ⅹxx高潮| 日韩欧美一级在线播放| 97se亚洲国产综合自在线 | 国产精品国产三级国产普通话蜜臀| 在线观看av一区| 国产在线精品一区二区不卡了| 亚洲精品免费在线播放| 久久亚洲春色中文字幕久久久| 欧美三级电影精品| 91在线视频官网| 国产乱子伦视频一区二区三区| 亚洲成人资源在线| 亚洲激情av在线| 国产女人aaa级久久久级| 日韩欧美一区二区久久婷婷| 欧美三级视频在线| jizz一区二区| 国产激情视频一区二区在线观看 | 国产凹凸在线观看一区二区| 肉色丝袜一区二区| 亚洲综合一区在线| 亚洲男人的天堂一区二区 | 91免费观看在线| 国产成人综合自拍| 狠狠色2019综合网| 免费成人av在线| 蜜臀久久久久久久| 首页欧美精品中文字幕| 亚洲成人av电影| 亚洲va欧美va天堂v国产综合| 亚洲视频一二区| 亚洲精品一二三四区| 国产精品福利av| 亚洲日韩欧美一区二区在线| 国产精品久久久久一区二区三区共| 精品国免费一区二区三区| 精品国产伦一区二区三区免费| 日韩一区二区在线观看视频播放| 欧美精品久久久久久久久老牛影院| 欧美视频一二三区| 欧美精品乱人伦久久久久久| 51精品国自产在线| 日韩一区二区三区电影在线观看| 欧美一二三区在线| 精品va天堂亚洲国产| 久久久精品中文字幕麻豆发布| wwwwww.欧美系列| 久久精品亚洲精品国产欧美kt∨| 国产日韩v精品一区二区| 国产精品美女www爽爽爽| 亚洲欧美精品午睡沙发| 亚洲专区一二三| 免费三级欧美电影| 福利一区二区在线观看| 91麻豆6部合集magnet| 精品视频资源站| 亚洲精品在线免费播放| 国产精品麻豆视频| 一区二区三区视频在线看| 天天影视网天天综合色在线播放| 久久成人精品无人区| 成人高清免费在线播放| 色综合天天综合给合国产| 欧美日韩国产高清一区二区三区 | 亚洲一区二区欧美日韩 | 国产午夜精品理论片a级大结局 | 国产成人aaa| 欧美亚洲另类激情小说| 精品少妇一区二区三区视频免付费| 国产欧美日韩在线| 午夜精品视频一区| 成人性生交大片免费看中文网站| 欧美日韩精品欧美日韩精品| 久久综合久久鬼色中文字| 亚洲精品视频一区二区| 激情综合色综合久久综合| 91美女片黄在线观看91美女| 日韩精品一区二区在线观看| 亚洲精品中文字幕在线观看| 国产综合一区二区| 欧美日韩成人综合| 亚洲免费观看高清完整| 精品一区二区三区日韩| 欧美色国产精品| 亚洲欧洲日韩综合一区二区|