|
@@ -0,0 +1,1366 @@
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 文件名称: usbh_mtp.c
|
|
|
+* 功能说明: This file is the MTP Layer Handlers for USB Host MTP class.
|
|
|
+* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
|
|
+* 注意事项:
|
|
|
+* 版本日期: V1.1.0 2020年11月3日
|
|
|
+* 升级记录:
|
|
|
+*
|
|
|
+*
|
|
|
+*******************************************************************************************************************************************
|
|
|
+* @attention
|
|
|
+*
|
|
|
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
|
|
+* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
|
|
+* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
|
|
+* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
|
|
+* -ECTION WITH THEIR PRODUCTS.
|
|
|
+*
|
|
|
+* COPYRIGHT 2012 Synwit Technology
|
|
|
+*******************************************************************************************************************************************/
|
|
|
+#include <stdlib.h>
|
|
|
+#include <string.h>
|
|
|
+#include "SWM341.h"
|
|
|
+#include "usbh_core.h"
|
|
|
+#include "usbh_mtp.h"
|
|
|
+
|
|
|
+
|
|
|
+static USBH_Status USBH_MTP_Init(USBH_Info_t *phost);
|
|
|
+static void USBH_MTP_DeInit(USBH_Info_t *phost);
|
|
|
+static USBH_Status USBH_MTP_Request(USBH_Info_t *phost);
|
|
|
+static USBH_Status USBH_MTP_Process(USBH_Info_t *phost);
|
|
|
+
|
|
|
+USBH_Class_cb_t USBH_MTP_cb =
|
|
|
+{
|
|
|
+ USBH_MTP_Init,
|
|
|
+ USBH_MTP_DeInit,
|
|
|
+ USBH_MTP_Request,
|
|
|
+ USBH_MTP_Process,
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+USBH_MTP_Info_t USBH_MTP_Info;
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_Init()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+static USBH_Status USBH_MTP_Init(USBH_Info_t *phost)
|
|
|
+{
|
|
|
+ USB_EpDesc_t *pEpIn, *pEpOut, *pEpNotify;
|
|
|
+
|
|
|
+ for(int i = 0; i < phost->Device.Cfg_Desc.bNumInterfaces; i++)
|
|
|
+ {
|
|
|
+ if(((phost->Device.Intf_Desc[i].bInterfaceClass == USB_MTP_CLASS) && (phost->Device.Intf_Desc[i].bNumEndpoints == 3)) ||
|
|
|
+ ((phost->Device.Intf_Desc[i].bInterfaceClass == 0xFF) && (phost->Device.Intf_Desc[i].bNumEndpoints == 3)))
|
|
|
+ {
|
|
|
+#define EpVerify(ep, dir, type) (((phost->Device.Ep_Desc[i][ep].bEndpointAddress & USB_EP_IN) == dir) && \
|
|
|
+ ((phost->Device.Ep_Desc[i][ep].bmAttributes & USB_EP_INT) == type))
|
|
|
+ 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))
|
|
|
+ {
|
|
|
+ pEpNotify = &phost->Device.Ep_Desc[i][0];
|
|
|
+ pEpIn = &phost->Device.Ep_Desc[i][1];
|
|
|
+ pEpOut = &phost->Device.Ep_Desc[i][2];
|
|
|
+ }
|
|
|
+ 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))
|
|
|
+ {
|
|
|
+ pEpNotify = &phost->Device.Ep_Desc[i][0];
|
|
|
+ pEpIn = &phost->Device.Ep_Desc[i][2];
|
|
|
+ pEpOut = &phost->Device.Ep_Desc[i][1];
|
|
|
+ }
|
|
|
+ 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))
|
|
|
+ {
|
|
|
+ pEpNotify = &phost->Device.Ep_Desc[i][1];
|
|
|
+ pEpIn = &phost->Device.Ep_Desc[i][0];
|
|
|
+ pEpOut = &phost->Device.Ep_Desc[i][2];
|
|
|
+ }
|
|
|
+ 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))
|
|
|
+ {
|
|
|
+ pEpNotify = &phost->Device.Ep_Desc[i][1];
|
|
|
+ pEpIn = &phost->Device.Ep_Desc[i][2];
|
|
|
+ pEpOut = &phost->Device.Ep_Desc[i][0];
|
|
|
+ }
|
|
|
+ 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))
|
|
|
+ {
|
|
|
+ pEpNotify = &phost->Device.Ep_Desc[i][2];
|
|
|
+ pEpIn = &phost->Device.Ep_Desc[i][0];
|
|
|
+ pEpOut = &phost->Device.Ep_Desc[i][1];
|
|
|
+ }
|
|
|
+ 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))
|
|
|
+ {
|
|
|
+ pEpNotify = &phost->Device.Ep_Desc[i][2];
|
|
|
+ pEpIn = &phost->Device.Ep_Desc[i][1];
|
|
|
+ pEpOut = &phost->Device.Ep_Desc[i][0];
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ USBH_MTP_Info.InEp = pEpIn->bEndpointAddress;
|
|
|
+ USBH_MTP_Info.InEpSize = pEpIn->wMaxPacketSize;
|
|
|
+ USBH_MTP_Info.OutEp = pEpOut->bEndpointAddress;
|
|
|
+ USBH_MTP_Info.OutEpSize = pEpOut->wMaxPacketSize;
|
|
|
+ USBH_MTP_Info.NotifyEp = pEpNotify->bEndpointAddress;
|
|
|
+ USBH_MTP_Info.NotifyEpSize = pEpNotify->wMaxPacketSize;
|
|
|
+
|
|
|
+ USBH_MTP_Info.events.poll = pEpNotify->bInterval;
|
|
|
+
|
|
|
+ SW_LOG_INFO("InEp: %x, InEpSize: %d", pEpIn->bEndpointAddress, pEpIn->wMaxPacketSize);
|
|
|
+ SW_LOG_INFO("OutEp: %x, OutEpSize: %d", pEpOut->bEndpointAddress, pEpOut->wMaxPacketSize);
|
|
|
+ SW_LOG_INFO("NotifyEp: %x, NotifyEpSize: %d, NotifyInterval: %d", pEpNotify->bEndpointAddress, pEpNotify->wMaxPacketSize, pEpNotify->bInterval);
|
|
|
+
|
|
|
+ USBH_MTP_DeInit(phost);
|
|
|
+
|
|
|
+ return USBH_OK;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(phost->usr_cb->DeviceNotSupported)
|
|
|
+ phost->usr_cb->DeviceNotSupported();
|
|
|
+
|
|
|
+ return USBH_NOT_SUPPORTED;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_DeInit()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+static void USBH_MTP_DeInit(USBH_Info_t *phost)
|
|
|
+{
|
|
|
+ USBH_MTP_Info.is_ready = 0;
|
|
|
+
|
|
|
+ USBH_MTP_Info.InEpDATAX = 0;
|
|
|
+ USBH_MTP_Info.OutEpDATAX = 0;
|
|
|
+ USBH_MTP_Info.NotifyEpDATAX = 0;
|
|
|
+
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_IDLE;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_GETDEVICEINFO;
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_IDLE;
|
|
|
+
|
|
|
+ SW_LOG_INFO("USBH_MTP_DeInit");
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_Request()
|
|
|
+* 功能说明: Used for handling Standard requests for MTP class.
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+static USBH_Status USBH_MTP_Request(USBH_Info_t *phost)
|
|
|
+{
|
|
|
+ return USBH_OK;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void USBH_MTP_XferProcess(USBH_Info_t *phost);
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_Process()
|
|
|
+* 功能说明: Used for managing state machine for MTP data transfers.
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+static USBH_Status USBH_MTP_Process(USBH_Info_t *phost)
|
|
|
+{
|
|
|
+ USBH_Resp resp;
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ if((USBH_MTP_Info.state != USBH_MTP_EVENT_WAIT) &&
|
|
|
+ (USBH_MTP_Info.state != USBH_MTP_EVENT_CHECK))
|
|
|
+ {
|
|
|
+ if(USBH_MTP_Info.stateReq != USBH_MTP_IDLE)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.stateBkp = USBH_MTP_Info.state;
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_Info.stateReq;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_IDLE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.state)
|
|
|
+ {
|
|
|
+ case USBH_MTP_GETDEVICEINFO:
|
|
|
+ status = USBH_MTP_GetDeviceInfo(phost, &USBH_MTP_Info.devinfo);
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ SW_LOG_INFO("MTP Device Information");
|
|
|
+ SW_LOG_INFO(" Standard version : %x", USBH_MTP_Info.devinfo.StandardVersion);
|
|
|
+ SW_LOG_INFO(" Vendor ExtID : %s", USBH_MTP_Info.devinfo.VendorExtensionID == 6 ? "MTP" : "NOT SUPPORTED");
|
|
|
+ SW_LOG_INFO(" Functional mode : %s", USBH_MTP_Info.devinfo.FunctionalMode == 0 ? "Standard" : "Vendor");
|
|
|
+ SW_LOG_INFO(" Number of Supported Operation(s) : %d", USBH_MTP_Info.devinfo.OperationsSupportedNbr);
|
|
|
+ SW_LOG_INFO(" Number of Supported Events(s) : %d", USBH_MTP_Info.devinfo.EventsSupportedNbr);
|
|
|
+ SW_LOG_INFO(" Number of Supported Proprieties : %d", USBH_MTP_Info.devinfo.DevicePropertiesSupportedNbr);
|
|
|
+ SW_LOG_INFO(" Manufacturer : %s", USBH_MTP_Info.devinfo.Manufacturer);
|
|
|
+ SW_LOG_INFO(" Model : %s", USBH_MTP_Info.devinfo.Model);
|
|
|
+ SW_LOG_INFO(" Device version : %s", USBH_MTP_Info.devinfo.DeviceVersion);
|
|
|
+ SW_LOG_INFO(" Serial number : %s", USBH_MTP_Info.devinfo.SerialNumber);
|
|
|
+
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_OPENSESSION;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OPENSESSION:
|
|
|
+ status = USBH_MTP_OpenSession(phost, 1);
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ SW_LOG_INFO("MTP Session #1 Opened");
|
|
|
+
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_GETSTORAGEIDS;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_GETSTORAGEIDS:
|
|
|
+ status = USBH_MTP_GetStorageIds(phost, &USBH_MTP_Info.storids);
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ SW_LOG_INFO("Number of storage ID items : %d", USBH_MTP_Info.storids.n);
|
|
|
+ for(int i = 0; i < USBH_MTP_Info.storids.n; i++)
|
|
|
+ {
|
|
|
+ SW_LOG_INFO("storage#%d ID : %x", i, USBH_MTP_Info.storids.Storage[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ USBH_MTP_Info.CurrentStorage = 0;
|
|
|
+ if(USBH_MTP_Info.storids.n)
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_GETSTORAGEINFO;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_GETSTORAGEINFO:
|
|
|
+ status = USBH_MTP_GetStorageInfo(phost, USBH_MTP_Info.storids.Storage[USBH_MTP_Info.CurrentStorage],
|
|
|
+ &USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage]);
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ SW_LOG_INFO("Volume#%u: %s [%s]", USBH_MTP_Info.CurrentStorage, USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage].StorageDescription,
|
|
|
+ USBH_MTP_Info.storinfo[USBH_MTP_Info.CurrentStorage].VolumeLabel);
|
|
|
+ USBH_MTP_Info.is_ready = 1;
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_IDLE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_IDLE:
|
|
|
+ if(abs((int)USBH->FRAMENR - (int)USBH_MTP_Info.events.timer) >= USBH_MTP_Info.events.poll)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.events.timer = USBH->FRAMENR;
|
|
|
+
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_EVENT;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ status = USBH_OK;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_EVENT_CHECK:
|
|
|
+ if(abs((int)USBH->FRAMENR - (int)USBH_MTP_Info.events.timer) >= USBH_MTP_Info.events.poll)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.events.timer = USBH->FRAMENR;
|
|
|
+
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_EVENT;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_TRANSFER; // Event 查询是在数据传输中间插入的,返回数据传输
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_EVENT:
|
|
|
+ if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.NotifyEp, USBH_MTP_Info.NotifyEpDATAX, USBH_MTP_Info.NotifyEpSize))
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_EVENT_WAIT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_EVENT_WAIT:
|
|
|
+ resp = USBH_State();
|
|
|
+ if(resp == USBR_ACK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.NotifyEpDATAX ^= 1;
|
|
|
+
|
|
|
+ USBH_ReadRxBuffer((uint8_t *)&USBH_MTP_Info.events.container, USBH_MTP_Info.NotifyEpSize);
|
|
|
+
|
|
|
+ USBH_MTP_EventsCallback(phost, USBH_MTP_Info.events.container.code, USBH_MTP_Info.events.container.param1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if((USBH_MTP_Info.XferState == USBH_MTP_XFER_DATA_OUT) ||
|
|
|
+ (USBH_MTP_Info.XferState == USBH_MTP_XFER_DATA_IN))
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_TRANSFER; // Event 查询是在数据传输中间插入的,返回数据传输
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_IDLE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_TRANSFER:
|
|
|
+ USBH_MTP_XferProcess(phost);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_XferProcess()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: USBH_Info_t *phost
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+void USBH_MTP_XferProcess(USBH_Info_t *phost)
|
|
|
+{
|
|
|
+ USBH_Resp resp;
|
|
|
+ uint32_t size;
|
|
|
+
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.XferState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_XFER_OP_REQ:
|
|
|
+ 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))
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ_WAIT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_OP_REQ_WAIT:
|
|
|
+ resp = USBH_State();
|
|
|
+ if(resp == USBR_ACK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.OutEpDATAX ^= 1;
|
|
|
+
|
|
|
+ if(USBH_MTP_Info.flags == PTP_DP_NODATA)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
|
|
|
+ }
|
|
|
+ else if(USBH_MTP_Info.flags == PTP_DP_SENDDATA)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT;
|
|
|
+ }
|
|
|
+ else if(USBH_MTP_Info.flags == PTP_DP_GETDATA)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(resp == USBR_NAK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ; // Resend Request
|
|
|
+ }
|
|
|
+ else if(resp == USBR_STALL)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_DATA_OUT:
|
|
|
+ size = USBH_MTP_Info.data_len > USBH_MTP_Info.OutEpSize ? USBH_MTP_Info.OutEpSize : USBH_MTP_Info.data_len;
|
|
|
+ if(USBH_SendOutPacket(phost->Device.Address, USBH_MTP_Info.OutEp, USBH_MTP_Info.OutEpDATAX, USBH_MTP_Info.data_ptr, size))
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT_WAIT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_DATA_OUT_WAIT:
|
|
|
+ resp = USBH_State();
|
|
|
+ if(resp == USBR_ACK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.OutEpDATAX ^= 1;
|
|
|
+
|
|
|
+ if(USBH_MTP_Info.data_len > USBH_MTP_Info.OutEpSize)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.data_ptr += USBH_MTP_Info.OutEpSize;
|
|
|
+ USBH_MTP_Info.data_len -= USBH_MTP_Info.OutEpSize;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(USBH_MTP_Info.data_len > 0)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(resp == USBR_NAK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_OUT; // Resend same data
|
|
|
+
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_EVENT_CHECK; // 从机返回 NAK 时,主机查询一下是否需要执行 Event 查询
|
|
|
+ }
|
|
|
+ else if(resp == USBR_STALL)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_DATA_IN:
|
|
|
+ if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.InEp, USBH_MTP_Info.InEpDATAX, USBH_MTP_Info.InEpSize))
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN_WAIT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_DATA_IN_WAIT:
|
|
|
+ resp = USBH_State();
|
|
|
+ if(resp == USBR_ACK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.InEpDATAX ^= 1;
|
|
|
+
|
|
|
+ uint32_t len = USBH_ReadRxBuffer(USBH_MTP_Info.data_ptr, USBH_MTP_Info.InEpSize);
|
|
|
+
|
|
|
+ if(USBH_MTP_Info.first_packet)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.data_len = *(uint32_t *)(void *)USBH_MTP_Info.data_ptr;
|
|
|
+
|
|
|
+ if(USBH_MTP_Info.first_packet == 3)
|
|
|
+ {
|
|
|
+ len -= PTP_USB_BULK_HDR_LEN;
|
|
|
+ USBH_MTP_Info.data_len -= PTP_USB_BULK_HDR_LEN;
|
|
|
+ memcpy(USBH_MTP_Info.data_ptr, USBH_MTP_Info.data_ptr + PTP_USB_BULK_HDR_LEN, len);
|
|
|
+ }
|
|
|
+
|
|
|
+ USBH_MTP_Info.first_packet = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ USBH_MTP_Info.data_ptr += len;
|
|
|
+ USBH_MTP_Info.data_len -= len;
|
|
|
+
|
|
|
+ if((USBH_MTP_Info.data_len > 0) || (len == USBH_MTP_Info.InEpSize))
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(resp == USBR_NAK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_DATA_IN;
|
|
|
+
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_EVENT_CHECK; // 从机返回 NAK 时,主机查询一下是否需要执行 Event 查询
|
|
|
+ }
|
|
|
+ else if(resp == USBR_STALL)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_RESP:
|
|
|
+ if(USBH_SendInPacket(phost->Device.Address, USBH_MTP_Info.InEp, USBH_MTP_Info.InEpDATAX, USBH_MTP_Info.InEpSize))
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP_WAIT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_RESP_WAIT:
|
|
|
+ resp = USBH_State();
|
|
|
+ if(resp == USBR_ACK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.InEpDATAX ^= 1;
|
|
|
+
|
|
|
+ USBH_ReadRxBuffer((uint8_t *)&USBH_MTP_Info.resp_container, USBH_MTP_Info.InEpSize);
|
|
|
+
|
|
|
+ if(USBH_MTP_Info.resp_container.code == PTP_RC_OK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_OK;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_FAIL;
|
|
|
+ }
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_Info.stateBkp;
|
|
|
+ }
|
|
|
+ else if(resp == USBR_NAK)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_RESP;
|
|
|
+ }
|
|
|
+ else if(resp == USBR_STALL)
|
|
|
+ {
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_ERROR;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_XFER_ERROR:
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_FAIL;
|
|
|
+ USBH_MTP_Info.state = USBH_MTP_Info.stateBkp;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetDeviceInfo()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetDeviceInfo(USBH_Info_t *phost, PTP_DeviceInfo_t *dev_info)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetDeviceInfo;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ PTP_DecodeDeviceInfo(phost, dev_info);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_OpenSession()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_OpenSession(USBH_Info_t *phost, uint32_t session)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Init session params */
|
|
|
+ USBH_MTP_Info.transaction_id = 0x00000000U;
|
|
|
+ USBH_MTP_Info.session_id = session;
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_NODATA;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_OpenSession;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = session;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetStorageIds()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetStorageIds(USBH_Info_t *phost, PTP_StorageIDs_t *storage_ids)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetStorageIDs;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ storage_ids->n = PTP_GetArray32(storage_ids->Storage, USBH_MTP_Info.data_container.payload, 0U);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetStorageInfo()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetStorageInfo(USBH_Info_t *phost, uint32_t storage_id, PTP_StorageInfo_t *storage_info)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetStorageInfo;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = storage_id;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ PTP_DecodeStorageInfo(phost, storage_info);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetNumObjects()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetNumObjects(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, uint32_t *numobs)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_NODATA;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetNumObjects;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = storage_id;
|
|
|
+ USBH_MTP_Info.op_container.param2 = format;
|
|
|
+ USBH_MTP_Info.op_container.param3 = folder;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ *numobs = USBH_MTP_Info.resp_container.param1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetObjectHandles()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetObjectHandles(USBH_Info_t *phost, uint32_t storage_id, uint32_t format, uint32_t folder, PTP_ObjectHandles_t *handles)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetObjectHandles;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = storage_id;
|
|
|
+ USBH_MTP_Info.op_container.param2 = format;
|
|
|
+ USBH_MTP_Info.op_container.param3 = folder;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ handles->n = PTP_GetArray32(handles->Handler, USBH_MTP_Info.data_container.payload, 0U);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetObjectInfo()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetObjectInfo(USBH_Info_t *phost, uint32_t handle, PTP_ObjectInfo_t *object_info)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetObjectInfo;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = handle;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ PTP_DecodeObjectInfo(phost, object_info);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetObject()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = object;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 3;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetObject;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = handle;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetPartialObject()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetPartialObject(USBH_Info_t *phost, uint32_t handle, uint32_t offset, uint32_t maxbytes, uint8_t *object, uint32_t *len)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = object;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 3;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetPartialObject;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = handle;
|
|
|
+ USBH_MTP_Info.op_container.param2 = offset;
|
|
|
+ USBH_MTP_Info.op_container.param3 = maxbytes;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 3;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ *len = USBH_MTP_Info.resp_container.param1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_DeleteObject()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_DeleteObject(USBH_Info_t *phost, uint32_t handle, uint32_t format)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_NODATA;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_DeleteObject;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = handle;
|
|
|
+ USBH_MTP_Info.op_container.param2 = format;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 2;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_SendObject()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_SendObject(USBH_Info_t *phost, uint32_t handle, uint8_t *object, uint32_t size)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_SENDDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = size + PTP_USB_BULK_HDR_LEN;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_SendObject;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 0;
|
|
|
+
|
|
|
+ /* Fill data_container */
|
|
|
+ USBH_MTP_Info.data_container.length = USBH_MTP_Info.data_len;
|
|
|
+ USBH_MTP_Info.data_container.type = PTP_USB_CONTAINER_DATA;
|
|
|
+ USBH_MTP_Info.data_container.code = USBH_MTP_Info.op_container.code;
|
|
|
+ USBH_MTP_Info.data_container.trans_id = USBH_MTP_Info.op_container.trans_id;
|
|
|
+ memcpy(USBH_MTP_Info.data_container.payload, object, size);
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetDevicePropDesc()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetDevicePropDesc(USBH_Info_t *phost, uint16_t propcode, PTP_DevicePropDesc_t *devicepropertydesc)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetDevicePropDesc;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = propcode;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ uint8_t *data = USBH_MTP_Info.data_container.payload;
|
|
|
+
|
|
|
+ devicepropertydesc->DevicePropertyCode = PTP_LE16(&data[PTP_dpd_DevicePropertyCode]);
|
|
|
+ devicepropertydesc->DataType = PTP_LE16(&data[PTP_dpd_DataType]);
|
|
|
+ devicepropertydesc->GetSet = *(uint8_t *)(&data[PTP_dpd_GetSet]);
|
|
|
+ devicepropertydesc->FormFlag = PTP_DPFF_None;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetObjectPropsSupported()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetObjectPropsSupported(USBH_Info_t *phost, uint16_t ofc, uint32_t *propnum, uint16_t *props)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetObjectPropsSupported;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = ofc;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 1;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ *propnum = PTP_GetArray16(props, USBH_MTP_Info.data_container.payload, 0U);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetObjectPropDesc()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetObjectPropDesc(USBH_Info_t *phost, uint16_t opc, uint16_t ofc, PTP_ObjectPropDesc_t *opd)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetObjectPropDesc;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = opc;
|
|
|
+ USBH_MTP_Info.op_container.param2 = ofc;
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 2;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ PTP_DecodeObjectPropDesc(phost, opd, USBH_MTP_Info.data_len);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_GetObjectPropList()
|
|
|
+* 功能说明:
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+USBH_Status USBH_MTP_GetObjectPropList(USBH_Info_t *phost, uint32_t handle, MTP_Properties_t *pprops, uint32_t *nrofprops)
|
|
|
+{
|
|
|
+ USBH_Status status = USBH_BUSY;
|
|
|
+
|
|
|
+ switch(USBH_MTP_Info.OpState)
|
|
|
+ {
|
|
|
+ case USBH_MTP_OP_SEND:
|
|
|
+ /* Set operation request type */
|
|
|
+ USBH_MTP_Info.flags = PTP_DP_GETDATA;
|
|
|
+ USBH_MTP_Info.data_ptr = (uint8_t *)(void *)&USBH_MTP_Info.data_container;
|
|
|
+ USBH_MTP_Info.data_len = 0;
|
|
|
+ USBH_MTP_Info.first_packet = 1;
|
|
|
+
|
|
|
+ /* Fill operation request params */
|
|
|
+ USBH_MTP_Info.op_container.type = PTP_USB_CONTAINER_COMMAND;
|
|
|
+ USBH_MTP_Info.op_container.code = PTP_OC_GetObjPropList;
|
|
|
+ USBH_MTP_Info.op_container.trans_id = USBH_MTP_Info.transaction_id++;
|
|
|
+ USBH_MTP_Info.op_container.param1 = handle;
|
|
|
+ USBH_MTP_Info.op_container.param2 = 0x00000000U; /* 0x00000000U should be "all formats" */
|
|
|
+ USBH_MTP_Info.op_container.param3 = 0xFFFFFFFFU; /* 0xFFFFFFFFU should be "all properties" */
|
|
|
+ USBH_MTP_Info.op_container.param4 = 0x00000000U;
|
|
|
+ USBH_MTP_Info.op_container.param5 = 0xFFFFFFFFU; /* Return full tree below the Param1 handle */
|
|
|
+ USBH_MTP_Info.op_container.length = PTP_USB_BULK_HDR_LEN + sizeof(uint32_t) * 5;
|
|
|
+
|
|
|
+ /* Setup State machine and start transfer */
|
|
|
+ USBH_MTP_Info.XferState = USBH_MTP_XFER_OP_REQ;
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_WAIT;
|
|
|
+
|
|
|
+ USBH_MTP_Info.stateReq = USBH_MTP_TRANSFER;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBH_MTP_OP_WAIT:
|
|
|
+ if(USBH_MTP_Info.XferStatus != USBH_BUSY)
|
|
|
+ {
|
|
|
+ status = USBH_MTP_Info.XferStatus;
|
|
|
+ USBH_MTP_Info.XferStatus = USBH_BUSY;
|
|
|
+
|
|
|
+ USBH_MTP_Info.OpState = USBH_MTP_OP_SEND;
|
|
|
+ }
|
|
|
+ if(status == USBH_OK)
|
|
|
+ {
|
|
|
+ PTP_DecodeObjectPropList(phost, pprops, USBH_MTP_Info.data_len);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************************************************************************
|
|
|
+* 函数名称: USBH_MTP_EventsCallback()
|
|
|
+* 功能说明: The function informs that host has received an event
|
|
|
+* 输 入: 无
|
|
|
+* 输 出: 无
|
|
|
+* 注意事项: 无
|
|
|
+******************************************************************************************************************************************/
|
|
|
+__attribute__((weak)) void USBH_MTP_EventsCallback(USBH_Info_t *phost, uint32_t event, uint32_t param)
|
|
|
+{
|
|
|
+}
|