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

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

?? msddriver.c

?? IAR5.2下 AT91SAM9260 ARM 對 MCP2515 控制源化碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* ----------------------------------------------------------------------------
 *         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.
 * ----------------------------------------------------------------------------
 */

//------------------------------------------------------------------------------
//      Includes
//------------------------------------------------------------------------------

#include "MSDDriver.h"
#include "MSDDriverDescriptors.h"
#include "SBCMethods.h"
#include <utility/trace.h>
#include <usb/common/core/USBGenericRequest.h>
#include <usb/common/core/USBFeatureRequest.h>
#include <usb/device/core/USBD.h>
#include <usb/device/core/USBDDriver.h>

//------------------------------------------------------------------------------
//      Structures
//------------------------------------------------------------------------------

//! \brief  MSD driver state variables
//! \see    MSDCommandState
//! \see    S_std_class
//! \see    MSDLun
typedef struct {

    MSDLun *luns;
    MSDCommandState commandState;       //!< State of the currently executing command
    unsigned char maxLun;             //!< Maximum LUN index
    unsigned char state;              //!< Current state of the driver
    unsigned char waitResetRecovery; //!< Indicates if the driver is
                                             //!< waiting for a reset recovery
} MSDDriver;

//------------------------------------------------------------------------------
//         Internal variables
//------------------------------------------------------------------------------

/// Mass storage device driver instance.
static MSDDriver msdDriver;

/// Standard device driver instance.
static USBDDriver usbdDriver;

//------------------------------------------------------------------------------
//      Internal functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//! \brief  Returns the expected transfer length and direction (IN, OUT or don't
//!         care) from the host point-of-view.
//! \param  cbw    Pointer to the CBW to examinate
//! \param  pLength Expected length of command
//! \param  pType   Expected direction of command
//------------------------------------------------------------------------------
static void MSDDriver_GetCommandInformation(MSCbw *cbw,
                                            unsigned int  *length,
                                            unsigned char *type)
{
    // Expected host transfer direction and length
    (*length) = cbw->dCBWDataTransferLength;

    if (*length == 0) {

        (*type) = MSDDriver_NO_TRANSFER;
    }
    else if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) != 0) {

        (*type) = MSDDriver_DEVICE_TO_HOST;
    }
    else {

        (*type) = MSDDriver_HOST_TO_DEVICE;
    }
}

//------------------------------------------------------------------------------
//! \brief  Pre-processes a command by checking the differences between the
//!         host and device expectations in term of transfer type and length.
//!
//!         Once one of the thirteen cases is identified, the actions to do
//!         during the post-processing phase are stored in the dCase variable
//!         of the command state.
//! \param  pBot Pointer to a S_bot instance
//! \return 1 if the command is supported, false otherwise
//------------------------------------------------------------------------------
static unsigned char MSDDriver_PreProcessCommand()
{
    unsigned int        hostLength;
    unsigned int        deviceLength;
    unsigned char       hostType;
    unsigned char       deviceType;
    unsigned char                isCommandSupported;
    MSDCommandState *commandState = &(msdDriver.commandState);
    MSCsw           *csw = &(commandState->csw);
    MSCbw           *cbw = &(commandState->cbw);
    MSDLun               *lun = &(msdDriver.luns[(unsigned char) cbw->bCBWLUN]);

    // Get information about the command
    // Host-side
    MSDDriver_GetCommandInformation(cbw, &hostLength, &hostType);

    // Device-side
    isCommandSupported = SBC_GetCommandInformation(cbw->pCommand,
                                                   &deviceLength,
                                                   &deviceType,
                                                   lun);

    // Initialize data residue and result status
    csw->dCSWDataResidue = 0;
    csw->bCSWStatus = MSD_CSW_COMMAND_PASSED;

    // Check if the command is supported
    if (isCommandSupported) {

        // Identify the command case
        if(hostType == MSDDriver_NO_TRANSFER) {

            // Case 1  (Hn = Dn)
            if(deviceType == MSDDriver_NO_TRANSFER) {

                trace_LOG(trace_WARNING, "W: Case 1\n\r");
                commandState->postprocess = 0;
                commandState->length = 0;
            }
            else if(deviceType == MSDDriver_DEVICE_TO_HOST) {

                // Case 2  (Hn < Di)
                trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 2\n\r");
                commandState->postprocess = MSDDriver_CASE_PHASE_ERROR;
                commandState->length = 0;
            }
            else { //if(deviceType == MSDDriver_HOST_TO_DEVICE) {

                // Case 3  (Hn < Do)
                trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 3\n\r");
                commandState->postprocess = MSDDriver_CASE_PHASE_ERROR;
                commandState->length = 0;
            }
        }

        // Case 4  (Hi > Dn)
        else if(hostType == MSDDriver_DEVICE_TO_HOST) {

            if(deviceType == MSDDriver_NO_TRANSFER) {

                trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 4\n\r");
                commandState->postprocess = MSDDriver_CASE_STALL_IN;
                commandState->length = 0;
                csw->dCSWDataResidue = hostLength;
            }
            else if(deviceType == MSDDriver_DEVICE_TO_HOST) {

                if(hostLength > deviceLength) {

                    // Case 5  (Hi > Di)
                    trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 5\n\r");
                    commandState->postprocess = MSDDriver_CASE_STALL_IN;
                    commandState->length = deviceLength;
                    csw->dCSWDataResidue = hostLength - deviceLength;
                }
                else if(hostLength == deviceLength) {

                    // Case 6  (Hi = Di)
//                    trace_LOG(trace_WARNING, "W: Case 6\n\r");
                    commandState->postprocess = 0;
                    commandState->length = deviceLength;
                }
                else { //if(hostLength < deviceLength) {

                    // Case 7  (Hi < Di)
                    trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 7\n\r");
                    commandState->postprocess = MSDDriver_CASE_PHASE_ERROR;
                    commandState->length = hostLength;
                }
            }
            else { //if(deviceType == MSDDriver_HOST_TO_DEVICE) {

                // Case 8  (Hi <> Do)
                trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 8\n\r");
                commandState->postprocess = MSDDriver_CASE_STALL_IN | MSDDriver_CASE_PHASE_ERROR;
                commandState->length = 0;
            }
        }
        else if(hostType == MSDDriver_HOST_TO_DEVICE) {

            if(deviceType == MSDDriver_NO_TRANSFER) {

                // Case 9  (Ho > Dn)
                trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 9\n\r");
                commandState->postprocess = MSDDriver_CASE_STALL_OUT;
                commandState->length = 0;
                csw->dCSWDataResidue = hostLength;
            }
            else if(deviceType == MSDDriver_DEVICE_TO_HOST) {

                // Case 10 (Ho <> Di)
                trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 10\n\r");
                commandState->postprocess = MSDDriver_CASE_STALL_OUT | MSDDriver_CASE_PHASE_ERROR;
                commandState->length = 0;
            }
            else { //if(deviceType == MSDDriver_HOST_TO_DEVICE) {

                if(hostLength > deviceLength) {

                    // Case 11 (Ho > Do)
                    trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 11\n\r");
                    commandState->postprocess = MSDDriver_CASE_STALL_OUT;
                    commandState->length = deviceLength;
                    csw->dCSWDataResidue = hostLength - deviceLength;
                }
                else if(hostLength == deviceLength) {

                    // Case 12 (Ho = Do)
                    trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 12\n\r");
                    commandState->postprocess = 0;
                    commandState->length = deviceLength;
                }
                else { //if(hostLength < deviceLength) {

                    // Case 13 (Ho < Do)
                    trace_LOG(trace_WARNING, "W: MSDDriver_PreProcessCommand: Case 13\n\r");
                    commandState->postprocess = MSDDriver_CASE_PHASE_ERROR;
                    commandState->length = hostLength;
                }
            }
        }
    }

    return isCommandSupported;
}

//------------------------------------------------------------------------------
//! \brief  Post-processes a command given the case identified during the
//!         pre-processing step.
//!
//!         Depending on the case, one of the following actions can be done:
//!             - Bulk IN endpoint is stalled
//!             - Bulk OUT endpoint is stalled
//!             - CSW status set to phase error
//! \param  pBot Pointer to a S_bot instance
//------------------------------------------------------------------------------
static void MSDDriver_PostProcessCommand()
{
    MSDCommandState *commandState = &(msdDriver.commandState);
    MSCsw           *csw = &(commandState->csw);

    // STALL Bulk IN endpoint ?
    if ((commandState->postprocess & MSDDriver_CASE_STALL_IN) != 0) {

        trace_LOG(trace_INFO, "StallIn ");
        USBD_Halt(MSDDriverDescriptors_BULKIN);
    }

    // STALL Bulk OUT endpoint ?
    if ((commandState->postprocess & MSDDriver_CASE_STALL_OUT) != 0) {

        trace_LOG(trace_INFO, "StallOut ");
        USBD_Halt(MSDDriverDescriptors_BULKOUT);
    }

    // Set CSW status code to phase error ?
    if ((commandState->postprocess & MSDDriver_CASE_PHASE_ERROR) != 0) {

        trace_LOG(trace_INFO, "PhaseErr ");
        csw->bCSWStatus = MSD_CSW_PHASE_ERROR;
    }
}

//------------------------------------------------------------------------------
//! \brief  Processes the latest command received by the device.
//! \param  pBot Pointer to a S_bot instance
//! \return 1 if the command has been completed, false otherwise.
//------------------------------------------------------------------------------
static unsigned char MSDDriver_ProcessCommand()
{
    unsigned char       status;
    MSDCommandState *commandState = &(msdDriver.commandState);
    MSCbw           *cbw = &(commandState->cbw);
    MSCsw           *csw = &(commandState->csw);
    MSDLun               *lun = &(msdDriver.luns[(unsigned char) cbw->bCBWLUN]);
    unsigned char                isCommandComplete = 0;

    // Check if LUN is valid
    if (cbw->bCBWLUN > msdDriver.maxLun) {

        trace_LOG(trace_WARNING, "W: MSDDriver_ProcessCommand: Requested LUN does not exist\n\r");
        status = MSDDriver_STATUS_ERROR;
    }
    else {

        // Process command
        if (msdDriver.maxLun > 0) {

            trace_LOG(trace_INFO, "LUN%d ", cbw->bCBWLUN);
        }

        status = SBC_ProcessCommand(lun, commandState);
    }

    // Check command result code
    if (status == MSDDriver_STATUS_PARAMETER) {

        trace_LOG(trace_WARNING, "W: MSDDriver_ProcessCommand: Unknown command 0x%02X\n\r",
                      cbw->pCommand[0]);

        // Update sense data
        SBC_UpdateSenseData(&(lun->requestSenseData),
                            SBC_SENSE_KEY_ILLEGAL_REQUEST,
                            SBC_ASC_INVALID_FIELD_IN_CDB,
                            0);

        // Result codes
        csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
        isCommandComplete = 1;

        // stall the request, IN or OUT
        if (((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0)
            && (cbw->dCBWDataTransferLength > 0)) {

            // Stall the OUT endpoint : host to device
            USBD_Halt(MSDDriverDescriptors_BULKOUT);
            trace_LOG(trace_INFO, "StaOUT ");
        }
        else {

            // Stall the IN endpoint : device to host
            USBD_Halt(MSDDriverDescriptors_BULKIN);
            trace_LOG(trace_INFO, "StaIN ");
        }
    }
    else if (status == MSDDriver_STATUS_ERROR) {

        trace_LOG(trace_WARNING, "W: MSD_ProcessCommand: Command failed\n\r");

        // Update sense data
// TODO (jjoannic#1#): Change code
        SBC_UpdateSenseData(&(lun->requestSenseData),
                            SBC_SENSE_KEY_MEDIUM_ERROR,
                            SBC_ASC_INVALID_FIELD_IN_CDB,
                            0);

        // Result codes
        csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
        isCommandComplete = 1;
    }
    else {

        // Update sense data
        SBC_UpdateSenseData(&(lun->requestSenseData),
                            SBC_SENSE_KEY_NO_SENSE,
                            0,
                            0);

        // Is command complete ?
        if (status == MSDDriver_STATUS_SUCCESS) {

            isCommandComplete = 1;
        }
    }

    // Check if command has been completed
    if (isCommandComplete) {

        trace_LOG(trace_INFO, "Cplt ");

        // Adjust data residue
        if (commandState->length != 0) {

            csw->dCSWDataResidue += commandState->length;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩精品福利网| av在线播放不卡| 国内欧美视频一区二区| 麻豆精品一区二区综合av| 国内久久婷婷综合| 成人av动漫网站| 欧美国产一区视频在线观看| 国产精品久线观看视频| 国产一区二区久久| 久久超碰97中文字幕| 国内精品国产成人国产三级粉色| 丝袜亚洲另类欧美综合| 久久精品国产77777蜜臀| 欧美午夜精品一区二区蜜桃| 久久国产成人午夜av影院| 欧美精品tushy高清| 久久精品一区四区| 一区二区三区在线播| 性感美女极品91精品| 91久久香蕉国产日韩欧美9色| 欧美刺激午夜性久久久久久久| 亚洲毛片av在线| 青娱乐精品在线视频| 青草国产精品久久久久久| 丰满少妇久久久久久久| 日韩av成人高清| 日韩电影免费在线看| 在线视频一区二区三| 日韩色在线观看| 欧美日韩中文字幕一区| 成人精品视频.| 久久婷婷综合激情| 日本不卡的三区四区五区| 一本久道久久综合中文字幕| 国产亚洲综合色| 无码av免费一区二区三区试看| 国产精品一区在线| 欧美一级二级三级乱码| 樱桃国产成人精品视频| 一二三区精品福利视频| 国产综合色产在线精品| 欧美一级二级在线观看| 日韩国产欧美在线视频| 一本大道久久a久久综合婷婷| 欧美日韩视频在线观看一区二区三区| 欧美大胆人体bbbb| 亚洲高清视频在线| 成人免费视频免费观看| 色综合天天综合在线视频| 舔着乳尖日韩一区| 欧美日韩一级大片网址| 亚洲最大的成人av| 99riav一区二区三区| 亚洲电影在线播放| 欧美日韩在线播| 老司机午夜精品| 一本一道综合狠狠老| 欧美一区二区三区免费视频 | 午夜视频一区二区| 免费观看久久久4p| 欧美综合视频在线观看| 国产精品国产精品国产专区不蜜| 久久精品久久99精品久久| 欧美体内she精高潮| 亚洲免费观看高清在线观看| 成人国产精品免费网站| 久久精品一级爱片| 国产乱码一区二区三区| 欧美人妇做爰xxxⅹ性高电影| 亚洲天堂成人网| 成人自拍视频在线观看| 日本一区二区三区在线不卡| 麻豆freexxxx性91精品| 正在播放亚洲一区| 天堂蜜桃一区二区三区| 欧美久久久久久久久久| 亚洲影院免费观看| 日本韩国一区二区三区视频| 亚洲日本在线天堂| 色噜噜狠狠色综合中国| 国产精品国产三级国产| 99久久精品国产一区| 国产精品天天看| 91麻豆蜜桃一区二区三区| 国产精品乱子久久久久| 成人丝袜视频网| 国产精品成人免费| 欧美唯美清纯偷拍| 亚洲国产另类av| 91精品国产高清一区二区三区蜜臀| 丝袜亚洲另类欧美| 久久久久久97三级| 成人听书哪个软件好| 中文字幕综合网| 欧洲视频一区二区| 午夜成人免费视频| 制服.丝袜.亚洲.中文.综合| 另类调教123区| 国产视频一区二区在线观看| 国产成人精品亚洲午夜麻豆| 午夜激情久久久| 亚洲一二三区视频在线观看| 久久影音资源网| 日韩欧美中文字幕公布| 欧美三区免费完整视频在线观看| 成人网在线播放| 美女视频黄a大片欧美| 亚洲品质自拍视频| 亚洲黄色尤物视频| 日本强好片久久久久久aaa| 亚洲自拍偷拍九九九| 一区二区三区四区精品在线视频| 综合分类小说区另类春色亚洲小说欧美| 欧美sm极限捆绑bd| wwwwxxxxx欧美| 亚洲欧美日韩中文播放| 国产一区三区三区| 亚洲午夜精品在线| 亚洲视频在线观看一区| 夜色激情一区二区| 蓝色福利精品导航| 国产99久久久精品| 在线观看日韩电影| 欧美成人免费网站| 国产精品午夜在线观看| 午夜视频在线观看一区二区三区| 亚洲sss视频在线视频| 精彩视频一区二区| 99国产精品国产精品久久| 欧美美女直播网站| 久久综合九色综合97婷婷女人| 中文字幕在线一区| 六月丁香婷婷色狠狠久久| www.亚洲精品| 久久伊99综合婷婷久久伊| 亚洲欧洲国产日韩| 六月丁香婷婷色狠狠久久| 色综合网色综合| 国产女主播在线一区二区| 亚洲成人综合视频| 99久久99久久久精品齐齐| 91精品久久久久久久91蜜桃| 中文字幕日韩欧美一区二区三区| 亚洲一区二区三区四区在线观看| 国产成人亚洲综合a∨猫咪| 在线电影国产精品| 亚洲精品免费在线观看| 国产麻豆一精品一av一免费 | 一区二区三区欧美| 波多野结衣的一区二区三区| 日韩欧美中文字幕精品| 婷婷久久综合九色国产成人| 欧美午夜电影网| 亚洲成av人综合在线观看| 色婷婷综合视频在线观看| 亚洲视频一二区| 91麻豆国产在线观看| 国产精品久久久久久久久搜平片 | 国产精品对白交换视频| 日韩欧美一级在线播放| 亚洲三级电影网站| 91视频你懂的| 亚洲综合久久久| 九九视频精品免费| 7777精品伊人久久久大香线蕉最新版| 亚洲国产一二三| 欧美精品v国产精品v日韩精品 | 日韩成人一级大片| 欧美大片日本大片免费观看| 久久99精品久久久久久动态图| 日韩美女一区二区三区| 国产成人一区在线| 国产精品久久久久婷婷| 欧美午夜一区二区三区免费大片| 亚洲国产欧美在线| 久久久国产精品午夜一区ai换脸| 成人小视频在线| 午夜激情综合网| 国产精品乱子久久久久| 欧美高清性hdvideosex| 91麻豆福利精品推荐| 亚洲一线二线三线视频| 91精品国产综合久久福利软件| 久久精品国产99国产| 亚洲精品国产视频| 精品国产凹凸成av人导航| 91一区一区三区| 奇米影视在线99精品| 91精品国产欧美日韩| 午夜精品一区二区三区免费视频 | 欧美色综合网站| 久久精品99国产精品| 国产精品免费免费| 制服.丝袜.亚洲.另类.中文| 成人精品一区二区三区中文字幕| 精品人伦一区二区色婷婷| 色噜噜狠狠成人中文综合| 久草热8精品视频在线观看| 国产精品免费丝袜| 久久精品在这里|