Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BSP_DISCO_F746NG_patch mbed-rtos mbed
usbh_msc_bot.c
00001 /** 00002 ****************************************************************************** 00003 * @file usbh_msc_bot.c 00004 * @author MCD Application Team 00005 * @version V3.2.2 00006 * @date 07-July-2015 00007 * @brief This file includes the BOT protocol related functions 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> 00012 * 00013 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00014 * You may not use this file except in compliance with the License. 00015 * You may obtain a copy of the License at: 00016 * 00017 * http://www.st.com/software_license_agreement_liberty_v2 00018 * 00019 * Unless required by applicable law or agreed to in writing, software 00020 * distributed under the License is distributed on an "AS IS" BASIS, 00021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00022 * See the License for the specific language governing permissions and 00023 * limitations under the License. 00024 * 00025 ****************************************************************************** 00026 */ 00027 00028 /* Includes ------------------------------------------------------------------*/ 00029 #include "usbh_msc_bot.h" 00030 #include "usbh_msc.h" 00031 00032 /** @addtogroup USBH_LIB 00033 * @{ 00034 */ 00035 00036 /** @addtogroup USBH_CLASS 00037 * @{ 00038 */ 00039 00040 /** @addtogroup USBH_MSC_CLASS 00041 * @{ 00042 */ 00043 00044 /** @defgroup USBH_MSC_BOT 00045 * @brief This file includes the mass storage related functions 00046 * @{ 00047 */ 00048 00049 00050 /** @defgroup USBH_MSC_BOT_Private_TypesDefinitions 00051 * @{ 00052 */ 00053 /** 00054 * @} 00055 */ 00056 00057 /** @defgroup USBH_MSC_BOT_Private_Defines 00058 * @{ 00059 */ 00060 /** 00061 * @} 00062 */ 00063 00064 /** @defgroup USBH_MSC_BOT_Private_Macros 00065 * @{ 00066 */ 00067 /** 00068 * @} 00069 */ 00070 00071 00072 /** @defgroup USBH_MSC_BOT_Private_Variables 00073 * @{ 00074 */ 00075 00076 /** 00077 * @} 00078 */ 00079 00080 00081 /** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes 00082 * @{ 00083 */ 00084 static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir); 00085 static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost); 00086 /** 00087 * @} 00088 */ 00089 00090 00091 /** @defgroup USBH_MSC_BOT_Exported_Variables 00092 * @{ 00093 */ 00094 /** 00095 * @} 00096 */ 00097 00098 00099 /** @defgroup USBH_MSC_BOT_Private_Functions 00100 * @{ 00101 */ 00102 00103 /** 00104 * @brief USBH_MSC_BOT_REQ_Reset 00105 * The function the MSC BOT Reset request. 00106 * @param phost: Host handle 00107 * @retval USBH Status 00108 */ 00109 USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost) 00110 { 00111 00112 phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \ 00113 USB_REQ_RECIPIENT_INTERFACE; 00114 00115 phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET; 00116 phost->Control.setup.b.wValue.w = 0; 00117 phost->Control.setup.b.wIndex.w = 0; 00118 phost->Control.setup.b.wLength.w = 0; 00119 00120 return USBH_CtlReq(phost, 0 , 0 ); 00121 } 00122 00123 /** 00124 * @brief USBH_MSC_BOT_REQ_GetMaxLUN 00125 * The function the MSC BOT GetMaxLUN request. 00126 * @param phost: Host handle 00127 * @param Maxlun: pointer to Maxlun variable 00128 * @retval USBH Status 00129 */ 00130 USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun) 00131 { 00132 phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \ 00133 USB_REQ_RECIPIENT_INTERFACE; 00134 00135 phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN; 00136 phost->Control.setup.b.wValue.w = 0; 00137 phost->Control.setup.b.wIndex.w = 0; 00138 phost->Control.setup.b.wLength.w = 1; 00139 00140 return USBH_CtlReq(phost, Maxlun , 1 ); 00141 } 00142 00143 00144 00145 /** 00146 * @brief USBH_MSC_BOT_Init 00147 * The function Initializes the BOT protocol. 00148 * @param phost: Host handle 00149 * @retval USBH Status 00150 */ 00151 USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost) 00152 { 00153 00154 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00155 00156 MSC_Handle->hbot.cbw.field.Signature = BOT_CBW_SIGNATURE; 00157 MSC_Handle->hbot.cbw.field.Tag = BOT_CBW_TAG; 00158 MSC_Handle->hbot.state = BOT_SEND_CBW; 00159 MSC_Handle->hbot.cmd_state = BOT_CMD_SEND; 00160 00161 return USBH_OK; 00162 } 00163 00164 00165 00166 /** 00167 * @brief USBH_MSC_BOT_Process 00168 * The function handle the BOT protocol. 00169 * @param phost: Host handle 00170 * @param lun: Logical Unit Number 00171 * @retval USBH Status 00172 */ 00173 USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) 00174 { 00175 USBH_StatusTypeDef status = USBH_BUSY; 00176 USBH_StatusTypeDef error = USBH_BUSY; 00177 BOT_CSWStatusTypeDef CSW_Status = BOT_CSW_CMD_FAILED; 00178 USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; 00179 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00180 uint8_t toggle = 0; 00181 00182 switch (MSC_Handle->hbot.state) 00183 { 00184 case BOT_SEND_CBW: 00185 MSC_Handle->hbot.cbw.field.LUN = lun; 00186 MSC_Handle->hbot.state = BOT_SEND_CBW_WAIT; 00187 USBH_BulkSendData (phost, 00188 MSC_Handle->hbot.cbw.data, 00189 BOT_CBW_LENGTH, 00190 MSC_Handle->OutPipe, 00191 1); 00192 00193 break; 00194 00195 case BOT_SEND_CBW_WAIT: 00196 00197 URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe); 00198 00199 if(URB_Status == USBH_URB_DONE) 00200 { 00201 if ( MSC_Handle->hbot.cbw.field.DataTransferLength != 0 ) 00202 { 00203 /* If there is Data Transfer Stage */ 00204 if (((MSC_Handle->hbot.cbw.field.Flags) & USB_REQ_DIR_MASK) == USB_D2H) 00205 { 00206 /* Data Direction is IN */ 00207 MSC_Handle->hbot.state = BOT_DATA_IN; 00208 } 00209 else 00210 { 00211 /* Data Direction is OUT */ 00212 MSC_Handle->hbot.state = BOT_DATA_OUT; 00213 } 00214 } 00215 00216 else 00217 {/* If there is NO Data Transfer Stage */ 00218 MSC_Handle->hbot.state = BOT_RECEIVE_CSW; 00219 } 00220 #if (USBH_USE_OS == 1) 00221 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00222 #endif 00223 00224 } 00225 else if(URB_Status == USBH_URB_NOTREADY) 00226 { 00227 /* Re-send CBW */ 00228 MSC_Handle->hbot.state = BOT_SEND_CBW; 00229 #if (USBH_USE_OS == 1) 00230 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00231 #endif 00232 } 00233 else if(URB_Status == USBH_URB_STALL) 00234 { 00235 MSC_Handle->hbot.state = BOT_ERROR_OUT; 00236 #if (USBH_USE_OS == 1) 00237 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00238 #endif 00239 } 00240 break; 00241 00242 case BOT_DATA_IN: 00243 /* Send first packet */ 00244 USBH_BulkReceiveData (phost, 00245 MSC_Handle->hbot.pbuf, 00246 MSC_Handle->InEpSize , 00247 MSC_Handle->InPipe); 00248 00249 MSC_Handle->hbot.state = BOT_DATA_IN_WAIT; 00250 00251 break; 00252 00253 case BOT_DATA_IN_WAIT: 00254 00255 URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe); 00256 00257 if(URB_Status == USBH_URB_DONE) 00258 { 00259 /* Adjust Data pointer and data length */ 00260 if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->InEpSize) 00261 { 00262 MSC_Handle->hbot.pbuf += MSC_Handle->InEpSize; 00263 MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->InEpSize; 00264 } 00265 else 00266 { 00267 MSC_Handle->hbot.cbw.field.DataTransferLength = 0; 00268 } 00269 00270 /* More Data To be Received */ 00271 if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0) 00272 { 00273 /* Send next packet */ 00274 USBH_BulkReceiveData (phost, 00275 MSC_Handle->hbot.pbuf, 00276 MSC_Handle->InEpSize , 00277 MSC_Handle->InPipe); 00278 00279 } 00280 else 00281 { 00282 /* If value was 0, and successful transfer, then change the state */ 00283 MSC_Handle->hbot.state = BOT_RECEIVE_CSW; 00284 #if (USBH_USE_OS == 1) 00285 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00286 #endif 00287 } 00288 } 00289 else if(URB_Status == USBH_URB_STALL) 00290 { 00291 /* This is Data IN Stage STALL Condition */ 00292 MSC_Handle->hbot.state = BOT_ERROR_IN; 00293 00294 /* Refer to USB Mass-Storage Class : BOT (www.usb.org) 00295 6.7.2 Host expects to receive data from the device 00296 3. On a STALL condition receiving data, then: 00297 The host shall accept the data received. 00298 The host shall clear the Bulk-In pipe. 00299 4. The host shall attempt to receive a CSW.*/ 00300 00301 #if (USBH_USE_OS == 1) 00302 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00303 #endif 00304 } 00305 break; 00306 00307 case BOT_DATA_OUT: 00308 00309 USBH_BulkSendData (phost, 00310 MSC_Handle->hbot.pbuf, 00311 MSC_Handle->OutEpSize , 00312 MSC_Handle->OutPipe, 00313 1); 00314 00315 00316 MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT; 00317 break; 00318 00319 case BOT_DATA_OUT_WAIT: 00320 URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe); 00321 00322 if(URB_Status == USBH_URB_DONE) 00323 { 00324 /* Adjust Data pointer and data length */ 00325 if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->OutEpSize) 00326 { 00327 MSC_Handle->hbot.pbuf += MSC_Handle->OutEpSize; 00328 MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->OutEpSize; 00329 } 00330 else 00331 { 00332 MSC_Handle->hbot.cbw.field.DataTransferLength = 0; 00333 } 00334 00335 /* More Data To be Sent */ 00336 if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0) 00337 { 00338 USBH_BulkSendData (phost, 00339 MSC_Handle->hbot.pbuf, 00340 MSC_Handle->OutEpSize , 00341 MSC_Handle->OutPipe, 00342 1); 00343 } 00344 else 00345 { 00346 /* If value was 0, and successful transfer, then change the state */ 00347 MSC_Handle->hbot.state = BOT_RECEIVE_CSW; 00348 } 00349 #if (USBH_USE_OS == 1) 00350 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00351 #endif 00352 } 00353 00354 else if(URB_Status == USBH_URB_NOTREADY) 00355 { 00356 /* Resend same data */ 00357 MSC_Handle->hbot.state = BOT_DATA_OUT; 00358 #if (USBH_USE_OS == 1) 00359 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00360 #endif 00361 } 00362 00363 else if(URB_Status == USBH_URB_STALL) 00364 { 00365 MSC_Handle->hbot.state = BOT_ERROR_OUT; 00366 00367 /* Refer to USB Mass-Storage Class : BOT (www.usb.org) 00368 6.7.3 Ho - Host expects to send data to the device 00369 3. On a STALL condition sending data, then: 00370 " The host shall clear the Bulk-Out pipe. 00371 4. The host shall attempt to receive a CSW. 00372 */ 00373 #if (USBH_USE_OS == 1) 00374 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00375 #endif 00376 } 00377 break; 00378 00379 case BOT_RECEIVE_CSW: 00380 00381 USBH_BulkReceiveData (phost, 00382 MSC_Handle->hbot.csw.data, 00383 BOT_CSW_LENGTH , 00384 MSC_Handle->InPipe); 00385 00386 MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT; 00387 break; 00388 00389 case BOT_RECEIVE_CSW_WAIT: 00390 00391 URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe); 00392 00393 /* Decode CSW */ 00394 if(URB_Status == USBH_URB_DONE) 00395 { 00396 MSC_Handle->hbot.state = BOT_SEND_CBW; 00397 MSC_Handle->hbot.cmd_state = BOT_CMD_SEND; 00398 CSW_Status = USBH_MSC_DecodeCSW(phost); 00399 00400 if(CSW_Status == BOT_CSW_CMD_PASSED) 00401 { 00402 status = USBH_OK; 00403 } 00404 else 00405 { 00406 status = USBH_FAIL; 00407 } 00408 #if (USBH_USE_OS == 1) 00409 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00410 #endif 00411 } 00412 else if(URB_Status == USBH_URB_STALL) 00413 { 00414 MSC_Handle->hbot.state = BOT_ERROR_IN; 00415 #if (USBH_USE_OS == 1) 00416 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); 00417 #endif 00418 } 00419 break; 00420 00421 case BOT_ERROR_IN: 00422 error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_IN); 00423 00424 if (error == USBH_OK) 00425 { 00426 MSC_Handle->hbot.state = BOT_RECEIVE_CSW; 00427 } 00428 else if (error == USBH_UNRECOVERED_ERROR) 00429 { 00430 /* This means that there is a STALL Error limit, Do Reset Recovery */ 00431 MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR; 00432 } 00433 break; 00434 00435 case BOT_ERROR_OUT: 00436 error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_OUT); 00437 00438 if ( error == USBH_OK) 00439 { 00440 00441 toggle = USBH_LL_GetToggle(phost, MSC_Handle->OutPipe); 00442 USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 1- toggle); 00443 USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0); 00444 MSC_Handle->hbot.state = BOT_ERROR_IN; 00445 } 00446 else if (error == USBH_UNRECOVERED_ERROR) 00447 { 00448 MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR; 00449 } 00450 break; 00451 00452 00453 case BOT_UNRECOVERED_ERROR: 00454 status = USBH_MSC_BOT_REQ_Reset(phost); 00455 if ( status == USBH_OK) 00456 { 00457 MSC_Handle->hbot.state = BOT_SEND_CBW; 00458 } 00459 break; 00460 00461 default: 00462 break; 00463 } 00464 return status; 00465 } 00466 00467 /** 00468 * @brief USBH_MSC_BOT_Abort 00469 * The function handle the BOT Abort process. 00470 * @param phost: Host handle 00471 * @param lun: Logical Unit Number 00472 * @param dir: direction (0: out / 1 : in) 00473 * @retval USBH Status 00474 */ 00475 static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir) 00476 { 00477 USBH_StatusTypeDef status = USBH_FAIL; 00478 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00479 00480 switch (dir) 00481 { 00482 case BOT_DIR_IN : 00483 /* send ClrFeture on Bulk IN endpoint */ 00484 status = USBH_ClrFeature(phost, MSC_Handle->InEp); 00485 00486 break; 00487 00488 case BOT_DIR_OUT : 00489 /*send ClrFeature on Bulk OUT endpoint */ 00490 status = USBH_ClrFeature(phost, MSC_Handle->OutEp); 00491 break; 00492 00493 default: 00494 break; 00495 } 00496 return status; 00497 } 00498 00499 /** 00500 * @brief USBH_MSC_BOT_DecodeCSW 00501 * This function decodes the CSW received by the device and updates the 00502 * same to upper layer. 00503 * @param phost: Host handle 00504 * @retval USBH Status 00505 * @notes 00506 * Refer to USB Mass-Storage Class : BOT (www.usb.org) 00507 * 6.3.1 Valid CSW Conditions : 00508 * The host shall consider the CSW valid when: 00509 * 1. dCSWSignature is equal to 53425355h 00510 * 2. the CSW is 13 (Dh) bytes in length, 00511 * 3. dCSWTag matches the dCBWTag from the corresponding CBW. 00512 */ 00513 00514 static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost) 00515 { 00516 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00517 BOT_CSWStatusTypeDef status = BOT_CSW_CMD_FAILED; 00518 00519 /*Checking if the transfer length is different than 13*/ 00520 if(USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != BOT_CSW_LENGTH) 00521 { 00522 /*(4) Hi > Dn (Host expects to receive data from the device, 00523 Device intends to transfer no data) 00524 (5) Hi > Di (Host expects to receive data from the device, 00525 Device intends to send data to the host) 00526 (9) Ho > Dn (Host expects to send data to the device, 00527 Device intends to transfer no data) 00528 (11) Ho > Do (Host expects to send data to the device, 00529 Device intends to receive data from the host)*/ 00530 00531 00532 status = BOT_CSW_PHASE_ERROR; 00533 } 00534 else 00535 { /* CSW length is Correct */ 00536 00537 /* Check validity of the CSW Signature and CSWStatus */ 00538 if(MSC_Handle->hbot.csw.field.Signature == BOT_CSW_SIGNATURE) 00539 {/* Check Condition 1. dCSWSignature is equal to 53425355h */ 00540 00541 if(MSC_Handle->hbot.csw.field.Tag == MSC_Handle->hbot.cbw.field.Tag) 00542 { 00543 /* Check Condition 3. dCSWTag matches the dCBWTag from the 00544 corresponding CBW */ 00545 00546 if(MSC_Handle->hbot.csw.field.Status == 0) 00547 { 00548 /* Refer to USB Mass-Storage Class : BOT (www.usb.org) 00549 00550 Hn Host expects no data transfers 00551 Hi Host expects to receive data from the device 00552 Ho Host expects to send data to the device 00553 00554 Dn Device intends to transfer no data 00555 Di Device intends to send data to the host 00556 Do Device intends to receive data from the host 00557 00558 Section 6.7 00559 (1) Hn = Dn (Host expects no data transfers, 00560 Device intends to transfer no data) 00561 (6) Hi = Di (Host expects to receive data from the device, 00562 Device intends to send data to the host) 00563 (12) Ho = Do (Host expects to send data to the device, 00564 Device intends to receive data from the host) 00565 00566 */ 00567 00568 status = BOT_CSW_CMD_PASSED; 00569 } 00570 else if(MSC_Handle->hbot.csw.field.Status == 1) 00571 { 00572 status = BOT_CSW_CMD_FAILED; 00573 } 00574 00575 else if(MSC_Handle->hbot.csw.field.Status == 2) 00576 { 00577 /* Refer to USB Mass-Storage Class : BOT (www.usb.org) 00578 Section 6.7 00579 (2) Hn < Di ( Host expects no data transfers, 00580 Device intends to send data to the host) 00581 (3) Hn < Do ( Host expects no data transfers, 00582 Device intends to receive data from the host) 00583 (7) Hi < Di ( Host expects to receive data from the device, 00584 Device intends to send data to the host) 00585 (8) Hi <> Do ( Host expects to receive data from the device, 00586 Device intends to receive data from the host) 00587 (10) Ho <> Di (Host expects to send data to the device, 00588 Di Device intends to send data to the host) 00589 (13) Ho < Do (Host expects to send data to the device, 00590 Device intends to receive data from the host) 00591 */ 00592 00593 status = BOT_CSW_PHASE_ERROR; 00594 } 00595 } /* CSW Tag Matching is Checked */ 00596 } /* CSW Signature Correct Checking */ 00597 else 00598 { 00599 /* If the CSW Signature is not valid, We sall return the Phase Error to 00600 Upper Layers for Reset Recovery */ 00601 00602 status = BOT_CSW_PHASE_ERROR; 00603 } 00604 } /* CSW Length Check*/ 00605 00606 return status; 00607 } 00608 00609 00610 /** 00611 * @} 00612 */ 00613 00614 /** 00615 * @} 00616 */ 00617 00618 /** 00619 * @} 00620 */ 00621 00622 /** 00623 * @} 00624 */ 00625 00626 /** 00627 * @} 00628 */ 00629 00630 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 00631 00632 00633
Generated on Tue Jul 12 2022 14:58:25 by
1.7.2