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