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