1 /******************************************************************************************************************************************
2 * 文件名称: usbh_mtp.c
3 * 功能说明: This file is the MTP Layer Handlers for USB Host MTP class.
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 <stdlib.h>
22 #include <string.h>
23 #include "SWM341.h"
24 #include "usbh_core.h"
25 #include "usbh_mtp.h"
26
27
28 static USBH_Status USBH_MTP_Init(USBH_Info_t *phost);
29 static void USBH_MTP_DeInit(USBH_Info_t *phost);
30 static USBH_Status USBH_MTP_Request(USBH_Info_t *phost);
31 static USBH_Status USBH_MTP_Process(USBH_Info_t *phost);
32
33 USBH_Class_cb_t USBH_MTP_cb =
34 {
35 USBH_MTP_Init,
36 USBH_MTP_DeInit,
37 USBH_MTP_Request,
38 USBH_MTP_Process,
39 };
40
41
42 USBH_MTP_Info_t USBH_MTP_Info;
43
44
45 /******************************************************************************************************************************************
46 * 函数名称: USBH_MTP_Init()
47 * 功能说明:
48 * 输 入: 无
49 * 输 出: 无
50 * 注意事项: 无
51 ******************************************************************************************************************************************/
USBH_MTP_Init(USBH_Info_t * phost)52 static USBH_Status USBH_MTP_Init(USBH_Info_t *phost)
53 {
54 USB_EpDesc_t *pEpIn, *pEpOut, *pEpNotify;
55
56 for(int i = 0; i < phost->Device.Cfg_Desc.bNumInterfaces; i++)
57 {
58 if(((phost->Device.Intf_Desc[i].bInterfaceClass == USB_MTP_CLASS) && (phost->Device.Intf_Desc[i].bNumEndpoints == 3)) ||
59 ((phost->Device.Intf_Desc[i].bInterfaceClass == 0xFF) && (phost->Device.Intf_Desc[i].bNumEndpoints == 3)))
60 {
61 #define EpVerify(ep, dir, type) (((phost->Device.Ep_Desc[i][ep].bEndpointAddress & USB_EP_IN) == dir) && \
62 ((phost->Device.Ep_Desc[i][ep].bmAttributes & USB_EP_INT) == type))
63 if(EpVerify(0, USB_EP_IN, USB_EP_INT) && EpVerify(1, USB_EP_IN, USB_EP_BULK) && EpVerify(2, USB_EP_OUT, USB_EP_BULK))
64 {
65 pEpNotify = &phost->Device.Ep_Desc[i][0];
66 pEpIn = &phost->Device.Ep_Desc[i][1];
67 pEpOut = &phost->Device.Ep_Desc[i][2];
68 }
69 else if(EpVerify(0, USB_EP_IN, USB_EP_INT) && EpVerify(2, USB_EP_IN, USB_EP_BULK) && EpVerify(1, USB_EP_OUT, USB_EP_BULK))
70 {
71 pEpNotify = &phost->Device.Ep_Desc[i][0];
72 pEpIn = &phost->Device.Ep_Desc[i][2];
73 pEpOut = &phost->Device.Ep_Desc[i][1];
74 }
75 else if(EpVerify(1, USB_EP_IN, USB_EP_INT) && EpVerify(0, USB_EP_IN, USB_EP_BULK) && EpVerify(2, USB_EP_OUT, USB_EP_BULK))
76 {
77 pEpNotify = &phost->Device.Ep_Desc[i][1];
78 pEpIn = &phost->Device.Ep_Desc[i][0];
79 pEpOut = &phost->Device.Ep_Desc[i][2];
80 }
81 else if(EpVerify(1, USB_EP_IN, USB_EP_INT) && EpVerify(2, USB_EP_IN, USB_EP_BULK) && EpVerify(0, USB_EP_OUT, USB_EP_BULK))
82 {
83 pEpNotify = &phost->Device.Ep_Desc[i][1];
84 pEpIn = &phost->Device.Ep_Desc[i][2];
85 pEpOut = &phost->Device.Ep_Desc[i][0];
86 }
87 else if(EpVerify(2, USB_EP_IN, USB_EP_INT) && EpVerify(0, USB_EP_IN, USB_EP_BULK) && EpVerify(1, USB_EP_OUT, USB_EP_BULK))
88 {
89 pEpNotify = &phost->Device.Ep_Desc[i][2];
90 pEpIn = &phost->Device.Ep_Desc[i][0];
91 pEpOut = &phost->Device.Ep_Desc[i][1];
92 }
93 else if(EpVerify(2, USB_EP_IN, USB_EP_INT) && EpVerify(1, USB_EP_IN, USB_EP_BULK) && EpVerify(0, USB_EP_OUT, USB_EP_BULK))
94 {
95 pEpNotify = &phost->Device.Ep_Desc[i][2];
96 pEpIn = &phost->Device.Ep_Desc[i][1];
97 pEpOut = &phost->Device.Ep_Desc[i][0];
98 }
99 else
100 {
101 continue;
102 }
103
104 USBH_MTP_Info.InEp = pEpIn->bEndpointAddress;
105 USBH_MTP_Info.InEpSize = pEpIn->wMaxPacketSize;
106 USBH_MTP_Info.OutEp = pEpOut->bEndpointAddress;
107 USBH_MTP_Info.OutEpSize = pEpOut->wMaxPacketSize;
108 USBH_MTP_Info.NotifyEp = pEpNotify->bEndpointAddress;
109 USBH_MTP_Info.NotifyEpSize = pEpNotify->wMaxPacketSize;
110
111 USBH_MTP_Info.events.poll = pEpNotify->bInterval;
112
113 SW_LOG_INFO("InEp: %x, InEpSize: %d", pEpIn->bEndpointAddress, pEpIn->wMaxPacketSize);
114 SW_LOG_INFO("OutEp: %x, OutEpSize: %d", pEpOut->bEndpointAddress, pEpOut->wMaxPacketSize);
115 SW_LOG_INFO("NotifyEp: %x, NotifyEpSize: %d, NotifyInterval: %d", pEpNotify->bEndpointAddress, pEpNotify->wMaxPacketSize, pEpNotify->bInterval);
116
117 USBH_MTP_DeInit(phost);
118
119 return USBH_OK;
120 }
121 else
122 {
123 continue;
124 }
125 }
126
127 if(phost->usr_cb->DeviceNotSupported)
128 phost->usr_cb->DeviceNotSupported();
129
130 return USBH_NOT_SUPPORTED;
131 }
132
133
134 /******************************************************************************************************************************************
135 * 函数名称: USBH_MTP_DeInit()
136 * 功能说明:
137 * 输 入: 无
138 * 输 出: 无
139 * 注意事项: 无
140 ******************************************************************************************************************************************/
USBH_MTP_DeInit(USBH_Info_t * phost)141 static void USBH_MTP_DeInit(USBH_Info_t *phost)
142 {
143 USBH_MTP_Info.is_ready = 0;
144
145 USBH_MTP_Info.InEpDATAX = 0;
146 USBH_MTP_Info.OutEpDATAX = 0;
147 USBH_MTP_Info.NotifyEpDATAX = 0;
148
149 USBH_MTP_Info.XferState = USBH_MTP_XFER_IDLE;
150 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
151
152 USBH_MTP_Info.state = USBH_MTP_GETDEVICEINFO;
153 USBH_MTP_Info.stateReq = USBH_MTP_IDLE;
154
155 SW_LOG_INFO("USBH_MTP_DeInit");
156 }
157
158
159 /******************************************************************************************************************************************
160 * 函数名称: USBH_MTP_Request()
161 * 功能说明: Used for handling Standard requests for MTP class.
162 * 输 入: 无
163 * 输 出: 无
164 * 注意事项: 无
165 ******************************************************************************************************************************************/
USBH_MTP_Request(USBH_Info_t * phost)166 static USBH_Status USBH_MTP_Request(USBH_Info_t *phost)
167 {
168 return USBH_OK;
169 }
170
171
172 void USBH_MTP_XferProcess(USBH_Info_t *phost);
173 /******************************************************************************************************************************************
174 * 函数名称: USBH_MTP_Process()
175 * 功能说明: Used for managing state machine for MTP data transfers.
176 * 输 入: 无
177 * 输 出: 无
178 * 注意事项: 无
179 ******************************************************************************************************************************************/
USBH_MTP_Process(USBH_Info_t * phost)180 static USBH_Status USBH_MTP_Process(USBH_Info_t *phost)
181 {
182 USBH_Resp resp;
183 USBH_Status status = USBH_BUSY;
184
185 if((USBH_MTP_Info.state != USBH_MTP_EVENT_WAIT) &&
186 (USBH_MTP_Info.state != USBH_MTP_EVENT_CHECK))
187 {
188 if(USBH_MTP_Info.stateReq != USBH_MTP_IDLE)
189 {
190 USBH_MTP_Info.stateBkp = USBH_MTP_Info.state;
191 USBH_MTP_Info.state = USBH_MTP_Info.stateReq;
192
193 USBH_MTP_Info.stateReq = USBH_MTP_IDLE;
194 }
195 }
196
197 switch(USBH_MTP_Info.state)
198 {
199 case USBH_MTP_GETDEVICEINFO:
200 status = USBH_MTP_GetDeviceInfo(phost, &USBH_MTP_Info.devinfo);
201 if(status == USBH_OK)
202 {
203 SW_LOG_INFO("MTP Device Information");
204 SW_LOG_INFO(" Standard version : %x", USBH_MTP_Info.devinfo.StandardVersion);
205 SW_LOG_INFO(" Vendor ExtID : %s", USBH_MTP_Info.devinfo.VendorExtensionID == 6 ? "MTP" : "NOT SUPPORTED");
206 SW_LOG_INFO(" Functional mode : %s", USBH_MTP_Info.devinfo.FunctionalMode == 0 ? "Standard" : "Vendor");
207 SW_LOG_INFO(" Number of Supported Operation(s) : %d", USBH_MTP_Info.devinfo.OperationsSupportedNbr);
208 SW_LOG_INFO(" Number of Supported Events(s) : %d", USBH_MTP_Info.devinfo.EventsSupportedNbr);
209 SW_LOG_INFO(" Number of Supported Proprieties : %d", USBH_MTP_Info.devinfo.DevicePropertiesSupportedNbr);
210 SW_LOG_INFO(" Manufacturer : %s", USBH_MTP_Info.devinfo.Manufacturer);
211 SW_LOG_INFO(" Model : %s", USBH_MTP_Info.devinfo.Model);
212 SW_LOG_INFO(" Device version : %s", USBH_MTP_Info.devinfo.DeviceVersion);
213 SW_LOG_INFO(" Serial number : %s", USBH_MTP_Info.devinfo.SerialNumber);
214
215 USBH_MTP_Info.state = USBH_MTP_OPENSESSION;
216 }
217 break;
218
219 case USBH_MTP_OPENSESSION:
220 status = USBH_MTP_OpenSession(phost, 1);
221 if(status == USBH_OK)
222 {
223 SW_LOG_INFO("MTP Session #1 Opened");
224
225 USBH_MTP_Info.state = USBH_MTP_GETSTORAGEIDS;
226 }
227 break;
228
229 case USBH_MTP_GETSTORAGEIDS:
230 status = USBH_MTP_GetStorageIds(phost, &USBH_MTP_Info.storids);
231 if(status == USBH_OK)
232 {
233 SW_LOG_INFO("Number of storage ID items : %d", USBH_MTP_Info.storids.n);
234 for(int i = 0; i < USBH_MTP_Info.storids.n; i++)
235 {
236 SW_LOG_INFO("storage#%d ID : %x", i, USBH_MTP_Info.storids.Storage[i]);
237 }
238
239 USBH_MTP_Info.CurrentStorage = 0;
240 if(USBH_MTP_Info.storids.n)
241 USBH_MTP_Info.state = USBH_MTP_GETSTORAGEINFO;
242 }
243 break;
244
245 case USBH_MTP_GETSTORAGEINFO:
246 status = USBH_MTP_GetStorageInfo(phost, USBH_MTP_Info.storids.Storage[USBH_MTP_Info.CurrentStorage],
247 &USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage]);
248 if(status == USBH_OK)
249 {
250 SW_LOG_INFO("Volume#%u: %s [%s]", USBH_MTP_Info.CurrentStorage, USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage].StorageDescription,
251 USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage].VolumeLabel);
252 USBH_MTP_Info.is_ready = 1;
253 USBH_MTP_Info.state = USBH_MTP_IDLE;
254 }
255 break;
256
257 case USBH_MTP_IDLE:
258 if(abs((int)USBH->FRAMENR - (int)USBH_MTP_Info.events.timer) >= USBH_MTP_Info.events.poll)
259 {
260 USBH_MTP_Info.events.timer = USBH->FRAMENR;
261
262 USBH_MTP_Info.state = USBH_MTP_EVENT;
263 }
264 else
265 {
266 status = USBH_OK;
267 }
268 break;
269
270 case USBH_MTP_EVENT_CHECK:
271 if(abs((int)USBH->FRAMENR - (int)USBH_MTP_Info.events.timer) >= USBH_MTP_Info.events.poll)
272 {
273 USBH_MTP_Info.events.timer = USBH->FRAMENR;
274
275 USBH_MTP_Info.state = USBH_MTP_EVENT;
276 }
277 else
278 {
279 USBH_MTP_Info.state = USBH_MTP_TRANSFER; // Event 查询是在数据传输中间插入的,返回数据传输
280 }
281 break;
282
283 case USBH_MTP_EVENT:
284 if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.NotifyEp, USBH_MTP_Info.NotifyEpDATAX, USBH_MTP_Info.NotifyEpSize))
285 {
286 USBH_MTP_Info.state = USBH_MTP_EVENT_WAIT;
287 }
288 break;
289
290 case USBH_MTP_EVENT_WAIT:
291 resp = USBH_State();
292 if(resp == USBR_ACK)
293 {
294 USBH_MTP_Info.NotifyEpDATAX ^= 1;
295
296 USBH_ReadRxBuffer((uint8_t *)&USBH_MTP_Info.events.container, USBH_MTP_Info.NotifyEpSize);
297
298 USBH_MTP_EventsCallback(phost, USBH_MTP_Info.events.container.code, USBH_MTP_Info.events.container.param1);
299 }
300
301 if((USBH_MTP_Info.XferState == USBH_MTP_XFER_DATA_OUT) ||
302 (USBH_MTP_Info.XferState == USBH_MTP_XFER_DATA_IN))
303 {
304 USBH_MTP_Info.state = USBH_MTP_TRANSFER; // Event 查询是在数据传输中间插入的,返回数据传输
305 }
306 else
307 {
308 USBH_MTP_Info.state = USBH_MTP_IDLE;
309 }
310 break;
311
312 case USBH_MTP_TRANSFER:
313 USBH_MTP_XferProcess(phost);
314 break;
315
316 default:
317 break;
318 }
319
320 return status;
321 }
322
323
324 /******************************************************************************************************************************************
325 * 函数名称: USBH_MTP_XferProcess()
326 * 功能说明:
327 * 输 入: USBH_Info_t *phost
328 * 输 出: 无
329 * 注意事项: 无
330 ******************************************************************************************************************************************/
USBH_MTP_XferProcess(USBH_Info_t * phost)331 void USBH_MTP_XferProcess(USBH_Info_t *phost)
332 {
333 USBH_Resp resp;
334 uint32_t size;
335
336 USBH_MTP_Info.XferStatus = USBH_BUSY;
337
338 switch(USBH_MTP_Info.XferState)
339 {
340 case USBH_MTP_XFER_OP_REQ:
341 if(USBH_SendOutPacket(phost->Device.Address, USBH_MTP_Info.OutEp, USBH_MTP_Info.OutEpDATAX, (uint8_t *)&USBH_MTP_Info.op_container, USBH_MTP_Info.op_container.length))
342 {
343 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ_WAIT;
344 }
345 break;
346
347 case USBH_MTP_XFER_OP_REQ_WAIT:
348 resp = USBH_State();
349 if(resp == USBR_ACK)
350 {
351 USBH_MTP_Info.OutEpDATAX ^= 1;
352
353 if(USBH_MTP_Info.flags == PTP_DP_NODATA)
354 {
355 USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
356 }
357 else if(USBH_MTP_Info.flags == PTP_DP_SENDDATA)
358 {
359 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT;
360 }
361 else if(USBH_MTP_Info.flags == PTP_DP_GETDATA)
362 {
363 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
364 }
365 }
366 else if(resp == USBR_NAK)
367 {
368 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ; // Resend Request
369 }
370 else if(resp == USBR_STALL)
371 {
372 USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
373 }
374 break;
375
376 case USBH_MTP_XFER_DATA_OUT:
377 size = USBH_MTP_Info.data_len > USBH_MTP_Info.OutEpSize ? USBH_MTP_Info.OutEpSize : USBH_MTP_Info.data_len;
378 if(USBH_SendOutPacket(phost->Device.Address, USBH_MTP_Info.OutEp, USBH_MTP_Info.OutEpDATAX, USBH_MTP_Info.data_ptr, size))
379 {
380 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT_WAIT;
381 }
382 break;
383
384 case USBH_MTP_XFER_DATA_OUT_WAIT:
385 resp = USBH_State();
386 if(resp == USBR_ACK)
387 {
388 USBH_MTP_Info.OutEpDATAX ^= 1;
389
390 if(USBH_MTP_Info.data_len > USBH_MTP_Info.OutEpSize)
391 {
392 USBH_MTP_Info.data_ptr += USBH_MTP_Info.OutEpSize;
393 USBH_MTP_Info.data_len -= USBH_MTP_Info.OutEpSize;
394 }
395 else
396 {
397 USBH_MTP_Info.data_len = 0;
398 }
399
400 if(USBH_MTP_Info.data_len > 0)
401 {
402 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT;
403 }
404 else
405 {
406 USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
407 }
408 }
409 else if(resp == USBR_NAK)
410 {
411 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT; // Resend same data
412
413 USBH_MTP_Info.state = USBH_MTP_EVENT_CHECK; // 从机返回 NAK 时,主机查询一下是否需要执行 Event 查询
414 }
415 else if(resp == USBR_STALL)
416 {
417 USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
418 }
419 break;
420
421 case USBH_MTP_XFER_DATA_IN:
422 if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.InEp, USBH_MTP_Info.InEpDATAX, USBH_MTP_Info.InEpSize))
423 {
424 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN_WAIT;
425 }
426 break;
427
428 case USBH_MTP_XFER_DATA_IN_WAIT:
429 resp = USBH_State();
430 if(resp == USBR_ACK)
431 {
432 USBH_MTP_Info.InEpDATAX ^= 1;
433
434 uint32_t len = USBH_ReadRxBuffer(USBH_MTP_Info.data_ptr, USBH_MTP_Info.InEpSize);
435
436 if(USBH_MTP_Info.first_packet)
437 {
438 USBH_MTP_Info.data_len = *(uint32_t *)(void *)USBH_MTP_Info.data_ptr;
439
440 if(USBH_MTP_Info.first_packet == 3)
441 {
442 len -= PTP_USB_BULK_HDR_LEN;
443 USBH_MTP_Info.data_len -= PTP_USB_BULK_HDR_LEN;
444 memcpy(USBH_MTP_Info.data_ptr, USBH_MTP_Info.data_ptr + PTP_USB_BULK_HDR_LEN, len);
445 }
446
447 USBH_MTP_Info.first_packet = 0;
448 }
449
450 USBH_MTP_Info.data_ptr += len;
451 USBH_MTP_Info.data_len -= len;
452
453 if((USBH_MTP_Info.data_len > 0) || (len == USBH_MTP_Info.InEpSize))
454 {
455 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
456 }
457 else
458 {
459 USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
460 }
461 }
462 else if(resp == USBR_NAK)
463 {
464 USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
465
466 USBH_MTP_Info.state = USBH_MTP_EVENT_CHECK; // 从机返回 NAK 时,主机查询一下是否需要执行 Event 查询
467 }
468 else if(resp == USBR_STALL)
469 {
470 USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
471 }
472 break;
473
474 case USBH_MTP_XFER_RESP:
475 if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.InEp, USBH_MTP_Info.InEpDATAX, USBH_MTP_Info.InEpSize))
476 {
477 USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP_WAIT;
478 }
479 break;
480
481 case USBH_MTP_XFER_RESP_WAIT:
482 resp = USBH_State();
483 if(resp == USBR_ACK)
484 {
485 USBH_MTP_Info.InEpDATAX ^= 1;
486
487 USBH_ReadRxBuffer((uint8_t *)&USBH_MTP_Info.resp_container, USBH_MTP_Info.InEpSize);
488
489 if(USBH_MTP_Info.resp_container.code == PTP_RC_OK)
490 {
491 USBH_MTP_Info.XferStatus = USBH_OK;
492 }
493 else
494 {
495 USBH_MTP_Info.XferStatus = USBH_FAIL;
496 }
497 USBH_MTP_Info.state = USBH_MTP_Info.stateBkp;
498 }
499 else if(resp == USBR_NAK)
500 {
501 USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
502 }
503 else if(resp == USBR_STALL)
504 {
505 USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
506 }
507 break;
508
509 case USBH_MTP_XFER_ERROR:
510 USBH_MTP_Info.XferStatus = USBH_FAIL;
511 USBH_MTP_Info.state = USBH_MTP_Info.stateBkp;
512 break;
513
514 default:
515 break;
516 }
517 }
518
519
520 /******************************************************************************************************************************************
521 * 函数名称: USBH_MTP_GetDeviceInfo()
522 * 功能说明:
523 * 输 入: 无
524 * 输 出: 无
525 * 注意事项: 无
526 ******************************************************************************************************************************************/
USBH_MTP_GetDeviceInfo(USBH_Info_t * phost,PTP_DeviceInfo_t * dev_info)527 USBH_Status USBH_MTP_GetDeviceInfo(USBH_Info_t *phost, PTP_DeviceInfo_t *dev_info)
528 {
529 USBH_Status status = USBH_BUSY;
530
531 switch(USBH_MTP_Info.OpState)
532 {
533 case USBH_MTP_OP_SEND:
534 /* Set operation request type */
535 USBH_MTP_Info.flags = PTP_DP_GETDATA;
536 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
537 USBH_MTP_Info.data_len = 0;
538 USBH_MTP_Info.first_packet = 1;
539
540 /* Fill operation request params */
541 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
542 USBH_MTP_Info.op_container.code = PTP_OC_GetDeviceInfo;
543 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
544 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
545
546 /* Setup State machine and start transfer */
547 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
548 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
549
550 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
551 break;
552
553 case USBH_MTP_OP_WAIT:
554 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
555 {
556 status = USBH_MTP_Info.XferStatus;
557 USBH_MTP_Info.XferStatus = USBH_BUSY;
558
559 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
560 }
561 if(status == USBH_OK)
562 {
563 PTP_DecodeDeviceInfo(phost, dev_info);
564 }
565 break;
566
567 default:
568 break;
569 }
570 return status;
571 }
572
573
574 /******************************************************************************************************************************************
575 * 函数名称: USBH_MTP_OpenSession()
576 * 功能说明:
577 * 输 入: 无
578 * 输 出: 无
579 * 注意事项: 无
580 ******************************************************************************************************************************************/
USBH_MTP_OpenSession(USBH_Info_t * phost,uint32_t session)581 USBH_Status USBH_MTP_OpenSession(USBH_Info_t *phost, uint32_t session)
582 {
583 USBH_Status status = USBH_BUSY;
584
585 switch(USBH_MTP_Info.OpState)
586 {
587 case USBH_MTP_OP_SEND:
588 /* Init session params */
589 USBH_MTP_Info.transaction_id = 0x00000000U;
590 USBH_MTP_Info.session_id = session;
591 USBH_MTP_Info.flags = PTP_DP_NODATA;
592
593 /* Fill operation request params */
594 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
595 USBH_MTP_Info.op_container.code = PTP_OC_OpenSession;
596 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
597 USBH_MTP_Info.op_container.param1 = session;
598 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
599
600 /* Setup State machine and start transfer */
601 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
602 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
603
604 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
605 break;
606
607 case USBH_MTP_OP_WAIT:
608 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
609 {
610 status = USBH_MTP_Info.XferStatus;
611 USBH_MTP_Info.XferStatus = USBH_BUSY;
612
613 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
614 }
615 break;
616
617 default:
618 break;
619 }
620
621 return status;
622 }
623
624
625 /******************************************************************************************************************************************
626 * 函数名称: USBH_MTP_GetStorageIds()
627 * 功能说明:
628 * 输 入: 无
629 * 输 出: 无
630 * 注意事项: 无
631 ******************************************************************************************************************************************/
USBH_MTP_GetStorageIds(USBH_Info_t * phost,PTP_StorageIDs_t * storage_ids)632 USBH_Status USBH_MTP_GetStorageIds(USBH_Info_t *phost, PTP_StorageIDs_t *storage_ids)
633 {
634 USBH_Status status = USBH_BUSY;
635
636 switch(USBH_MTP_Info.OpState)
637 {
638 case USBH_MTP_OP_SEND:
639 /* Set operation request type */
640 USBH_MTP_Info.flags = PTP_DP_GETDATA;
641 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
642 USBH_MTP_Info.data_len = 0;
643 USBH_MTP_Info.first_packet = 1;
644
645 /* Fill operation request params */
646 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
647 USBH_MTP_Info.op_container.code = PTP_OC_GetStorageIDs;
648 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
649 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
650
651 /* Setup State machine and start transfer */
652 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
653 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
654
655 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
656 break;
657
658 case USBH_MTP_OP_WAIT:
659 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
660 {
661 status = USBH_MTP_Info.XferStatus;
662 USBH_MTP_Info.XferStatus = USBH_BUSY;
663
664 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
665 }
666 if(status == USBH_OK)
667 {
668 storage_ids->n = PTP_GetArray32(storage_ids->Storage, USBH_MTP_Info.data_container.payload, 0U);
669 }
670 break;
671
672 default:
673 break;
674 }
675
676 return status;
677 }
678
679
680 /******************************************************************************************************************************************
681 * 函数名称: USBH_MTP_GetStorageInfo()
682 * 功能说明:
683 * 输 入: 无
684 * 输 出: 无
685 * 注意事项: 无
686 ******************************************************************************************************************************************/
USBH_MTP_GetStorageInfo(USBH_Info_t * phost,uint32_t storage_id,PTP_StorageInfo_t * storage_info)687 USBH_Status USBH_MTP_GetStorageInfo(USBH_Info_t *phost, uint32_t storage_id, PTP_StorageInfo_t *storage_info)
688 {
689 USBH_Status status = USBH_BUSY;
690
691 switch(USBH_MTP_Info.OpState)
692 {
693 case USBH_MTP_OP_SEND:
694 /* Set operation request type */
695 USBH_MTP_Info.flags = PTP_DP_GETDATA;
696 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
697 USBH_MTP_Info.data_len = 0;
698 USBH_MTP_Info.first_packet = 1;
699
700 /* Fill operation request params */
701 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
702 USBH_MTP_Info.op_container.code = PTP_OC_GetStorageInfo;
703 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
704 USBH_MTP_Info.op_container.param1 = storage_id;
705 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
706
707 /* Setup State machine and start transfer */
708 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
709 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
710
711 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
712 break;
713
714 case USBH_MTP_OP_WAIT:
715 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
716 {
717 status = USBH_MTP_Info.XferStatus;
718 USBH_MTP_Info.XferStatus = USBH_BUSY;
719
720 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
721 }
722 if(status == USBH_OK)
723 {
724 PTP_DecodeStorageInfo(phost, storage_info);
725 }
726 break;
727
728 default:
729 break;
730 }
731
732 return status;
733 }
734
735
736 /******************************************************************************************************************************************
737 * 函数名称: USBH_MTP_GetNumObjects()
738 * 功能说明:
739 * 输 入: 无
740 * 输 出: 无
741 * 注意事项: 无
742 ******************************************************************************************************************************************/
USBH_MTP_GetNumObjects(USBH_Info_t * phost,uint32_t storage_id,uint32_t format,uint32_t folder,uint32_t * numobs)743 USBH_Status USBH_MTP_GetNumObjects(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, uint32_t *numobs)
744 {
745 USBH_Status status = USBH_BUSY;
746
747 switch(USBH_MTP_Info.OpState)
748 {
749 case USBH_MTP_OP_SEND:
750 /* Set operation request type */
751 USBH_MTP_Info.flags = PTP_DP_NODATA;
752
753 /* Fill operation request params */
754 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
755 USBH_MTP_Info.op_container.code = PTP_OC_GetNumObjects;
756 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
757 USBH_MTP_Info.op_container.param1 = storage_id;
758 USBH_MTP_Info.op_container.param2 = format;
759 USBH_MTP_Info.op_container.param3 = folder;
760 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
761
762 /* Setup State machine and start transfer */
763 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
764 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
765
766 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
767 break;
768
769 case USBH_MTP_OP_WAIT:
770 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
771 {
772 status = USBH_MTP_Info.XferStatus;
773 USBH_MTP_Info.XferStatus = USBH_BUSY;
774
775 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
776 }
777 if(status == USBH_OK)
778 {
779 *numobs = USBH_MTP_Info.resp_container.param1;
780 }
781 break;
782
783 default:
784 break;
785 }
786
787 return status;
788 }
789
790
791 /******************************************************************************************************************************************
792 * 函数名称: USBH_MTP_GetObjectHandles()
793 * 功能说明:
794 * 输 入: 无
795 * 输 出: 无
796 * 注意事项: 无
797 ******************************************************************************************************************************************/
USBH_MTP_GetObjectHandles(USBH_Info_t * phost,uint32_t storage_id,uint32_t format,uint32_t folder,PTP_ObjectHandles_t * handles)798 USBH_Status USBH_MTP_GetObjectHandles(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, PTP_ObjectHandles_t *handles)
799 {
800 USBH_Status status = USBH_BUSY;
801
802 switch(USBH_MTP_Info.OpState)
803 {
804 case USBH_MTP_OP_SEND:
805 /* Set operation request type */
806 USBH_MTP_Info.flags = PTP_DP_GETDATA;
807 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
808 USBH_MTP_Info.data_len = 0;
809 USBH_MTP_Info.first_packet = 1;
810
811 /* Fill operation request params */
812 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
813 USBH_MTP_Info.op_container.code = PTP_OC_GetObjectHandles;
814 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
815 USBH_MTP_Info.op_container.param1 = storage_id;
816 USBH_MTP_Info.op_container.param2 = format;
817 USBH_MTP_Info.op_container.param3 = folder;
818 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
819
820 /* Setup State machine and start transfer */
821 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
822 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
823
824 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
825 break;
826
827 case USBH_MTP_OP_WAIT:
828 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
829 {
830 status = USBH_MTP_Info.XferStatus;
831 USBH_MTP_Info.XferStatus = USBH_BUSY;
832
833 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
834 }
835 if(status == USBH_OK)
836 {
837 handles->n = PTP_GetArray32(handles->Handler, USBH_MTP_Info.data_container.payload, 0U);
838 }
839 break;
840
841 default:
842 break;
843 }
844
845 return status;
846 }
847
848
849 /******************************************************************************************************************************************
850 * 函数名称: USBH_MTP_GetObjectInfo()
851 * 功能说明:
852 * 输 入: 无
853 * 输 出: 无
854 * 注意事项: 无
855 ******************************************************************************************************************************************/
USBH_MTP_GetObjectInfo(USBH_Info_t * phost,uint32_t handle,PTP_ObjectInfo_t * object_info)856 USBH_Status USBH_MTP_GetObjectInfo(USBH_Info_t *phost, uint32_t handle, PTP_ObjectInfo_t *object_info)
857 {
858 USBH_Status status = USBH_BUSY;
859
860 switch(USBH_MTP_Info.OpState)
861 {
862 case USBH_MTP_OP_SEND:
863 /* Set operation request type */
864 USBH_MTP_Info.flags = PTP_DP_GETDATA;
865 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
866 USBH_MTP_Info.data_len = 0;
867 USBH_MTP_Info.first_packet = 1;
868
869 /* Fill operation request params */
870 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
871 USBH_MTP_Info.op_container.code = PTP_OC_GetObjectInfo;
872 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
873 USBH_MTP_Info.op_container.param1 = handle;
874 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
875
876 /* Setup State machine and start transfer */
877 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
878 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
879
880 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
881 break;
882
883 case USBH_MTP_OP_WAIT:
884 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
885 {
886 status = USBH_MTP_Info.XferStatus;
887 USBH_MTP_Info.XferStatus = USBH_BUSY;
888
889 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
890 }
891 if(status == USBH_OK)
892 {
893 PTP_DecodeObjectInfo(phost, object_info);
894 }
895 break;
896
897 default:
898 break;
899 }
900
901 return status;
902 }
903
904
905 /******************************************************************************************************************************************
906 * 函数名称: USBH_MTP_GetObject()
907 * 功能说明:
908 * 输 入: 无
909 * 输 出: 无
910 * 注意事项: 无
911 ******************************************************************************************************************************************/
USBH_MTP_GetObject(USBH_Info_t * phost,uint32_t handle,uint8_t * object)912 USBH_Status USBH_MTP_GetObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object)
913 {
914 USBH_Status status = USBH_BUSY;
915
916 switch(USBH_MTP_Info.OpState)
917 {
918 case USBH_MTP_OP_SEND:
919 /* Set operation request type */
920 USBH_MTP_Info.flags = PTP_DP_GETDATA;
921 USBH_MTP_Info.data_ptr = object;
922 USBH_MTP_Info.data_len = 0;
923 USBH_MTP_Info.first_packet = 3;
924
925 /* Fill operation request params */
926 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
927 USBH_MTP_Info.op_container.code = PTP_OC_GetObject;
928 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
929 USBH_MTP_Info.op_container.param1 = handle;
930 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
931
932 /* Setup State machine and start transfer */
933 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
934 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
935
936 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
937 break;
938
939 case USBH_MTP_OP_WAIT:
940 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
941 {
942 status = USBH_MTP_Info.XferStatus;
943 USBH_MTP_Info.XferStatus = USBH_BUSY;
944
945 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
946 }
947 break;
948
949 default:
950 break;
951 }
952
953 return status;
954 }
955
956
957 /******************************************************************************************************************************************
958 * 函数名称: USBH_MTP_GetPartialObject()
959 * 功能说明:
960 * 输 入: 无
961 * 输 出: 无
962 * 注意事项: 无
963 ******************************************************************************************************************************************/
USBH_MTP_GetPartialObject(USBH_Info_t * phost,uint32_t handle,uint32_t offset,uint32_t maxbytes,uint8_t * object,uint32_t * len)964 USBH_Status USBH_MTP_GetPartialObject(USBH_Info_t *phost, uint32_t handle, uint32_t offset, uint32_t maxbytes, uint8_t *object, uint32_t *len)
965 {
966 USBH_Status status = USBH_BUSY;
967
968 switch(USBH_MTP_Info.OpState)
969 {
970 case USBH_MTP_OP_SEND:
971 /* Set operation request type */
972 USBH_MTP_Info.flags = PTP_DP_GETDATA;
973 USBH_MTP_Info.data_ptr = object;
974 USBH_MTP_Info.data_len = 0;
975 USBH_MTP_Info.first_packet = 3;
976
977 /* Fill operation request params */
978 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
979 USBH_MTP_Info.op_container.code = PTP_OC_GetPartialObject;
980 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
981 USBH_MTP_Info.op_container.param1 = handle;
982 USBH_MTP_Info.op_container.param2 = offset;
983 USBH_MTP_Info.op_container.param3 = maxbytes;
984 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
985
986 /* Setup State machine and start transfer */
987 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
988 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
989
990 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
991 break;
992
993 case USBH_MTP_OP_WAIT:
994 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
995 {
996 status = USBH_MTP_Info.XferStatus;
997 USBH_MTP_Info.XferStatus = USBH_BUSY;
998
999 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
1000 }
1001 if(status == USBH_OK)
1002 {
1003 *len = USBH_MTP_Info.resp_container.param1;
1004 }
1005 break;
1006
1007 default:
1008 break;
1009 }
1010
1011 return status;
1012 }
1013
1014
1015 /******************************************************************************************************************************************
1016 * 函数名称: USBH_MTP_DeleteObject()
1017 * 功能说明:
1018 * 输 入: 无
1019 * 输 出: 无
1020 * 注意事项: 无
1021 ******************************************************************************************************************************************/
USBH_MTP_DeleteObject(USBH_Info_t * phost,uint32_t handle,uint32_t format)1022 USBH_Status USBH_MTP_DeleteObject(USBH_Info_t *phost, uint32_t handle, uint32_t format)
1023 {
1024 USBH_Status status = USBH_BUSY;
1025
1026 switch(USBH_MTP_Info.OpState)
1027 {
1028 case USBH_MTP_OP_SEND:
1029 /* Set operation request type */
1030 USBH_MTP_Info.flags = PTP_DP_NODATA;
1031
1032 /* Fill operation request params */
1033 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
1034 USBH_MTP_Info.op_container.code = PTP_OC_DeleteObject;
1035 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
1036 USBH_MTP_Info.op_container.param1 = handle;
1037 USBH_MTP_Info.op_container.param2 = format;
1038 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 2;
1039
1040 /* Setup State machine and start transfer */
1041 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
1042 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
1043
1044 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
1045 break;
1046
1047 case USBH_MTP_OP_WAIT:
1048 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
1049 {
1050 status = USBH_MTP_Info.XferStatus;
1051 USBH_MTP_Info.XferStatus = USBH_BUSY;
1052
1053 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
1054 }
1055 break;
1056
1057 default:
1058 break;
1059 }
1060
1061 return status;
1062 }
1063
1064
1065 /******************************************************************************************************************************************
1066 * 函数名称: USBH_MTP_SendObject()
1067 * 功能说明:
1068 * 输 入: 无
1069 * 输 出: 无
1070 * 注意事项: 无
1071 ******************************************************************************************************************************************/
USBH_MTP_SendObject(USBH_Info_t * phost,uint32_t handle,uint8_t * object,uint32_t size)1072 USBH_Status USBH_MTP_SendObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object, uint32_t size)
1073 {
1074 USBH_Status status = USBH_BUSY;
1075
1076 switch(USBH_MTP_Info.OpState)
1077 {
1078 case USBH_MTP_OP_SEND:
1079 /* Set operation request type */
1080 USBH_MTP_Info.flags = PTP_DP_SENDDATA;
1081 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
1082 USBH_MTP_Info.data_len = size + PTP_USB_BULK_HDR_LEN;
1083 USBH_MTP_Info.first_packet = 1;
1084
1085 /* Fill operation request params */
1086 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
1087 USBH_MTP_Info.op_container.code = PTP_OC_SendObject;
1088 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
1089 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
1090
1091 /* Fill data_container */
1092 USBH_MTP_Info.data_container.length = USBH_MTP_Info.data_len;
1093 USBH_MTP_Info.data_container.type = PTP_USB_CONTAINER_DATA;
1094 USBH_MTP_Info.data_container.code = USBH_MTP_Info.op_container.code;
1095 USBH_MTP_Info.data_container.trans_id = USBH_MTP_Info.op_container.trans_id;
1096 memcpy(USBH_MTP_Info.data_container.payload, object, size);
1097
1098 /* Setup State machine and start transfer */
1099 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
1100 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
1101
1102 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
1103 break;
1104
1105 case USBH_MTP_OP_WAIT:
1106 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
1107 {
1108 status = USBH_MTP_Info.XferStatus;
1109 USBH_MTP_Info.XferStatus = USBH_BUSY;
1110
1111 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
1112 }
1113 break;
1114
1115 default:
1116 break;
1117 }
1118
1119 return status;
1120 }
1121
1122
1123 /******************************************************************************************************************************************
1124 * 函数名称: USBH_MTP_GetDevicePropDesc()
1125 * 功能说明:
1126 * 输 入: 无
1127 * 输 出: 无
1128 * 注意事项: 无
1129 ******************************************************************************************************************************************/
USBH_MTP_GetDevicePropDesc(USBH_Info_t * phost,uint16_t propcode,PTP_DevicePropDesc_t * devicepropertydesc)1130 USBH_Status USBH_MTP_GetDevicePropDesc(USBH_Info_t *phost, uint16_t propcode, PTP_DevicePropDesc_t *devicepropertydesc)
1131 {
1132 USBH_Status status = USBH_BUSY;
1133
1134 switch(USBH_MTP_Info.OpState)
1135 {
1136 case USBH_MTP_OP_SEND:
1137 /* Set operation request type */
1138 USBH_MTP_Info.flags = PTP_DP_GETDATA;
1139 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
1140 USBH_MTP_Info.data_len = 0;
1141 USBH_MTP_Info.first_packet = 1;
1142
1143 /* Fill operation request params */
1144 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
1145 USBH_MTP_Info.op_container.code = PTP_OC_GetDevicePropDesc;
1146 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
1147 USBH_MTP_Info.op_container.param1 = propcode;
1148 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
1149
1150 /* Setup State machine and start transfer */
1151 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
1152 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
1153
1154 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
1155 break;
1156
1157 case USBH_MTP_OP_WAIT:
1158 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
1159 {
1160 status = USBH_MTP_Info.XferStatus;
1161 USBH_MTP_Info.XferStatus = USBH_BUSY;
1162
1163 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
1164 }
1165 if(status == USBH_OK)
1166 {
1167 uint8_t *data = USBH_MTP_Info.data_container.payload;
1168
1169 devicepropertydesc->DevicePropertyCode = PTP_LE16(&data[PTP_dpd_DevicePropertyCode]);
1170 devicepropertydesc->DataType = PTP_LE16(&data[PTP_dpd_DataType]);
1171 devicepropertydesc->GetSet = *(uint8_t *)(&data[PTP_dpd_GetSet]);
1172 devicepropertydesc->FormFlag = PTP_DPFF_None;
1173 }
1174 break;
1175
1176 default:
1177 break;
1178 }
1179
1180 return status;
1181 }
1182
1183
1184 /******************************************************************************************************************************************
1185 * 函数名称: USBH_MTP_GetObjectPropsSupported()
1186 * 功能说明:
1187 * 输 入: 无
1188 * 输 出: 无
1189 * 注意事项: 无
1190 ******************************************************************************************************************************************/
USBH_MTP_GetObjectPropsSupported(USBH_Info_t * phost,uint16_t ofc,uint32_t * propnum,uint16_t * props)1191 USBH_Status USBH_MTP_GetObjectPropsSupported(USBH_Info_t *phost, uint16_t ofc, uint32_t *propnum, uint16_t *props)
1192 {
1193 USBH_Status status = USBH_BUSY;
1194
1195 switch(USBH_MTP_Info.OpState)
1196 {
1197 case USBH_MTP_OP_SEND:
1198 /* Set operation request type */
1199 USBH_MTP_Info.flags = PTP_DP_GETDATA;
1200 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
1201 USBH_MTP_Info.data_len = 0;
1202 USBH_MTP_Info.first_packet = 1;
1203
1204 /* Fill operation request params */
1205 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
1206 USBH_MTP_Info.op_container.code = PTP_OC_GetObjectPropsSupported;
1207 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
1208 USBH_MTP_Info.op_container.param1 = ofc;
1209 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
1210
1211 /* Setup State machine and start transfer */
1212 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
1213 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
1214
1215 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
1216 break;
1217
1218 case USBH_MTP_OP_WAIT:
1219 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
1220 {
1221 status = USBH_MTP_Info.XferStatus;
1222 USBH_MTP_Info.XferStatus = USBH_BUSY;
1223
1224 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
1225 }
1226 if(status == USBH_OK)
1227 {
1228 *propnum = PTP_GetArray16(props, USBH_MTP_Info.data_container.payload, 0U);
1229 }
1230 break;
1231
1232 default:
1233 break;
1234 }
1235
1236 return status;
1237 }
1238
1239
1240 /******************************************************************************************************************************************
1241 * 函数名称: USBH_MTP_GetObjectPropDesc()
1242 * 功能说明:
1243 * 输 入: 无
1244 * 输 出: 无
1245 * 注意事项: 无
1246 ******************************************************************************************************************************************/
USBH_MTP_GetObjectPropDesc(USBH_Info_t * phost,uint16_t opc,uint16_t ofc,PTP_ObjectPropDesc_t * opd)1247 USBH_Status USBH_MTP_GetObjectPropDesc(USBH_Info_t *phost, uint16_t opc, uint16_t ofc, PTP_ObjectPropDesc_t *opd)
1248 {
1249 USBH_Status status = USBH_BUSY;
1250
1251 switch(USBH_MTP_Info.OpState)
1252 {
1253 case USBH_MTP_OP_SEND:
1254 /* Set operation request type */
1255 USBH_MTP_Info.flags = PTP_DP_GETDATA;
1256 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
1257 USBH_MTP_Info.data_len = 0;
1258 USBH_MTP_Info.first_packet = 1;
1259
1260 /* Fill operation request params */
1261 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
1262 USBH_MTP_Info.op_container.code = PTP_OC_GetObjectPropDesc;
1263 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
1264 USBH_MTP_Info.op_container.param1 = opc;
1265 USBH_MTP_Info.op_container.param2 = ofc;
1266 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 2;
1267
1268 /* Setup State machine and start transfer */
1269 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
1270 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
1271
1272 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
1273 break;
1274
1275 case USBH_MTP_OP_WAIT:
1276 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
1277 {
1278 status = USBH_MTP_Info.XferStatus;
1279 USBH_MTP_Info.XferStatus = USBH_BUSY;
1280
1281 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
1282 }
1283 if(status == USBH_OK)
1284 {
1285 PTP_DecodeObjectPropDesc(phost, opd, USBH_MTP_Info.data_len);
1286 }
1287 break;
1288
1289 default:
1290 break;
1291 }
1292
1293 return status;
1294 }
1295
1296
1297 /******************************************************************************************************************************************
1298 * 函数名称: USBH_MTP_GetObjectPropList()
1299 * 功能说明:
1300 * 输 入: 无
1301 * 输 出: 无
1302 * 注意事项: 无
1303 ******************************************************************************************************************************************/
USBH_MTP_GetObjectPropList(USBH_Info_t * phost,uint32_t handle,MTP_Properties_t * pprops,uint32_t * nrofprops)1304 USBH_Status USBH_MTP_GetObjectPropList(USBH_Info_t *phost, uint32_t handle, MTP_Properties_t *pprops, uint32_t *nrofprops)
1305 {
1306 USBH_Status status = USBH_BUSY;
1307
1308 switch(USBH_MTP_Info.OpState)
1309 {
1310 case USBH_MTP_OP_SEND:
1311 /* Set operation request type */
1312 USBH_MTP_Info.flags = PTP_DP_GETDATA;
1313 USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
1314 USBH_MTP_Info.data_len = 0;
1315 USBH_MTP_Info.first_packet = 1;
1316
1317 /* Fill operation request params */
1318 USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
1319 USBH_MTP_Info.op_container.code = PTP_OC_GetObjPropList;
1320 USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
1321 USBH_MTP_Info.op_container.param1 = handle;
1322 USBH_MTP_Info.op_container.param2 = 0x00000000U; /* 0x00000000U should be "all formats" */
1323 USBH_MTP_Info.op_container.param3 = 0xFFFFFFFFU; /* 0xFFFFFFFFU should be "all properties" */
1324 USBH_MTP_Info.op_container.param4 = 0x00000000U;
1325 USBH_MTP_Info.op_container.param5 = 0xFFFFFFFFU; /* Return full tree below the Param1 handle */
1326 USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 5;
1327
1328 /* Setup State machine and start transfer */
1329 USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
1330 USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
1331
1332 USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
1333 break;
1334
1335 case USBH_MTP_OP_WAIT:
1336 if(USBH_MTP_Info.XferStatus != USBH_BUSY)
1337 {
1338 status = USBH_MTP_Info.XferStatus;
1339 USBH_MTP_Info.XferStatus = USBH_BUSY;
1340
1341 USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
1342 }
1343 if(status == USBH_OK)
1344 {
1345 PTP_DecodeObjectPropList(phost, pprops, USBH_MTP_Info.data_len);
1346 }
1347 break;
1348
1349 default:
1350 break;
1351 }
1352
1353 return status;
1354 }
1355
1356
1357 /******************************************************************************************************************************************
1358 * 函数名称: USBH_MTP_EventsCallback()
1359 * 功能说明: The function informs that host has received an event
1360 * 输 入: 无
1361 * 输 出: 无
1362 * 注意事项: 无
1363 ******************************************************************************************************************************************/
USBH_MTP_EventsCallback(USBH_Info_t * phost,uint32_t event,uint32_t param)1364 __attribute__((weak)) void USBH_MTP_EventsCallback(USBH_Info_t *phost, uint32_t event, uint32_t param)
1365 {
1366 }
1367