F1 and F3 HAL / LL libraries
[betaflight.git] / lib / main / STM32F3 / Middlewares / ST / STM32_USB_Device_Library / Class / MSC / Src / usbd_msc_bot.c
blob83da84adf02616501327eee5aaca0b05cfee8e3d
1 /**
2 ******************************************************************************
3 * @file usbd_msc_bot.c
4 * @author MCD Application Team
5 * @version V2.4.2
6 * @date 11-December-2015
7 * @brief This file provides all the BOT protocol core functions.
8 ******************************************************************************
9 * @attention
11 * <h2><center>&copy; 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 ******************************************************************************
26 */
28 /* Includes ------------------------------------------------------------------*/
29 #include "usbd_msc_bot.h"
30 #include "usbd_msc.h"
31 #include "usbd_msc_scsi.h"
32 #include "usbd_ioreq.h"
34 /** @addtogroup STM32_USB_DEVICE_LIBRARY
35 * @{
39 /** @defgroup MSC_BOT
40 * @brief BOT protocol module
41 * @{
42 */
44 /** @defgroup MSC_BOT_Private_TypesDefinitions
45 * @{
46 */
47 /**
48 * @}
49 */
52 /** @defgroup MSC_BOT_Private_Defines
53 * @{
54 */
56 /**
57 * @}
58 */
61 /** @defgroup MSC_BOT_Private_Macros
62 * @{
63 */
64 /**
65 * @}
66 */
69 /** @defgroup MSC_BOT_Private_Variables
70 * @{
71 */
73 /**
74 * @}
75 */
78 /** @defgroup MSC_BOT_Private_FunctionPrototypes
79 * @{
80 */
81 static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev);
83 static void MSC_BOT_SendData (USBD_HandleTypeDef *pdev,
84 uint8_t* pbuf,
85 uint16_t len);
87 static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
88 /**
89 * @}
90 */
93 /** @defgroup MSC_BOT_Private_Functions
94 * @{
95 */
99 /**
100 * @brief MSC_BOT_Init
101 * Initialize the BOT Process
102 * @param pdev: device instance
103 * @retval None
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,
122 MSC_EPOUT_ADDR,
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
131 * @retval None
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,
142 MSC_EPOUT_ADDR,
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
151 * @retval None
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
164 * @retval None
166 void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev,
167 uint8_t epnum)
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,
175 hmsc->cbw.bLUN,
176 &hmsc->cbw.CB[0]) < 0)
178 MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED);
180 break;
182 case USBD_BOT_SEND_DATA:
183 case USBD_BOT_LAST_DATA_IN:
184 MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_PASSED);
186 break;
188 default:
189 break;
193 * @brief MSC_BOT_DataOut
194 * Process MSC OUT data
195 * @param pdev: device instance
196 * @param epnum: endpoint index
197 * @retval None
199 void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev,
200 uint8_t epnum)
202 USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData;
204 switch (hmsc->bot_state)
206 case USBD_BOT_IDLE:
207 MSC_BOT_CBW_Decode(pdev);
208 break;
210 case USBD_BOT_DATA_OUT:
212 if(SCSI_ProcessCmd(pdev,
213 hmsc->cbw.bLUN,
214 &hmsc->cbw.CB[0]) < 0)
216 MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED);
219 break;
221 default:
222 break;
227 * @brief MSC_BOT_CBW_Decode
228 * Decode the CBW command and set the BOT state machine accordingly
229 * @param pdev: device instance
230 * @retval None
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))
246 SCSI_SenseCode(pdev,
247 hmsc->cbw.bLUN,
248 ILLEGAL_REQUEST,
249 INVALID_CDB);
251 hmsc->bot_status = USBD_BOT_STATUS_ERROR;
252 MSC_BOT_Abort(pdev);
255 else
257 if(SCSI_ProcessCmd(pdev,
258 hmsc->cbw.bLUN,
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);
266 else
268 MSC_BOT_Abort(pdev);
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,
279 hmsc->bot_data,
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
297 * @retval None
299 static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev,
300 uint8_t* buf,
301 uint16_t len)
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
318 * @retval None
320 void MSC_BOT_SendCSW (USBD_HandleTypeDef *pdev,
321 uint8_t CSW_Status)
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,
330 MSC_EPIN_ADDR,
331 (uint8_t *)&hmsc->csw,
332 USBD_BOT_CSW_LENGTH);
334 /* Prepare EP to Receive next Cmd */
335 USBD_LL_PrepareReceive (pdev,
336 MSC_EPOUT_ADDR,
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
346 * @retval status
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,
364 MSC_EPOUT_ADDR,
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
375 * @retval None
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);
394 * @}
399 * @}
404 * @}
407 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/