SAMV71 Xplained Ultra Software Package 1.3

MSDFunction.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         ATMEL Microcontroller Software Support
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2008, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 
00030 /** \file
00031  *  \addtogroup usbd_msd
00032  *@{
00033  *  Implements Massstorage Function for USB device.
00034  */
00035 
00036 /*------------------------------------------------------------------------------
00037  *      Includes
00038  *------------------------------------------------------------------------------*/
00039 
00040 #include <MSDescriptors.h>
00041 
00042 #include <MSDDriver.h>
00043 #include <USBLib_Trace.h>
00044 #include "USBD.h"
00045 #include <USBD_HAL.h>
00046 #include <USBDDriver.h>
00047 
00048 /*-----------------------------------------------------------------------------
00049  *         Internal Types
00050  *-----------------------------------------------------------------------------*/
00051 
00052 /** Parse data extension */
00053 typedef struct _MSDParseData {
00054     /** Pointer to driver instance */
00055     MSDDriver *pMsdd;
00056     /** Pointer to currently processed interface descriptor */
00057     USBInterfaceDescriptor *pIf;
00058 } MSDParseData;
00059 
00060 
00061 /*-----------------------------------------------------------------------------
00062  *         Internal variables
00063  *-----------------------------------------------------------------------------*/
00064 
00065 /** MSD Driver instance for device function */
00066 static MSDDriver msdFunction;
00067 
00068 /*-----------------------------------------------------------------------------
00069  *      Internal functions
00070  *-----------------------------------------------------------------------------*/
00071 
00072 /**
00073  * Parse descriptors: Bulk EP IN/OUT.
00074  * \param desc Pointer to current processed descriptor.
00075  * \param arg  Pointer to data extention struct for parsing.
00076  */
00077 static uint8_t MSDFunction_Parse(USBGenericDescriptor* desc, MSDParseData* arg)
00078 {
00079     MSDDriver *pMsdd = arg->pMsdd;
00080     USBInterfaceDescriptor *pIf;
00081 
00082     /* Not a valid descriptor */
00083     if (desc->bLength == 0) {
00084         return USBD_STATUS_INVALID_PARAMETER;
00085     }
00086     /* Find interface descriptor */
00087     if (desc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00088         pIf = (USBInterfaceDescriptor*)desc;
00089         if (pIf->bInterfaceClass == MSInterfaceDescriptor_CLASS) {
00090             /* First found IF */
00091             if (pMsdd->interfaceNb == 0xFF) {
00092                 pMsdd->interfaceNb = pIf->bInterfaceNumber;
00093                 arg->pIf = pIf;
00094             }
00095             /* Specific IF */
00096             else if (pMsdd->interfaceNb == pIf->bInterfaceNumber) {
00097                 arg->pIf = pIf;
00098             }
00099             
00100         }
00101     }
00102     /* Start parse endpoints */
00103     if (arg->pIf) {
00104         if (desc->bDescriptorType == USBGenericDescriptor_ENDPOINT) {
00105             USBEndpointDescriptor *pEP = (USBEndpointDescriptor*)desc;
00106             if (pEP->bmAttributes == USBEndpointDescriptor_BULK) {
00107                 if (pEP->bEndpointAddress & 0x80)
00108                     pMsdd->commandState.pipeIN = pEP->bEndpointAddress & 0x7F;
00109                 else
00110                     pMsdd->commandState.pipeOUT = pEP->bEndpointAddress;
00111             }
00112         }
00113 
00114         /* Finish when found all pipes */
00115         if (pMsdd->commandState.pipeIN != 0
00116             && pMsdd->commandState.pipeOUT != 0) {
00117             return USBRC_FINISHED;
00118         }
00119     }
00120     return 0;
00121 }
00122 
00123 /**
00124  * Resets the state of the MSD driver
00125  */
00126 static void MSDFunction_Reset(void)
00127 {
00128     MSDDriver *pMsdd = &msdFunction;
00129 
00130     TRACE_INFO_WP("MSDReset ");
00131 
00132     pMsdd->state = MSDD_STATE_READ_CBW;
00133     pMsdd->waitResetRecovery = 0;
00134     pMsdd->commandState.state = 0;
00135 }
00136 
00137 /*-----------------------------------------------------------------------------
00138  *      Exported functions
00139  *-----------------------------------------------------------------------------*/
00140 
00141 /**
00142  * Initializes the MSD driver and the associated USB driver.
00143  * \param  pUsbd        Pointer to USBDDriver instance.
00144  * \param  bInterfaceNb Interface number for the function.
00145  * \param  pLuns        Pointer to a list of LUNs
00146  * \param  numLuns      Number of LUN in list
00147  * \see MSDLun
00148  */
00149 void MSDFunction_Initialize(
00150     USBDDriver *pUsbd, uint8_t bInterfaceNb,
00151     MSDLun *pLuns, uint8_t numLuns)
00152 {
00153     MSDDriver *pMsdDriver = &msdFunction;
00154 
00155     TRACE_INFO("MSDFun init\n\r");
00156 
00157     /* Driver instance */
00158     pMsdDriver->pUsbd = pUsbd;
00159     pMsdDriver->interfaceNb = bInterfaceNb;
00160 
00161     /* Command state initialization */
00162     pMsdDriver->commandState.state = 0;
00163     pMsdDriver->commandState.postprocess = 0;
00164     pMsdDriver->commandState.length = 0;
00165     pMsdDriver->commandState.transfer.semaphore = 0;
00166 
00167     /* LUNs */
00168     pMsdDriver->luns = pLuns;
00169     pMsdDriver->maxLun = (uint8_t) (numLuns - 1);
00170 
00171     /* Reset BOT driver */
00172     MSDFunction_Reset();
00173 }
00174 
00175 /**
00176  * Invoked when the configuration of the device changes. 
00177  * Pass endpoints and resets the mass storage function.
00178  * \pDescriptors Pointer to the descriptors for function configure.
00179  * \wLength      Length of descriptors in number of bytes.
00180  */
00181 void MSDFunction_Configure(USBGenericDescriptor *pDescriptors,
00182                            uint16_t wLength)
00183 {
00184     MSDDriver *pMsdDriver = &msdFunction;
00185     MSDParseData parseData;
00186 
00187     TRACE_INFO_WP("MSDFunCfg ");
00188 
00189     pMsdDriver->state = MSDD_STATE_READ_CBW;
00190     pMsdDriver->waitResetRecovery = 0;
00191     pMsdDriver->commandState.state = 0;
00192 
00193     parseData.pIf = 0;
00194     parseData.pMsdd = pMsdDriver;
00195     USBGenericDescriptor_Parse((USBGenericDescriptor*)pDescriptors, wLength,
00196                 (USBDescriptorParseFunction)MSDFunction_Parse, &parseData);
00197 
00198     MSDFunction_Reset();
00199 }
00200 
00201 /**
00202  * Handler for incoming SETUP requests on default Control endpoint 0.
00203  *
00204  * Standard requests are forwarded to the USBDDriver_RequestHandler
00205  * method.
00206  * \param  pMsdDriver  Pointer to MSDDriver instance.
00207  * \param  request Pointer to a USBGenericRequest instance
00208  */
00209 uint32_t MSDFunction_RequestHandler(
00210     const USBGenericRequest *request)
00211 {
00212     MSDDriver *pMsdDriver = &msdFunction;
00213     uint32_t reqCode = (USBGenericRequest_GetType(request) << 8)
00214                      | (USBGenericRequest_GetRequest(request));
00215 
00216     TRACE_INFO_WP("Msdf ");
00217 
00218     /* Handle requests */
00219     switch (reqCode) {
00220     /*--------------------- */
00221     case USBGenericRequest_CLEARFEATURE:
00222     /*--------------------- */
00223         TRACE_INFO_WP("ClrFeat ");
00224 
00225         switch (USBFeatureRequest_GetFeatureSelector(request)) {
00226 
00227         /*--------------------- */
00228         case USBFeatureRequest_ENDPOINTHALT:
00229         /*--------------------- */
00230             TRACE_INFO_WP("Hlt ");
00231 
00232             /* Do not clear the endpoint halt status if the device is waiting */
00233             /* for a reset recovery sequence */
00234             if (!pMsdDriver->waitResetRecovery) {
00235 
00236                 /* Forward the request to the standard handler */
00237                 USBDDriver_RequestHandler(USBD_GetDriver(), request);
00238             }
00239             else {
00240 
00241                 TRACE_INFO_WP("No ");
00242             }
00243 
00244             USBD_Write(0, 0, 0, 0, 0);
00245 
00246             return USBRC_SUCCESS; /* Handled */
00247 
00248         }
00249         break;
00250 
00251     /*------------------- */
00252     case (USBGenericRequest_CLASS<<8)|MSD_GET_MAX_LUN:
00253     /*------------------- */
00254         TRACE_INFO_WP("gMaxLun ");
00255 
00256         /* Check request parameters */
00257         if ((request->wValue == 0)
00258             && (request->wIndex == pMsdDriver->interfaceNb)
00259             && (request->wLength == 1)) {
00260 
00261             USBD_Write(0, &(pMsdDriver->maxLun), 1, 0, 0);
00262 
00263         }
00264         else {
00265 
00266             TRACE_WARNING(
00267                 "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
00268                 request->wValue, request->wIndex, request->wLength);
00269             USBD_Stall(0);
00270         }
00271         return USBRC_SUCCESS; /* Handled */
00272 
00273     /*----------------------- */
00274     case (USBGenericRequest_CLASS<<8)|MSD_BULK_ONLY_RESET:
00275     /*----------------------- */
00276         TRACE_INFO_WP("Rst ");
00277 
00278         /* Check parameters */
00279         if ((request->wValue == 0)
00280             && (request->wIndex == pMsdDriver->interfaceNb)
00281             && (request->wLength == 0)) {
00282 
00283             /* Reset the MSD driver */
00284             MSDFunction_Reset();
00285             USBD_Write(0, 0, 0, 0, 0);
00286         }
00287         else {
00288 
00289             TRACE_WARNING(
00290                 "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r",
00291                 request->wValue, request->wIndex, request->wLength);
00292             USBD_Stall(0);
00293         }
00294         return USBRC_SUCCESS; /* Handled */
00295     }
00296 
00297     return USBRC_PARAM_ERR;
00298 }
00299 
00300 /**
00301  * State machine for the MSD driver
00302  */
00303 void MSDFunction_StateMachine(void)
00304 {
00305     if (USBD_GetState() < USBD_STATE_CONFIGURED){}
00306     else MSDD_StateMachine(&msdFunction);
00307 
00308 }
00309 
00310 /**@}*/
00311 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines