1 /******************************************************************************************************************************************
2 * 文件名称: usbh_msc_core.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 USBH_Class_cb_t USBH_MSC_cb =
30 {
31 USBH_MSC_Init,
32 USBH_MSC_DeInit,
33 USBH_MSC_Request,
34 USBH_MSC_Process,
35 };
36
37
38 volatile USBH_MSC_Info_t USBH_MSC_Info;
39 volatile USBH_BOTXfer_t USBH_BOTXfer;
40
41
42 static uint8_t DataInBuffer[64];
43
44
45 /******************************************************************************************************************************************
46 * 函数名称: USBH_MSC_Init()
47 * 功能说明:
48 * 输 入: 无
49 * 输 出: 无
50 * 注意事项: 无
51 ******************************************************************************************************************************************/
USBH_MSC_Init(USBH_Info_t * phost)52 USBH_Status USBH_MSC_Init(USBH_Info_t *phost)
53 {
54 USB_EpDesc_t *pEpIn, *pEpOut;
55
56 if((phost->Device.Intf_Desc[0].bInterfaceClass == USB_MSC_CLASS) && \
57 (phost->Device.Intf_Desc[0].bInterfaceProtocol == USB_MSC_BOT))
58 {
59 if(phost->Device.Ep_Desc[0][0].bEndpointAddress & USB_EP_IN)
60 {
61 pEpIn = &phost->Device.Ep_Desc[0][0];
62 pEpOut = &phost->Device.Ep_Desc[0][1];
63 }
64 else
65 {
66 pEpIn = &phost->Device.Ep_Desc[0][1];
67 pEpOut = &phost->Device.Ep_Desc[0][0];
68 }
69
70 USBH_MSC_Info.InEp = pEpIn->bEndpointAddress;
71 USBH_MSC_Info.InEpSize = pEpIn->wMaxPacketSize;
72 USBH_MSC_Info.OutEp = pEpOut->bEndpointAddress;
73 USBH_MSC_Info.OutEpSize = pEpOut->wMaxPacketSize;
74
75 USBH_MSC_DeInit(phost);
76 }
77 else
78 {
79 if(phost->usr_cb->DeviceNotSupported)
80 phost->usr_cb->DeviceNotSupported();
81 }
82
83 return USBH_OK ;
84 }
85
86
87 /******************************************************************************************************************************************
88 * 函数名称: USBH_MSC_DeInit()
89 * 功能说明:
90 * 输 入: 无
91 * 输 出: 无
92 * 注意事项: 无
93 ******************************************************************************************************************************************/
USBH_MSC_DeInit(USBH_Info_t * phost)94 void USBH_MSC_DeInit(USBH_Info_t *phost)
95 {
96 USBH_MSC_Info.Ready = 0;
97 USBH_MSC_Info.InEpDATAX = 0;
98 USBH_MSC_Info.OutEpDATAX = 0;
99
100 USBH_MSC_BOT_Init();
101 }
102
103
104 /******************************************************************************************************************************************
105 * 函数名称: USBH_MSC_Request()
106 * 功能说明:
107 * 输 入: 无
108 * 输 出: 无
109 * 注意事项: 无
110 ******************************************************************************************************************************************/
USBH_MSC_Request(USBH_Info_t * phost)111 USBH_Status USBH_MSC_Request(USBH_Info_t *phost)
112 {
113 USBH_BOTXfer.MSCState = USBH_MSC_GET_MAXLUN;
114
115 return USBH_OK;
116 }
117
118
119 /******************************************************************************************************************************************
120 * 函数名称: USBH_MSC_Process()
121 * 功能说明: MSC state machine handler
122 * 输 入: 无
123 * 输 出: 无
124 * 注意事项: 无
125 ******************************************************************************************************************************************/
USBH_MSC_Process(USBH_Info_t * phost)126 USBH_Status USBH_MSC_Process(USBH_Info_t *phost)
127 {
128 USBH_Status status = USBH_BUSY;
129
130 uint8_t mscStatus;
131 uint8_t appStatus;
132
133 switch(USBH_BOTXfer.MSCState)
134 {
135 case USBH_MSC_GET_MAXLUN:
136 status = USBH_MSC_getMaxLUN(phost);
137 if(status == USBH_OK)
138 {
139 USBH_MSC_Info.MaxLUN = DataInBuffer[0];
140
141 USBH_BOTXfer.MSCState = USBH_MSC_TEST_UNIT_READY;
142 }
143 else if(status == USBH_NOT_SUPPORTED)
144 {
145 /* 清除 STALL 后,进入 USBH_MSC_TEST_UNIT_READY */
146 USBH_BOTXfer.MSCStateBkp = USBH_MSC_TEST_UNIT_READY;
147
148 USBH_BOTXfer.MSCState = USBH_MSC_CLEAR_STALL;
149 }
150 break;
151
152 case USBH_MSC_CLEAR_STALL:
153 status = USBH_ClrFeature(phost, USBH_MSC_Info.InEp);
154 if(status == USBH_OK)
155 {
156 USBH_MSC_Info.MaxLUN = 0; // 不支持 GetMaxLUN 请求,假设只有一个逻辑单元
157
158 USBH_BOTXfer.MSCState = USBH_BOTXfer.MSCStateBkp;
159 }
160 break;
161
162 case USBH_MSC_TEST_UNIT_READY:
163 mscStatus = USBH_MSC_TestUnitReady();
164 if(mscStatus == USBH_MSC_OK)
165 {
166 USBH_BOTXfer.MSCState = USBH_MSC_READ_CAPACITY10;
167
168 status = USBH_OK;
169 }
170 else
171 {
172 USBH_MSC_ErrorHandle(mscStatus);
173 }
174 break;
175
176 case USBH_MSC_READ_CAPACITY10:
177 mscStatus = USBH_MSC_ReadCapacity10();
178 if(mscStatus == USBH_MSC_OK)
179 {
180 USBH_BOTXfer.MSCState = USBH_MSC_DEFAULT_APP;
181
182 USBH_MSC_Info.Ready = 1;
183
184 status = USBH_OK;
185 }
186 else
187 {
188 USBH_MSC_ErrorHandle(mscStatus);
189 }
190 break;
191
192 case USBH_MSC_MODE_SENSE6:
193 /* Issue ModeSense6 SCSI command for detecting if device is write-protected */
194 mscStatus = USBH_MSC_ModeSense6();
195 if(mscStatus == USBH_MSC_OK)
196 {
197 USBH_BOTXfer.MSCState = USBH_MSC_DEFAULT_APP;
198
199 status = USBH_OK;
200 }
201 else
202 {
203 USBH_MSC_ErrorHandle(mscStatus);
204 }
205 break;
206
207 case USBH_MSC_DEFAULT_APP:
208 /* Process Application callback for MSC */
209 appStatus = phost->usr_cb->UserApplication();
210 if(appStatus == 1)
211 {
212 /* De-init requested from application layer */
213 status = USBH_APPLY_DEINIT;
214 }
215 break;
216
217 case USBH_MSC_BOT_TRANSFER:
218 USBH_MSC_BOT_Process(phost);
219 break;
220
221 case USBH_MSC_UNRECOVERED_STATE:
222 status = USBH_UNRECOVERED_ERROR;
223 break;
224
225 case USBH_MSC_REQUEST_SENSE:
226 /* Issue RequestSense SCSI command for retrieving error code */
227 mscStatus = USBH_MSC_RequestSense();
228 if(mscStatus == USBH_MSC_OK)
229 {
230 USBH_BOTXfer.MSCState = USBH_BOTXfer.MSCStateBkp;
231
232 status = USBH_OK;
233 }
234 else
235 {
236 USBH_MSC_ErrorHandle(mscStatus);
237 }
238 break;
239
240 default:
241 break;
242 }
243
244 return status;
245 }
246
247
248 /******************************************************************************************************************************************
249 * 函数名称: USBH_MSC_getMaxLUN()
250 * 功能说明:
251 * 输 入: 无
252 * 输 出: 无
253 * 注意事项: 无
254 ******************************************************************************************************************************************/
USBH_MSC_getMaxLUN(USBH_Info_t * phost)255 USBH_Status USBH_MSC_getMaxLUN(USBH_Info_t *phost)
256 {
257 phost->Ctrl.setup.bRequestType = USB_REQ_D2H | USB_REQ_CLASS | USB_REQ_TO_INTERFACE;
258
259 phost->Ctrl.setup.bRequest = 0xFE;
260 phost->Ctrl.setup.wValue = 0;
261 phost->Ctrl.setup.wIndex = 0;
262 phost->Ctrl.setup.wLength = 1;
263
264 return USBH_CtrlTransfer(phost, DataInBuffer , 1);
265 }
266
267
268 /******************************************************************************************************************************************
269 * 函数名称: USBH_MSC_ErrorHandle()
270 * 功能说明:
271 * 输 入: 无
272 * 输 出: 无
273 * 注意事项: 无
274 ******************************************************************************************************************************************/
USBH_MSC_ErrorHandle(uint8_t status)275 void USBH_MSC_ErrorHandle(uint8_t status)
276 {
277 if(status == USBH_MSC_FAIL)
278 {
279 /* Try MSC level error recovery, Issue the request Sense to get Drive error reason */
280 USBH_BOTXfer.MSCState = USBH_MSC_REQUEST_SENSE;
281 }
282 else if(status == USBH_MSC_PHASE_ERROR)
283 {
284 /* Phase error, Go to Unrecovered state */
285 USBH_BOTXfer.MSCState = USBH_MSC_UNRECOVERED_STATE;
286 }
287 }
288