2 ******************************************************************************
4 * @author MCD Application Team
7 * @brief This file provides all the BOT protocol core functions.
8 ******************************************************************************
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
19 ******************************************************************************
22 /* Includes ------------------------------------------------------------------*/
23 #include "usbd_msc_bot.h"
24 #include "usbd_msc_scsi.h"
25 #include "usbd_ioreq.h"
26 #include "usbd_msc_mem.h"
27 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
33 * @brief BOT protocol module
37 /** @defgroup MSC_BOT_Private_TypesDefinitions
45 /** @defgroup MSC_BOT_Private_Defines
54 /** @defgroup MSC_BOT_Private_Macros
62 /** @defgroup MSC_BOT_Private_Variables
65 uint16_t MSC_BOT_DataLen;
66 uint8_t MSC_BOT_State;
67 uint8_t MSC_BOT_Status;
69 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
70 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
71 #pragma data_alignment=4
73 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
74 __ALIGN_BEGIN uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET] __ALIGN_END ;
76 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
77 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
78 #pragma data_alignment=4
80 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
81 __ALIGN_BEGIN MSC_BOT_CBW_TypeDef MSC_BOT_cbw __ALIGN_END ;
83 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
84 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
85 #pragma data_alignment=4
87 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
88 __ALIGN_BEGIN MSC_BOT_CSW_TypeDef MSC_BOT_csw __ALIGN_END ;
94 /** @defgroup MSC_BOT_Private_FunctionPrototypes
97 static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev);
99 static void MSC_BOT_SendData (USB_OTG_CORE_HANDLE *pdev,
103 static void MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev);
109 /** @defgroup MSC_BOT_Private_Functions
116 * @brief MSC_BOT_Init
117 * Initialize the BOT Process
118 * @param pdev: device instance
121 void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev)
123 MSC_BOT_State = BOT_IDLE;
124 MSC_BOT_Status = BOT_STATE_NORMAL;
125 USBD_STORAGE_fops->Init(0);
127 DCD_EP_Flush(pdev, MSC_OUT_EP);
128 DCD_EP_Flush(pdev, MSC_IN_EP);
129 /* Prapare EP to Receive First BOT Cmd */
130 DCD_EP_PrepareRx (pdev,
132 (uint8_t *)&MSC_BOT_cbw,
137 * @brief MSC_BOT_Reset
138 * Reset the BOT Machine
139 * @param pdev: device instance
142 void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev)
144 MSC_BOT_State = BOT_IDLE;
145 MSC_BOT_Status = BOT_STATE_RECOVERY;
146 /* Prapare EP to Receive First BOT Cmd */
147 DCD_EP_PrepareRx (pdev,
149 (uint8_t *)&MSC_BOT_cbw,
154 * @brief MSC_BOT_DeInit
155 * Uninitialize the BOT Machine
156 * @param pdev: device instance
159 void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev)
161 MSC_BOT_State = BOT_IDLE;
165 * @brief MSC_BOT_DataIn
166 * Handle BOT IN data stage
167 * @param pdev: device instance
168 * @param epnum: endpoint index
171 void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev,
175 switch (MSC_BOT_State)
178 if(SCSI_ProcessCmd(pdev,
180 &MSC_BOT_cbw.CB[0]) < 0)
182 MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
187 case BOT_LAST_DATA_IN:
188 MSC_BOT_SendCSW (pdev, CSW_CMD_PASSED);
197 * @brief MSC_BOT_DataOut
198 * Proccess MSC OUT data
199 * @param pdev: device instance
200 * @param epnum: endpoint index
203 void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev,
206 switch (MSC_BOT_State)
209 MSC_BOT_CBW_Decode(pdev);
214 if(SCSI_ProcessCmd(pdev,
216 &MSC_BOT_cbw.CB[0]) < 0)
218 MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
230 * @brief MSC_BOT_CBW_Decode
231 * Decode the CBW command and set the BOT state machine accordingtly
232 * @param pdev: device instance
235 static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev)
238 MSC_BOT_csw.dTag = MSC_BOT_cbw.dTag;
239 MSC_BOT_csw.dDataResidue = MSC_BOT_cbw.dDataLength;
241 if ((USBD_GetRxCount (pdev ,MSC_OUT_EP) != BOT_CBW_LENGTH) ||
242 (MSC_BOT_cbw.dSignature != BOT_CBW_SIGNATURE)||
243 (MSC_BOT_cbw.bLUN > 1) ||
244 (MSC_BOT_cbw.bCBLength < 1) ||
245 (MSC_BOT_cbw.bCBLength > 16))
248 SCSI_SenseCode(MSC_BOT_cbw.bLUN,
251 MSC_BOT_Status = BOT_STATE_ERROR;
257 if(SCSI_ProcessCmd(pdev,
259 &MSC_BOT_cbw.CB[0]) < 0)
263 /*Burst xfer handled internally*/
264 else if ((MSC_BOT_State != BOT_DATA_IN) &&
265 (MSC_BOT_State != BOT_DATA_OUT) &&
266 (MSC_BOT_State != BOT_LAST_DATA_IN))
268 if (MSC_BOT_DataLen > 0)
270 MSC_BOT_SendData(pdev,
274 else if (MSC_BOT_DataLen == 0)
276 MSC_BOT_SendCSW (pdev,
284 * @brief MSC_BOT_SendData
285 * Send the requested data
286 * @param pdev: device instance
287 * @param buf: pointer to data buffer
288 * @param len: Data Length
291 static void MSC_BOT_SendData(USB_OTG_CORE_HANDLE *pdev,
296 len = MIN (MSC_BOT_cbw.dDataLength, len);
297 MSC_BOT_csw.dDataResidue -= len;
298 MSC_BOT_csw.bStatus = CSW_CMD_PASSED;
299 MSC_BOT_State = BOT_SEND_DATA;
301 DCD_EP_Tx (pdev, MSC_IN_EP, buf, len);
305 * @brief MSC_BOT_SendCSW
306 * Send the Command Status Wrapper
307 * @param pdev: device instance
308 * @param status : CSW status
311 void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev,
314 MSC_BOT_csw.dSignature = BOT_CSW_SIGNATURE;
315 MSC_BOT_csw.bStatus = CSW_Status;
316 MSC_BOT_State = BOT_IDLE;
320 (uint8_t *)&MSC_BOT_csw,
323 /* Prapare EP to Receive next Cmd */
324 DCD_EP_PrepareRx (pdev,
326 (uint8_t *)&MSC_BOT_cbw,
332 * @brief MSC_BOT_Abort
333 * Abort the current transfer
334 * @param pdev: device instance
338 static void MSC_BOT_Abort (USB_OTG_CORE_HANDLE *pdev)
341 if ((MSC_BOT_cbw.bmFlags == 0) &&
342 (MSC_BOT_cbw.dDataLength != 0) &&
343 (MSC_BOT_Status == BOT_STATE_NORMAL) )
345 DCD_EP_Stall(pdev, MSC_OUT_EP );
347 DCD_EP_Stall(pdev, MSC_IN_EP);
349 if(MSC_BOT_Status == BOT_STATE_ERROR)
351 DCD_EP_PrepareRx (pdev,
353 (uint8_t *)&MSC_BOT_cbw,
359 * @brief MSC_BOT_CplClrFeature
360 * Complete the clear feature request
361 * @param pdev: device instance
362 * @param epnum: endpoint index
366 void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
368 if(MSC_BOT_Status == BOT_STATE_ERROR )/* Bad CBW Signature */
370 DCD_EP_Stall(pdev, MSC_IN_EP);
371 MSC_BOT_Status = BOT_STATE_NORMAL;
373 else if(((epnum & 0x80) == 0x80) && ( MSC_BOT_Status != BOT_STATE_RECOVERY))
375 MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
393 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/