SAMV71 Xplained Ultra Software Package 1.3

MSDDStateMachine.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  */
00034 
00035 /*-----------------------------------------------------------------------------
00036  *      Includes
00037  *-----------------------------------------------------------------------------*/
00038 
00039 #include "SBCMethods.h"
00040 #include "MSDDStateMachine.h"
00041 
00042 /*-----------------------------------------------------------------------------
00043  *      Internal functions
00044  *-----------------------------------------------------------------------------*/
00045 
00046 /**
00047  * This function is to be used as a callback for USB or LUN transfers.
00048  * \param  transfer    Pointer to the transfer structure to update
00049  * \param  status      Operation result code
00050  * \param  transferred Number of bytes transferred by the command
00051  * \param  remaining   Number of bytes not transferred
00052  */
00053 static void MSDDriver_Callback(MSDTransfer *transfer,
00054                                uint8_t status,
00055                                uint32_t transferred,
00056                                uint32_t remaining)
00057 {
00058     TRACE_DEBUG_WP( "Cbk " ) ;
00059     transfer->semaphore++;
00060     transfer->status = status;
00061     transfer->transferred = transferred;
00062     transfer->remaining = remaining;
00063 }
00064 
00065 /**
00066  * Returns the expected transfer length and direction (IN, OUT or don't care)
00067  * from the host point-of-view.
00068  * \param  cbw     Pointer to the CBW to examinate
00069  * \param  pLength Expected length of command
00070  * \param  pType   Expected direction of command
00071  */
00072 static void MSDD_GetCommandInformation(MSCbw *cbw,
00073                                        unsigned int  *length,
00074                                        unsigned char *type)
00075 {
00076     /* Expected host transfer direction and length */
00077     (*length) = cbw->dCBWDataTransferLength;
00078 
00079     if (*length == 0) {
00080 
00081         (*type) = MSDD_NO_TRANSFER;
00082     }
00083     else if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) != 0) {
00084 
00085         (*type) = MSDD_DEVICE_TO_HOST;
00086     }
00087     else {
00088 
00089         (*type) = MSDD_HOST_TO_DEVICE;
00090     }
00091 }
00092 
00093 /**
00094  * Pre-processes a command by checking the differences between the host and
00095  * device expectations in term of transfer type and length.
00096  * Once one of the thirteen cases is identified, the actions to do during the
00097  * post-processing phase are stored in the dCase variable of the command
00098  * state.
00099  * \param  pMsdDriver Pointer to a MSDDriver instance
00100  * \return 1 if the command is supported, false otherwise
00101  */
00102 static unsigned char MSDD_PreProcessCommand(MSDDriver *pMsdDriver)
00103 {
00104     unsigned int        hostLength = 0;
00105     unsigned int        deviceLength = 0;
00106     unsigned char       hostType;
00107     unsigned char       deviceType;
00108     unsigned char       isCommandSupported;
00109     MSDCommandState *commandState = &(pMsdDriver->commandState);
00110     MSCsw           *csw = &(commandState->csw);
00111     MSCbw           *cbw = &(commandState->cbw);
00112     MSDLun          *lun = &(pMsdDriver->luns[(unsigned char) cbw->bCBWLUN]);
00113 
00114     /* Get information about the command */
00115     /* Host-side */
00116     MSDD_GetCommandInformation(cbw, &hostLength, &hostType);
00117 
00118     /* Device-side */
00119     isCommandSupported = SBC_GetCommandInformation(cbw->pCommand,
00120                                                    &deviceLength,
00121                                                    &deviceType,
00122                                                    lun);
00123 
00124     /* Initialize data residue and result status */
00125     csw->dCSWDataResidue = 0;
00126     csw->bCSWStatus = MSD_CSW_COMMAND_PASSED;
00127 
00128     /* Check if the command is supported */
00129     if (isCommandSupported) {
00130 
00131         /* Identify the command case */
00132         if(hostType == MSDD_NO_TRANSFER) {
00133 
00134             /* Case 1  (Hn = Dn) */
00135             if(deviceType == MSDD_NO_TRANSFER) {
00136 
00137                 /*TRACE_WARNING("Case 1\n\r"); */
00138                 commandState->postprocess = 0;
00139                 commandState->length = 0;
00140             }
00141             else if(deviceType == MSDD_DEVICE_TO_HOST) {
00142 
00143                 /* Case 2  (Hn < Di) */
00144                 TRACE_WARNING(
00145                     "MSDD_PreProcessCommand: Case 2\n\r");
00146                 commandState->postprocess = MSDD_CASE_PHASE_ERROR;
00147                 commandState->length = 0;
00148             }
00149             else { /*if(deviceType == MSDD_HOST_TO_DEVICE) { */
00150 
00151                 /* Case 3  (Hn < Do) */
00152                 TRACE_WARNING(
00153                     "MSDD_PreProcessCommand: Case 3\n\r");
00154                 commandState->postprocess = MSDD_CASE_PHASE_ERROR;
00155                 commandState->length = 0;
00156             }
00157         }
00158 
00159         /* Case 4  (Hi > Dn) */
00160         else if(hostType == MSDD_DEVICE_TO_HOST) {
00161 
00162             if(deviceType == MSDD_NO_TRANSFER) {
00163 
00164                 TRACE_WARNING(
00165                     "MSDD_PreProcessCommand: Case 4\n\r");
00166                 commandState->postprocess = MSDD_CASE_STALL_IN;
00167                 commandState->length = 0;
00168                 csw->dCSWDataResidue = hostLength;
00169             }
00170             else if(deviceType == MSDD_DEVICE_TO_HOST) {
00171 
00172                 if(hostLength > deviceLength) {
00173 
00174                     /* Case 5  (Hi > Di) */
00175                     TRACE_WARNING(
00176                         "MSDD_PreProcessCommand: Case 5\n\r");
00177                     commandState->postprocess = MSDD_CASE_STALL_IN;
00178                     commandState->length = deviceLength;
00179                     csw->dCSWDataResidue = hostLength - deviceLength;
00180                 }
00181                 else if(hostLength == deviceLength) {
00182 
00183                     /* Case 6  (Hi = Di) */
00184                     commandState->postprocess = 0;
00185                     commandState->length = deviceLength;
00186                 }
00187                 else { /*if(hostLength < deviceLength) { */
00188 
00189                     /* Case 7  (Hi < Di) */
00190                     TRACE_WARNING(
00191                         "MSDD_PreProcessCommand: Case 7\n\r");
00192                     commandState->postprocess = MSDD_CASE_PHASE_ERROR;
00193                     commandState->length = hostLength;
00194                 }
00195             }
00196             else { /*if(deviceType == MSDD_HOST_TO_DEVICE) { */
00197 
00198                 /* Case 8  (Hi <> Do) */
00199                 TRACE_WARNING(
00200                     "MSDD_PreProcessCommand: Case 8\n\r");
00201                 commandState->postprocess =
00202                     MSDD_CASE_STALL_IN | MSDD_CASE_PHASE_ERROR;
00203                 commandState->length = 0;
00204             }
00205         }
00206         else if(hostType == MSDD_HOST_TO_DEVICE) {
00207 
00208             if(deviceType == MSDD_NO_TRANSFER) {
00209 
00210                 /* Case 9  (Ho > Dn) */
00211                 TRACE_WARNING(
00212                     "MSDD_PreProcessCommand: Case 9\n\r");
00213                 commandState->postprocess = MSDD_CASE_STALL_OUT;
00214                 commandState->length = 0;
00215                 csw->dCSWDataResidue = hostLength;
00216             }
00217             else if(deviceType == MSDD_DEVICE_TO_HOST) {
00218 
00219                 /* Case 10 (Ho <> Di) */
00220                 TRACE_WARNING(
00221                     "MSDD_PreProcessCommand: Case 10\n\r");
00222                 commandState->postprocess =
00223                     MSDD_CASE_STALL_OUT | MSDD_CASE_PHASE_ERROR;
00224                 commandState->length = 0;
00225             }
00226             else { /*if(deviceType == MSDD_HOST_TO_DEVICE) { */
00227 
00228                 if(hostLength > deviceLength) {
00229 
00230                     /* Case 11 (Ho > Do) */
00231                     TRACE_WARNING(
00232                         "MSDD_PreProcessCommand: Case 11\n\r");
00233                     commandState->postprocess = MSDD_CASE_STALL_OUT;
00234 /*                    commandState->length = deviceLength; */
00235 /*                    csw->dCSWDataResidue = hostLength - deviceLength; */
00236                     commandState->length = 0;
00237                     csw->dCSWDataResidue = deviceLength;
00238                 }
00239                 else if(hostLength == deviceLength) {
00240 
00241                     /* Case 12 (Ho = Do) */
00242                     /*TRACE_WARNING( */
00243                     /*    "MSDD_PreProcessCommand: Case 12\n\r"); */
00244                     commandState->postprocess = 0;
00245                     commandState->length = deviceLength;
00246                 }
00247                 else { /*if(hostLength < deviceLength) { */
00248 
00249                     /* Case 13 (Ho < Do) */
00250                     TRACE_WARNING(
00251                         "MSDD_PreProcessCommand: Case 13\n\r");
00252                     commandState->postprocess = MSDD_CASE_PHASE_ERROR;
00253                     commandState->length = hostLength;
00254                 }
00255             }
00256         }
00257     }
00258 
00259     return isCommandSupported;
00260 }
00261 
00262 /**
00263  * Post-processes a command given the case identified during the
00264  * pre-processing step.
00265  * Depending on the case, one of the following actions can be done:
00266  *           - Bulk IN endpoint is stalled
00267  *           - Bulk OUT endpoint is stalled
00268  *           - CSW status set to phase error
00269  * \param  pMsdDriver Pointer to a MSDDriver instance
00270  * \return If the device is halted
00271  */
00272 static unsigned char MSDD_PostProcessCommand(MSDDriver *pMsdDriver)
00273 {
00274     MSDCommandState *commandState = &(pMsdDriver->commandState);
00275     MSCsw           *csw = &(commandState->csw);
00276     unsigned char haltStatus = 0;
00277 
00278     /* STALL Bulk IN endpoint ? */
00279     if ((commandState->postprocess & MSDD_CASE_STALL_IN) != 0) {
00280 
00281         TRACE_INFO_WP("StallIn ");
00282         //MSDD_Halt(MSDD_CASE_STALL_IN);
00283         USBD_Halt(commandState->pipeIN);
00284         haltStatus = 1;
00285     }
00286 
00287     /* STALL Bulk OUT endpoint ? */
00288     if ((commandState->postprocess & MSDD_CASE_STALL_OUT) != 0) {
00289 
00290         TRACE_INFO_WP("StallOut ");
00291         //MSDD_Halt(MSDD_CASE_STALL_OUT);
00292         USBD_Halt(commandState->pipeOUT);
00293         haltStatus = 1;
00294     }
00295 
00296     /* Set CSW status code to phase error ? */
00297     if ((commandState->postprocess & MSDD_CASE_PHASE_ERROR) != 0) {
00298 
00299         TRACE_INFO_WP("PhaseErr ");
00300         csw->bCSWStatus = MSD_CSW_PHASE_ERROR;
00301     }
00302 
00303     return haltStatus;
00304 }
00305 
00306 /**
00307  * Processes the latest command received by the %device.
00308  * \param  pMsdDriver Pointer to a MSDDriver instance
00309  * \return 1 if the command has been completed, false otherwise.
00310  */
00311 static unsigned char MSDD_ProcessCommand(MSDDriver * pMsdDriver)
00312 {
00313     unsigned char   status;
00314     MSDCommandState *commandState = &(pMsdDriver->commandState);
00315     MSCbw           *cbw = &(commandState->cbw);
00316     MSCsw           *csw = &(commandState->csw);
00317     MSDLun          *lun = &(pMsdDriver->luns[(unsigned char) cbw->bCBWLUN]);
00318     unsigned char   isCommandComplete = 0;
00319 
00320     /* Check if LUN is valid */
00321     if (cbw->bCBWLUN > pMsdDriver->maxLun) {
00322 
00323         TRACE_WARNING(
00324             "MSDD_ProcessCommand: LUN %d not exist\n\r", cbw->bCBWLUN);
00325         status = MSDD_STATUS_ERROR;
00326     }
00327     else {
00328 
00329         /* Process command */
00330         if (pMsdDriver->maxLun > 0) {
00331 
00332             TRACE_INFO_WP("LUN%d ", cbw->bCBWLUN);
00333         }
00334 
00335         status = SBC_ProcessCommand(lun, commandState);
00336     }
00337 
00338     /* Check command result code */
00339     if (status == MSDD_STATUS_PARAMETER) {
00340 
00341         TRACE_WARNING(
00342             "MSDD_ProcessCommand: Unknown cmd 0x%02X\n\r",
00343             cbw->pCommand[0]);
00344 
00345         /* Update sense data */
00346         SBC_UpdateSenseData(&(lun->requestSenseData),
00347                             SBC_SENSE_KEY_ILLEGAL_REQUEST,
00348                             SBC_ASC_INVALID_FIELD_IN_CDB,
00349                             0);
00350 
00351         /* Result codes */
00352         csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00353         isCommandComplete = 1;
00354 
00355         /* stall the request, IN or OUT */
00356         if (((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0)
00357             && (cbw->dCBWDataTransferLength > 0)) {
00358 
00359             /* Stall the OUT endpoint : host to device */
00360             /* MSDD_Halt(MSDD_CASE_STALL_OUT); */
00361             commandState->postprocess = MSDD_CASE_STALL_OUT;
00362             TRACE_INFO_WP("StaOUT ");
00363         }
00364         else {
00365 
00366             /* Stall the IN endpoint : device to host */
00367             /* MSDD_Halt(MSDD_CASE_STALL_IN); */
00368             commandState->postprocess = MSDD_CASE_STALL_IN;
00369             TRACE_INFO_WP("StaIN ");
00370         }
00371     }
00372     else if (status == MSDD_STATUS_ERROR) {
00373 
00374         TRACE_WARNING("MSD_ProcessCommand: Cmd %x fail\n\r",
00375                    ((SBCCommand*)commandState->cbw.pCommand)->bOperationCode);
00376 
00377         /* Update sense data */
00378         SBC_UpdateSenseData(&(lun->requestSenseData),
00379                             SBC_SENSE_KEY_MEDIUM_ERROR,
00380                             SBC_ASC_INVALID_FIELD_IN_CDB,
00381                             0);
00382 
00383         /* Result codes */
00384         csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00385         isCommandComplete = 1;
00386     }
00387     else if (status == MSDD_STATUS_RW) {
00388 
00389         csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00390         isCommandComplete = 1;
00391     }
00392     else {
00393 
00394         /* Update sense data */
00395         SBC_UpdateSenseData(&(lun->requestSenseData),
00396                             SBC_SENSE_KEY_NO_SENSE,
00397                             0,
00398                             0);
00399 
00400         /* Is command complete ? */
00401         if (status == MSDD_STATUS_SUCCESS) {
00402 
00403             isCommandComplete = 1;
00404         }
00405     }
00406 
00407     /* Check if command has been completed */
00408     if (isCommandComplete) {
00409 
00410         TRACE_INFO_WP("Cplt ");
00411 
00412         /* Adjust data residue */
00413         if (commandState->length != 0) {
00414 
00415             csw->dCSWDataResidue += commandState->length;
00416 
00417             /* STALL the endpoint waiting for data */
00418             if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0) {
00419 
00420                 /* Stall the OUT endpoint : host to device */
00421                 /* MSDD_Halt(MSDD_CASE_STALL_OUT); */
00422                 commandState->postprocess = MSDD_CASE_STALL_OUT;
00423                 TRACE_INFO_WP("StaOUT ");
00424             }
00425             else {
00426 
00427                 /* Stall the IN endpoint : device to host */
00428                 /* MSDD_Halt(MSDD_CASE_STALL_IN); */
00429                 commandState->postprocess = MSDD_CASE_STALL_IN;
00430                 TRACE_INFO_WP("StaIN ");
00431             }
00432         }
00433 
00434         /* Reset command state */
00435         commandState->state = 0;
00436     }
00437 
00438     return isCommandComplete;
00439 }
00440 
00441 /**
00442  * State machine for the MSD %device driver
00443  * \param  pMsdDriver Pointer to a MSDDriver instance
00444  */
00445 void MSDD_StateMachine(MSDDriver * pMsdDriver)
00446 {
00447     MSDCommandState *commandState = &(pMsdDriver->commandState);
00448     MSCbw           *cbw = &(commandState->cbw);
00449     MSCsw           *csw = &(commandState->csw);
00450     MSDTransfer     *transfer = &(commandState->transfer);
00451     unsigned char   status;
00452 
00453     /* Identify current driver state */
00454     switch (pMsdDriver->state) {
00455     /*---------------------- */
00456     case MSDD_STATE_READ_CBW:
00457     /*---------------------- */
00458         /* Start the CBW read operation */
00459         transfer->semaphore = 0;
00460     #if 1
00461         status = USBD_Read(commandState->pipeOUT,
00462                            cbw,
00463                            MSD_CBW_SIZE,
00464                            (TransferCallback) MSDDriver_Callback,
00465                            (void *) transfer);
00466     #else
00467         status = MSDD_Read(cbw,
00468                            MSD_CBW_SIZE,
00469                            (TransferCallback) MSDDriver_Callback,
00470                            (void *) transfer);
00471     #endif
00472 
00473         /* Check operation result code */
00474         if (status == USBD_STATUS_SUCCESS) {
00475 
00476             /* If the command was successful, wait for transfer */
00477             pMsdDriver->state = MSDD_STATE_WAIT_CBW;
00478         }
00479         break;
00480 
00481     /*---------------------- */
00482     case MSDD_STATE_WAIT_CBW:
00483     /*---------------------- */
00484         /* Check transfer semaphore */
00485         if (transfer->semaphore > 0) {
00486 
00487             /* Take semaphore and terminate transfer */
00488             transfer->semaphore--;
00489 
00490             /* Check if transfer was successful */
00491             if (transfer->status == USBD_STATUS_SUCCESS) {
00492 
00493                 TRACE_INFO_WP("\n\r------------------------------\n\r");
00494 
00495                 /* Process received command */
00496                 pMsdDriver->state = MSDD_STATE_PROCESS_CBW;
00497             }
00498             else if (transfer->status == USBD_STATUS_RESET) {
00499 
00500                 TRACE_INFO("MSDD_StateMachine: EP resetted\n\r");
00501                 pMsdDriver->state = MSDD_STATE_READ_CBW;
00502             }
00503             else {
00504 
00505                 TRACE_WARNING(
00506                     "MSDD_StateMachine: Failed to read CBW\n\r");
00507                 pMsdDriver->state = MSDD_STATE_READ_CBW;
00508             }
00509         }
00510         break;
00511 
00512     /*------------------------- */
00513     case MSDD_STATE_PROCESS_CBW:
00514     /*------------------------- */
00515         /* Check if this is a new command */
00516         if (commandState->state == 0) {
00517 
00518             /* Copy the CBW tag */
00519             csw->dCSWTag = cbw->dCBWTag;
00520 
00521             /* Check that the CBW is 31 bytes long */
00522             if ((transfer->transferred != MSD_CBW_SIZE) ||
00523                 (transfer->remaining != 0)) {
00524 
00525                 TRACE_WARNING(
00526                     "MSDD_StateMachine: Invalid CBW (len %d)\n\r",
00527                     (int)transfer->transferred);
00528 
00529                 /* Wait for a reset recovery */
00530                 pMsdDriver->waitResetRecovery = 1;
00531 
00532                 /* Halt the Bulk-IN and Bulk-OUT pipes */
00533                 //MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN);
00534                 USBD_Halt(commandState->pipeIN);
00535                 USBD_Halt(commandState->pipeOUT);
00536 
00537                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00538                 pMsdDriver->state = MSDD_STATE_READ_CBW;
00539 
00540             }
00541             /* Check the CBW Signature */
00542             else if (cbw->dCBWSignature != MSD_CBW_SIGNATURE) {
00543 
00544                 TRACE_WARNING(
00545                     "MSD_BOTStateMachine: Invalid CBW (Bad signature)\n\r");
00546 
00547                 /* Wait for a reset recovery */
00548                 pMsdDriver->waitResetRecovery = 1;
00549 
00550                 /* Halt the Bulk-IN and Bulk-OUT pipes */
00551                 //MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN);
00552                 USBD_Halt(commandState->pipeIN);
00553                 USBD_Halt(commandState->pipeOUT);
00554 
00555                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00556                 pMsdDriver->state = MSDD_STATE_READ_CBW;
00557             }
00558             else {
00559 
00560                 /* Pre-process command */
00561                 MSDD_PreProcessCommand(pMsdDriver);
00562             }
00563         }
00564 
00565         /* Process command */
00566         if (csw->bCSWStatus == MSDD_STATUS_SUCCESS) {
00567 
00568             if (MSDD_ProcessCommand(pMsdDriver)) {
00569 
00570                 /* Post-process command if it is finished */
00571                 if (MSDD_PostProcessCommand(pMsdDriver)) {
00572 
00573                     TRACE_INFO_WP("WaitHALT ");
00574                     pMsdDriver->state = MSDD_STATE_WAIT_HALT;
00575                 }
00576                 else {
00577 
00578                     pMsdDriver->state = MSDD_STATE_SEND_CSW;
00579                 }
00580             }
00581             TRACE_INFO_WP("\n\r");
00582         }
00583 
00584         break;
00585 
00586     /*---------------------- */
00587     case MSDD_STATE_SEND_CSW:
00588     /*---------------------- */
00589         /* Set signature */
00590         csw->dCSWSignature = MSD_CSW_SIGNATURE;
00591 
00592         /* Start the CSW write operation */
00593       #if 1
00594         status = USBD_Write(commandState->pipeIN,
00595                             csw,
00596                             MSD_CSW_SIZE,
00597                             (TransferCallback) MSDDriver_Callback,
00598                             (void *) transfer);
00599       #else
00600         status = MSDD_Write(csw,
00601                             MSD_CSW_SIZE,
00602                             (TransferCallback) MSDDriver_Callback,
00603                             (void *) transfer);
00604       #endif
00605 
00606         /* Check operation result code */
00607         if (status == USBD_STATUS_SUCCESS) {
00608 
00609             TRACE_INFO_WP("SendCSW ");
00610 
00611             /* Wait for end of transfer */
00612             pMsdDriver->state = MSDD_STATE_WAIT_CSW;
00613         }
00614         break;
00615 
00616     /*---------------------- */
00617     case MSDD_STATE_WAIT_CSW:
00618     /*---------------------- */
00619         /* Check transfer semaphore */
00620         if (transfer->semaphore > 0) {
00621 
00622             /* Take semaphore and terminate transfer */
00623             transfer->semaphore--;
00624 
00625             /* Check if transfer was successful */
00626             if (transfer->status == USBD_STATUS_RESET) {
00627 
00628                 TRACE_INFO("MSDD_StateMachine: EP resetted\n\r");
00629             }
00630             else if (transfer->status == USBD_STATUS_ABORTED) {
00631 
00632                 TRACE_WARNING(
00633                     "MSDD_StateMachine: Failed to send CSW\n\r");
00634             }
00635             else {
00636 
00637                 TRACE_INFO_WP("ok");
00638             }
00639 
00640             /* Read new CBW */
00641             pMsdDriver->state = MSDD_STATE_READ_CBW;
00642         }
00643         break;
00644 
00645     /*---------------------- */
00646     case MSDD_STATE_WAIT_HALT:
00647     /*---------------------- */
00648         //if (MSDD_IsHalted() == 0) {
00649         if (!USBD_IsHalted(commandState->pipeIN)) {
00650 
00651             pMsdDriver->state = MSDD_STATE_SEND_CSW;
00652         }
00653         break;
00654     }
00655 }
00656 
00657 /**@}*/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines