1 /******************************************************************************************************************************************
2 * 文件名称: usbh_msc_bot.c
3 * 功能说明:
4 * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
5 * 注意事项:
6 * 版本日期: V1.1.0      2020年11月3日
7 * 升级记录:
8 *
9 *
10 *******************************************************************************************************************************************
11 * @attention
12 *
13 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
14 * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
15 * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
16 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
17 * -ECTION WITH THEIR PRODUCTS.
18 *
19 * COPYRIGHT 2012 Synwit Technology
20 *******************************************************************************************************************************************/
21 #include "SWM341.h"
22 #include "usbh_core.h"
23 #include "usbh_stdreq.h"
24 #include "usbh_msc_bot.h"
25 #include "usbh_msc_core.h"
26 #include "usbh_msc_scsi.h"
27 
28 
29 #define MSC_CBW_SIGNATURE   0x43425355
30 #define MSC_CBW_TAG         0x20304050
31 #define MSC_CSW_SIGNATURE   0x53425355
32 #define MSC_CBW_LENGTH      31
33 #define MSC_CSW_LENGTH      13
34 
35 
36 USBH_CBWPkt_t USBH_CBWData;
37 USBH_CSWPkt_t USBH_CSWData;
38 
39 
40 static uint32_t BOT_StallCount;
41 static uint32_t BOT_ErrorCount;
42 
43 
44 /******************************************************************************************************************************************
45 * 函数名称: USBH_MSC_BOT_Init()
46 * 功能说明:
47 * 输    入: 无
48 * 输    出: 无
49 * 注意事项: 无
50 ******************************************************************************************************************************************/
USBH_MSC_BOT_Init(void)51 void USBH_MSC_BOT_Init(void)
52 {
53     USBH_CBWData.CBWSignature = MSC_CBW_SIGNATURE;
54     USBH_CBWData.CBWTag = MSC_CBW_TAG;
55     USBH_CBWData.CBWLUN = 0;
56 
57     BOT_StallCount = 0;
58     BOT_ErrorCount = 0;
59 }
60 
61 
62 /******************************************************************************************************************************************
63 * 函数名称: USBH_MSC_BOT_Process()
64 * 功能说明:
65 * 输    入: 无
66 * 输    出: 无
67 * 注意事项: 无
68 ******************************************************************************************************************************************/
USBH_MSC_BOT_Process(USBH_Info_t * phost)69 void USBH_MSC_BOT_Process(USBH_Info_t *phost)
70 {
71     static uint32_t remLen;     // remaining length
72     static uint8_t *pdBuff;
73     USBH_Status stat;
74     USBH_Resp resp;
75     uint32_t size;
76 
77     switch(USBH_BOTXfer.BOTState)
78     {
79     case USBH_MSC_BOT_CBW:
80         if(USBH_SendOutPacket(phost->Device.Address, USBH_MSC_Info.OutEp, USBH_MSC_Info.OutEpDATAX, (uint8_t *)&USBH_CBWData, MSC_CBW_LENGTH))
81         {
82             USBH_BOTXfer.BOTStateBkp = USBH_BOTXfer.BOTState;
83             USBH_BOTXfer.BOTState = USBH_MSC_BOT_CBW_WAIT;
84             BOT_ErrorCount = 0;
85         }
86         break;
87 
88     case USBH_MSC_BOT_CBW_WAIT:
89         resp = USBH_State();
90         if(resp == USBR_ACK)
91         {
92             BOT_StallCount = 0;
93 
94             USBH_MSC_Info.OutEpDATAX ^= 1;
95 
96             if(USBH_CBWData.CBWTransferLength != 0)
97             {
98                 remLen = USBH_CBWData.CBWTransferLength;
99                 pdBuff = USBH_BOTXfer.pDataBuffer;
100 
101                 if((USBH_CBWData.CBWFlags & USB_REQ_DIR_MASK) == USB_REQ_D2H)
102                 {
103                     USBH_BOTXfer.BOTState = USBH_MSC_BOT_DIN;
104                 }
105                 else
106                 {
107                     USBH_BOTXfer.BOTState = USBH_MSC_BOT_DOUT;
108                 }
109             }
110             else    // NO Data Transfer Stage
111             {
112                 USBH_BOTXfer.BOTState = USBH_MSC_BOT_CSW;
113             }
114         }
115         else if(resp == USBR_NAK)
116         {
117             USBH_BOTXfer.BOTState = USBH_BOTXfer.BOTStateBkp;
118         }
119         else if(resp == USBR_STALL)
120         {
121             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_STALL_OUT;
122         }
123         else if(resp == USBR_ERROR)
124         {
125             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_ERROR;
126         }
127         break;
128 
129     case USBH_MSC_BOT_DIN:
130         size = (remLen > USBH_MSC_Info.InEpSize) ? USBH_MSC_Info.InEpSize : remLen;
131         if(USBH_SendInPacket(phost->Device.Address, USBH_MSC_Info.InEp, USBH_MSC_Info.InEpDATAX, size))
132         {
133             USBH_BOTXfer.BOTStateBkp = USBH_BOTXfer.BOTState;
134             USBH_BOTXfer.BOTState = USBH_MSC_BOT_DIN_WAIT;
135         }
136         break;
137 
138     case USBH_MSC_BOT_DIN_WAIT:
139         resp = USBH_State();
140         if(resp == USBR_ACK)
141         {
142             BOT_StallCount = 0;
143 
144             USBH_MSC_Info.InEpDATAX ^= 1;
145 
146             if(remLen > USBH_MSC_Info.InEpSize)
147             {
148                 USBH_ReadRxBuffer(pdBuff, USBH_MSC_Info.InEpSize);
149 
150                 remLen -= USBH_MSC_Info.InEpSize;
151                 pdBuff += USBH_MSC_Info.InEpSize;
152 
153                 USBH_BOTXfer.BOTState = USBH_MSC_BOT_DIN;
154             }
155             else
156             {
157                 USBH_ReadRxBuffer(pdBuff, remLen);
158 
159                 USBH_BOTXfer.BOTState = USBH_MSC_BOT_CSW;
160             }
161         }
162         else if(resp == USBR_NAK)
163         {
164             USBH_BOTXfer.BOTState = USBH_BOTXfer.BOTStateBkp;
165         }
166         else if(resp == USBR_STALL)
167         {
168             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_STALL_IN;
169         }
170         else if(resp == USBR_ERROR)
171         {
172             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_ERROR;
173         }
174         break;
175 
176     case USBH_MSC_BOT_DOUT:
177         size = (remLen > USBH_MSC_Info.OutEpSize) ? USBH_MSC_Info.OutEpSize : remLen;
178         if(USBH_SendOutPacket(phost->Device.Address, USBH_MSC_Info.OutEp, USBH_MSC_Info.OutEpDATAX, pdBuff, size))
179         {
180             USBH_BOTXfer.BOTStateBkp = USBH_BOTXfer.BOTState;
181             USBH_BOTXfer.BOTState = USBH_MSC_BOT_DOUT_WAIT;
182         }
183         break;
184 
185     case USBH_MSC_BOT_DOUT_WAIT:
186         resp = USBH_State();
187         if(resp == USBR_ACK)
188         {
189             BOT_StallCount = 0;
190 
191             USBH_MSC_Info.OutEpDATAX ^= 1;
192 
193             if(remLen > USBH_MSC_Info.OutEpSize)
194             {
195                 remLen -= USBH_MSC_Info.OutEpSize;
196                 pdBuff += USBH_MSC_Info.OutEpSize;
197 
198                 USBH_BOTXfer.BOTState = USBH_MSC_BOT_DOUT;
199             }
200             else
201             {
202                 USBH_BOTXfer.BOTState = USBH_MSC_BOT_CSW;
203             }
204         }
205         else if(resp == USBR_NAK)
206         {
207             USBH_BOTXfer.BOTState = USBH_BOTXfer.BOTStateBkp;
208         }
209         else if(resp == USBR_STALL)
210         {
211             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_STALL_OUT;
212         }
213         else if(resp == USBR_ERROR)
214         {
215             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_ERROR;
216         }
217         break;
218 
219     case USBH_MSC_BOT_CSW:
220         if(USBH_SendInPacket(phost->Device.Address, USBH_MSC_Info.InEp, USBH_MSC_Info.InEpDATAX, MSC_CSW_LENGTH))
221         {
222             USBH_BOTXfer.BOTStateBkp = USBH_BOTXfer.BOTState;
223             USBH_BOTXfer.BOTState = USBH_MSC_BOT_CSW_WAIT;
224         }
225         break;
226 
227     case USBH_MSC_BOT_CSW_WAIT:
228         resp = USBH_State();
229         if(resp == USBR_ACK)
230         {
231             BOT_StallCount = 0;
232 
233             USBH_MSC_Info.InEpDATAX ^= 1;
234 
235             USBH_ReadRxBuffer((uint8_t *)&USBH_CSWData, MSC_CSW_LENGTH);
236             USBH_BOTXfer.bCSWStatus = USBH_MSC_BOT_DecodeCSW(phost);
237 
238             USBH_BOTXfer.MSCState = USBH_BOTXfer.MSCStateBkp;
239         }
240         else if(resp == USBR_NAK)
241         {
242             USBH_BOTXfer.BOTState = USBH_BOTXfer.BOTStateBkp;
243         }
244         else if(resp == USBR_STALL)
245         {
246             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_STALL_IN;
247         }
248         else if(resp == USBR_ERROR)
249         {
250             USBH_BOTXfer.BOTState = USBH_MSC_BOT_HANDLE_ERROR;
251         }
252         break;
253 
254     case USBH_MSC_BOT_HANDLE_ERROR:
255         BOT_ErrorCount++;
256         if(BOT_ErrorCount < 5)
257         {
258             USBH_BOTXfer.BOTState = USBH_BOTXfer.BOTStateBkp;   // retry
259         }
260         else
261         {
262             USBH_BOTXfer.bCSWStatus = USBH_MSC_PHASE_ERROR;     // unrecovered error
263 
264             USBH_BOTXfer.MSCState = USBH_BOTXfer.MSCStateBkp;
265         }
266         break;
267 
268     case USBH_MSC_BOT_HANDLE_STALL_IN:
269         stat = USBH_ClrFeature(phost, USBH_MSC_Info.InEp);
270         if(stat == USBH_OK)
271         {
272             USBH_MSC_Info.InEpDATAX = 0;
273 
274             USBH_BOTXfer.BOTState = USBH_BOTXfer.BOTStateBkp;
275         }
276         break;
277 
278     case USBH_MSC_BOT_HANDLE_STALL_OUT:
279         stat = USBH_ClrFeature(phost, USBH_MSC_Info.OutEp);
280         if(stat == USBH_OK)
281         {
282             USBH_MSC_Info.OutEpDATAX = 0;
283 
284             USBH_BOTXfer.BOTState = USBH_BOTXfer.BOTStateBkp;
285         }
286         break;
287 
288     default:
289         break;
290     }
291 }
292 
293 
294 /******************************************************************************************************************************************
295 * 函数名称: USBH_MSC_BOT_DecodeCSW()
296 * 功能说明:
297 * 输    入: 无
298 * 输    出: 无
299 * 注意事项: 无
300 ******************************************************************************************************************************************/
USBH_MSC_BOT_DecodeCSW(USBH_Info_t * phost)301 uint8_t USBH_MSC_BOT_DecodeCSW(USBH_Info_t *phost)
302 {
303     uint8_t status;
304 
305     if(USBH_CSWData.CSWSignature == MSC_CSW_SIGNATURE)
306     {
307         if(USBH_CSWData.CSWTag == USBH_CBWData.CBWTag)
308         {
309             status = USBH_CSWData.CSWStatus;
310         }
311         else    // CSW Tag Error
312         {
313             status = USBH_MSC_PHASE_ERROR;
314         }
315     }
316     else        // CSW Signature Error
317     {
318         status = USBH_MSC_PHASE_ERROR;
319     }
320 
321     return status;
322 }
323 
324