亚洲欧美第一页_禁久久精品乱码_粉嫩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人综合在线观看| 国产精品传媒视频| 美女视频免费一区| 91免费视频网| 在线精品观看国产| 欧美精品日韩综合在线| 欧美一级二级三级蜜桃| 精品免费国产二区三区| 欧美激情一区二区三区全黄| 国产精品伦一区| 五月天中文字幕一区二区| 免费亚洲电影在线| 成人网页在线观看| 成人做爰69片免费看网站| 精品久久久影院| 亚洲人精品午夜| 久久9热精品视频| 日日摸夜夜添夜夜添国产精品| 国产精品高清亚洲| 日韩激情av在线| aaa国产一区| 日韩无一区二区| 亚洲美腿欧美偷拍| 久久国产婷婷国产香蕉| 9l国产精品久久久久麻豆| 欧美一区二区三区小说| 国产片一区二区三区| 日韩—二三区免费观看av| 高清国产午夜精品久久久久久| 欧美日韩国产三级| 国产精品国产三级国产专播品爱网| 精品国产1区二区| 亚洲日本在线观看| 国产一区二区三区国产| 91视频一区二区三区| 337p日本欧洲亚洲大胆精品| 欧美男女性生活在线直播观看| 欧美日韩一二区| 日韩一区欧美小说| 开心九九激情九九欧美日韩精美视频电影| 国产成都精品91一区二区三| 亚洲777理论| 91蜜桃传媒精品久久久一区二区| 精品奇米国产一区二区三区| 综合色天天鬼久久鬼色| 美国av一区二区| 91精品久久久久久久91蜜桃| 中文字幕一区免费在线观看| 国产精品 欧美精品| 欧美精品自拍偷拍| 国产日本一区二区| 精品一区在线看| 欧美一a一片一级一片| 亚洲私人黄色宅男| 国产激情偷乱视频一区二区三区 | 欧美国产禁国产网站cc| 免费一级片91| 欧美一区二区三区婷婷月色| 亚洲欧美日韩中文播放| 亚洲麻豆国产自偷在线| 一本色道a无线码一区v| 国产欧美视频一区二区| 亚洲蜜桃精久久久久久久| 91在线视频播放| 最新久久zyz资源站| 国产一区中文字幕| 欧美大片免费久久精品三p | 亚洲v精品v日韩v欧美v专区| 日本韩国欧美三级| 亚洲一区免费观看| 欧美日韩免费观看一区二区三区| 亚洲欧洲日韩av| 色综合天天在线| 一区二区三区四区在线播放 | 成人丝袜视频网| 日本一区二区三区国色天香| 国产一区在线观看视频| 国产亚洲精品资源在线26u| 成人伦理片在线| 666欧美在线视频| 亚洲午夜在线视频| 欧美美女一区二区三区| 视频一区二区国产| 日韩欧美国产一区二区三区 | 天天操天天色综合| 欧美一a一片一级一片| 夜夜嗨av一区二区三区| 538prom精品视频线放| 麻豆成人久久精品二区三区红| 欧美一区二区成人| 国产美女久久久久| 欧美亚男人的天堂| 国产欧美综合在线观看第十页 | 亚洲欧美精品午睡沙发| 色88888久久久久久影院按摩| 亚洲成人av福利| 日韩区在线观看| 亚洲h精品动漫在线观看| 久久青草欧美一区二区三区| 成人av小说网| 日韩成人dvd| 成人欧美一区二区三区| 91麻豆精品国产| 国产精品丝袜在线| 在线观看一区二区精品视频| 欧洲精品视频在线观看| 九九精品视频在线看| 国产一区二区伦理片| 国产欧美日韩三区| 欧美天堂亚洲电影院在线播放| 青青草97国产精品免费观看 | 在线一区二区三区| 日本欧美在线看| 中文字幕一区在线| 日韩欧美精品在线| 欧美丰满嫩嫩电影| 91免费在线视频观看| 一区二区三区四区在线免费观看| 久久午夜电影网| 91精品国产综合久久久久久漫画| 成人av资源网站| 国产精品正在播放| 久久99蜜桃精品| 日韩专区一卡二卡| 久久亚洲精华国产精华液 | 精品视频色一区| 国产成人在线影院| 美女视频一区在线观看| 亚洲人亚洲人成电影网站色| 26uuu久久天堂性欧美| 日韩一区二区三区av| 欧美性大战久久久| 激情都市一区二区| 青青草97国产精品免费观看| 亚洲成人av一区二区三区| 欧美日产在线观看| 色综合激情久久| 成人开心网精品视频| 日本中文字幕一区二区视频| 午夜欧美2019年伦理| 视频在线观看国产精品| aaa亚洲精品| 日韩一级完整毛片| 老司机一区二区| 国产嫩草影院久久久久| 国产精品中文字幕日韩精品| 久久精品国产久精国产爱| 色欧美乱欧美15图片| 亚洲色图视频免费播放| av高清久久久| 亚洲一区二区在线免费观看视频| heyzo一本久久综合| 亚洲人123区| 欧美精品黑人性xxxx| 日本不卡在线视频| 精品国产乱码久久久久久牛牛| 免费在线观看精品| 精品久久久久一区| 国产成人精品一区二区三区四区 | 99这里只有精品| 国产精品黄色在线观看| 色一情一乱一乱一91av| 午夜不卡在线视频| 欧美成人猛片aaaaaaa| 国产精品911| 又紧又大又爽精品一区二区| 在线视频欧美精品| 久久精品国产成人一区二区三区| 国产亚洲婷婷免费| 97精品久久久午夜一区二区三区| 一级中文字幕一区二区| 欧美一二三在线| 成a人片亚洲日本久久| 亚洲一区二区三区四区的| 欧美www视频| 99精品黄色片免费大全| 日韩在线观看一区二区| 国产女主播在线一区二区| 在线观看亚洲一区| 国产一级精品在线| 亚洲激情在线激情| 日韩免费电影网站| 在线亚洲高清视频| 国产麻豆精品95视频| 亚洲精品视频观看| 26uuu另类欧美亚洲曰本| 色哟哟一区二区| 久久精品999| 一区二区国产盗摄色噜噜| 日韩欧美成人一区| 91国产免费观看| 国产精品一区免费在线观看| 一区二区三区在线视频免费观看| 欧美成人艳星乳罩| 色综合亚洲欧洲| 极品少妇一区二区三区精品视频| 亚洲六月丁香色婷婷综合久久 | 国产精品高清亚洲| 在线成人午夜影院| 一二三四社区欧美黄|