SAMV71 Xplained Ultra Software Package 1.5

MSDFunction.c

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