2 ******************************************************************************
4 * @author MCD Application Team
6 * @date 11-December-2015
7 * @brief This file provides all the BOT protocol core functions.
8 ******************************************************************************
11 * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
13 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
14 * You may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at:
17 * http://www.st.com/software_license_agreement_liberty_v2
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
25 ******************************************************************************
28 /* Includes ------------------------------------------------------------------*/
29 #include "usbd_msc_bot.h"
31 #include "usbd_msc_scsi.h"
32 #include "usbd_ioreq.h"
34 /** @addtogroup STM32_USB_DEVICE_LIBRARY
40 * @brief BOT protocol module
44 /** @defgroup MSC_BOT_Private_TypesDefinitions
52 /** @defgroup MSC_BOT_Private_Defines
61 /** @defgroup MSC_BOT_Private_Macros
69 /** @defgroup MSC_BOT_Private_Variables
78 /** @defgroup MSC_BOT_Private_FunctionPrototypes
81 static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef
*pdev
);
83 static void MSC_BOT_SendData (USBD_HandleTypeDef
*pdev
,
87 static void MSC_BOT_Abort(USBD_HandleTypeDef
*pdev
);
93 /** @defgroup MSC_BOT_Private_Functions
100 * @brief MSC_BOT_Init
101 * Initialize the BOT Process
102 * @param pdev: device instance
105 void MSC_BOT_Init (USBD_HandleTypeDef
*pdev
)
107 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
109 hmsc
->bot_state
= USBD_BOT_IDLE
;
110 hmsc
->bot_status
= USBD_BOT_STATUS_NORMAL
;
112 hmsc
->scsi_sense_tail
= 0;
113 hmsc
->scsi_sense_head
= 0;
115 ((USBD_StorageTypeDef
*)pdev
->pUserData
)->Init(0);
117 USBD_LL_FlushEP(pdev
, MSC_EPOUT_ADDR
);
118 USBD_LL_FlushEP(pdev
, MSC_EPIN_ADDR
);
120 /* Prapare EP to Receive First BOT Cmd */
121 USBD_LL_PrepareReceive (pdev
,
123 (uint8_t *)&hmsc
->cbw
,
124 USBD_BOT_CBW_LENGTH
);
128 * @brief MSC_BOT_Reset
129 * Reset the BOT Machine
130 * @param pdev: device instance
133 void MSC_BOT_Reset (USBD_HandleTypeDef
*pdev
)
135 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
137 hmsc
->bot_state
= USBD_BOT_IDLE
;
138 hmsc
->bot_status
= USBD_BOT_STATUS_RECOVERY
;
140 /* Prapare EP to Receive First BOT Cmd */
141 USBD_LL_PrepareReceive (pdev
,
143 (uint8_t *)&hmsc
->cbw
,
144 USBD_BOT_CBW_LENGTH
);
148 * @brief MSC_BOT_DeInit
149 * Deinitialize the BOT Machine
150 * @param pdev: device instance
153 void MSC_BOT_DeInit (USBD_HandleTypeDef
*pdev
)
155 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
156 hmsc
->bot_state
= USBD_BOT_IDLE
;
160 * @brief MSC_BOT_DataIn
161 * Handle BOT IN data stage
162 * @param pdev: device instance
163 * @param epnum: endpoint index
166 void MSC_BOT_DataIn (USBD_HandleTypeDef
*pdev
,
169 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
171 switch (hmsc
->bot_state
)
173 case USBD_BOT_DATA_IN
:
174 if(SCSI_ProcessCmd(pdev
,
176 &hmsc
->cbw
.CB
[0]) < 0)
178 MSC_BOT_SendCSW (pdev
, USBD_CSW_CMD_FAILED
);
182 case USBD_BOT_SEND_DATA
:
183 case USBD_BOT_LAST_DATA_IN
:
184 MSC_BOT_SendCSW (pdev
, USBD_CSW_CMD_PASSED
);
193 * @brief MSC_BOT_DataOut
194 * Process MSC OUT data
195 * @param pdev: device instance
196 * @param epnum: endpoint index
199 void MSC_BOT_DataOut (USBD_HandleTypeDef
*pdev
,
202 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
204 switch (hmsc
->bot_state
)
207 MSC_BOT_CBW_Decode(pdev
);
210 case USBD_BOT_DATA_OUT
:
212 if(SCSI_ProcessCmd(pdev
,
214 &hmsc
->cbw
.CB
[0]) < 0)
216 MSC_BOT_SendCSW (pdev
, USBD_CSW_CMD_FAILED
);
227 * @brief MSC_BOT_CBW_Decode
228 * Decode the CBW command and set the BOT state machine accordingly
229 * @param pdev: device instance
232 static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef
*pdev
)
234 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
236 hmsc
->csw
.dTag
= hmsc
->cbw
.dTag
;
237 hmsc
->csw
.dDataResidue
= hmsc
->cbw
.dDataLength
;
239 if ((USBD_LL_GetRxDataSize (pdev
,MSC_EPOUT_ADDR
) != USBD_BOT_CBW_LENGTH
) ||
240 (hmsc
->cbw
.dSignature
!= USBD_BOT_CBW_SIGNATURE
)||
241 (hmsc
->cbw
.bLUN
> 1) ||
242 (hmsc
->cbw
.bCBLength
< 1) ||
243 (hmsc
->cbw
.bCBLength
> 16))
251 hmsc
->bot_status
= USBD_BOT_STATUS_ERROR
;
257 if(SCSI_ProcessCmd(pdev
,
259 &hmsc
->cbw
.CB
[0]) < 0)
261 if(hmsc
->bot_state
== USBD_BOT_NO_DATA
)
263 MSC_BOT_SendCSW (pdev
,
264 USBD_CSW_CMD_FAILED
);
271 /*Burst xfer handled internally*/
272 else if ((hmsc
->bot_state
!= USBD_BOT_DATA_IN
) &&
273 (hmsc
->bot_state
!= USBD_BOT_DATA_OUT
) &&
274 (hmsc
->bot_state
!= USBD_BOT_LAST_DATA_IN
))
276 if (hmsc
->bot_data_length
> 0)
278 MSC_BOT_SendData(pdev
,
280 hmsc
->bot_data_length
);
282 else if (hmsc
->bot_data_length
== 0)
284 MSC_BOT_SendCSW (pdev
,
285 USBD_CSW_CMD_PASSED
);
292 * @brief MSC_BOT_SendData
293 * Send the requested data
294 * @param pdev: device instance
295 * @param buf: pointer to data buffer
296 * @param len: Data Length
299 static void MSC_BOT_SendData(USBD_HandleTypeDef
*pdev
,
303 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
305 len
= MIN (hmsc
->cbw
.dDataLength
, len
);
306 hmsc
->csw
.dDataResidue
-= len
;
307 hmsc
->csw
.bStatus
= USBD_CSW_CMD_PASSED
;
308 hmsc
->bot_state
= USBD_BOT_SEND_DATA
;
310 USBD_LL_Transmit (pdev
, MSC_EPIN_ADDR
, buf
, len
);
314 * @brief MSC_BOT_SendCSW
315 * Send the Command Status Wrapper
316 * @param pdev: device instance
317 * @param status : CSW status
320 void MSC_BOT_SendCSW (USBD_HandleTypeDef
*pdev
,
323 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
325 hmsc
->csw
.dSignature
= USBD_BOT_CSW_SIGNATURE
;
326 hmsc
->csw
.bStatus
= CSW_Status
;
327 hmsc
->bot_state
= USBD_BOT_IDLE
;
329 USBD_LL_Transmit (pdev
,
331 (uint8_t *)&hmsc
->csw
,
332 USBD_BOT_CSW_LENGTH
);
334 /* Prepare EP to Receive next Cmd */
335 USBD_LL_PrepareReceive (pdev
,
337 (uint8_t *)&hmsc
->cbw
,
338 USBD_BOT_CBW_LENGTH
);
343 * @brief MSC_BOT_Abort
344 * Abort the current transfer
345 * @param pdev: device instance
349 static void MSC_BOT_Abort (USBD_HandleTypeDef
*pdev
)
351 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
353 if ((hmsc
->cbw
.bmFlags
== 0) &&
354 (hmsc
->cbw
.dDataLength
!= 0) &&
355 (hmsc
->bot_status
== USBD_BOT_STATUS_NORMAL
) )
357 USBD_LL_StallEP(pdev
, MSC_EPOUT_ADDR
);
359 USBD_LL_StallEP(pdev
, MSC_EPIN_ADDR
);
361 if(hmsc
->bot_status
== USBD_BOT_STATUS_ERROR
)
363 USBD_LL_PrepareReceive (pdev
,
365 (uint8_t *)&hmsc
->cbw
,
366 USBD_BOT_CBW_LENGTH
);
371 * @brief MSC_BOT_CplClrFeature
372 * Complete the clear feature request
373 * @param pdev: device instance
374 * @param epnum: endpoint index
378 void MSC_BOT_CplClrFeature (USBD_HandleTypeDef
*pdev
, uint8_t epnum
)
380 USBD_MSC_BOT_HandleTypeDef
*hmsc
= (USBD_MSC_BOT_HandleTypeDef
*)pdev
->pClassData
;
382 if(hmsc
->bot_status
== USBD_BOT_STATUS_ERROR
)/* Bad CBW Signature */
384 USBD_LL_StallEP(pdev
, MSC_EPIN_ADDR
);
385 hmsc
->bot_status
= USBD_BOT_STATUS_NORMAL
;
387 else if(((epnum
& 0x80) == 0x80) && ( hmsc
->bot_status
!= USBD_BOT_STATUS_RECOVERY
))
389 MSC_BOT_SendCSW (pdev
, USBD_CSW_CMD_FAILED
);
407 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/