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

📄 msddriver.c

📁 Include startup files and peripherial devices Code for Atmel ARM7 development
💻 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.
 * ----------------------------------------------------------------------------
 */

//------------------------------------------------------------------------------
//      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/USBDCallbacks.h>
#include <usb/device/core/USBDDriver.h>
#include <usb/device/core/USBDDriverCallbacks.h>

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

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

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

//-----------------------------------------------------------------------------
//      Internal functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
/// Resets the state of the MSD driver
//-----------------------------------------------------------------------------
static void MSDDriver_Reset(void)
{
    TRACE_INFO_WP("MSDReset ");

    msdDriver.state = MSDD_STATE_READ_CBW;
    msdDriver.waitResetRecovery = 0;
    msdDriver.commandState.state = 0;
}

//-----------------------------------------------------------------------------
//         Callback re-implementation
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/// Invoked when a new SETUP request is received from the host. Forwards the
/// request to the Mass Storage device driver handler function.
/// \param request  Pointer to a USBGenericRequest instance.
//-----------------------------------------------------------------------------
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
{
    MSDDriver_RequestHandler(request);
}

//-----------------------------------------------------------------------------
/// Invoked when the configuration of the device changes. Resets the mass
/// storage driver.
/// \param cfgnum New configuration number.
//-----------------------------------------------------------------------------
void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
{
    if (cfgnum > 0) {

        MSDDriver_Reset();
    }
}

//-----------------------------------------------------------------------------
//      Driver functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
/// Reads from host through MSD defined bulk OUT pipe. Act as USBD_Read but by
/// a fixed OUT endpoint.
/// \param data Pointer to the data buffer that contains data read from host.
/// \param size The number of bytes should be read (buffer size).
/// \param callback Pointer to the function invoked on end of reading.
/// \param argument Pointer to additional argument data struct.
//-----------------------------------------------------------------------------
char MSDD_Read(void *data,
               unsigned int size,
               TransferCallback callback,
               void *argument)

{
    return USBD_Read(MSDDriverDescriptors_BULKOUT,
                     data,
                     size,
                     callback,
                     argument);
}

//-----------------------------------------------------------------------------
/// Writes to host through MSD defined bulk IN pipe. Act as USBD_Write but by
/// a fixed IN endpoint.
/// \param data Pointer to the data that writes to the host.
/// \param size The number of bytes should be write.
/// \param callback Pointer to the function invoked on end of writing.
/// \param argument Pointer to additional argument data struct.
//-----------------------------------------------------------------------------
char MSDD_Write(void *data,
                unsigned int size,
                TransferCallback callback,
                void *argument)
{
    return USBD_Write(MSDDriverDescriptors_BULKIN,
                      data,
                      size,
                      callback,
                      argument);
}

//-----------------------------------------------------------------------------
/// HALT Specified USB pipe.
/// \param stallCASE Case of the stall condition (Bulk In/Out/Both).
//-----------------------------------------------------------------------------
void MSDD_Halt(unsigned int stallCASE)
{
    if (stallCASE & MSDD_CASE_STALL_OUT) {

        USBD_Halt(MSDDriverDescriptors_BULKOUT);
    }

    if (stallCASE & MSDD_CASE_STALL_IN) {

        USBD_Halt(MSDDriverDescriptors_BULKIN);
    }
}

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

//-----------------------------------------------------------------------------
/// Initializes the MSD driver and the associated USB driver.
/// \param  luns   Pointer to a list of LUNs
/// \param  numLuns Number of LUN in list
/// \see MSDLun
//-----------------------------------------------------------------------------
void MSDDriver_Initialize(MSDLun *luns, unsigned char numLuns)
{
    TRACE_INFO("MSD init\n\r");

    // Command state initialization
    msdDriver.commandState.state = 0;
    msdDriver.commandState.postprocess = 0;
    msdDriver.commandState.length = 0;
    msdDriver.commandState.transfer.semaphore = 0;

    // LUNs
    msdDriver.luns = luns;
    msdDriver.maxLun = (unsigned char) (numLuns - 1);

    // Reset BOT driver
    MSDDriver_Reset();

    // Init the USB driver
    USBDDriver_Initialize(&usbdDriver, &msdDriverDescriptors, 0);
    USBD_Init();
}

//-----------------------------------------------------------------------------
/// Handler for incoming SETUP requests on default Control endpoint 0.
///
/// Standard requests are forwarded to the USBDDriver_RequestHandler
/// method.
/// \param  request Pointer to a USBGenericRequest instance
//-----------------------------------------------------------------------------
void MSDDriver_RequestHandler(const USBGenericRequest *request)
{
    TRACE_INFO_WP("NewReq ");

    // Handle requests
    switch (USBGenericRequest_GetRequest(request)) {
    //---------------------
    case USBGenericRequest_CLEARFEATURE:
    //---------------------
        TRACE_INFO_WP("ClrFeat ");

        switch (USBFeatureRequest_GetFeatureSelector(request)) {

        //---------------------
        case USBFeatureRequest_ENDPOINTHALT:
        //---------------------
            TRACE_INFO_WP("Hlt ");

            // Do not clear the endpoint halt status if the device is waiting
            // for a reset recovery sequence
            if (!msdDriver.waitResetRecovery) {

                // Forward the request to the standard handler
                USBDDriver_RequestHandler(&usbdDriver, request);
            }
            else {

                TRACE_INFO_WP("No ");
            }

            USBD_Write(0, 0, 0, 0, 0);
            break;

        //------
        default:
        //------
            // Forward the request to the standard handler
            USBDDriver_RequestHandler(&usbdDriver, request);
        }
        break;

    //-------------------
    case MSD_GET_MAX_LUN:
    //-------------------
        TRACE_INFO_WP("gMaxLun ");

        // Check request parameters
        if ((request->wValue == 0)
            && (request->wIndex == 0)
            && (request->wLength == 1)) {

            USBD_Write(0, &(msdDriver.maxLun), 1, 0, 0);

        }
        else {

            TRACE_WARNING(
                "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
                request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        break;

    //-----------------------
    case MSD_BULK_ONLY_RESET:
    //-----------------------
        TRACE_INFO_WP("Rst ");

        // Check parameters
        if ((request->wValue == 0)
            && (request->wIndex == 0)
            && (request->wLength == 0)) {

            // Reset the MSD driver
            MSDDriver_Reset();
            USBD_Write(0, 0, 0, 0, 0);
        }
        else {

            TRACE_WARNING(
                "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r",
                request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        break;

    //------
    default:
    //------
        // Forward request to standard handler
        USBDDriver_RequestHandler(&usbdDriver, request);

        break;
    }
}

//-----------------------------------------------------------------------------
/// State machine for the MSD driver
//-----------------------------------------------------------------------------
void MSDDriver_StateMachine(void)
{
    MSDD_StateMachine(&msdDriver);
}

//-----------------------------------------------------------------------------
/// Starts a remote wake-up sequence if the host has explicitely enabled it
/// by sending the appropriate SET_FEATURE request.
//-----------------------------------------------------------------------------
void MSDDriver_RemoteWakeUp(void)
{
    // Remote wake-up has been enabled
    if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver)) {

        USBD_RemoteWakeUp();
    }
    // Remote wake-up NOT enabled
    else {

        TRACE_WARNING(
            "MSD..RemoteWakeUp: Host has not enabled remote wake-up\n\r");
    }
}

⌨️ 快捷键说明

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