262 lines
11 KiB
C
262 lines
11 KiB
C
/*
|
|
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "usb_host_config.h"
|
|
#include "usb_host.h"
|
|
#include "usb_host_hci.h"
|
|
#include "usb_host_devices.h"
|
|
#include "usb_host_framework.h"
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
|
|
/* Component ID definition, used by tools. */
|
|
#ifndef FSL_COMPONENT_ID
|
|
#define FSL_COMPONENT_ID "middleware.usb.host.fatfs_usb_stack"
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
|
|
usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
uint8_t *buffer,
|
|
uint32_t bufferLen)
|
|
{
|
|
/* initialize transfer */
|
|
transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)bufferLen);
|
|
transfer->transferBuffer = buffer;
|
|
transfer->transferLength = bufferLen;
|
|
|
|
if (USB_HostSendSetup(deviceInstance->hostHandle, deviceInstance->controlPipe, transfer) !=
|
|
kStatus_USB_Success) /* send setup transfer */
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("failed for USB_HostSendSetup\r\n");
|
|
#endif
|
|
(void)USB_HostFreeTransfer(deviceInstance->hostHandle, transfer);
|
|
return kStatus_USB_Error;
|
|
}
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
usb_host_get_status_param_t *statusParam;
|
|
uint8_t length;
|
|
|
|
/* initialize transfer */
|
|
statusParam = (usb_host_get_status_param_t *)param;
|
|
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_STANDARD;
|
|
if (statusParam->requestType == (uint8_t)kRequestDevice)
|
|
{
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
|
|
}
|
|
else if (statusParam->requestType == (uint8_t)kRequestInterface)
|
|
{
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
|
}
|
|
else
|
|
{
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
|
|
}
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(statusParam->statusSelector);
|
|
|
|
length = 2;
|
|
if (statusParam->statusSelector == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR)
|
|
{
|
|
length = 1;
|
|
}
|
|
return USB_HostCh9RequestCommon(deviceInstance, transfer, statusParam->statusBuffer, length);
|
|
}
|
|
|
|
usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
usb_host_process_feature_param_t *featureParam;
|
|
|
|
/* initialize transfer */
|
|
featureParam = (usb_host_process_feature_param_t *)param;
|
|
if (featureParam->requestType == (uint8_t)kRequestDevice)
|
|
{
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
|
|
}
|
|
else if (featureParam->requestType == (uint8_t)kRequestInterface)
|
|
{
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
|
}
|
|
else
|
|
{
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
|
|
}
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->featureSelector);
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->interfaceOrEndpoint);
|
|
|
|
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
|
|
}
|
|
|
|
usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
uint8_t address;
|
|
|
|
/* initialize transfer */
|
|
address = *(uint8_t *)param;
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(address);
|
|
|
|
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
|
|
}
|
|
|
|
usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
usb_host_process_descriptor_param_t *descriptorParam;
|
|
|
|
/* initialize transfer */
|
|
descriptorParam = (usb_host_process_descriptor_param_t *)param;
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(
|
|
(uint16_t)((uint16_t)descriptorParam->descriptorType << 8) | descriptorParam->descriptorIndex);
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(descriptorParam->languageId);
|
|
return USB_HostCh9RequestCommon(deviceInstance, transfer, descriptorParam->descriptorBuffer,
|
|
descriptorParam->descriptorLength);
|
|
}
|
|
|
|
usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
usb_host_get_interface_param_t *interfaceParam;
|
|
|
|
/* initialize transfer */
|
|
interfaceParam = (usb_host_get_interface_param_t *)param;
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(interfaceParam->interface);
|
|
|
|
return USB_HostCh9RequestCommon(deviceInstance, transfer, interfaceParam->alternateInterfaceBuffer, 1);
|
|
}
|
|
|
|
usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
usb_host_set_interface_param_t *setParam;
|
|
|
|
/* initialize transfer */
|
|
setParam = (usb_host_set_interface_param_t *)param;
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(setParam->interface);
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(setParam->alternateSetting);
|
|
|
|
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
|
|
}
|
|
|
|
usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
usb_host_synch_frame_param_t *frameParam;
|
|
|
|
/* initialize transfer */
|
|
frameParam = (usb_host_synch_frame_param_t *)param;
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(frameParam->endpoint);
|
|
|
|
return USB_HostCh9RequestCommon(deviceInstance, transfer, frameParam->frameNumberBuffer, 2);
|
|
}
|
|
|
|
usb_status_t USB_HostRequestControl(usb_device_handle deviceHandle,
|
|
uint8_t usbRequest,
|
|
usb_host_transfer_t *transfer,
|
|
void *param)
|
|
{
|
|
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
|
|
usb_status_t status = kStatus_USB_Error;
|
|
|
|
if (deviceHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
/* reset transfer fields */
|
|
transfer->setupPacket->bmRequestType = 0x00;
|
|
transfer->setupPacket->bRequest = usbRequest;
|
|
transfer->setupPacket->wIndex = 0;
|
|
transfer->setupPacket->wLength = 0;
|
|
transfer->setupPacket->wValue = 0;
|
|
|
|
switch (usbRequest)
|
|
{
|
|
case USB_REQUEST_STANDARD_GET_STATUS: /* standard get status request */
|
|
status = USB_HostStandardGetStatus(deviceInstance, transfer, param);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_CLEAR_FEATURE: /* standard clear status request */
|
|
case USB_REQUEST_STANDARD_SET_FEATURE: /* standard set feature request */
|
|
status = USB_HostStandardSetClearFeature(deviceInstance, transfer, param);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_SET_ADDRESS: /* standard set address request */
|
|
status = USB_HostStandardSetAddress(deviceInstance, transfer, param);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_GET_DESCRIPTOR: /* standard get descriptor request */
|
|
case USB_REQUEST_STANDARD_SET_DESCRIPTOR: /* standard set descriptor request */
|
|
if (usbRequest == USB_REQUEST_STANDARD_GET_DESCRIPTOR)
|
|
{
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
|
}
|
|
status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, param);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_GET_CONFIGURATION: /* standard get configuration descriptor request */
|
|
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
|
status =
|
|
USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, (uint8_t *)param, 1);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_SET_CONFIGURATION: /* standard set configuration request */
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(*((uint8_t *)param));
|
|
status = USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, NULL, 0);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_GET_INTERFACE: /* standard get interface request */
|
|
status = USB_HostStandardGetInterface(deviceInstance, transfer, param);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_SET_INTERFACE: /* standard set interface request */
|
|
status = USB_HostStandardSetInterface(deviceInstance, transfer, param);
|
|
break;
|
|
|
|
case USB_REQUEST_STANDARD_SYNCH_FRAME: /* standard synch frame request */
|
|
status = USB_HostStandardSyncFrame(deviceInstance, transfer, param);
|
|
break;
|
|
|
|
default:
|
|
/*no action*/
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|