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

📄 bot_driver.c

📁 This software package contains the USB framework core developped by ATMEL, as well as a Mass stora
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support  -  ROUSSET  -
 * ----------------------------------------------------------------------------
 * Copyright (c) 2006, 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 disclaiimer below.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the disclaimer below in the documentation and/or
 * other materials provided with the distribution.
 *
 * 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.
 * ----------------------------------------------------------------------------
 */

/*
$Id: bot_driver.c 198 2006-10-30 10:01:09Z jjoannic $
*/

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

#include "core/common.h"
#include "core/device.h"
#include "core/board.h"
#include "core/trace.h"
#include "core/usb.h"
#include "core/standard.h"

#include "msd.h"
#include "media.h"
#include "sbc.h"
#include "lun.h"
#include "bot_driver.h"
#include "sbc_methods.h"

//------------------------------------------------------------------------------
//      Global variables
//------------------------------------------------------------------------------

//! \brief  Descriptors used by the BOT driver

//! \brief  Device descriptor
//! \see    S_usb_device_descriptor
const S_usb_device_descriptor sDevice = {

    sizeof(S_usb_device_descriptor), // Size of this descriptor in bytes
    USB_DEVICE_DESCRIPTOR,           // DEVICE Descriptor Type
    USB2_00,                         // USB specification 2.00
    0x00,                            // Class is specified in interface
    0x00,                            // Subclass is specified in interface
    0x00,                            // Protocol is specified in interface
    USB_ENDPOINT0_MAXPACKETSIZE,     // Maximum packet size for endpoint zero
    USB_VENDOR_ATMEL,                // Vendor ID (ATMEL, 03EBh)
    BOT_PRODUCT_ID,                  // Product ID (6202h)
    0x0001,                          // Device release number is 0.01
    0x01,                            // Index of manufacturer string
    0x02,                            // Index of product string
    0x03,                            // Index of serial number string
    0x01                             // One possible configuration
};

//! \brief  Configuration descriptor
//! \see    S_bot_configuration_descriptor
//! \see    S_usb_configuration_descriptor
//! \see    S_usb_interface_descriptor
//! \see    S_usb_endpoint_descriptor
const S_bot_configuration_descriptor sConfiguration = {

    // Configuration Descriptor
    {
        sizeof(S_usb_configuration_descriptor), // Size of this descriptor
        USB_CONFIGURATION_DESCRIPTOR,           // CONFIGURATION descriptor type
        sizeof(S_bot_configuration_descriptor), // Total size of descriptors
        0x01,                                   // One interface
        0x01,                                   // Configuration number 1
        0x00,                                   // No string description
        USB_CONFIG_SELF_NOWAKEUP,               // Device is self-powered
                                                // Remote wakeup not supported
        USB_POWER_MA(100),                      // 100mA consumption
    },
    // MSD Class Interface Descriptor
    {
        sizeof(S_usb_interface_descriptor), // Size of this descriptor in bytes
        USB_INTERFACE_DESCRIPTOR,           // INTERFACE descriptor type
        0x00,                               // Interface number 0
        0x00,                               // Setting 0
        BOT_NUM_ENDPOINTS - 1,              // Two endpoints used (excluding endpoint 0)
        USB_CLASS_MASS_STORAGE,             // Mass storage class code
        MSD_SUBCLASS_SCSI,                  // SCSI subclass code
        MSD_PROTOCOL_BULK_ONLY,             // Bulk-only transport protocol
        0x00                                // No string description
    },
    // Bulk-OUT Endpoint Descriptor
    {
        sizeof(S_usb_endpoint_descriptor),   // Size of this descriptor in bytes
        USB_ENDPOINT_DESCRIPTOR,             // ENDPOINT descriptor type
        USB_ENDPOINT_OUT | BOT_EPT_BULK_OUT, // OUT endpoint, address 01h
        ENDPOINT_TYPE_BULK,                  // Bulk endpoint
        64,                                  // Maximum packet size is 64 bytes
        0x00,                                // Must be 0 for full-speed bulk
    },
    // Bulk_IN Endpoint Descriptor
    {
        sizeof(S_usb_endpoint_descriptor), // Size of this descriptor in bytes
        USB_ENDPOINT_DESCRIPTOR,           // ENDPOINT descriptor type
        USB_ENDPOINT_IN | BOT_EPT_BULK_IN, // IN endpoint, address 02h
        ENDPOINT_TYPE_BULK,                // Bulk endpoint
        64,                                // Maximum packet size if 64 bytes
        0x00,                              // Must be 0 for full-speed bulk
    }
};

//! \brief  Language ID
//! \see    S_usb_language_id
static const S_usb_language_id sLanguageID = {

    USB_STRING_DESCRIPTOR_SIZE(1),
    USB_STRING_DESCRIPTOR,
    USB_LANGUAGE_ENGLISH_US
};

//! \brief  Manufacturer description string
static const char pStringManufacturer[] = {

    USB_STRING_DESCRIPTOR_SIZE(5),
    USB_STRING_DESCRIPTOR,
    USB_UNICODE('A'),
    USB_UNICODE('T'),
    USB_UNICODE('M'),
    USB_UNICODE('E'),
    USB_UNICODE('L')
};

//! \brief  Product description string
static const char pStringProduct[] = {

    USB_STRING_DESCRIPTOR_SIZE(14),
    USB_STRING_DESCRIPTOR,
    USB_UNICODE('A'),
    USB_UNICODE('T'),
    USB_UNICODE('M'),
    USB_UNICODE('E'),
    USB_UNICODE('L'),
    USB_UNICODE(' '),
    USB_UNICODE('A'),
    USB_UNICODE('T'),
    USB_UNICODE('9'),
    USB_UNICODE('1'),
    USB_UNICODE(' '),
    USB_UNICODE('M'),
    USB_UNICODE('S'),
    USB_UNICODE('D')
};

//! \brief  Device serial number
//!
//!         The serial number must be at least 12 characters long and made up
//!         of only letters & numbers to be compliant with the MSD specification
static const char pStringSerialNumber[] = {

    USB_STRING_DESCRIPTOR_SIZE(12),
    USB_STRING_DESCRIPTOR,
    USB_UNICODE('0'),
    USB_UNICODE('1'),
    USB_UNICODE('2'),
    USB_UNICODE('3'),
    USB_UNICODE('4'),
    USB_UNICODE('5'),
    USB_UNICODE('6'),
    USB_UNICODE('7'),
    USB_UNICODE('8'),
    USB_UNICODE('9'),
    USB_UNICODE('A'),
    USB_UNICODE('B')
};

//! \brief  List of string descriptors used by the device
static const char *pStrings[] = {

    (char *) &sLanguageID,
    pStringManufacturer,
    pStringProduct,
    pStringSerialNumber
};

//! \brief  List of endpoint descriptors used by the device
static const S_usb_endpoint_descriptor *pEndpoints[] = {

    &(sConfiguration.sBulkOut),
    &(sConfiguration.sBulkIn)
};

//! \brief  List of standard descriptors
//! \see    S_std_descriptors
static const S_std_descriptors sDescriptors = {

    &sDevice,
    (S_usb_configuration_descriptor *) &sConfiguration,
    pStrings,
    pEndpoints
};

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

    if (*pLength == 0) {

        (*pType) = BOT_NO_TRANSFER;
    }
    else if (ISSET(pCbw->bmCBWFlags, MSD_CBW_DEVICE_TO_HOST)) {

        (*pType) = BOT_DEVICE_TO_HOST;
    }
    else {

        (*pType) = BOT_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 true if the command is supported, false otherwise
//------------------------------------------------------------------------------
static bool BOT_PreProcessCommand(S_bot *pBot)
{
    unsigned int        dHostLength;
    unsigned int        dDeviceLength;
    unsigned char       bHostType;
    unsigned char       bDeviceType;
    bool                isCommandSupported;
    S_bot_command_state *pCommandState = &(pBot->sCommandState);
    S_msd_csw           *pCsw = &(pCommandState->sCsw);
    S_msd_cbw           *pCbw = &(pCommandState->sCbw);
    S_lun               *pLun = &(pBot->pLun[(unsigned char) pCbw->bCBWLUN]);

    // Get information about the command
    // Host-side
    BOT_GetCommandInformation(pCbw, &dHostLength, &bHostType);

    // Device-side
    isCommandSupported = SBC_GetCommandInformation(pCbw->pCommand,
                                                   &dDeviceLength,
                                                   &bDeviceType,
                                                   pLun);

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

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

        // Identify the command case
        // Case 1  (Hn = Dn)
        if ((bHostType == BOT_NO_TRANSFER)
            && (bDeviceType == BOT_NO_TRANSFER)) {

            pCommandState->bCase = 0;
            pCommandState->dLength = 0;
        }
        // Case 2  (Hn < Di)
        else if ((bHostType == BOT_NO_TRANSFER)
                 && (bDeviceType == BOT_DEVICE_TO_HOST)) {

            TRACE_WARNING("W: BOT_PreProcessCommand: Case 2\n\r");
            pCommandState->bCase = BOT_CASE_PHASE_ERROR;
            pCommandState->dLength = 0;

⌨️ 快捷键说明

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