MIMXRT1050_EVK: Add USB support

Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
pull/13115/head
Mahesh Mahadevan 2020-02-18 15:32:51 -06:00
parent a870fcface
commit 81a1193012
27 changed files with 12923 additions and 4 deletions

View File

@ -1,5 +1,6 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* Copyright (c) 2006-2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,9 +21,17 @@
#include "fsl_iomuxc.h"
#include "fsl_gpio.h"
#include "lpm.h"
#include "usb_phy.h"
#include "usb_device_config.h"
#define LPSPI_CLOCK_SOURCE_DIVIDER (7U)
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
/* USB PHY condfiguration */
#define BOARD_USB_PHY_D_CAL (0x0CU)
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
uint8_t mbed_otp_mac_address(char *mac);
void mbed_default_mac_address(char *mac);
@ -311,3 +320,28 @@ void mbed_default_mac_address(char *mac) {
return;
}
void USB_DeviceClockInit(void)
{
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL,
BOARD_USB_PHY_TXCAL45DP,
BOARD_USB_PHY_TXCAL45DM,
};
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ, &phyConfig);
}
uint32_t USB_DeviceGetIrqNumber(void)
{
uint8_t irqNumber;
uint8_t usbDeviceEhciIrq[] = USBHS_IRQS;
irqNumber = usbDeviceEhciIrq[CONTROLLER_ID - kUSB_ControllerEhci0];
return irqNumber;
}

View File

@ -0,0 +1,952 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_dci.h"
#include "usb_device_class.h"
#include "usb_device_ch9.h"
#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @brief Standard request callback function typedef.
*
* This function is used to handle the standard request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @return A USB error code or kStatus_USB_Success.
*/
typedef usb_status_t (*usb_standard_request_callback_t)(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
/*******************************************************************************
* Prototypes
******************************************************************************/
static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length);
/*******************************************************************************
* Variables
******************************************************************************/
/* The function list to handle the standard request. */
static const usb_standard_request_callback_t s_UsbDeviceStandardRequest[] = {
USB_DeviceCh9GetStatus,
USB_DeviceCh9SetClearFeature,
(usb_standard_request_callback_t)NULL,
USB_DeviceCh9SetClearFeature,
(usb_standard_request_callback_t)NULL,
USB_DeviceCh9SetAddress,
USB_DeviceCh9GetDescriptor,
(usb_standard_request_callback_t)NULL,
USB_DeviceCh9GetConfiguration,
USB_DeviceCh9SetConfiguration,
USB_DeviceCh9GetInterface,
USB_DeviceCh9SetInterface,
USB_DeviceCh9SynchFrame,
};
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Handle get status request.
*
* This function is used to handle get status request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t state;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state))
{
return error;
}
if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
{
#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
if (setup->wIndex == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR)
{
error =
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusOtg, &classHandle->standardTranscationBuffer);
classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
/* The device status length must be USB_DEVICE_STATUS_SIZE. */
*length = 1;
}
else /* Get the device status */
{
#endif
error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDevice,
&classHandle->standardTranscationBuffer);
classHandle->standardTranscationBuffer =
classHandle->standardTranscationBuffer & USB_GET_STATUS_DEVICE_MASK;
classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
/* The device status length must be USB_DEVICE_STATUS_SIZE. */
*length = USB_DEVICE_STATUS_SIZE;
#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
}
#endif
}
else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
{
/* Get the interface status */
error = kStatus_USB_Success;
classHandle->standardTranscationBuffer = 0U;
/* The interface status length must be USB_INTERFACE_STATUS_SIZE. */
*length = USB_INTERFACE_STATUS_SIZE;
}
else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
{
/* Get the endpoint status */
usb_device_endpoint_status_struct_t endpointStatus;
endpointStatus.endpointAddress = (uint8_t)setup->wIndex;
endpointStatus.endpointStatus = kUSB_DeviceEndpointStateIdle;
error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusEndpoint, &endpointStatus);
classHandle->standardTranscationBuffer = endpointStatus.endpointStatus & USB_GET_STATUS_ENDPOINT_MASK;
classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
/* The endpoint status length must be USB_INTERFACE_STATUS_SIZE. */
*length = USB_ENDPOINT_STATUS_SIZE;
}
else
{
}
*buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
return error;
}
/*!
* @brief Handle set or clear device feature request.
*
* This function is used to handle set or clear device feature request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t state;
uint8_t isSet = 0U;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state))
{
return error;
}
/* Identify the request is set or clear the feature. */
if (USB_REQUEST_STANDARD_SET_FEATURE == setup->bRequest)
{
isSet = 1U;
}
if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
{
/* Set or Clear the device feature. */
if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP == setup->wValue)
{
#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusRemoteWakeup, &isSet);
#endif
/* Set or Clear the device remote wakeup feature. */
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetRemoteWakeup, &isSet);
}
#if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
(defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE == setup->wValue)
{
state = kUSB_DeviceStateTestMode;
error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
}
#endif
#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE == setup->wValue)
{
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetBHNPEnable, &isSet);
}
#endif
else
{
}
}
else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
{
/* Set or Clear the endpoint feature. */
if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT == setup->wValue)
{
if (USB_CONTROL_ENDPOINT == (setup->wIndex & USB_ENDPOINT_NUMBER_MASK))
{
/* Set or Clear the control endpoint status(halt or not). */
if (isSet)
{
USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex);
}
else
{
USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex);
}
}
/* Set or Clear the endpoint status feature. */
if (isSet)
{
error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetEndpointHalt, &setup->wIndex);
}
else
{
error =
USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventClearEndpointHalt, &setup->wIndex);
}
}
else
{
}
}
else
{
}
return error;
}
/*!
* @brief Handle set address request.
*
* This function is used to handle set address request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state.
*/
static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t state;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if ((kUSB_DeviceStateAddressing != state) && (kUSB_DeviceStateAddress != state) &&
(kUSB_DeviceStateDefault != state) && (kUSB_DeviceStateConfigured != state))
{
return error;
}
if (kUSB_DeviceStateAddressing != state)
{
/* If the device address is not setting, pass the address and the device state will change to
* kUSB_DeviceStateAddressing internally. */
state = setup->wValue & 0xFFU;
error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, &state);
}
else
{
/* If the device address is setting, set device address and the address will be write into the controller
* internally. */
error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, NULL);
/* And then change the device state to kUSB_DeviceStateAddress. */
if (kStatus_USB_Success == error)
{
state = kUSB_DeviceStateAddress;
error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
}
}
return error;
}
/*!
* @brief Handle get descriptor request.
*
* This function is used to handle get descriptor request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
usb_device_get_descriptor_common_union_t commonDescriptor;
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t state;
uint8_t descriptorType = (uint8_t)((setup->wValue & 0xFF00U) >> 8U);
uint8_t descriptorIndex = (uint8_t)((setup->wValue & 0x00FFU));
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state) &&
(kUSB_DeviceStateDefault != state))
{
return error;
}
commonDescriptor.commonDescriptor.length = setup->wLength;
if (USB_DESCRIPTOR_TYPE_DEVICE == descriptorType)
{
/* Get the device descriptor */
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetDeviceDescriptor,
&commonDescriptor.deviceDescriptor);
}
else if (USB_DESCRIPTOR_TYPE_CONFIGURE == descriptorType)
{
/* Get the configuration descriptor */
commonDescriptor.configurationDescriptor.configuration = descriptorIndex;
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetConfigurationDescriptor,
&commonDescriptor.configurationDescriptor);
}
else if (USB_DESCRIPTOR_TYPE_STRING == descriptorType)
{
/* Get the string descriptor */
commonDescriptor.stringDescriptor.stringIndex = descriptorIndex;
commonDescriptor.stringDescriptor.languageId = setup->wIndex;
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetStringDescriptor,
&commonDescriptor.stringDescriptor);
}
#if (defined(USB_DEVICE_CONFIG_HID) && (USB_DEVICE_CONFIG_HID > 0U))
else if (USB_DESCRIPTOR_TYPE_HID == descriptorType)
{
/* Get the hid descriptor */
commonDescriptor.hidDescriptor.interfaceNumber = setup->wIndex;
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetHidDescriptor,
&commonDescriptor.hidDescriptor);
}
else if (USB_DESCRIPTOR_TYPE_HID_REPORT == descriptorType)
{
/* Get the hid report descriptor */
commonDescriptor.hidReportDescriptor.interfaceNumber = setup->wIndex;
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetHidReportDescriptor,
&commonDescriptor.hidReportDescriptor);
}
else if (USB_DESCRIPTOR_TYPE_HID_PHYSICAL == descriptorType)
{
/* Get the hid physical descriptor */
commonDescriptor.hidPhysicalDescriptor.index = descriptorIndex;
commonDescriptor.hidPhysicalDescriptor.interfaceNumber = setup->wIndex;
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetHidPhysicalDescriptor,
&commonDescriptor.hidPhysicalDescriptor);
}
#endif
#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
else if (USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER == descriptorType)
{
/* Get the device descriptor */
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetDeviceQualifierDescriptor,
&commonDescriptor.deviceDescriptor);
}
#endif
#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
else if (USB_DESCRIPTOR_TYPE_BOS == descriptorType)
{
/* Get the configuration descriptor */
commonDescriptor.configurationDescriptor.configuration = descriptorIndex;
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetBOSDescriptor,
&commonDescriptor.configurationDescriptor);
}
#endif
else
{
}
*buffer = commonDescriptor.commonDescriptor.buffer;
*length = commonDescriptor.commonDescriptor.length;
return error;
}
/*!
* @brief Handle get current configuration request.
*
* This function is used to handle get current configuration request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
uint8_t state;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if ((kUSB_DeviceStateAddress != state) && ((kUSB_DeviceStateConfigured != state)))
{
return kStatus_USB_InvalidRequest;
}
*length = USB_CONFIGURE_SIZE;
*buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
return USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetConfiguration,
&classHandle->standardTranscationBuffer);
}
/*!
* @brief Handle set current configuration request.
*
* This function is used to handle set current configuration request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
uint8_t state;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state))
{
return kStatus_USB_InvalidRequest;
}
/* The device state is changed to kUSB_DeviceStateConfigured */
state = kUSB_DeviceStateConfigured;
USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if (!setup->wValue)
{
/* If the new configuration is zero, the device state is changed to kUSB_DeviceStateAddress */
state = kUSB_DeviceStateAddress;
USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
}
/* Notify the class layer the configuration is changed */
USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetConfiguration, &setup->wValue);
/* Notify the application the configuration is changed */
return USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetConfiguration, &setup->wValue);
}
/*!
* @brief Handle get the alternate setting of a interface request.
*
* This function is used to handle get the alternate setting of a interface request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t state;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if (state != kUSB_DeviceStateConfigured)
{
return error;
}
*length = USB_INTERFACE_SIZE;
*buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
classHandle->standardTranscationBuffer = (uint16_t)(((uint32_t)setup->wIndex & 0xFFU) << 8U);
/* The Bit[15~8] is used to save the interface index, and the alternate setting will be saved in Bit[7~0] by
* application. */
error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetInterface,
&classHandle->standardTranscationBuffer);
classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
return error;
}
/*!
* @brief Handle set the alternate setting of a interface request.
*
* This function is used to handle set the alternate setting of a interface request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
uint8_t state;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if (state != kUSB_DeviceStateConfigured)
{
return kStatus_USB_InvalidRequest;
}
classHandle->standardTranscationBuffer = ((setup->wIndex & 0xFFU) << 8U) | (setup->wValue & 0xFFU);
/* Notify the class driver the alternate setting of the interface is changed. */
/* The Bit[15~8] is used to save the interface index, and the alternate setting is saved in Bit[7~0]. */
USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetInterface,
&classHandle->standardTranscationBuffer);
/* Notify the application the alternate setting of the interface is changed. */
/* The Bit[15~8] is used to save the interface index, and the alternate setting will is saved in Bit[7~0]. */
return USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetInterface,
&classHandle->standardTranscationBuffer);
}
/*!
* @brief Handle get sync frame request.
*
* This function is used to handle get sync frame request.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @retval kStatus_USB_Success The request is handled successfully.
* @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
* or, the request is unsupported.
*/
static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle,
usb_setup_struct_t *setup,
uint8_t **buffer,
uint32_t *length)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t state;
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
if (state != kUSB_DeviceStateConfigured)
{
return error;
}
classHandle->standardTranscationBuffer = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex);
/* Get the sync frame value */
error =
USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSynchFrame, &classHandle->standardTranscationBuffer);
*buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
*length = sizeof(classHandle->standardTranscationBuffer);
return error;
}
/*!
* @brief Send the response to the host.
*
* This function is used to send the response to the host.
*
* There are two cases this function will be called.
* Case one when a setup packet is received in control endpoint callback function:
* 1. If there is not data phase in the setup transfer, the function will prime an IN transfer with the data
* length is zero for status phase.
* 2. If there is an IN data phase, the function will prime an OUT transfer with the actual length to need to
* send for data phase. And then prime an IN transfer with the data length is zero for status phase.
* 3. If there is an OUT data phase, the function will prime an IN transfer with the actual length to want to
* receive for data phase.
*
* Case two when is not a setup packet received in control endpoint callback function:
* 1. The function will prime an IN transfer with data length is zero for status phase.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param setup The pointer of the setup packet.
* @param error The error code returned from the standard request function.
* @param stage The stage of the control transfer.
* @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
* @param length It is an out parameter, the data length.
*
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceControlCallbackFeedback(usb_device_handle handle,
usb_setup_struct_t *setup,
usb_status_t error,
usb_device_control_read_write_sequence_t stage,
uint8_t **buffer,
uint32_t *length)
{
usb_status_t errorCode = kStatus_USB_Error;
uint8_t direction = USB_IN;
if (kStatus_USB_InvalidRequest == error)
{
/* Stall the control pipe when the request is unsupported. */
if ((!((setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)) &&
((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT) && (setup->wLength) &&
(kUSB_DeviceControlPipeSetupStage == stage))
{
direction = USB_OUT;
}
errorCode = USB_DeviceStallEndpoint(
handle,
(USB_CONTROL_ENDPOINT) | (uint8_t)((uint32_t)direction << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
}
else
{
if (*length > setup->wLength)
{
*length = setup->wLength;
}
errorCode = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), *buffer, *length);
if ((kStatus_USB_Success == errorCode) &&
(USB_REQUEST_TYPE_DIR_IN == (setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK)))
{
errorCode = USB_DeviceRecvRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U);
}
}
return errorCode;
}
/*!
* @brief Control endpoint callback function.
*
* This callback function is used to notify uplayer the transfser result of a transfer.
* This callback pointer is passed when a specified endpoint initialized by calling API USB_DeviceInitEndpoint.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param message The result of a transfer, includes transfer buffer, transfer length and whether is in setup
* phase for control pipe.
* @param callbackParam The parameter for this callback. It is same with
* usb_device_endpoint_callback_struct_t::callbackParam.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceControlCallback(usb_device_handle handle,
usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam)
{
usb_setup_struct_t *deviceSetup, *setup;
usb_device_common_class_struct_t *classHandle;
uint8_t *buffer = (uint8_t *)NULL;
uint32_t length = 0U;
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t state;
if ((0xFFFFFFFFU == message->length) || (NULL == callbackParam))
{
return error;
}
classHandle = (usb_device_common_class_struct_t *)callbackParam;
deviceSetup = (usb_setup_struct_t *)&classHandle->setupBuffer[0];
USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
if (message->isSetup)
{
if ((USB_SETUP_PACKET_SIZE != message->length) || (NULL == message->buffer))
{
/* If a invalid setup is received, the control pipes should be de-init and init again.
* Due to the IP can not meet this require, it is reserved for feature.
*/
/*
USB_DeviceDeinitEndpoint(handle,
USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
USB_DeviceDeinitEndpoint(handle,
USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
USB_DeviceControlPipeInit(handle, callbackParam);
*/
return error;
}
/* Receive a setup request */
setup = (usb_setup_struct_t *)(message->buffer);
/* Copy the setup packet to the application buffer */
deviceSetup->wValue = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wValue);
deviceSetup->wIndex = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex);
deviceSetup->wLength = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wLength);
deviceSetup->bRequest = setup->bRequest;
deviceSetup->bmRequestType = setup->bmRequestType;
if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)
{
/* Handle the standard request, only handle the request in request array. */
if(deviceSetup->bRequest < (sizeof(s_UsbDeviceStandardRequest)/4))
{
if (s_UsbDeviceStandardRequest[deviceSetup->bRequest] != (usb_standard_request_callback_t)NULL)
{
error = s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length);
}
}
}
else
{
if ((deviceSetup->wLength) &&
((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
{
/* Class or vendor request with the OUT data phase. */
if ((deviceSetup->wLength) &&
((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS))
{
/* Get data buffer to receive the data from the host. */
usb_device_control_request_struct_t controlRequest;
controlRequest.buffer = (uint8_t *)NULL;
controlRequest.isSetup = 1U;
controlRequest.setup = deviceSetup;
controlRequest.length = deviceSetup->wLength;
error = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
length = controlRequest.length;
buffer = controlRequest.buffer;
}
else if ((deviceSetup->wLength) &&
((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR))
{
/* Get data buffer to receive the data from the host. */
usb_device_control_request_struct_t controlRequest;
controlRequest.buffer = (uint8_t *)NULL;
controlRequest.isSetup = 1U;
controlRequest.setup = deviceSetup;
controlRequest.length = deviceSetup->wLength;
error = USB_DeviceClassCallback(handle, kUSB_DeviceEventVendorRequest, &controlRequest);
length = controlRequest.length;
buffer = controlRequest.buffer;
}
else
{
}
if (kStatus_USB_Success == error)
{
/* Prime an OUT transfer */
error = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, buffer, deviceSetup->wLength);
return error;
}
}
else
{
/* Class or vendor request with the IN data phase. */
if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS))
{
/* Get data buffer to response the host. */
usb_device_control_request_struct_t controlRequest;
controlRequest.buffer = (uint8_t *)NULL;
controlRequest.isSetup = 1U;
controlRequest.setup = deviceSetup;
controlRequest.length = deviceSetup->wLength;
error = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
length = controlRequest.length;
buffer = controlRequest.buffer;
}
else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR))
{
/* Get data buffer to response the host. */
usb_device_control_request_struct_t controlRequest;
controlRequest.buffer = (uint8_t *)NULL;
controlRequest.isSetup = 1U;
controlRequest.setup = deviceSetup;
controlRequest.length = deviceSetup->wLength;
error = USB_DeviceClassCallback(handle, kUSB_DeviceEventVendorRequest, &controlRequest);
length = controlRequest.length;
buffer = controlRequest.buffer;
}
else
{
}
}
}
/* Send the response to the host. */
error = USB_DeviceControlCallbackFeedback(handle, deviceSetup, error, kUSB_DeviceControlPipeSetupStage, &buffer,
&length);
}
else if (kUSB_DeviceStateAddressing == state)
{
/* Set the device address to controller. */
error = s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length);
}
#if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
(defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
else if (kUSB_DeviceStateTestMode == state)
{
uint8_t portTestControl = (uint8_t)(deviceSetup->wIndex >> 8);
/* Set the controller.into test mode. */
error = USB_DeviceSetStatus(handle, kUSB_DeviceStatusTestMode, &portTestControl);
}
#endif
else if ((message->length) && (deviceSetup->wLength) &&
((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
{
if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS))
{
/* Data received in OUT phase, and notify the class driver. */
usb_device_control_request_struct_t controlRequest;
controlRequest.buffer = message->buffer;
controlRequest.isSetup = 0U;
controlRequest.setup = deviceSetup;
controlRequest.length = message->length;
error = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
}
else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR))
{
/* Data received in OUT phase, and notify the application. */
usb_device_control_request_struct_t controlRequest;
controlRequest.buffer = message->buffer;
controlRequest.isSetup = 0U;
controlRequest.setup = deviceSetup;
controlRequest.length = message->length;
error = USB_DeviceClassCallback(handle, kUSB_DeviceEventVendorRequest, &controlRequest);
}
else
{
}
/* Send the response to the host. */
error = USB_DeviceControlCallbackFeedback(handle, deviceSetup, error, kUSB_DeviceControlPipeDataStage, &buffer,
&length);
}
else
{
}
return error;
}
/*!
* @brief Control endpoint initialization function.
*
* This callback function is used to initialize the control pipes.
*
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
* @param param The up layer handle.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param)
{
usb_device_endpoint_init_struct_t epInitStruct;
usb_device_endpoint_callback_struct_t epCallback;
usb_status_t error;
epCallback.callbackFn = USB_DeviceControlCallback;
epCallback.callbackParam = param;
epInitStruct.zlt = 1U;
epInitStruct.transferType = USB_ENDPOINT_CONTROL;
epInitStruct.interval = 0;
epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
epInitStruct.maxPacketSize = USB_CONTROL_MAX_PACKET_SIZE;
/* Initialize the control IN pipe */
error = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback);
if (kStatus_USB_Success != error)
{
return error;
}
epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
/* Initialize the control OUT pipe */
error = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback);
if (kStatus_USB_Success != error)
{
USB_DeviceDeinitEndpoint(handle,
USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
return error;
}
return kStatus_USB_Success;
}
#endif /* USB_DEVICE_CONFIG_NUM */

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_CH9_H__
#define __USB_DEVICE_CH9_H__
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @addtogroup usb_device_ch9
* @{
*/
/*! @brief Defines USB device status size when the host request to get device status */
#define USB_DEVICE_STATUS_SIZE (0x02U)
/*! @brief Defines USB device interface status size when the host request to get interface status */
#define USB_INTERFACE_STATUS_SIZE (0x02U)
/*! @brief Defines USB device endpoint status size when the host request to get endpoint status */
#define USB_ENDPOINT_STATUS_SIZE (0x02U)
/*! @brief Defines USB device configuration size when the host request to get current configuration */
#define USB_CONFIGURE_SIZE (0X01U)
/*! @brief Defines USB device interface alternate setting size when the host request to get interface alternate setting
*/
#define USB_INTERFACE_SIZE (0X01U)
/*! @brief Defines USB device status mask */
#define USB_GET_STATUS_DEVICE_MASK (0x03U)
/*! @brief Defines USB device interface status mask */
#define USB_GET_STATUS_INTERFACE_MASK (0x03U)
/*! @brief Defines USB device endpoint status mask */
#define USB_GET_STATUS_ENDPOINT_MASK (0x03U)
/*! @brief Control read and write sequence */
typedef enum _usb_device_control_read_write_sequence
{
kUSB_DeviceControlPipeSetupStage = 0U, /*!< Setup stage */
kUSB_DeviceControlPipeDataStage, /*!< Data stage */
kUSB_DeviceControlPipeStatusStage, /*!< status stage */
} usb_device_control_read_write_sequence_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Initializes the control pipes.
*
* The function is used to initialize the control pipes. This function should be called when event
* kUSB_DeviceEventBusReset is received.
*
* @param[in] handle The device handle.
* @param[in] param The event parameter.
*
* @return A USB error code or kStatus_USB_Success.
*/
extern usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param);
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __USB_DEVICE_CH9_H__ */

View File

@ -0,0 +1,552 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016, 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_ch9.h"
#include "usb_device_class.h"
#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
/* Include the class drivers according to the usb_device_config.h. */
#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U))
#include "usb_device_hid.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U))
#include "usb_device_cdc_acm.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U))
#include "usb_device_msc.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_AUDIO)) && (USB_DEVICE_CONFIG_AUDIO > 0U))
#include "usb_device_audio.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_PHDC)) && (USB_DEVICE_CONFIG_PHDC > 0U))
#include "usb_device_phdc.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_VIDEO)) && (USB_DEVICE_CONFIG_VIDEO > 0U))
#include "usb_device_video.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U))
#include "usb_device_printer.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_DFU)) && (USB_DEVICE_CONFIG_DFU > 0U))
#include "usb_device_dfu.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_CCID)) && (USB_DEVICE_CONFIG_CCID > 0U))
#include "usb_device_ccid.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle);
static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId);
static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId,
usb_device_common_class_struct_t **handle);
static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle,
usb_device_common_class_struct_t **handle);
/*******************************************************************************
* Variables
******************************************************************************/
/* The device class driver list. */
static const usb_device_class_map_t s_UsbDeviceClassInterfaceMap[] = {
#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U))
{USB_DeviceHidInit, USB_DeviceHidDeinit, USB_DeviceHidEvent, kUSB_DeviceClassTypeHid},
#endif
#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U))
{USB_DeviceCdcAcmInit, USB_DeviceCdcAcmDeinit, USB_DeviceCdcAcmEvent, kUSB_DeviceClassTypeCdc},
#endif
#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U))
{USB_DeviceMscInit, USB_DeviceMscDeinit, USB_DeviceMscEvent, kUSB_DeviceClassTypeMsc},
#endif
#if ((defined USB_DEVICE_CONFIG_AUDIO) && (USB_DEVICE_CONFIG_AUDIO > 0U))
{USB_DeviceAudioInit, USB_DeviceAudioDeinit, USB_DeviceAudioEvent, kUSB_DeviceClassTypeAudio},
#endif
#if ((defined USB_DEVICE_CONFIG_PHDC) && (USB_DEVICE_CONFIG_PHDC > 0U))
{USB_DevicePhdcInit, USB_DevicePhdcDeinit, USB_DevicePhdcEvent, kUSB_DeviceClassTypePhdc},
#endif
#if ((defined USB_DEVICE_CONFIG_VIDEO) && (USB_DEVICE_CONFIG_VIDEO > 0U))
{USB_DeviceVideoInit, USB_DeviceVideoDeinit, USB_DeviceVideoEvent, kUSB_DeviceClassTypeVideo},
#endif
#if ((defined USB_DEVICE_CONFIG_PRINTER) && (USB_DEVICE_CONFIG_PRINTER > 0U))
{USB_DevicePrinterInit, USB_DevicePrinterDeinit, USB_DevicePrinterEvent, kUSB_DeviceClassTypePrinter},
#endif
#if ((defined USB_DEVICE_CONFIG_DFU) && (USB_DEVICE_CONFIG_DFU > 0U))
{USB_DeviceDfuInit, USB_DeviceDfuDeinit, USB_DeviceDfuEvent, kUSB_DeviceClassTypeDfu},
#endif
#if ((defined USB_DEVICE_CONFIG_CCID) && (USB_DEVICE_CONFIG_CCID > 0U))
{USB_DeviceCcidInit, USB_DeviceCcidDeinit, USB_DeviceCcidEvent, kUSB_DeviceClassTypeCcid},
#endif
{(usb_device_class_init_call_t)NULL, (usb_device_class_deinit_call_t)NULL, (usb_device_class_event_callback_t)NULL,
(usb_device_class_type_t)0},
};
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_common_class_struct_t
s_UsbDeviceCommonClassStruct[USB_DEVICE_CONFIG_NUM];
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
s_UsbDeviceSetupBuffer[USB_DEVICE_CONFIG_NUM][USB_DATA_ALIGN_SIZE_MULTIPLE(USB_SETUP_PACKET_SIZE)];
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Allocate a device common class handle.
*
* This function allocates a a device common class handle.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param handle It is out parameter, is used to return pointer of the device common class handle to the
* caller.
*
* @retval kStatus_USB_Success Get a device handle successfully.
* @retval kStatus_USB_Busy Cannot allocate a common class handle.
* @retval kStatus_USB_Error The common class has been initialized.
*/
static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle)
{
uint32_t count;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
/* Check the controller is initialized or not. */
for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
OSA_EXIT_CRITICAL();
return kStatus_USB_Error;
}
}
/* Get a free common class handle. */
for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
{
if (NULL == s_UsbDeviceCommonClassStruct[count].handle)
{
s_UsbDeviceCommonClassStruct[count].controllerId = controllerId;
s_UsbDeviceCommonClassStruct[count].setupBuffer = s_UsbDeviceSetupBuffer[count];
*handle = &s_UsbDeviceCommonClassStruct[count];
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Busy;
}
/*!
* @brief Free a device common class handle.
*
* This function frees a device common class handle.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The common class can not be found.
*/
static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
s_UsbDeviceCommonClassStruct[count].handle = NULL;
s_UsbDeviceCommonClassStruct[count].configList = (usb_device_class_config_list_struct_t *)NULL;
s_UsbDeviceCommonClassStruct[count].controllerId = 0U;
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Get the device common class handle according to the controller id.
*
* This function gets the device common class handle according to the controller id.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param handle It is out parameter, is used to return pointer of the device common class handle to the
* caller.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The common class can not be found.
*/
static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId,
usb_device_common_class_struct_t **handle)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
*handle = &s_UsbDeviceCommonClassStruct[count];
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Get the device common class handle according to the device handle.
*
* This function gets the device common class handle according to the device handle.
*
* @param deviceHandle The device handle, got from the USB_DeviceInit.
* @param handle It is out parameter, is used to return pointer of the device common class handle to the
* caller.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The common class can not be found.
*/
static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle,
usb_device_common_class_struct_t **handle)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if (deviceHandle == s_UsbDeviceCommonClassStruct[count].handle)
{
*handle = &s_UsbDeviceCommonClassStruct[count];
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Get the device handle according to the controller id.
*
* This function gets the device handle according to the controller id.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param handle It is out parameter, is used to return pointer of the device handle to the caller.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The device handle not be found.
*/
usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
*handle = s_UsbDeviceCommonClassStruct[count].handle;
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Handle the event passed to the class drivers.
*
* This function handles the event passed to the class drivers.
*
* @param handle The device handle, got from the USB_DeviceInit.
* @param event The event codes. Please refer to the enumeration usb_device_class_event_t.
* @param param The param type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success A valid request has been handled.
* @retval kStatus_USB_InvalidParameter The device handle not be found.
* @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller.
*/
usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param)
{
usb_device_common_class_struct_t *classHandle;
uint8_t mapIndex;
uint8_t classIndex;
usb_status_t errorReturn = kStatus_USB_Error;
usb_status_t error = kStatus_USB_Error;
if (NULL == param)
{
return kStatus_USB_InvalidParameter;
}
/* Get the common class handle according to the device handle. */
errorReturn = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle);
if (kStatus_USB_Success != errorReturn)
{
return kStatus_USB_InvalidParameter;
}
for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
{
for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t));
mapIndex++)
{
if (s_UsbDeviceClassInterfaceMap[mapIndex].type ==
classHandle->configList->config[classIndex].classInfomation->type)
{
/* Call class event callback of supported class */
errorReturn = s_UsbDeviceClassInterfaceMap[mapIndex].classEventCallback(
(void *)classHandle->configList->config[classIndex].classHandle, event, param);
/* Return the error code kStatus_USB_InvalidRequest immediately, when a class returns
* kStatus_USB_InvalidRequest. */
if (kStatus_USB_InvalidRequest == errorReturn)
{
return kStatus_USB_InvalidRequest;
}
/* For composite device, it should return kStatus_USB_Success once a valid request has been handled */
if (kStatus_USB_Success == errorReturn)
{
error = kStatus_USB_Success;
}
break;
}
}
}
return error;
}
/*!
* @brief Handle the common class callback.
*
* This function handles the common class callback.
*
* @param handle The device handle, got from the USB_DeviceInit.
* @param event The event codes. Please refer to the enumeration usb_device_event_t.
* @param param The param type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error = kStatus_USB_Error;
/* Get the common class handle according to the device handle. */
error = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
if (kUSB_DeviceEventBusReset == event)
{
/* Initialize the control pipes */
USB_DeviceControlPipeInit(handle, classHandle);
/* Notify the classes the USB bus reset signal detected. */
USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle);
}
/* Call the application device callback function. deviceCallback is from the second parameter of
USB_DeviceClassInit */
error = classHandle->configList->deviceCallback(handle, event, param);
return error;
}
/*!
* @brief Initialize the common class and the supported classes.
*
* This function is used to initialize the common class and the supported classes.
*
* @param[in] controllerId The controller id of the USB IP. Please refer to the enumeration #usb_controller_index_t.
* @param[in] configList The class configurations. The pointer must point to the global variable.
* Please refer to the structure #usb_device_class_config_list_struct_t.
* @param[out] handle It is out parameter, is used to return pointer of the device handle to the caller.
* The value of parameter is a pointer points the device handle, and this design is used to
* make simple device align with composite device. For composite device, there are many
* kinds of class handle, but there is only one device handle. So the handle points to
* a device instead of a class. And the class handle can be got from the
* #usb_device_class_config_struct_t::classHandle after the function successfully.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassInit(
uint8_t controllerId, /*!< [IN] Controller ID */
usb_device_class_config_list_struct_t *configList, /*!< [IN] Pointer to class configuration list */
usb_device_handle *handle /*!< [OUT] Pointer to the device handle */
)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error = kStatus_USB_Error;
uint8_t mapIndex;
uint8_t classIndex;
if ((NULL == handle) || (NULL == configList) || ((usb_device_callback_t)NULL == configList->deviceCallback))
{
return kStatus_USB_InvalidParameter;
}
/* Allocate a common class driver handle. */
error = USB_DeviceClassAllocateHandle(controllerId, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
/* Save the configuration list */
classHandle->configList = configList;
/* Initialize the device stack. */
error = USB_DeviceInit(controllerId, USB_DeviceClassCallback, &classHandle->handle);
if (kStatus_USB_Success != error)
{
USB_DeviceDeinit(classHandle->handle);
USB_DeviceClassFreeHandle(controllerId);
return error;
}
/* Initialize the all supported classes according to the configuration list. */
for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
{
for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t));
mapIndex++)
{
if (classHandle->configList->config[classIndex].classInfomation->type ==
s_UsbDeviceClassInterfaceMap[mapIndex].type)
{
(void)s_UsbDeviceClassInterfaceMap[mapIndex].classInit(
controllerId, &classHandle->configList->config[classIndex],
&classHandle->configList->config[classIndex].classHandle);
}
}
}
*handle = classHandle->handle;
return error;
}
/*!
* @brief De-initialize the common class and the supported classes.
*
* This function is used to de-initialize the common class and the supported classes.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassDeinit(uint8_t controllerId /*!< [IN] Controller ID */
)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error = kStatus_USB_Error;
uint8_t mapIndex;
uint8_t classIndex;
/* Get the common class handle according to the controller id. */
error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
/* De-initialize the all supported classes according to the configuration list. */
for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
{
for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t));
mapIndex++)
{
if (classHandle->configList->config[classIndex].classInfomation->type ==
s_UsbDeviceClassInterfaceMap[mapIndex].type)
{
(void)s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit(
classHandle->configList->config[classIndex].classHandle);
}
}
}
/* De-initialize the USB device stack. */
error = USB_DeviceDeinit(classHandle->handle);
if (kStatus_USB_Success == error)
{
/* Free the common class handle. */
(void)USB_DeviceClassFreeHandle(controllerId);
}
return error;
}
/*!
* @brief Get the USB bus speed.
*
* This function is used to get the USB bus speed.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param speed It is an OUT parameter, return current speed of the controller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, /*!< [IN] Controller ID */
uint8_t *speed /*!< [OUT] Current speed */
)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error = kStatus_USB_Error;
/* Get the common class handle according to the controller id. */
error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
/* Get the current speed. */
error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSpeed, speed);
return error;
}
#endif /* USB_DEVICE_CONFIG_NUM */

View File

@ -0,0 +1,421 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_CLASS_H__
#define __USB_DEVICE_CLASS_H__
/*!
* @addtogroup usb_device_class_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Macro to define class handle */
typedef void *class_handle_t;
/*! @brief Available class types. */
typedef enum _usb_usb_device_class_type
{
kUSB_DeviceClassTypeHid = 1U,
kUSB_DeviceClassTypeCdc,
kUSB_DeviceClassTypeMsc,
kUSB_DeviceClassTypeAudio,
kUSB_DeviceClassTypePhdc,
kUSB_DeviceClassTypeVideo,
kUSB_DeviceClassTypePrinter,
kUSB_DeviceClassTypeDfu,
kUSB_DeviceClassTypeCcid,
} usb_device_class_type_t;
/*! @brief Available common class events. */
typedef enum _usb_device_class_event
{
kUSB_DeviceClassEventClassRequest = 1U,
kUSB_DeviceClassEventDeviceReset,
kUSB_DeviceClassEventSetConfiguration,
kUSB_DeviceClassEventSetInterface,
kUSB_DeviceClassEventSetEndpointHalt,
kUSB_DeviceClassEventClearEndpointHalt,
} usb_device_class_event_t;
/*!
* @brief Obtains the endpoint data structure.
*
* Define the endpoint data structure.
*
*/
typedef struct _usb_device_endpoint_struct
{
uint8_t endpointAddress; /*!< Endpoint address*/
uint8_t transferType; /*!< Endpoint transfer type*/
uint16_t maxPacketSize; /*!< Endpoint maximum packet size */
uint8_t interval; /*!< Endpoint interval*/
} usb_device_endpoint_struct_t;
/*!
* @brief Obtains the endpoint group.
*
* Structure representing endpoints and the number of endpoints that the user wants.
*
*/
typedef struct _usb_device_endpoint_list
{
uint8_t count; /*!< How many endpoints in current interface*/
usb_device_endpoint_struct_t *endpoint; /*!< Endpoint structure list*/
} usb_device_endpoint_list_t;
/*!
* @brief Obtains the interface list data structure.
*
* Structure representing an interface.
*
*/
typedef struct _usb_device_interface_struct
{
uint8_t alternateSetting; /*!< Alternate setting number*/
usb_device_endpoint_list_t endpointList; /*!< Endpoints of the interface*/
void *classSpecific; /*!< Class specific structure handle*/
} usb_device_interface_struct_t;
/*!
* @brief Obtains the interface data structure.
*
* Structure representing interface.
*
*/
typedef struct _usb_device_interfaces_struct
{
uint8_t classCode; /*!< Class code of the interface*/
uint8_t subclassCode; /*!< Subclass code of the interface*/
uint8_t protocolCode; /*!< Protocol code of the interface*/
uint8_t interfaceNumber; /*!< Interface number*/
usb_device_interface_struct_t *interface; /*!< Interface structure list*/
uint8_t count; /*!< Number of interfaces in the current interface*/
} usb_device_interfaces_struct_t;
/*!
* @brief Obtains the interface group.
*
* Structure representing how many interfaces in one class type.
*
*/
typedef struct _usb_device_interface_list
{
uint8_t count; /*!< Number of interfaces of the class*/
usb_device_interfaces_struct_t *interfaces; /*!< All interfaces*/
} usb_device_interface_list_t;
/*!
* @brief Obtains the class data structure.
*
* Structure representing how many configurations in one class type.
*
*/
typedef struct _usb_device_class_struct
{
usb_device_interface_list_t *interfaceList; /*!< Interfaces of the class*/
usb_device_class_type_t type; /*!< Class type*/
uint8_t configurations; /*!< Number of configurations of the class*/
} usb_device_class_struct_t;
/*callback function pointer structure for application to provide class parameters*/
typedef usb_status_t (*usb_device_class_callback_t)(class_handle_t classHandle,
uint32_t callbackEvent,
void *eventParam);
/*!
* @brief Obtains the device class information structure.
*
* Structure representing the device class information. This structure only can be stored in RAM space.
*
*/
typedef struct _usb_device_class_config_struct
{
usb_device_class_callback_t classCallback; /*!< Class callback function to handle the device status-related event
for the specified type of class*/
class_handle_t classHandle; /*!< The class handle of the class, filled by the common driver.*/
usb_device_class_struct_t *classInfomation; /*!< Detailed information of the class*/
} usb_device_class_config_struct_t;
/*!
* @brief Obtains the device class configuration structure.
*
* Structure representing the device class configuration information.
*
*/
typedef struct _usb_device_class_config_list_struct
{
usb_device_class_config_struct_t *config; /*!< Array of class configuration structures */
usb_device_callback_t deviceCallback; /*!< Device callback function */
uint8_t count; /*!< Number of class supported */
} usb_device_class_config_list_struct_t;
/*!
* @brief Obtains the control request structure.
*
* This structure is used to pass the control request information.
* The structure is used in following two cases.
* 1. Case one, the host wants to send data to the device in the control data stage: @n
* a. If a setup packet is received, the structure is used to pass the setup packet data and wants to get the
* buffer to receive data sent from the host.
* The field isSetup is 1.
* The length is the requested buffer length.
* The buffer is filled by the class or application by using the valid buffer address.
* The setup is the setup packet address.
* b. If the data received is sent by the host, the structure is used to pass the data buffer address and the
* data
* length sent by the host.
* In this way, the field isSetup is 0.
* The buffer is the address of the data sent from the host.
* The length is the received data length.
* The setup is the setup packet address. @n
* 2. Case two, the host wants to get data from the device in control data stage: @n
* If the setup packet is received, the structure is used to pass the setup packet data and wants to get the
* data buffer address to send data to the host.
* The field isSetup is 1.
* The length is the requested data length.
* The buffer is filled by the class or application by using the valid buffer address.
* The setup is the setup packet address.
*
*/
typedef struct _usb_device_control_request_struct
{
usb_setup_struct_t *setup; /*!< The pointer of the setup packet data. */
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length or requested length. */
uint8_t isSetup; /*!< Indicates whether a setup packet is received. */
} usb_device_control_request_struct_t;
/*! @brief Obtains the control get descriptor request common structure. */
typedef struct _usb_device_get_descriptor_common_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_descriptor_common_struct_t;
/*! @brief Obtains the control get device descriptor request structure. */
typedef struct _usb_device_get_device_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_device_descriptor_struct_t;
/*! @brief Obtains the control get device qualifier descriptor request structure. */
typedef struct _usb_device_get_device_qualifier_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_device_qualifier_descriptor_struct_t;
/*! @brief Obtains the control get configuration descriptor request structure. */
typedef struct _usb_device_get_configuration_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t configuration; /*!< The configuration number. */
} usb_device_get_configuration_descriptor_struct_t;
/*! @brief Obtains the control get bos descriptor request structure. */
typedef struct _usb_device_get_bos_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_bos_descriptor_struct_t;
/*! @brief Obtains the control get string descriptor request structure. */
typedef struct _usb_device_get_string_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint16_t languageId; /*!< Language ID. */
uint8_t stringIndex; /*!< String index. */
} usb_device_get_string_descriptor_struct_t;
/*! @brief Obtains the control get HID descriptor request structure. */
typedef struct _usb_device_get_hid_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t interfaceNumber; /*!< The interface number. */
} usb_device_get_hid_descriptor_struct_t;
/*! @brief Obtains the control get HID report descriptor request structure. */
typedef struct _usb_device_get_hid_report_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t interfaceNumber; /*!< The interface number. */
} usb_device_get_hid_report_descriptor_struct_t;
/*! @brief Obtains the control get HID physical descriptor request structure. */
typedef struct _usb_device_get_hid_physical_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t index; /*!< Physical index */
uint8_t interfaceNumber; /*!< The interface number. */
} usb_device_get_hid_physical_descriptor_struct_t;
/*! @brief Obtains the control get descriptor request common union. */
typedef union _usb_device_get_descriptor_common_union
{
usb_device_get_descriptor_common_struct_t commonDescriptor; /*!< Common structure. */
usb_device_get_device_descriptor_struct_t deviceDescriptor; /*!< The structure to get device descriptor. */
usb_device_get_device_qualifier_descriptor_struct_t
deviceQualifierDescriptor; /*!< The structure to get device qualifier descriptor. */
usb_device_get_configuration_descriptor_struct_t
configurationDescriptor; /*!< The structure to get configuration descriptor. */
usb_device_get_string_descriptor_struct_t stringDescriptor; /*!< The structure to get string descriptor. */
usb_device_get_hid_descriptor_struct_t hidDescriptor; /*!< The structure to get HID descriptor. */
usb_device_get_hid_report_descriptor_struct_t
hidReportDescriptor; /*!< The structure to get HID report descriptor. */
usb_device_get_hid_physical_descriptor_struct_t
hidPhysicalDescriptor; /*!< The structure to get HID physical descriptor. */
} usb_device_get_descriptor_common_union_t;
/*! @brief Define function type for class device instance initialization */
typedef usb_status_t (*usb_device_class_init_call_t)(uint8_t controllerId,
usb_device_class_config_struct_t *classConfig,
class_handle_t *classHandle);
/*! @brief Define function type for class device instance deinitialization, internal */
typedef usb_status_t (*usb_device_class_deinit_call_t)(class_handle_t handle);
/*! @brief Define function type for class device instance Event change */
typedef usb_status_t (*usb_device_class_event_callback_t)(void *classHandle, uint32_t event, void *param);
/*! @brief Define class driver interface structure. */
typedef struct _usb_device_class_map
{
usb_device_class_init_call_t classInit; /*!< Class driver initialization- entry of the class driver */
usb_device_class_deinit_call_t classDeinit; /*!< Class driver de-initialization*/
usb_device_class_event_callback_t classEventCallback; /*!< Class driver event callback*/
usb_device_class_type_t type; /*!< Class type*/
} usb_device_class_map_t;
/*! @brief Structure holding common class state information */
typedef struct _usb_device_common_class_struct
{
usb_device_handle handle; /*!< USB device handle*/
usb_device_class_config_list_struct_t *configList; /*!< USB device configure list*/
uint8_t *setupBuffer; /*!< Setup packet data buffer*/
uint16_t standardTranscationBuffer; /*!<
* This variable is used in:
* get status request
* get configuration request
* get interface request
* set interface request
* get sync frame request
*/
uint8_t controllerId; /*!< Controller ID*/
} usb_device_common_class_struct_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initializes the common class and the supported classes.
*
* This function is used to initialize the common class and the supported classes.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[in] configList The class configurations. The pointer must point to the global variable.
* See the structure #usb_device_class_config_list_struct_t.
* @param[out] handle A parameter used to return pointer of the device handle to the caller.
* The value of the parameter is a pointer to the device handle. This design is used to
* make a simple device align with the composite device. For the composite device, there are
* many
* kinds of class handles. However, there is only one device handle. Therefore, the handle
* points to
* a device instead of a class. The class handle can be received from the
* #usb_device_class_config_struct_t::classHandle after the function successfully.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassInit(uint8_t controllerId,
usb_device_class_config_list_struct_t *configList,
usb_device_handle *handle);
/*!
* @brief Deinitializes the common class and the supported classes.
*
* This function is used to deinitialize the common class and the supported classes.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassDeinit(uint8_t controllerId);
/*!
* @brief Gets the USB bus speed.
*
* This function is used to get the USB bus speed.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[out] speed It is an OUT parameter, which returns the current speed of the controller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, uint8_t *speed);
/*!
* @brief Handles the event passed to the class drivers.
*
* This function handles the event passed to the class drivers.
*
* @param[in] handle The device handle received from the #USB_DeviceInit.
* @param[in] event The event codes. See the enumeration #usb_device_class_event_t.
* @param[in,out] param The parameter type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success A valid request has been handled.
* @retval kStatus_USB_InvalidParameter The device handle not be found.
* @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe is stalled by the caller.
*/
usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param);
/*!
* @brief Handles the common class callback.
*
* This function handles the common class callback.
*
* @param[in] handle The device handle received from the #USB_DeviceInit.
* @param[in] event The event codes. See the enumeration #usb_device_event_t.
* @param[in,out] param The parameter type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param);
/*!
* @brief Gets the device handle according to the controller ID.
*
* This function gets the device handle according to the controller ID.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[out] handle An out parameter used to return the pointer of the device handle to the caller.
*
* @retval kStatus_USB_Success Get device handle successfully.
* @retval kStatus_USB_InvalidParameter The device handle can't be found.
*/
usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle);
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __USB_DEVICE_CLASS_H__ */

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_DEVICE_CONFIG_H_
#define _USB_DEVICE_CONFIG_H_
#include "usb.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @addtogroup usb_device_configuration
* @{
*/
/*!
* @name Hardware instance define
* @{
*/
#define CONTROLLER_ID kUSB_ControllerEhci0
#define USB_INSTANCE 1
/*! @brief KHCI instance count */
#define USB_DEVICE_CONFIG_KHCI (0U)
/*! @brief EHCI instance count */
#define USB_DEVICE_CONFIG_EHCI (1U)
/*! @brief LPC USB IP3511 FS instance count */
#define USB_DEVICE_CONFIG_LPCIP3511FS (0U)
/*! @brief LPC USB IP3511 HS instance count */
#define USB_DEVICE_CONFIG_LPCIP3511HS (0U)
/*! @brief Device instance count, the sum of KHCI and EHCI instance counts*/
#define USB_DEVICE_CONFIG_NUM \
(USB_DEVICE_CONFIG_KHCI + USB_DEVICE_CONFIG_EHCI + USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS)
/* @} */
/*!
* @name class instance define
* @{
*/
/*! @brief HID instance count */
#define USB_DEVICE_CONFIG_HID (0U)
/*! @brief CDC ACM instance count */
#define USB_DEVICE_CONFIG_CDC_ACM (0U)
/*! @brief MSC instance count */
#define USB_DEVICE_CONFIG_MSC (0U)
/*! @brief Audio instance count */
#define USB_DEVICE_CONFIG_AUDIO (0U)
/*! @brief PHDC instance count */
#define USB_DEVICE_CONFIG_PHDC (0U)
/*! @brief Video instance count */
#define USB_DEVICE_CONFIG_VIDEO (0U)
/*! @brief CCID instance count */
#define USB_DEVICE_CONFIG_CCID (0U)
/*! @brief Printer instance count */
#define USB_DEVICE_CONFIG_PRINTER (0U)
/*! @brief DFU instance count */
#define USB_DEVICE_CONFIG_DFU (0U)
/* @} */
/*! @brief Whether device is self power. 1U supported, 0U not supported */
#define USB_DEVICE_CONFIG_SELF_POWER (1U)
/*! @brief How many endpoints are supported in the stack. */
#define USB_DEVICE_CONFIG_ENDPOINTS (4U)
/*! @brief Whether the device task is enabled. */
#define USB_DEVICE_CONFIG_USE_TASK (0U)
/*! @brief How many the notification message are supported when the device task is enabled. */
#define USB_DEVICE_CONFIG_MAX_MESSAGES (8U)
/*! @brief Whether test mode enabled. */
#define USB_DEVICE_CONFIG_USB20_TEST_MODE (0U)
/*! @brief Whether device CV test is enabled. */
#define USB_DEVICE_CONFIG_CV_TEST (0U)
/*! @brief Whether device compliance test is enabled. If the macro is enabled,
the test mode and CV test macroes will be set.*/
#define USB_DEVICE_CONFIG_COMPLIANCE_TEST (0U)
#if ((defined(USB_DEVICE_CONFIG_COMPLIANCE_TEST)) && (USB_DEVICE_CONFIG_COMPLIANCE_TEST > 0U))
/*! @brief Undefine the macro USB_DEVICE_CONFIG_USB20_TEST_MODE. */
#undef USB_DEVICE_CONFIG_USB20_TEST_MODE
/*! @brief Undefine the macro USB_DEVICE_CONFIG_CV_TEST. */
#undef USB_DEVICE_CONFIG_CV_TEST
/*! @brief enable the test mode. */
#define USB_DEVICE_CONFIG_USB20_TEST_MODE (1U)
/*! @brief enable the CV test */
#define USB_DEVICE_CONFIG_CV_TEST (1U)
#endif
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
/*! @brief The MAX buffer length for the KHCI DMA workaround.*/
#define USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH (64U)
#endif
#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
/*! @brief How many the DTD are supported. */
#define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U)
/*! @brief Whether test mode enabled. */
#define USB_DEVICE_CONFIG_EHCI_TEST_MODE (0U)
/*! @brief Whether the EHCI ID pin detect feature enabled. */
#define USB_DEVICE_CONFIG_EHCI_ID_PIN_DETECT (0U)
#endif
/*! @brief Whether the keep alive feature enabled. */
#define USB_DEVICE_CONFIG_KEEP_ALIVE_MODE (0U)
/*! @brief Whether the transfer buffer is cache-enabled or not. */
#ifndef USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE
#define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U)
#endif
/*! @brief Whether the low power mode is enabled or not. */
#define USB_DEVICE_CONFIG_LOW_POWER_MODE (0U)
#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
/*! @brief Whether device remote wakeup supported. 1U supported, 0U not supported */
#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U)
/*! @brief Whether LPM is supported. 1U supported, 0U not supported */
#define USB_DEVICE_CONFIG_LPM_L1 (0U)
#else
/*! @brief The device remote wakeup is unsupported. */
#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U)
#endif
/*! @brief Whether the device detached feature is enabled or not. */
#define USB_DEVICE_CONFIG_DETACH_ENABLE (0U)
/*! @brief Whether handle the USB bus error. */
#define USB_DEVICE_CONFIG_ERROR_HANDLING (0U)
/* @} */
#endif /* _USB_DEVICE_CONFIG_H_ */

View File

@ -0,0 +1,62 @@
/* mbed Microcontroller Library
* Copyright (c) 2018-2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define NUMBER_OF_LOGICAL_ENDPOINTS (4)
#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2)
/* Define physical endpoint numbers */
/* Endpoint No. */
/* ---------------- */
#define EP0OUT (0x00)
#define EP0IN (0x80)
#define EP1OUT (0x01)
#define EP1IN (0x81)
#define EP2OUT (0x02)
#define EP2IN (0x82)
#define EP3OUT (0x03)
#define EP3IN (0x83)
/* Maximum Packet sizes */
#define MAX_PACKET_SIZE_EP0 (64)
#define MAX_PACKET_SIZE_EP1 (64)
#define MAX_PACKET_SIZE_EP2 (64)
#define MAX_PACKET_SIZE_EP3 (1023)
/* Generic endpoints - intended to be portable accross devices */
/* and be suitable for simple USB devices. */
/* Bulk endpoints */
#define EPBULK_OUT (EP2OUT)
#define EPBULK_IN (EP2IN)
#define EPBULK_OUT_callback EP2_OUT_callback
#define EPBULK_IN_callback EP2_IN_callback
/* Interrupt endpoints */
#define EPINT_OUT (EP1OUT)
#define EPINT_IN (EP1IN)
#define EPINT_OUT_callback EP1_OUT_callback
#define EPINT_IN_callback EP1_IN_callback
/* Isochronous endpoints */
#define EPISO_OUT (EP3OUT)
#define EPISO_IN (EP3IN)
#define EPISO_OUT_callback EP3_OUT_callback
#define EPISO_IN_callback EP3_IN_callback
#define MAX_PACKET_SIZE_EPBULK (MAX_PACKET_SIZE_EP2)
#define MAX_PACKET_SIZE_EPINT (MAX_PACKET_SIZE_EP1)
#define MAX_PACKET_SIZE_EPISO (MAX_PACKET_SIZE_EP3)

View File

@ -0,0 +1,80 @@
/* mbed Microcontroller Library
* Copyright (c) 2018-2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBPHYHW_H
#define USBPHYHW_H
#include "mbed.h"
#include "USBPhy.h"
#include "usb_device_config.h"
#include "usb_device.h"
#include "usb_device_ch9.h"
class USBPhyHw : public USBPhy {
public:
USBPhyHw();
virtual ~USBPhyHw();
virtual void init(USBPhyEvents *events);
virtual void deinit();
virtual bool powered();
virtual void connect();
virtual void disconnect();
virtual void configure();
virtual void unconfigure();
virtual void sof_enable();
virtual void sof_disable();
virtual void set_address(uint8_t address);
virtual void remote_wakeup();
virtual const usb_ep_table_t *endpoint_table();
virtual uint32_t ep0_set_max_packet(uint32_t max_packet);
virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size);
virtual void ep0_read(uint8_t *data, uint32_t size);
virtual uint32_t ep0_read_result();
virtual void ep0_write(uint8_t *buffer, uint32_t size);
virtual void ep0_stall();
virtual bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type);
virtual void endpoint_remove(usb_ep_t endpoint);
virtual void endpoint_stall(usb_ep_t endpoint);
virtual void endpoint_unstall(usb_ep_t endpoint);
virtual bool endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size);
virtual uint32_t endpoint_read_result(usb_ep_t endpoint);
virtual bool endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size);
virtual void endpoint_abort(usb_ep_t endpoint);
virtual void process();
private:
USBPhyEvents *events;
uint8_t *read_buffers[16];
uint16_t read_sizes[16];
bool endpoint_read_core(usb_ep_t endpoint, uint32_t max_packet);
bool endpoint_read_result_core(usb_ep_t endpoint, uint8_t *data, uint32_t size, uint32_t *bytesRead);
static void _usbisr(void);
friend usb_status_t USBPhy_DeviceCallback(usb_device_handle handle, uint32_t event, void *param);
friend usb_status_t USBPhy_EndpointCallback(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam);
};
#endif

View File

@ -0,0 +1,514 @@
/* mbed Microcontroller Library
* Copyright (c) 2018-2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(DEVICE_USBDEVICE) && DEVICE_USBDEVICE
#include "USBPhyHw_MCUXpresso.h"
#include "USBEndpoints_MCUXpresso.h"
#include "fsl_clock_config.h"
static USBPhyHw *instance;
static volatile int epComplete = 0;
static uint32_t usb_irq = 0;
usb_device_handle g_deviceHandle;
static USB_Type * const usb_addrs[] = USB_BASE_PTRS;
// Convert physical endpoint number to register bit
#define EP(endpoint) (1<<(endpoint))
// Conversion macros
#define PHY_TO_LOG(endpoint) ((endpoint)>>1)
#define DESC_TO_LOG(endpoint) ((endpoint) & 0xF)
#define DESC_TO_PHY(endpoint) ((((endpoint)&0x0F)<<1) | (((endpoint) & 0x80) ? 1:0))
#define PHY_TO_DESC(endpoint) (((endpoint)>>1)|(((endpoint)&1)?0x80:0))
// Get endpoint direction
#define DESC_EP_IN(endpoint) ((endpoint) & 0x80U ? true : false)
#define DESC_EP_OUT(endpoint) ((endpoint) & 0x80U ? false : true)
#define TX 1
#define RX 0
#define ODD 0
#define EVEN 1
// this macro waits a physical endpoint number
#define EP_BDT_IDX(ep, dir, odd) (((ep * 4) + (2 * dir) + (1 * odd)))
uint8_t *endpoint_buffer[NUMBER_OF_PHYSICAL_ENDPOINTS * 2];
uint16_t endpoint_packet_size[NUMBER_OF_PHYSICAL_ENDPOINTS];
USB_CONTROLLER_DATA uint32_t ep0_buffer[2][MAX_PACKET_SIZE_EP0 / 4];
USB_CONTROLLER_DATA uint32_t ep1_buffer[2][MAX_PACKET_SIZE_EP1 / 4];
USB_CONTROLLER_DATA uint32_t ep2_buffer[2][MAX_PACKET_SIZE_EP2 / 4];
USB_CONTROLLER_DATA uint32_t ep3_buffer[2][MAX_PACKET_SIZE_EP3 / 4];
static uint8_t set_addr = 0;
extern "C" uint32_t USB_DeviceGetIrqNumber(void);
extern "C" void USB_DeviceClockInit(void);
static uint32_t frameNumber()
{
return (usb_addrs[USB_INSTANCE]->FRINDEX >> 3);
}
USBPhy *get_usb_phy()
{
static USBPhyHw usbphy;
return &usbphy;
}
USBPhyHw::USBPhyHw(): events(NULL)
{
}
USBPhyHw::~USBPhyHw()
{
}
usb_status_t USBPhy_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{
switch (event) {
// reset interrupt
case kUSB_DeviceEventBusReset:
instance->endpoint_add(EP0OUT, MAX_PACKET_SIZE_EP0, USB_EP_TYPE_CTRL);
instance->endpoint_add(EP0IN, MAX_PACKET_SIZE_EP0, USB_EP_TYPE_CTRL);
memset(instance->read_buffers, 0, sizeof(instance->read_buffers));
memset(instance->read_sizes, 0, sizeof(instance->read_sizes));
// reset bus for USBDevice layer
instance->events->reset();
break;
case kUSB_DeviceEventResume:
instance->events->suspend(false);
break;
case kUSB_DeviceEventSuspend:
instance->events->suspend(true);
break;
default:
break;
}
return kStatus_USB_Success;
}
usb_status_t USBPhy_EndpointCallback(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam)
{
usb_ep_t endpoint = (usb_ep_t )((long)callbackParam);
int phy_ep = DESC_TO_PHY(endpoint);
uint8_t state;
if (message->length == USB_UNINITIALIZED_VAL_32) {
return kStatus_USB_Success;
}
/* Update the read size to what was actually read */
instance->read_sizes[phy_ep] = message->length;
// setup packet
if (message->isSetup) {
memcpy(&ep0_buffer[0][0], message->buffer, 8U);
// EP0 SETUP event (SETUP data received)
instance->events->ep0_setup();
} else {
if (DESC_EP_IN(endpoint)) {
if ((endpoint & USB_ENDPOINT_NUMBER_MASK) == 0) {
instance->events->ep0_in();
if (set_addr == 1) {
state = (uint8_t)kUSB_DeviceStateAddress;
USB_DeviceSetStatus(g_deviceHandle, kUSB_DeviceStatusAddress, &state);
set_addr = 0;
}
} else {
epComplete |= EP(phy_ep);
instance->events->in(endpoint);
}
} else {
if ((endpoint & USB_ENDPOINT_NUMBER_MASK) == 0) {
instance->events->ep0_out();
} else {
epComplete |= EP(phy_ep);
instance->events->out(endpoint);
}
}
}
return kStatus_USB_Success;
}
void USBPhyHw::init(USBPhyEvents *events)
{
if (this->events == NULL) {
sleep_manager_lock_deep_sleep();
}
this->events = events;
usb_irq = USB_DeviceGetIrqNumber();
// Disable IRQ
NVIC_DisableIRQ((IRQn_Type)usb_irq);
// Attach IRQ
instance = this;
USB_DeviceClockInit();
if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USBPhy_DeviceCallback, &g_deviceHandle)) {
return;
}
/* Allocate control endpoint buffers */
endpoint_buffer[EP_BDT_IDX(0, TX, ODD)] = (uint8_t*)ep0_buffer[TX];
endpoint_buffer[EP_BDT_IDX(0, RX, ODD)] = (uint8_t*)ep0_buffer[RX];
endpoint_buffer[EP_BDT_IDX(1, TX, ODD)] = (uint8_t*)ep1_buffer[TX];
endpoint_buffer[EP_BDT_IDX(1, RX, ODD)] = (uint8_t*)ep1_buffer[RX];
endpoint_buffer[EP_BDT_IDX(2, TX, ODD)] = (uint8_t*)ep2_buffer[TX];
endpoint_buffer[EP_BDT_IDX(2, RX, ODD)] = (uint8_t*)ep2_buffer[RX];
endpoint_buffer[EP_BDT_IDX(3, TX, ODD)] = (uint8_t*)ep3_buffer[TX];
endpoint_buffer[EP_BDT_IDX(3, RX, ODD)] = (uint8_t*)ep3_buffer[RX];
endpoint_packet_size[0] = sizeof (ep0_buffer[TX]);
endpoint_packet_size[1] = sizeof (ep0_buffer[RX]);
endpoint_packet_size[2] = sizeof (ep1_buffer[TX]);
endpoint_packet_size[3] = sizeof (ep1_buffer[RX]);
endpoint_packet_size[4] = sizeof (ep2_buffer[TX]);
endpoint_packet_size[5] = sizeof (ep2_buffer[RX]);
endpoint_packet_size[6] = sizeof (ep3_buffer[TX]);
endpoint_packet_size[7] = sizeof (ep3_buffer[RX]);
NVIC_SetVector((IRQn_Type)usb_irq, (uint32_t)&_usbisr);
NVIC_EnableIRQ((IRQn_Type)usb_irq);
}
void USBPhyHw::deinit()
{
USB_DeviceDeinit(g_deviceHandle);
disconnect();
NVIC_DisableIRQ((IRQn_Type)usb_irq);
if (events != NULL) {
sleep_manager_unlock_deep_sleep();
}
events = NULL;
}
bool USBPhyHw::powered()
{
return true;
}
void USBPhyHw::connect()
{
USB_DeviceRun(g_deviceHandle);
}
void USBPhyHw::disconnect()
{
// disable all endpoints to prevent them from nacking when disconnected
for (uint8_t i = 0; i < (USB_DEVICE_CONFIG_ENDPOINTS); i++) {
USB_DeviceDeinitEndpoint(g_deviceHandle,
(i & USB_ENDPOINT_NUMBER_MASK) |
(USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
USB_DeviceDeinitEndpoint(g_deviceHandle,
(i & USB_ENDPOINT_NUMBER_MASK) |
(USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
}
USB_DeviceStop(g_deviceHandle);
}
void USBPhyHw::configure()
{
}
void USBPhyHw::unconfigure()
{
}
void USBPhyHw::sof_enable()
{
usb_addrs[USB_INSTANCE]->USBINTR |= USBHS_USBINTR_SRE_MASK;
}
void USBPhyHw::sof_disable()
{
usb_addrs[USB_INSTANCE]->USBINTR &= ~USBHS_USBINTR_SRE_MASK;
}
void USBPhyHw::set_address(uint8_t address)
{
uint8_t state;
// we don't set the address now, we set a flag instead.
// see usbisr when an IN token is received
set_addr = 1;
state = address & 0xFFU;
USB_DeviceSetStatus(g_deviceHandle, kUSB_DeviceStatusAddress, &state);
}
void USBPhyHw::remote_wakeup()
{
}
#define ALLOW_BULK_OR_INT_ENDPOINTS (USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_ALLOW_INT)
#define ALLOW_NO_ENDPOINTS 0
const usb_ep_table_t *USBPhyHw::endpoint_table()
{
static const usb_ep_table_t endpoint_table = {
1, // No cost per endpoint - everything allocated up front
{
{USB_EP_ATTR_ALLOW_CTRL | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_BULK_OR_INT_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_BULK_OR_INT_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{USB_EP_ATTR_ALLOW_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
{ALLOW_NO_ENDPOINTS | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}
}
};
return &endpoint_table;
}
uint32_t USBPhyHw::ep0_set_max_packet(uint32_t max_packet)
{
return USB_CONTROL_MAX_PACKET_SIZE;
}
// read setup packet
void USBPhyHw::ep0_setup_read_result(uint8_t *buffer, uint32_t size)
{
memcpy(buffer, &ep0_buffer[0][0], 8U);
}
void USBPhyHw::ep0_read(uint8_t *data, uint32_t size)
{
endpoint_read(EP0OUT, data, size);
}
uint32_t USBPhyHw::ep0_read_result()
{
return endpoint_read_result(EP0OUT);
}
void USBPhyHw::ep0_write(uint8_t *buffer, uint32_t size)
{
endpoint_write(EP0IN, buffer, size);
}
void USBPhyHw::ep0_stall()
{
endpoint_stall(EP0IN);
endpoint_stall(EP0OUT);
}
bool USBPhyHw::endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type)
{
usb_device_endpoint_init_struct_t epInit;
usb_device_endpoint_callback_struct_t epCallback;
memset(&epInit, 0, sizeof(epInit));
memset(&epCallback, 0, sizeof(epCallback));
if (DESC_TO_PHY(endpoint) > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
return false;
}
epInit.transferType = (uint8_t)type;
epInit.maxPacketSize = (uint16_t)max_packet;
epInit.endpointAddress = endpoint;
if (type == USB_EP_TYPE_CTRL) {
epInit.zlt = 1;
}
epCallback.callbackFn = USBPhy_EndpointCallback;
epCallback.callbackParam = (void *)((long)endpoint);
if (USB_DeviceInitEndpoint(g_deviceHandle, &epInit, &epCallback) != kStatus_USB_Success) {
return false;
}
return true;
}
void USBPhyHw::endpoint_remove(usb_ep_t endpoint)
{
USB_DeviceDeinitEndpoint(g_deviceHandle, endpoint);
}
void USBPhyHw::endpoint_stall(usb_ep_t endpoint)
{
USB_DeviceStallEndpoint(g_deviceHandle, endpoint);
}
void USBPhyHw::endpoint_unstall(usb_ep_t endpoint)
{
USB_DeviceUnstallEndpoint(g_deviceHandle, endpoint);
}
bool USBPhyHw::endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size)
{
uint8_t log = DESC_TO_PHY(endpoint);
read_buffers[log] = data;
read_sizes[log] = size;
return endpoint_read_core(endpoint, size);
}
bool USBPhyHw::endpoint_read_core(usb_ep_t endpoint, uint32_t max_packet)
{
uint8_t log_endpoint = DESC_TO_LOG(endpoint);
uint8_t *buf;
buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0];
if (USB_DeviceRecvRequest(g_deviceHandle, endpoint, buf, (max_packet > endpoint_packet_size[log_endpoint] ? endpoint_packet_size[log_endpoint] : max_packet)) != kStatus_USB_Success) {
return false;
}
return true;
}
uint32_t USBPhyHw::endpoint_read_result(usb_ep_t endpoint)
{
uint8_t log = DESC_TO_PHY(endpoint);
uint32_t bytes_read = 0;
endpoint_read_result_core(endpoint, read_buffers[log], read_sizes[log], &bytes_read);
read_buffers[log] = NULL;
read_sizes[log] = 0;
return bytes_read;
}
bool USBPhyHw::endpoint_read_result_core(usb_ep_t endpoint, uint8_t *data, uint32_t size, uint32_t *bytes_read)
{
uint32_t n, idx;
uint8_t *ep_buf;
uint32_t log_endpoint = DESC_TO_LOG(endpoint);
if (DESC_TO_PHY(endpoint) > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
return false;
}
// if read on a IN endpoint -> error
if (DESC_EP_IN(endpoint)) {
return false;
}
idx = EP_BDT_IDX(log_endpoint, RX, 0);
if ((log_endpoint != 0) && !(epComplete & EP(DESC_TO_PHY(endpoint)))) {
return false;
}
ep_buf = endpoint_buffer[idx];
for (n = 0; n < read_sizes[DESC_TO_PHY(endpoint)]; n++) {
data[n] = ep_buf[n];
}
*bytes_read = read_sizes[DESC_TO_PHY(endpoint)];
epComplete &= ~EP(DESC_TO_PHY(endpoint));
return true;
}
bool USBPhyHw::endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size)
{
uint32_t idx, n;
uint8_t *ep_buf;
if (DESC_TO_PHY(endpoint) > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
return false;
}
// if write on a OUT endpoint -> error
if (DESC_EP_OUT(endpoint)) {
return false;
}
idx = EP_BDT_IDX(DESC_TO_LOG(endpoint), TX, 0);
ep_buf = endpoint_buffer[idx];
if (size > endpoint_packet_size[DESC_TO_LOG(endpoint)]) {
size = endpoint_packet_size[DESC_TO_LOG(endpoint)];
}
for (n = 0; n < size; n++) {
ep_buf[n] = data[n];
}
if (USB_DeviceSendRequest(g_deviceHandle, endpoint, ep_buf, size) != kStatus_USB_Success) {
return false;
}
return true;
}
void USBPhyHw::endpoint_abort(usb_ep_t endpoint)
{
USB_DeviceCancel(g_deviceHandle, endpoint);
}
void USBPhyHw::process()
{
uint32_t istat = usb_addrs[USB_INSTANCE]->USBSTS & usb_addrs[USB_INSTANCE]->USBINTR;
// SOF interrupt
if (istat & USBHS_USBSTS_SRI_MASK) {
// SOF event, read frame number
events->sof(frameNumber());
}
USB_DeviceEhciIsrFunction(g_deviceHandle);
NVIC_ClearPendingIRQ((IRQn_Type)usb_irq);
NVIC_EnableIRQ((IRQn_Type)usb_irq);
}
void USBPhyHw::_usbisr(void)
{
NVIC_DisableIRQ((IRQn_Type)usb_irq);
instance->events->start_process();
}
#endif

View File

@ -0,0 +1,615 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_H__
#define __USB_DEVICE_H__
/*!
* @addtogroup usb_device_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines Get/Set status Types */
typedef enum _usb_device_status
{
kUSB_DeviceStatusTestMode = 1U, /*!< Test mode */
kUSB_DeviceStatusSpeed, /*!< Current speed */
kUSB_DeviceStatusOtg, /*!< OTG status */
kUSB_DeviceStatusDevice, /*!< Device status */
kUSB_DeviceStatusEndpoint, /*!< Endpoint state usb_device_endpoint_status_t */
kUSB_DeviceStatusDeviceState, /*!< Device state */
kUSB_DeviceStatusAddress, /*!< Device address */
kUSB_DeviceStatusSynchFrame, /*!< Current frame */
kUSB_DeviceStatusBus, /*!< Bus status */
kUSB_DeviceStatusBusSuspend, /*!< Bus suspend */
kUSB_DeviceStatusBusSleep, /*!< Bus suspend */
kUSB_DeviceStatusBusResume, /*!< Bus resume */
kUSB_DeviceStatusRemoteWakeup, /*!< Remote wakeup state */
kUSB_DeviceStatusBusSleepResume, /*!< Bus resume */
} usb_device_status_t;
/*! @brief Defines USB 2.0 device state */
typedef enum _usb_device_state
{
kUSB_DeviceStateConfigured = 0U, /*!< Device state, Configured*/
kUSB_DeviceStateAddress, /*!< Device state, Address*/
kUSB_DeviceStateDefault, /*!< Device state, Default*/
kUSB_DeviceStateAddressing, /*!< Device state, Address setting*/
kUSB_DeviceStateTestMode, /*!< Device state, Test mode*/
} usb_device_state_t;
/*! @brief Defines endpoint state */
typedef enum _usb_endpoint_status
{
kUSB_DeviceEndpointStateIdle = 0U, /*!< Endpoint state, idle*/
kUSB_DeviceEndpointStateStalled, /*!< Endpoint state, stalled*/
} usb_device_endpoint_status_t;
/*! @brief Control endpoint index */
#define USB_CONTROL_ENDPOINT (0U)
/*! @brief Control endpoint maxPacketSize */
#define USB_CONTROL_MAX_PACKET_SIZE (64U)
#if (USB_DEVICE_CONFIG_EHCI && (USB_CONTROL_MAX_PACKET_SIZE != (64U)))
#error For high speed, USB_CONTROL_MAX_PACKET_SIZE must be 64!!!
#endif
/*! @brief The setup packet size of USB control transfer. */
#define USB_SETUP_PACKET_SIZE (8U)
/*! @brief USB endpoint mask */
#define USB_ENDPOINT_NUMBER_MASK (0x0FU)
/*! @brief Default invalid value or the endpoint callback length of cancelled transfer */
#define USB_UNINITIALIZED_VAL_32 (0xFFFFFFFFU)
/*! @brief Available common EVENT types in device callback */
typedef enum _usb_device_event
{
kUSB_DeviceEventBusReset = 1U, /*!< USB bus reset signal detected */
kUSB_DeviceEventSuspend, /*!< USB bus suspend signal detected */
kUSB_DeviceEventResume, /*!< USB bus resume signal detected. The resume signal is driven by itself or a host */
kUSB_DeviceEventSleeped, /*!< USB bus LPM suspend signal detected */
kUSB_DeviceEventLPMResume, /*!< USB bus LPM resume signal detected. The resume signal is driven by itself or a host
*/
kUSB_DeviceEventError, /*!< An error is happened in the bus. */
kUSB_DeviceEventDetach, /*!< USB device is disconnected from a host. */
kUSB_DeviceEventAttach, /*!< USB device is connected to a host. */
kUSB_DeviceEventSetConfiguration, /*!< Set configuration. */
kUSB_DeviceEventSetInterface, /*!< Set interface. */
kUSB_DeviceEventGetDeviceDescriptor, /*!< Get device descriptor. */
kUSB_DeviceEventGetConfigurationDescriptor, /*!< Get configuration descriptor. */
kUSB_DeviceEventGetStringDescriptor, /*!< Get string descriptor. */
kUSB_DeviceEventGetHidDescriptor, /*!< Get HID descriptor. */
kUSB_DeviceEventGetHidReportDescriptor, /*!< Get HID report descriptor. */
kUSB_DeviceEventGetHidPhysicalDescriptor, /*!< Get HID physical descriptor. */
kUSB_DeviceEventGetBOSDescriptor, /*!< Get configuration descriptor. */
kUSB_DeviceEventGetDeviceQualifierDescriptor, /*!< Get device qualifier descriptor. */
kUSB_DeviceEventVendorRequest, /*!< Vendor request. */
kUSB_DeviceEventSetRemoteWakeup, /*!< Enable or disable remote wakeup function. */
kUSB_DeviceEventGetConfiguration, /*!< Get current configuration index */
kUSB_DeviceEventGetInterface, /*!< Get current interface alternate setting value */
kUSB_DeviceEventSetBHNPEnable,
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
kUSB_DeviceEventDcdDetectionfinished, /*!< The DCD detection finished */
#endif
} usb_device_event_t;
/*! @brief Endpoint callback message structure */
typedef struct _usb_device_endpoint_callback_message_struct
{
uint8_t *buffer; /*!< Transferred buffer */
uint32_t length; /*!< Transferred data length */
uint8_t isSetup; /*!< Is in a setup phase */
} usb_device_endpoint_callback_message_struct_t;
/*!
* @brief Endpoint callback function typedef.
*
* This callback function is used to notify the upper layer what the transfer result is.
* This callback pointer is passed when a specified endpoint is initialized by calling API #USB_DeviceInitEndpoint.
*
* @param handle The device handle. It equals to the value returned from #USB_DeviceInit.
* @param message The result of a transfer, which includes transfer buffer, transfer length, and whether is in a
* setup phase.
* phase for control pipe.
* @param callbackParam The parameter for this callback. It is same with
* usb_device_endpoint_callback_struct_t::callbackParam.
*
* @return A USB error code or kStatus_USB_Success.
*/
typedef usb_status_t (*usb_device_endpoint_callback_t)(usb_device_handle handle,
usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam);
/*!
* @brief Device callback function typedef.
*
* This callback function is used to notify the upper layer that the device status has changed.
* This callback pointer is passed by calling API #USB_DeviceInit.
*
* @param handle The device handle. It equals the value returned from #USB_DeviceInit.
* @param callbackEvent The callback event type. See enumeration #usb_device_event_t.
* @param eventParam The event parameter for this callback. The parameter type is determined by the callback event.
*
* @return A USB error code or kStatus_USB_Success.
*/
typedef usb_status_t (*usb_device_callback_t)(usb_device_handle handle, uint32_t callbackEvent, void *eventParam);
/*! @brief Endpoint callback structure */
typedef struct _usb_device_endpoint_callback_struct
{
usb_device_endpoint_callback_t callbackFn; /*!< Endpoint callback function*/
void *callbackParam; /*!< Parameter for callback function*/
uint8_t isBusy;
} usb_device_endpoint_callback_struct_t;
/*! @brief Endpoint initialization structure */
typedef struct _usb_device_endpoint_init_struct
{
uint16_t maxPacketSize; /*!< Endpoint maximum packet size */
uint8_t endpointAddress; /*!< Endpoint address*/
uint8_t transferType; /*!< Endpoint transfer type*/
uint8_t zlt; /*!< ZLT flag*/
uint8_t interval; /*!< Endpoint interval*/
} usb_device_endpoint_init_struct_t;
/*! @brief Endpoint status structure */
typedef struct _usb_device_endpoint_status_struct
{
uint8_t endpointAddress; /*!< Endpoint address */
uint16_t endpointStatus; /*!< Endpoint status : idle or stalled */
} usb_device_endpoint_status_struct_t;
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @name USB device APIs
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Initializes the USB device stack.
*
* This function initializes the USB device module specified by the controllerId.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[in] deviceCallback Function pointer of the device callback.
* @param[out] handle It is an out parameter used to return the pointer of the device handle to the caller.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer.
* @retval kStatus_USB_Busy Cannot allocate a device handle.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id.
* @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invalid. There is an empty
* interface entity.
* @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than the IP's endpoint number.
* Or, the device has been initialized.
* Or, the mutex or message queue is created failed.
*/
extern usb_status_t USB_DeviceInit(uint8_t controllerId,
usb_device_callback_t deviceCallback,
usb_device_handle *handle);
/*!
* @brief Enables the device functionality.
*
* The function enables the device functionality, so that the device can be recognized by the host when the device
* detects that it has been connected to a host.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device is run successfully.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
*
*/
extern usb_status_t USB_DeviceRun(usb_device_handle handle);
/*!
* @brief Disables the device functionality.
*
* The function disables the device functionality. After this function called, even if the device is detached to the
* host,
* it can't work.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device is stopped successfully.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
*/
extern usb_status_t USB_DeviceStop(usb_device_handle handle);
/*!
* @brief De-initializes the device controller.
*
* The function de-initializes the device controller specified by the handle.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device is stopped successfully.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
*/
extern usb_status_t USB_DeviceDeinit(usb_device_handle handle);
/*!
* @brief Sends data through a specified endpoint.
*
* The function is used to send data through a specified endpoint.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to hold the data need to be sent. The function is not reentrant.
* @param[in] length The data length need to be sent.
*
* @retval kStatus_USB_Success The send request is sent successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error The device is doing reset.
*
* @note The return value indicates whether the sending request is successful or not. The transfer done is notified by
* the
* corresponding callback function.
* Currently, only one transfer request can be supported for one specific endpoint.
* If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
* should implement a queue on the application level.
* The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint
* callback).
*/
extern usb_status_t USB_DeviceSendRequest(usb_device_handle handle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Receives data through a specified endpoint.
*
* The function is used to receive data through a specified endpoint. The function is not reentrant.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to save the received data.
* @param[in] length The data length want to be received.
*
* @retval kStatus_USB_Success The receive request is sent successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error The device is doing reset.
*
* @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by
* the
* corresponding callback function.
* Currently, only one transfer request can be supported for one specific endpoint.
* If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
* should implement a queue on the application level.
* The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint
* callback).
*/
extern usb_status_t USB_DeviceRecvRequest(usb_device_handle handle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Cancels the pending transfer in a specified endpoint.
*
* The function is used to cancel the pending transfer in a specified endpoint.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The transfer is cancelled.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer or the controller handle is invalid.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Initializes a specified endpoint.
*
* The function is used to initialize a specified endpoint. The corresponding endpoint callback is also initialized.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
* @param[in] epInit Endpoint initialization structure. See the structure usb_device_endpoint_init_struct_t.
* @param[in] epCallback Endpoint callback structure. See the structure
* usb_device_endpoint_callback_struct_t.
*
* @retval kStatus_USB_Success The endpoint is initialized successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is
* more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle,
usb_device_endpoint_init_struct_t *epInit,
usb_device_endpoint_callback_struct_t *epCallback);
/*!
* @brief Deinitializes a specified endpoint.
*
* The function is used to deinitializes a specified endpoint.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The endpoint is de-initialized successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Stalls a specified endpoint.
*
* The function is used to stall a specified endpoint.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The endpoint is stalled successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Un-stall a specified endpoint.
*
* The function is used to unstall a specified endpoint.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The endpoint is un-stalled successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Gets the status of the selected item.
*
* The function is used to get the status of the selected item.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] type The selected item. See the structure #usb_device_status_t.
* @param[out] param The parameter type is determined by the selected item.
*
* @retval kStatus_USB_Success Get status successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The parameter is NULL pointer.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error Unsupported type.
*/
extern usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param);
/*!
* @brief Sets the status of the selected item.
*
* The function is used to set the status of the selected item.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] type The selected item. See the structure #usb_device_status_t.
* @param[in] param The parameter type is determined by the selected item.
*
* @retval kStatus_USB_Success Set status successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error Unsupported type or the parameter is NULL pointer.
*/
extern usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param);
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
/*!
* @brief Enable the device dcd module.
*
* The function enable the device dcd module.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device could run.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
*
*/
extern usb_status_t USB_DeviceDcdEnable(usb_device_handle handle);
/*!
* @brief Disable the device dcd module.
*
* The function disable the device dcd module.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The dcd is reset and stopped.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
*
*/
extern usb_status_t USB_DeviceDcdDisable(usb_device_handle handle);
#endif
/*!
* @brief Device task function.
*
* The function is used to handle the controller message.
* This function should not be called in the application directly.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceTaskFunction(void *deviceHandle);
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
/*!
* @brief Device KHCI task function.
*
* The function is used to handle the KHCI controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
#define USB_DeviceKhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
#endif
#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
/*!
* @brief Device EHCI task function.
*
* The function is used to handle the EHCI controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
#define USB_DeviceEhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
/*!
* @brief Device ehci DCD ISR function.
*
* The function is the ehci DCD interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceEhciIsrHSDCDFunction(void *deviceHandle);
#endif
#endif
#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
/*!
* @brief Device LPC ip3511 controller task function.
*
* The function is used to handle the LPC ip3511 controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
#define USB_DeviceLpcIp3511TaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
/*!
* @brief Device IP3511 DCD ISR function.
*
* The function is the IP3511 DCD interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceLpcIp3511IsrDCDFunction(void *deviceHandle);
#endif
#endif
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
/*!
* @brief Device KHCI ISR function.
*
* The function is the KHCI interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceKhciIsrFunction(void *deviceHandle);
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
/*!
* @brief Device KHCI DCD ISR function.
*
* The function is the KHCI DCD interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceDcdIsrFunction(void *deviceHandle);
#endif
#endif
#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
/*!
* @brief Device EHCI ISR function.
*
* The function is the EHCI interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceEhciIsrFunction(void *deviceHandle);
#endif
#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
/*!
* @brief Device LPC USB ISR function.
*
* The function is the LPC USB interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle);
#endif
#if (((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) || \
((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)))
/*!
* @brief Device USB DWC3 ISR function.
*
* The function is the USB interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceDwc3IsrFunction(void *deviceHandle);
#endif
/*!
* @brief Gets the device stack version function.
*
* The function is used to get the device stack version.
*
* @param[out] version The version structure pointer to keep the device stack version.
*
*/
extern void USB_DeviceGetVersion(uint32_t *version);
#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) || \
((defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)))
/*!
* @brief Update the hardware tick.
*
* The function is used to update the hardware tick.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] tick Current hardware tick(uint is ms).
*
*/
extern usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick);
#endif
/*! @}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*! @}*/
#endif /* __USB_DEVICE_H__ */

View File

@ -0,0 +1,154 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_DCI_H__
#define __USB_DEVICE_DCI_H__
/*!
* @addtogroup usb_device_controller_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Macro to define controller handle */
#define usb_device_controller_handle usb_device_handle
#define USB_DEVICE_MESSAGES_SIZE (sizeof(uint32_t)*(1U + (sizeof(usb_device_callback_message_struct_t) - 1U) / sizeof(uint32_t)))
/*! @brief Available notify types for device notification */
typedef enum _usb_device_notification
{
kUSB_DeviceNotifyBusReset = 0x10U, /*!< Reset signal detected */
kUSB_DeviceNotifySuspend, /*!< Suspend signal detected */
kUSB_DeviceNotifyResume, /*!< Resume signal detected */
kUSB_DeviceNotifyLPMSleep, /*!< LPM signal detected */
kUSB_DeviceNotifyLPMResume, /*!< Resume signal detected */
kUSB_DeviceNotifyError, /*!< Errors happened in bus */
kUSB_DeviceNotifyDetach, /*!< Device disconnected from a host */
kUSB_DeviceNotifyAttach, /*!< Device connected to a host */
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
kUSB_DeviceNotifyDcdDetectFinished, /*!< Device charger detection finished */
#endif
} usb_device_notification_t;
/*! @brief Device notification message structure */
typedef struct _usb_device_callback_message_struct
{
uint8_t *buffer; /*!< Transferred buffer */
uint32_t length; /*!< Transferred data length */
uint8_t code; /*!< Notification code */
uint8_t isSetup; /*!< Is in a setup phase */
} usb_device_callback_message_struct_t;
/*! @brief Control type for controller */
typedef enum _usb_device_control_type
{
kUSB_DeviceControlRun = 0U, /*!< Enable the device functionality */
kUSB_DeviceControlStop, /*!< Disable the device functionality */
kUSB_DeviceControlEndpointInit, /*!< Initialize a specified endpoint */
kUSB_DeviceControlEndpointDeinit, /*!< De-initialize a specified endpoint */
kUSB_DeviceControlEndpointStall, /*!< Stall a specified endpoint */
kUSB_DeviceControlEndpointUnstall, /*!< Un-stall a specified endpoint */
kUSB_DeviceControlGetDeviceStatus, /*!< Get device status */
kUSB_DeviceControlGetEndpointStatus, /*!< Get endpoint status */
kUSB_DeviceControlSetDeviceAddress, /*!< Set device address */
kUSB_DeviceControlGetSynchFrame, /*!< Get current frame */
kUSB_DeviceControlResume, /*!< Drive controller to generate a resume signal in USB bus */
kUSB_DeviceControlSleepResume, /*!< Drive controller to generate a LPM resume signal in USB bus */
kUSB_DeviceControlSuspend, /*!< Drive controller to enter into suspend mode */
kUSB_DeviceControlSleep, /*!< Drive controller to enter into sleep mode */
kUSB_DeviceControlSetDefaultStatus, /*!< Set controller to default status */
kUSB_DeviceControlGetSpeed, /*!< Get current speed */
kUSB_DeviceControlGetOtgStatus, /*!< Get OTG status */
kUSB_DeviceControlSetOtgStatus, /*!< Set OTG status */
kUSB_DeviceControlSetTestMode, /*!< Drive xCHI into test mode */
kUSB_DeviceControlGetRemoteWakeUp, /*!< Get flag of LPM Remote Wake-up Enabled by USB host. */
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
kUSB_DeviceControlDcdDisable, /*!< disable dcd module function. */
kUSB_DeviceControlDcdEnable, /*!< enable dcd module function. */
#endif
kUSB_DeviceControlPreSetDeviceAddress, /*!< Pre set device address */
kUSB_DeviceControlUpdateHwTick, /*!< update hardware tick */
} usb_device_control_type_t;
/*! @brief USB device controller initialization function typedef */
typedef usb_status_t (*usb_device_controller_init_t)(uint8_t controllerId,
usb_device_handle handle,
usb_device_controller_handle *controllerHandle);
/*! @brief USB device controller de-initialization function typedef */
typedef usb_status_t (*usb_device_controller_deinit_t)(usb_device_controller_handle controllerHandle);
/*! @brief USB device controller send data function typedef */
typedef usb_status_t (*usb_device_controller_send_t)(usb_device_controller_handle controllerHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*! @brief USB device controller receive data function typedef */
typedef usb_status_t (*usb_device_controller_recv_t)(usb_device_controller_handle controllerHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*! @brief USB device controller cancel transfer function in a specified endpoint typedef */
typedef usb_status_t (*usb_device_controller_cancel_t)(usb_device_controller_handle controllerHandle,
uint8_t endpointAddress);
/*! @brief USB device controller control function typedef */
typedef usb_status_t (*usb_device_controller_control_t)(usb_device_controller_handle controllerHandle,
usb_device_control_type_t command,
void *param);
/*! @brief USB device controller interface structure */
typedef struct _usb_device_controller_interface_struct
{
usb_device_controller_init_t deviceInit; /*!< Controller initialization */
usb_device_controller_deinit_t deviceDeinit; /*!< Controller de-initialization */
usb_device_controller_send_t deviceSend; /*!< Controller send data */
usb_device_controller_recv_t deviceRecv; /*!< Controller receive data */
usb_device_controller_cancel_t deviceCancel; /*!< Controller cancel transfer */
usb_device_controller_control_t deviceControl; /*!< Controller control */
} usb_device_controller_interface_struct_t;
/*! @brief USB device status structure */
typedef struct _usb_device_struct
{
#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) || \
(defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
volatile uint64_t hwTick; /*!< Current hw tick(ms)*/
#endif
usb_device_controller_handle controllerHandle; /*!< Controller handle */
const usb_device_controller_interface_struct_t *controllerInterface; /*!< Controller interface handle */
#if USB_DEVICE_CONFIG_USE_TASK
MSGQ_HANDLE_BUFFER_DEFINE(notificationQueueBuffer, USB_DEVICE_CONFIG_MAX_MESSAGES, USB_DEVICE_MESSAGES_SIZE); /*!< Message queue buffer*/
osa_msgq_handle_t notificationQueue; /*!< Message queue*/
#endif
usb_device_callback_t deviceCallback; /*!< Device callback function pointer */
usb_device_endpoint_callback_struct_t
epCallback[USB_DEVICE_CONFIG_ENDPOINTS << 1U]; /*!< Endpoint callback function structure */
uint8_t deviceAddress; /*!< Current device address */
uint8_t controllerId; /*!< Controller ID */
uint8_t state; /*!< Current device state */
#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
uint8_t remotewakeup; /*!< Remote wakeup is enabled or not */
#endif
uint8_t isResetting; /*!< Is doing device reset or not */
#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
uint8_t epCallbackDirectly; /*!< Whether call ep callback directly when the task is enabled */
#endif
} usb_device_struct_t;
/*******************************************************************************
* API
******************************************************************************/
/*! @}*/
#endif /* __USB_DEVICE_DCI_H__ */

View File

@ -0,0 +1,298 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_EHCI_H__
#define __USB_DEVICE_EHCI_H__
/*!
* @addtogroup usb_device_controller_ehci_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief The maximum value of ISO type maximum packet size for HS in USB specification 2.0 */
#define USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE (1024U)
/*! @brief The maximum value of interrupt type maximum packet size for HS in USB specification 2.0 */
#define USB_DEVICE_MAX_HS_INTERUPT_MAX_PACKET_SIZE (1024U)
/*! @brief The maximum value of bulk type maximum packet size for HS in USB specification 2.0 */
#define USB_DEVICE_MAX_HS_BULK_MAX_PACKET_SIZE (512U)
/*! @brief The maximum value of control type maximum packet size for HS in USB specification 2.0 */
#define USB_DEVICE_MAX_HS_CONTROL_MAX_PACKET_SIZE (64U)
#define USB_DEVICE_MAX_TRANSFER_PRIME_TIMES (10000000U) /* The max prime times of EPPRIME, if still doesn't take effect, means status has been reset*/
/* Device QH */
#define USB_DEVICE_EHCI_QH_POINTER_MASK (0xFFFFFFC0U)
#define USB_DEVICE_EHCI_QH_MULT_MASK (0xC0000000U)
#define USB_DEVICE_EHCI_QH_ZLT_MASK (0x20000000U)
#define USB_DEVICE_EHCI_QH_MAX_PACKET_SIZE_MASK (0x07FF0000U)
#define USB_DEVICE_EHCI_QH_MAX_PACKET_SIZE (0x00000800U)
#define USB_DEVICE_EHCI_QH_IOS_MASK (0x00008000U)
/* Device DTD */
#define USB_DEVICE_ECHI_DTD_POINTER_MASK (0xFFFFFFE0U)
#define USB_DEVICE_ECHI_DTD_TERMINATE_MASK (0x00000001U)
#define USB_DEVICE_ECHI_DTD_PAGE_MASK (0xFFFFF000U)
#define USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK (0x00000FFFU)
#define USB_DEVICE_ECHI_DTD_PAGE_BLOCK (0x00001000U)
#define USB_DEVICE_ECHI_DTD_TOTAL_BYTES_MASK (0x7FFF0000U)
#define USB_DEVICE_ECHI_DTD_TOTAL_BYTES (0x00004000U)
#define USB_DEVICE_ECHI_DTD_IOC_MASK (0x00008000U)
#define USB_DEVICE_ECHI_DTD_MULTIO_MASK (0x00000C00U)
#define USB_DEVICE_ECHI_DTD_STATUS_MASK (0x000000FFU)
#define USB_DEVICE_EHCI_DTD_STATUS_ERROR_MASK (0x00000068U)
#define USB_DEVICE_ECHI_DTD_STATUS_ACTIVE (0x00000080U)
#define USB_DEVICE_ECHI_DTD_STATUS_HALTED (0x00000040U)
#define USB_DEVICE_ECHI_DTD_STATUS_DATA_BUFFER_ERROR (0x00000020U)
#define USB_DEVICE_ECHI_DTD_STATUS_TRANSACTION_ERROR (0x00000008U)
typedef struct _usb_device_ehci_qh_struct
{
union
{
volatile uint32_t capabilttiesCharacteristics;
struct
{
volatile uint32_t reserved1 : 15;
volatile uint32_t ios : 1;
volatile uint32_t maxPacketSize : 11;
volatile uint32_t reserved2 : 2;
volatile uint32_t zlt : 1;
volatile uint32_t mult : 2;
} capabilttiesCharacteristicsBitmap;
} capabilttiesCharacteristicsUnion;
volatile uint32_t currentDtdPointer;
volatile uint32_t nextDtdPointer;
union
{
volatile uint32_t dtdToken;
struct
{
volatile uint32_t status : 8;
volatile uint32_t reserved1 : 2;
volatile uint32_t multiplierOverride : 2;
volatile uint32_t reserved2 : 3;
volatile uint32_t ioc : 1;
volatile uint32_t totalBytes : 15;
volatile uint32_t reserved3 : 1;
} dtdTokenBitmap;
} dtdTokenUnion;
volatile uint32_t bufferPointerPage[5];
volatile uint32_t reserved1;
uint32_t setupBuffer[2];
uint32_t setupBufferBack[2];
union
{
uint32_t endpointStatus;
struct
{
uint32_t isOpened : 1;
uint32_t zlt: 1;
uint32_t : 30;
} endpointStatusBitmap;
} endpointStatusUnion;
uint32_t reserved2;
} usb_device_ehci_qh_struct_t;
typedef struct _usb_device_ehci_dtd_struct
{
volatile uint32_t nextDtdPointer;
union
{
volatile uint32_t dtdToken;
struct
{
volatile uint32_t status : 8;
volatile uint32_t reserved1 : 2;
volatile uint32_t multiplierOverride : 2;
volatile uint32_t reserved2 : 3;
volatile uint32_t ioc : 1;
volatile uint32_t totalBytes : 15;
volatile uint32_t reserved3 : 1;
} dtdTokenBitmap;
} dtdTokenUnion;
volatile uint32_t bufferPointerPage[5];
union
{
volatile uint32_t reserved;
struct
{
uint32_t originalBufferOffest : 12;
uint32_t originalBufferLength : 19;
uint32_t dtdInvalid : 1;
} originalBufferInfo;
} reservedUnion;
} usb_device_ehci_dtd_struct_t;
/*! @brief EHCI state structure */
typedef struct _usb_device_ehci_state_struct
{
usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object is belonged to */
USBHS_Type *registerBase; /*!< The base address of the register */
#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
USBPHY_Type *registerPhyBase; /*!< The base address of the PHY register */
#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
USBNC_Type *registerNcBase; /*!< The base address of the USBNC register */
#endif
#endif
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
((defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) || \
(defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)))
void* dcdHandle; /*!< Dcd handle used to identify the device object belongs to */
#endif
usb_device_ehci_qh_struct_t *qh; /*!< The QH structure base address */
usb_device_ehci_dtd_struct_t *dtd; /*!< The DTD structure base address */
usb_device_ehci_dtd_struct_t *dtdFree; /*!< The idle DTD list head */
usb_device_ehci_dtd_struct_t
*dtdHard[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< The transferring DTD list head for each endpoint */
usb_device_ehci_dtd_struct_t
*dtdTail[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< The transferring DTD list tail for each endpoint */
int8_t dtdCount; /*!< The idle DTD node count */
uint8_t endpointCount; /*!< The endpoint number of EHCI */
uint8_t isResetting; /*!< Whether a PORT reset is occurring or not */
uint8_t controllerId; /*!< Controller ID */
uint8_t speed; /*!< Current speed of EHCI */
uint8_t isSuspending; /*!< Is suspending of the PORT */
} usb_device_ehci_state_struct_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name USB device EHCI functions
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Initializes the USB device EHCI instance.
*
* This function initializes the USB device EHCI module specified by the controllerId.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t.
* @param[in] handle Pointer of the device handle used to identify the device object is belonged to.
* @param[out] ehciHandle An out parameter used to return the pointer of the device EHCI handle to the caller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceEhciInit(uint8_t controllerId,
usb_device_handle handle,
usb_device_controller_handle *ehciHandle);
/*!
* @brief Deinitializes the USB device EHCI instance.
*
* This function deinitializes the USB device EHCI module.
*
* @param[in] ehciHandle Pointer of the device EHCI handle.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceEhciDeinit(usb_device_controller_handle ehciHandle);
/*!
* @brief Sends data through a specified endpoint.
*
* This function sends data through a specified endpoint.
*
* @param[in] ehciHandle Pointer of the device EHCI handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to hold the data need to be sent.
* @param[in] length The data length to be sent.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value means whether the sending request is successful or not. The transfer completion is indicated
* by the
* corresponding callback function.
* Currently, only one transfer request can be supported for a specific endpoint.
* If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer can begin only when the previous transfer is done (a notification is received through the
* endpoint
* callback).
*/
usb_status_t USB_DeviceEhciSend(usb_device_controller_handle ehciHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Receive data through a specified endpoint.
*
* This function Receives data through a specified endpoint.
*
* @param[in] ehciHandle Pointer of the device EHCI handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to save the received data.
* @param[in] length The data length want to be received.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
* corresponding callback function.
* Currently, only one transfer request can be supported for one specific endpoint.
* If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
* callback).
*/
usb_status_t USB_DeviceEhciRecv(usb_device_controller_handle ehciHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Cancels the pending transfer in a specified endpoint.
*
* The function is used to cancel the pending transfer in a specified endpoint.
*
* @param[in] ehciHandle Pointer of the device EHCI handle.
* @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, 0U - OUT.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8_t ep);
/*!
* @brief Controls the status of the selected item.
*
* The function is used to control the status of the selected item.
*
* @param[in] ehciHandle Pointer of the device EHCI handle.
* @param[in] type The selected item. See enumeration type usb_device_control_type_t.
* @param[in,out] param The parameter type is determined by the selected item.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle,
usb_device_control_type_t type,
void *param);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* __USB_DEVICE_EHCI_H__ */

View File

@ -0,0 +1,262 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_KHCI_H__
#define __USB_DEVICE_KHCI_H__
/*!
* @addtogroup usb_device_controller_khci_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief The maximum value of ISO maximum packet size for FS in USB specification 2.0 */
#define USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE (1023U)
/*! @brief The maximum value of non-ISO maximum packet size for FS in USB specification 2.0 */
#define USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE (64U)
#define USB_KHCI_BDT_DEVICE_OUT_TOKEN (0x01U)
#define USB_KHCI_BDT_DEVICE_IN_TOKEN (0x09U)
#define USB_KHCI_BDT_DEVICE_SETUP_TOKEN (0x0DU)
#define USB_KHCI_BDT_OWN (0x80U)
#define USB_KHCI_BDT_DATA01(x) ((((uint32_t)(x)) & 0x01U) << 0x06U)
#define USB_KHCI_BDT_BC(x) ((((uint32_t)(x)) & 0x3FFU) << 0x10U)
#define UBS_KHCI_BDT_KEEP (0x20U)
#define UBS_KHCI_BDT_NINC (0x10U)
#define USB_KHCI_BDT_DTS (0x08U)
#define USB_KHCI_BDT_STALL (0x04U)
typedef enum _usb_khci_interrupt_type
{
kUSB_KhciInterruptReset = 0x01U,
kUSB_KhciInterruptError = 0x02U,
kUSB_KhciInterruptSofToken = 0x04U,
kUSB_KhciInterruptTokenDone = 0x08U,
kUSB_KhciInterruptSleep = 0x10U,
kUSB_KhciInterruptResume = 0x20U,
kUSB_KhciInterruptAttach = 0x40U,
kUSB_KhciInterruptStall = 0x80U,
} usb_khci_interrupt_type_t;
/*! @brief Set BDT buffer address */
#define USB_KHCI_BDT_SET_ADDRESS(bdt_base, ep, direction, odd, address) \
*(((volatile uint32_t *)((uint8_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
(((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)))) + \
1U) = address
/*! @brief Set BDT control fields*/
#define USB_KHCI_BDT_SET_CONTROL(bdt_base, ep, direction, odd, control) \
*((volatile uint32_t *)((uint8_t *)(((bdt_base) & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
(((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)))) = control
/*! @brief Get BDT buffer address*/
#define USB_KHCI_BDT_GET_ADDRESS(bdt_base, ep, direction, odd) \
(*((volatile uint32_t *)((uint8_t *)(((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
(((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)))) + \
1U))
/*! @brief Get BDT control fields*/
#define USB_KHCI_BDT_GET_CONTROL(bdt_base, ep, direction, odd) \
(*(volatile uint32_t *)((uint8_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
(((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U))))
/*! @brief Endpoint state structure */
typedef struct _usb_device_khci_endpoint_state_struct
{
uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */
uint32_t transferLength; /*!< Length of data to transmit. */
uint32_t transferDone; /*!< The data length has been transferred*/
union
{
uint32_t state; /*!< The state of the endpoint */
struct
{
uint32_t maxPacketSize : 10U; /*!< The maximum packet size of the endpoint */
uint32_t stalled : 1U; /*!< The endpoint is stalled or not */
uint32_t data0 : 1U; /*!< The data toggle of the transaction */
uint32_t bdtOdd : 1U; /*!< The BDT toggle of the endpoint */
uint32_t dmaAlign : 1U; /*!< Whether the transferBuffer is DMA aligned or not */
uint32_t transferring : 1U; /*!< The endpoint is transferring */
uint32_t zlt : 1U; /*!< zlt flag */
} stateBitField;
} stateUnion;
} usb_device_khci_endpoint_state_struct_t;
/*! @brief KHCI state structure */
typedef struct _usb_device_khci_state_struct
{
usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */
uint8_t *bdt; /*!< BDT buffer address */
USB_Type *registerBase; /*!< The base address of the register */
uint8_t setupPacketBuffer[USB_SETUP_PACKET_SIZE * 2]; /*!< The setup request buffer */
uint8_t *dmaAlignBuffer; /*!< This buffer is used to fix the transferBuffer or transferLength does
not align to 4-bytes when the function USB_DeviceKhciRecv is called.
The macro USB_DEVICE_CONFIG_KHCI_DMA_ALIGN is used to enable or disable this feature.
If the feature is enabled, when the transferBuffer or transferLength does not align to
4-bytes,
the transferLength is not more than USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH, and
the flag isDmaAlignBufferInusing is zero, the dmaAlignBuffer is used to receive data
and the flag isDmaAlignBufferInusing is set to 1.
When the transfer is done, the received data, kept in dmaAlignBuffer, is copied
to the transferBuffer, and the flag isDmaAlignBufferInusing is cleared.
*/
usb_device_khci_endpoint_state_struct_t
endpointState[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< Endpoint state structures */
uint8_t isDmaAlignBufferInusing; /*!< The dmaAlignBuffer is used or not */
uint8_t isResetting; /*!< Is doing device reset or not */
uint8_t controllerId; /*!< Controller ID */
uint8_t setupBufferIndex; /*!< A valid setup buffer flag */
#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
uint8_t otgStatus;
#endif
} usb_device_khci_state_struct_t;
#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
(defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
typedef struct _usb_device_dcd_state_struct
{
usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */
USBDCD_Type *dcdRegisterBase; /*!< The base address of the dcd module */
uint8_t controllerId; /*!< Controller ID */
} usb_device_dcd_state_struct_t;
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name USB device KHCI functions
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Initializes the USB device KHCI instance.
*
* This function initializes the USB device KHCI module specified by the controllerId.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t.
* @param[in] handle Pointer of the device handle used to identify the device object belongs to.
* @param[out] khciHandle An out parameter used to return the pointer of the device KHCI handle to the caller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceKhciInit(uint8_t controllerId,
usb_device_handle handle,
usb_device_controller_handle *khciHandle);
/*!
* @brief Deinitializes the USB device KHCI instance.
*
* This function deinitializes the USB device KHCI module.
*
* @param[in] khciHandle Pointer of the device KHCI handle.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle);
/*!
* @brief Sends data through a specified endpoint.
*
* This function sends data through a specified endpoint.
*
* @param[in] khciHandle Pointer of the device KHCI handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to hold the data need to be sent.
* @param[in] length The data length need to be sent.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value indicates whether the sending request is successful or not. The transfer completion is
* notified by the
* corresponding callback function.
* Currently, only one transfer request can be supported for a specific endpoint.
* If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
* endpoint
* callback).
*/
usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Receives data through a specified endpoint.
*
* This function receives data through a specified endpoint.
*
* @param[in] khciHandle Pointer of the device KHCI handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to save the received data.
* @param[in] length The data length to be received.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value indicates whether the receiving request is successful or not. The transfer completion is
* notified by the
* corresponding callback function.
* Currently, only one transfer request can be supported for a specific endpoint.
* If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
* endpoint
* callback).
*/
usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Cancels the pending transfer in a specified endpoint.
*
* The function is used to cancel the pending transfer in a specified endpoint.
*
* @param[in] khciHandle Pointer of the device KHCI handle.
* @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep);
/*!
* @brief Controls the status of the selected item.
*
* The function is used to control the status of the selected item.
*
* @param[in] khciHandle Pointer of the device KHCI handle.
* @param[in] type The selected item. See enumeration type usb_device_control_type_t.
* @param[in,out] param The parameter type is determined by the selected item.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle,
usb_device_control_type_t type,
void *param);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* __USB_DEVICE_KHCI_H__ */

View File

@ -0,0 +1,261 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_LPC3511IP_H__
#define __USB_DEVICE_LPC3511IP_H__
#include "fsl_device_registers.h"
/*!
* @addtogroup usb_device_controller_lpcip3511_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief The reserved buffer size, the buffer is for the memory copy if the application transfer buffer is
((not 64 bytes alignment) || (not in the same 64K ram) || (HS && OUT && not multiple of 4)) */
#define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE (5 * 1024)
/*! @brief Use one bit to represent one reserved 64 bytes to allocate the buffer by uint of 64 bytes. */
#define USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER ((USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE + 63) / 64)
/*! @brief How many IPs support the reserved buffer */
#define USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY (USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS)
/*! @brief Prime all the double endpoint buffer at the same time, if the transfer length is larger than max packet size.
*/
#define USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE (1u)
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#define USB_LPC3511IP_Type USBHSD_Type
#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USBHSD_EP_NUM
#else
#define USB_LPC3511IP_Type USB_Type
#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USB_EP_NUM
#endif
/* for out endpoint,only use buffer toggle, disable prime double buffer at the same time*/
/*host send data less than maxpacket size and in endpoint prime length more more than maxpacketsize, there will be state
* mismtach*/
#if USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE
#define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (1u)
#else
#define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (0u)
#endif
#define USB_DEVICE_IP3511HS_LPM_ADPPROBE_ATTACH_DEBOUNCE_COUNT (3)
/*! @brief Endpoint state structure */
typedef struct _usb_device_lpc3511ip_endpoint_state_struct
{
uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */
uint32_t transferLength; /*!< Length of data to transmit. */
uint32_t transferDone; /*!< The data length has been transferred*/
uint32_t transferPrimedLength; /*!< it may larger than transferLength, because the primed length may larger than the
transaction length. */
uint8_t *epPacketBuffer; /*!< The max packet buffer for copying*/
union
{
uint32_t state; /*!< The state of the endpoint */
struct
{
uint32_t maxPacketSize : 11U; /*!< The maximum packet size of the endpoint */
uint32_t stalled : 1U; /*!< The endpoint is stalled or not */
uint32_t transferring : 1U; /*!< The endpoint is transferring */
uint32_t zlt : 1U; /*!< zlt flag */
uint32_t stallPrimed : 1U;
uint32_t epPacketCopyed : 1U; /*!< whether use the copy buffer */
uint32_t epControlDefault : 5u; /*!< The EP command/status 26~30 bits */
uint32_t doubleBufferBusy : 2U; /*!< How many buffers are primed, for control endpoint it is not used */
uint32_t producerOdd : 1U; /*!< When priming one transaction, prime to this endpoint buffer */
uint32_t consumerOdd : 1U; /*!< When transaction is done, read result from this endpoint buffer */
uint32_t endpointType : 2U;
uint32_t reserved1 : 5U;
} stateBitField;
} stateUnion;
union
{
uint16_t epBufferStatus;
/* If double buff is disable, only epBufferStatusUnion[0] is used;
For control endpoint, only epBufferStatusUnion[0] is used. */
struct
{
uint16_t transactionLength : 11U;
uint16_t epPacketCopyed : 1U;
} epBufferStatusField;
} epBufferStatusUnion[2];
} usb_device_lpc3511ip_endpoint_state_struct_t;
/*! @brief LPC USB controller (IP3511) state structure */
typedef struct _usb_device_lpc3511ip_state_struct
{
/*!< control data buffer, must align with 64 */
uint8_t *controlData;
/*!< 8 bytes' setup data, must align with 64 */
uint8_t *setupData;
/*!< 4 bytes for zero length transaction, must align with 64 */
uint8_t *zeroTransactionData;
/* Endpoint state structures */
usb_device_lpc3511ip_endpoint_state_struct_t endpointState[(USB_DEVICE_IP3511_ENDPOINTS_NUM * 2)];
usb_device_handle deviceHandle; /*!< (4 bytes) Device handle used to identify the device object belongs to */
USB_LPC3511IP_Type *registerBase; /*!< (4 bytes) ip base address */
volatile uint32_t *epCommandStatusList; /* endpoint list */
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
void *dcdHandle; /*!< Dcd handle used to identify the device object belongs to */
#endif
uint8_t controllerId; /*!< Controller ID */
uint8_t isResetting; /*!< Is doing device reset or not */
uint8_t deviceSpeed; /*!< some controller support the HS */
#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U))
uint8_t *epReservedBuffer;
uint8_t epReservedBufferBits[(USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER + 7) / 8];
#endif
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
uint8_t controllerSpeed;
#endif
#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE))
uint8_t deviceState; /*!< Is device attached,1 attached,0 detached */
#endif
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \
(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))
uint8_t hsInterruptIssue;
#endif
#endif
} usb_device_lpc3511ip_state_struct_t;
/*!
* @name USB device controller (IP3511) functions
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initializes the USB device controller instance.
*
* This function initializes the USB device controller module specified by the controllerId.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t.
* @param[in] handle Pointer of the device handle used to identify the device object belongs to.
* @param[out] controllerHandle An out parameter used to return the pointer of the device controller handle to the
* caller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpInit(uint8_t controllerId,
usb_device_handle handle,
usb_device_controller_handle *controllerHandle);
/*!
* @brief Deinitializes the USB device controller instance.
*
* This function deinitializes the USB device controller module.
*
* @param[in] controllerHandle Pointer of the device controller handle.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpDeinit(usb_device_controller_handle controllerHandle);
/*!
* @brief Sends data through a specified endpoint.
*
* This function sends data through a specified endpoint.
*
* @param[in] controllerHandle Pointer of the device controller handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to hold the data need to be sent.
* @param[in] length The data length need to be sent.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value indicates whether the sending request is successful or not. The transfer completion is
* notified by the
* corresponding callback function.
* Currently, only one transfer request can be supported for a specific endpoint.
* If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
* endpoint
* callback).
*/
usb_status_t USB_DeviceLpc3511IpSend(usb_device_controller_handle controllerHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Receives data through a specified endpoint.
*
* This function receives data through a specified endpoint.
*
* @param[in] controllerHandle Pointer of the device controller handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to save the received data.
* @param[in] length The data length to be received.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value indicates whether the receiving request is successful or not. The transfer completion is
* notified by the
* corresponding callback function.
* Currently, only one transfer request can be supported for a specific endpoint.
* If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
* endpoint
* callback).
*/
usb_status_t USB_DeviceLpc3511IpRecv(usb_device_controller_handle controllerHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Cancels the pending transfer in a specified endpoint.
*
* The function is used to cancel the pending transfer in a specified endpoint.
*
* @param[in] controllerHandle ointer of the device controller handle.
* @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpCancel(usb_device_controller_handle controllerHandle, uint8_t ep);
/*!
* @brief Controls the status of the selected item.
*
* The function is used to control the status of the selected item.
*
* @param[in] controllerHandle Pointer of the device controller handle.
* @param[in] type The selected item. Please refer to enumeration type usb_device_control_type_t.
* @param[in,out] param The parameter type is determined by the selected item.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpControl(usb_device_controller_handle controllerHandle,
usb_device_control_type_t type,
void *param);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* __USB_DEVICE_LPC3511IP_H__ */

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_H__
#define __USB_H__
#include <stdint.h>
#include <stdio.h>
#include "fsl_common.h"
#include "fsl_os_abstraction.h"
#include "usb_misc.h"
#include "usb_spec.h"
/*!
* @addtogroup usb_drv
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines USB stack major version */
#define USB_STACK_VERSION_MAJOR (2U)
/*! @brief Defines USB stack minor version */
#define USB_STACK_VERSION_MINOR (5U)
/*! @brief Defines USB stack bugfix version */
#define USB_STACK_VERSION_BUGFIX (0U)
/*! @brief USB stack version definition */
#define USB_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
/*! @brief USB stack component version definition, changed with component in yaml together */
#define USB_STACK_COMPONENT_VERSION MAKE_VERSION(2, 5, 0)
/*
* Component ID used by tools
*
* FSL_COMPONENT_ID "middleware.usb.stack_common"
*/
/*! @brief USB error code */
typedef enum _usb_status
{
kStatus_USB_Success = 0x00U, /*!< Success */
kStatus_USB_Error, /*!< Failed */
kStatus_USB_Busy, /*!< Busy */
kStatus_USB_InvalidHandle, /*!< Invalid handle */
kStatus_USB_InvalidParameter, /*!< Invalid parameter */
kStatus_USB_InvalidRequest, /*!< Invalid request */
kStatus_USB_ControllerNotFound, /*!< Controller cannot be found */
kStatus_USB_InvalidControllerInterface, /*!< Invalid controller interface */
kStatus_USB_NotSupported, /*!< Configuration is not supported */
kStatus_USB_Retry, /*!< Enumeration get configuration retry */
kStatus_USB_TransferStall, /*!< Transfer stalled */
kStatus_USB_TransferFailed, /*!< Transfer failed */
kStatus_USB_AllocFail, /*!< Allocation failed */
kStatus_USB_LackSwapBuffer, /*!< Insufficient swap buffer for KHCI */
kStatus_USB_TransferCancel, /*!< The transfer cancelled */
kStatus_USB_BandwidthFail, /*!< Allocate bandwidth failed */
kStatus_USB_MSDStatusFail, /*!< For MSD, the CSW status means fail */
kStatus_USB_EHCIAttached,
kStatus_USB_EHCIDetached,
kStatus_USB_DataOverRun, /*!< The amount of data returned by the endpoint exceeded
either the size of the maximum data packet allowed
from the endpoint or the remaining buffer size. */
} usb_status_t;
/*! @brief USB host handle type define */
typedef void *usb_host_handle;
/*! @brief USB device handle type define. For device stack it is the whole device handle; for host stack it is the
* attached device instance handle*/
typedef void *usb_device_handle;
/*! @brief USB OTG handle type define */
typedef void *usb_otg_handle;
/*! @brief USB controller ID */
typedef enum _usb_controller_index
{
kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
to be used in the future. */
kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved
to be used in the future. */
kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */
kUSB_ControllerLpcIp3511Fs1 =
5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511 IPs, this is reserved
to be used in the future. */
kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */
kUSB_ControllerLpcIp3511Hs1 =
7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511 IPs, this is reserved
to be used in the future. */
kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */
kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved
to be used in the future. */
kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */
kUSB_ControllerIp3516Hs1 =
11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs, this is reserved
to be used in the future. */
kUSB_ControllerDwc30 = 12U, /*!< DWC3 0U */
kUSB_ControllerDwc31 =
13U, /*!< DWC3 1U Currently, there are no platforms which have two Dwc IPs, this is reserved
to be used in the future.*/
} usb_controller_index_t;
/**
* @brief USB stack version fields
*/
typedef struct _usb_version
{
uint8_t major; /*!< Major */
uint8_t minor; /*!< Minor */
uint8_t bugfix; /*!< Bug fix */
} usb_version_t;
/*******************************************************************************
* API
******************************************************************************/
/*! @} */
#endif /* __USB_H__ */

View File

@ -0,0 +1,488 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016, 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_MISC_H__
#define __USB_MISC_H__
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Define big endian */
#define USB_BIG_ENDIAN (0U)
/*! @brief Define little endian */
#define USB_LITTLE_ENDIAN (1U)
/*! @brief Define current endian */
#ifndef ENDIANNESS
#define ENDIANNESS USB_LITTLE_ENDIAN
#endif
/*! @brief Define default timeout value */
#if (defined(USE_RTOS) && (USE_RTOS > 0))
#define USB_OSA_WAIT_TIMEOUT (osaWaitForever_c)
#else
#define USB_OSA_WAIT_TIMEOUT (0U)
#endif /* (defined(USE_RTOS) && (USE_RTOS > 0)) */
/*! @brief Define USB printf */
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
extern int DbgConsole_Printf(const char *fmt_s, ...);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#ifndef __DSC__
#if defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE < 1)
#define usb_echo printf
#else
#define usb_echo DbgConsole_Printf
#endif
#else
#define usb_echo
#endif
#if defined(__ICCARM__)
#ifndef STRUCT_PACKED
#define STRUCT_PACKED __packed
#endif
#ifndef STRUCT_UNPACKED
#define STRUCT_UNPACKED
#endif
#elif defined(__GNUC__)
#ifndef STRUCT_PACKED
#define STRUCT_PACKED
#endif
#ifndef STRUCT_UNPACKED
#define STRUCT_UNPACKED __attribute__((__packed__))
#endif
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION))
#ifndef STRUCT_PACKED
#define STRUCT_PACKED _Pragma("pack(1U)")
#endif
#ifndef STRUCT_UNPACKED
#define STRUCT_UNPACKED _Pragma("pack()")
#endif
#endif
#define USB_SHORT_GET_LOW(x) (((uint16_t)x) & 0xFFU)
#define USB_SHORT_GET_HIGH(x) ((uint8_t)(((uint16_t)x) >> 8U) & 0xFFU)
#define USB_LONG_GET_BYTE0(x) ((uint8_t)(((uint32_t)(x))) & 0xFFU)
#define USB_LONG_GET_BYTE1(x) ((uint8_t)(((uint32_t)(x)) >> 8U) & 0xFFU)
#define USB_LONG_GET_BYTE2(x) ((uint8_t)(((uint32_t)(x)) >> 16U) & 0xFFU)
#define USB_LONG_GET_BYTE3(x) ((uint8_t)(((uint32_t)(x)) >> 24U) & 0xFFU)
#define USB_MEM4_ALIGN_MASK (0x03U)
/* accessory macro */
#define USB_MEM4_ALIGN(n) ((n + 3U) & (0xFFFFFFFCu))
#define USB_MEM32_ALIGN(n) ((n + 31U) & (0xFFFFFFE0u))
#define USB_MEM64_ALIGN(n) ((n + 63U) & (0xFFFFFFC0u))
/* big/little endian */
#define SWAP2BYTE_CONST(n) ((((n)&0x00FFU) << 8U) | (((n)&0xFF00U) >> 8U))
#define SWAP4BYTE_CONST(n) \
((((n)&0x000000FFU) << 24U) | (((n)&0x0000FF00U) << 8U) | (((n)&0x00FF0000U) >> 8U) | (((n)&0xFF000000U) >> 24U))
#define USB_ASSIGN_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
*((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \
*((uint8_t *)&(n) + 2) = *((uint8_t *)&(m) + 2); \
*((uint8_t *)&(n) + 3) = *((uint8_t *)&(m) + 3); \
}
#define USB_ASSIGN_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
*((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \
}
#define USB_ASSIGN_MACRO_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = (uint8_t)m; \
*((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \
*((uint8_t *)&(n) + 2) = (uint8_t)(m >> 16); \
*((uint8_t *)&(n) + 3) = (uint8_t)(m >> 24); \
}
#define USB_ASSIGN_MACRO_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = (uint8_t)m; \
*((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \
}
#if (ENDIANNESS == USB_BIG_ENDIAN)
#define USB_SHORT_TO_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_TO_LITTLE_ENDIAN(n) SWAP4BYTE_CONST(n)
#define USB_SHORT_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_SHORT_TO_BIG_ENDIAN(n) (n)
#define USB_LONG_TO_BIG_ENDIAN(n) (n)
#define USB_SHORT_FROM_BIG_ENDIAN(n) (n)
#define USB_LONG_FROM_BIG_ENDIAN(n) (n)
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[3] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \
(((uint8_t)n[0]) << 0U)))
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[3] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \
(((uint8_t)n[3]) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U)))
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[1] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U)))
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
*((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
*((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \
((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))))))
#else
#define USB_SHORT_TO_LITTLE_ENDIAN(n) (n)
#define USB_LONG_TO_LITTLE_ENDIAN(n) (n)
#define USB_SHORT_FROM_LITTLE_ENDIAN(n) (n)
#define USB_LONG_FROM_LITTLE_ENDIAN(n) (n)
#define USB_SHORT_TO_BIG_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_TO_BIG_ENDIAN(n) SWAP4BYTE_CONST(n)
#define USB_SHORT_FROM_BIG_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_FROM_BIG_ENDIAN(n) SWAP4BYTE_CONST(n)
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[3] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \
(((uint8_t)n[0]) << 0U)))
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[3] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \
(((uint8_t)n[3]) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U)))
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[1] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U)))
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
*((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
*((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \
((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))))))
#endif
/*
* The following MACROs (USB_GLOBAL, USB_BDT, USB_RAM_ADDRESS_ALIGNMENT, etc) are only used for USB device stack.
* The USB device global variables are put into the section m_usb_global and m_usb_bdt
* by using the MACRO USB_GLOBAL and USB_BDT. In this way, the USB device
* global variables can be linked into USB dedicated RAM by USB_STACK_USE_DEDICATED_RAM.
* The MACRO USB_STACK_USE_DEDICATED_RAM is used to decide the USB stack uses dedicated RAM or not. The value of
* the macro can be set as 0, USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL, or USB_STACK_DEDICATED_RAM_TYPE_BDT.
* The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL means USB device global variables, including USB_BDT and
* USB_GLOBAL, are put into the USB dedicated RAM. This feature can only be enabled when the USB dedicated RAM
* is not less than 2K Bytes.
* The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT means USB device global variables, only including USB_BDT, are put
* into the USB dedicated RAM, the USB_GLOBAL will be put into .bss section. This feature is used for some SOCs,
* the USB dedicated RAM size is not more than 512 Bytes.
*/
#define USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL 1
#define USB_STACK_DEDICATED_RAM_TYPE_BDT 2
#if defined(__ICCARM__)
#define USB_WEAK_VAR __attribute__((weak))
#define USB_WEAK_FUN __attribute__((weak))
/* disable misra 19.13 */
_Pragma("diag_suppress=Pm120")
#define USB_ALIGN_PRAGMA(x) _Pragma(#x)
_Pragma("diag_default=Pm120")
#define USB_RAM_ADDRESS_ALIGNMENT(n) USB_ALIGN_PRAGMA(data_alignment = n)
_Pragma("diag_suppress=Pm120")
#define USB_LINK_SECTION_PART(str) _Pragma(#str)
#define USB_LINK_DMA_INIT_DATA(sec) USB_LINK_SECTION_PART(location = #sec)
#define USB_LINK_USB_GLOBAL _Pragma("location = \"m_usb_global\"")
#define USB_LINK_USB_BDT _Pragma("location = \"m_usb_bdt\"")
#define USB_LINK_USB_GLOBAL_BSS
#define USB_LINK_USB_BDT_BSS
_Pragma("diag_default=Pm120")
#define USB_LINK_DMA_NONINIT_DATA _Pragma("location = \"m_usb_dma_noninit_data\"")
#define USB_LINK_NONCACHE_NONINIT_DATA _Pragma("location = \"NonCacheable\"")
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION))
#define USB_WEAK_VAR __attribute__((weak))
#define USB_WEAK_FUN __attribute__((weak))
#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n)))
#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec)))
#if defined(__CC_ARM)
#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global"))) __attribute__((zero_init))
#else
#define USB_LINK_USB_GLOBAL __attribute__((section(".bss.m_usb_global")))
#endif
#if defined(__CC_ARM)
#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt"))) __attribute__((zero_init))
#else
#define USB_LINK_USB_BDT __attribute__((section(".bss.m_usb_bdt")))
#endif
#define USB_LINK_USB_GLOBAL_BSS
#define USB_LINK_USB_BDT_BSS
#if defined(__CC_ARM)
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data"))) __attribute__((zero_init))
#else
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section(".bss.m_usb_dma_noninit_data")))
#endif
#if defined(__CC_ARM)
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable"))) __attribute__((zero_init))
#else
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section(".bss.NonCacheable")))
#endif
#elif defined(__GNUC__)
#define USB_WEAK_VAR __attribute__((weak))
#define USB_WEAK_FUN __attribute__((weak))
#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n)))
#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec)))
#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global, \"aw\", %nobits @")))
#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt, \"aw\", %nobits @")))
#define USB_LINK_USB_GLOBAL_BSS
#define USB_LINK_USB_BDT_BSS
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data, \"aw\", %nobits @")))
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable, \"aw\", %nobits @")))
#elif defined(__DSC__)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define USB_RAM_ADDRESS_ALIGNMENT(n)
#define USB_LINK_USB_BDT_BSS
#define USB_LINK_USB_GLOBAL_BSS
#else
#error The tool-chain is not supported.
#endif
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#if ((defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) && (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#elif (defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))
#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, 0)
#elif (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))
#define USB_CACHE_LINESIZE MAX(0, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#else
#define USB_CACHE_LINESIZE 4
#endif
#else
#define USB_CACHE_LINESIZE 4
#endif
#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
#define USB_DATA_ALIGN 64
#else
#define USB_DATA_ALIGN 4
#endif
#define USB_DATA_ALIGN_SIZE MAX(USB_CACHE_LINESIZE, USB_DATA_ALIGN)
#define USB_DATA_ALIGN_SIZE_MULTIPLE(n) ((n + USB_DATA_ALIGN_SIZE - 1U) & (~(USB_DATA_ALIGN_SIZE - 1U)))
#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL)
#define USB_GLOBAL USB_LINK_USB_GLOBAL
#define USB_BDT USB_LINK_USB_BDT
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE))
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA USB_LINK_USB_GLOBAL
#endif
#endif
#elif defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT)
#define USB_BDT USB_LINK_USB_BDT
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE))
#define USB_GLOBAL USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
#define USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA
#endif
#endif
#else
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA
#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE))
#define USB_GLOBAL USB_LINK_NONCACHE_NONINIT_DATA
#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
#define USB_BDT USB_LINK_USB_BDT_BSS
#define USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA
#endif
#endif
#endif
#define USB_DMA_NONINIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_INIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_INIT_SUB
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_DMA_DATA_NONCACHEABLE USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_DMA_DATA_NONCACHEABLE
#endif
#define USB_GLOBAL_DEDICATED_RAM USB_LINK_USB_GLOBAL
/* #define USB_RAM_ADDRESS_NONCACHEREG_ALIGNMENT(n, var) AT_NONCACHEABLE_SECTION_ALIGN(var, n) */
/* #define USB_RAM_ADDRESS_NONCACHEREG(var) AT_NONCACHEABLE_SECTION(var) */
#endif /* __USB_MISC_H__ */

View File

@ -0,0 +1,300 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_SPEC_H__
#define __USB_SPEC_H__
/*******************************************************************************
* Definitions
******************************************************************************/
/* USB speed (the value cannot be changed because EHCI QH use the value directly)*/
#define USB_SPEED_FULL (0x00U)
#define USB_SPEED_LOW (0x01U)
#define USB_SPEED_HIGH (0x02U)
#define USB_SPEED_SUPER (0x04U)
/* Set up packet structure */
typedef struct _usb_setup_struct
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} usb_setup_struct_t;
/* USB standard descriptor endpoint type */
#define USB_ENDPOINT_CONTROL (0x00U)
#define USB_ENDPOINT_ISOCHRONOUS (0x01U)
#define USB_ENDPOINT_BULK (0x02U)
#define USB_ENDPOINT_INTERRUPT (0x03U)
/* USB standard descriptor transfer direction (cannot change the value because iTD use the value directly) */
#define USB_OUT (0U)
#define USB_IN (1U)
/* USB standard descriptor length */
#define USB_DESCRIPTOR_LENGTH_DEVICE (0x12U)
#define USB_DESCRIPTOR_LENGTH_CONFIGURE (0x09U)
#define USB_DESCRIPTOR_LENGTH_INTERFACE (0x09U)
#define USB_DESCRIPTOR_LENGTH_ENDPOINT (0x07U)
#define USB_DESCRIPTOR_LENGTH_ENDPOINT_COMPANION (0x06U)
#define USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER (0x0AU)
#define USB_DESCRIPTOR_LENGTH_OTG_DESCRIPTOR (5U)
#define USB_DESCRIPTOR_LENGTH_BOS_DESCRIPTOR (5U)
#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_USB20_EXTENSION (0x07U)
#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_SUPERSPEED (0x0AU)
/* USB Device Capability Type Codes */
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_WIRELESS (0x01U)
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_USB20_EXTENSION (0x02U)
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_SUPERSPEED (0x03U)
/* USB standard descriptor type */
#define USB_DESCRIPTOR_TYPE_DEVICE (0x01U)
#define USB_DESCRIPTOR_TYPE_CONFIGURE (0x02U)
#define USB_DESCRIPTOR_TYPE_STRING (0x03U)
#define USB_DESCRIPTOR_TYPE_INTERFACE (0x04U)
#define USB_DESCRIPTOR_TYPE_ENDPOINT (0x05U)
#define USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER (0x06U)
#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION (0x07U)
#define USB_DESCRIPTOR_TYPE_INTERFAACE_POWER (0x08U)
#define USB_DESCRIPTOR_TYPE_OTG (0x09U)
#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION (0x0BU)
#define USB_DESCRIPTOR_TYPE_BOS (0x0F)
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY (0x10)
#define USB_DESCRIPTOR_TYPE_HID (0x21U)
#define USB_DESCRIPTOR_TYPE_HID_REPORT (0x22U)
#define USB_DESCRIPTOR_TYPE_HID_PHYSICAL (0x23U)
#define USB_DESCRIPTOR_TYPE_ENDPOINT_COMPANION (0x30U)
/* USB standard request type */
#define USB_REQUEST_TYPE_DIR_MASK (0x80U)
#define USB_REQUEST_TYPE_DIR_SHIFT (7U)
#define USB_REQUEST_TYPE_DIR_OUT (0x00U)
#define USB_REQUEST_TYPE_DIR_IN (0x80U)
#define USB_REQUEST_TYPE_TYPE_MASK (0x60U)
#define USB_REQUEST_TYPE_TYPE_SHIFT (5U)
#define USB_REQUEST_TYPE_TYPE_STANDARD (0U)
#define USB_REQUEST_TYPE_TYPE_CLASS (0x20U)
#define USB_REQUEST_TYPE_TYPE_VENDOR (0x40U)
#define USB_REQUEST_TYPE_RECIPIENT_MASK (0x1FU)
#define USB_REQUEST_TYPE_RECIPIENT_SHIFT (0U)
#define USB_REQUEST_TYPE_RECIPIENT_DEVICE (0x00U)
#define USB_REQUEST_TYPE_RECIPIENT_INTERFACE (0x01U)
#define USB_REQUEST_TYPE_RECIPIENT_ENDPOINT (0x02U)
#define USB_REQUEST_TYPE_RECIPIENT_OTHER (0x03U)
/* USB standard request */
#define USB_REQUEST_STANDARD_GET_STATUS (0x00U)
#define USB_REQUEST_STANDARD_CLEAR_FEATURE (0x01U)
#define USB_REQUEST_STANDARD_SET_FEATURE (0x03U)
#define USB_REQUEST_STANDARD_SET_ADDRESS (0x05U)
#define USB_REQUEST_STANDARD_GET_DESCRIPTOR (0x06U)
#define USB_REQUEST_STANDARD_SET_DESCRIPTOR (0x07U)
#define USB_REQUEST_STANDARD_GET_CONFIGURATION (0x08U)
#define USB_REQUEST_STANDARD_SET_CONFIGURATION (0x09U)
#define USB_REQUEST_STANDARD_GET_INTERFACE (0x0AU)
#define USB_REQUEST_STANDARD_SET_INTERFACE (0x0BU)
#define USB_REQUEST_STANDARD_SYNCH_FRAME (0x0CU)
/* USB standard request GET Status */
#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT (0U)
#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT (1U)
#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_MASK (0x01U)
#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_SHIFT (0U)
#define USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR (0xF000U)
/* USB standard request CLEAR/SET feature */
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT (0U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP (1U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE (2U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE (3U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_HNP_SUPPORT (4U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_ALT_HNP_SUPPORT (5U)
/* USB standard descriptor configure bmAttributes */
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK (0x80U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_SHIFT (7U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK (0x40U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT (6U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_MASK (0x20U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT (5U)
/* USB standard descriptor endpoint bmAttributes */
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK (0x80U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT (7U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT (0U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN (0x80U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK (0x0FU)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_SHFIT (0U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK (0x03U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_NUMBER_SHFIT (0U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_MASK (0x0CU)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SHFIT (2U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_NO_SYNC (0x00U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ASYNC (0x04U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ADAPTIVE (0x08U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SYNC (0x0CU)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_MASK (0x30U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_SHFIT (4U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_DATA_ENDPOINT (0x00U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_FEEDBACK_ENDPOINT (0x10U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_IMPLICIT_FEEDBACK_DATA_ENDPOINT (0x20U)
#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK (0x07FFu)
#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK (0x1800u)
#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT (11U)
/* USB standard descriptor otg bmAttributes */
#define USB_DESCRIPTOR_OTG_ATTRIBUTES_SRP_MASK (0x01u)
#define USB_DESCRIPTOR_OTG_ATTRIBUTES_HNP_MASK (0x02u)
#define USB_DESCRIPTOR_OTG_ATTRIBUTES_ADP_MASK (0x04u)
/* USB standard descriptor device capability usb20 extension bmAttributes */
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_MASK (0x02U)
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_SHIFT (1U)
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_MASK (0x04U)
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_SHIFT (2U)
/* Language structure */
typedef struct _usb_language
{
uint8_t **string; /* The Strings descriptor array */
uint32_t *length; /* The strings descriptor length array */
uint16_t languageId; /* The language id of current language */
} usb_language_t;
typedef struct _usb_language_list
{
uint8_t *languageString; /* The String 0U pointer */
uint32_t stringLength; /* The String 0U Length */
usb_language_t *languageList; /* The language list */
uint8_t count; /* The language count */
} usb_language_list_t;
typedef struct _usb_descriptor_common
{
uint8_t bLength; /* Size of this descriptor in bytes */
uint8_t bDescriptorType; /* DEVICE Descriptor Type */
uint8_t bData[1]; /* Data */
} usb_descriptor_common_t;
typedef struct _usb_descriptor_device
{
uint8_t bLength; /* Size of this descriptor in bytes */
uint8_t bDescriptorType; /* DEVICE Descriptor Type */
uint8_t bcdUSB[2]; /* UUSB Specification Release Number in Binary-Coded Decimal, e.g. 0x0200U */
uint8_t bDeviceClass; /* Class code */
uint8_t bDeviceSubClass; /* Sub-Class code */
uint8_t bDeviceProtocol; /* Protocol code */
uint8_t bMaxPacketSize0; /* Maximum packet size for endpoint zero */
uint8_t idVendor[2]; /* Vendor ID (assigned by the USB-IF) */
uint8_t idProduct[2]; /* Product ID (assigned by the manufacturer) */
uint8_t bcdDevice[2]; /* Device release number in binary-coded decimal */
uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */
uint8_t iProduct; /* Index of string descriptor describing product */
uint8_t iSerialNumber; /* Index of string descriptor describing the device serial number */
uint8_t bNumConfigurations; /* Number of possible configurations */
} usb_descriptor_device_t;
typedef struct _usb_descriptor_configuration
{
uint8_t bLength; /* Descriptor size in bytes = 9U */
uint8_t bDescriptorType; /* CONFIGURATION type = 2U or 7U */
uint8_t wTotalLength[2]; /* Length of concatenated descriptors */
uint8_t bNumInterfaces; /* Number of interfaces, this configuration. */
uint8_t bConfigurationValue; /* Value to set this configuration. */
uint8_t iConfiguration; /* Index to configuration string */
uint8_t bmAttributes; /* Configuration characteristics */
uint8_t bMaxPower; /* Maximum power from bus, 2 mA units */
} usb_descriptor_configuration_t;
typedef struct _usb_descriptor_interface
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} usb_descriptor_interface_t;
typedef struct _usb_descriptor_endpoint
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint8_t wMaxPacketSize[2];
uint8_t bInterval;
} usb_descriptor_endpoint_t;
typedef struct _usb_descriptor_endpoint_companion
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bMaxBurst;
uint8_t bmAttributes;
uint8_t wBytesPerInterval[2];
} usb_descriptor_endpoint_companion_t;
typedef struct _usb_descriptor_binary_device_object_store
{
uint8_t bLength; /* Descriptor size in bytes = 5U */
uint8_t bDescriptorType; /* BOS Descriptor type = 0FU*/
uint8_t wTotalLength[2]; /*Length of this descriptor and all of its sub descriptors*/
uint8_t bNumDeviceCaps; /*The number of separate device capability descriptors in the BOS*/
} usb_descriptor_bos_t;
typedef struct _usb_descriptor_usb20_extension
{
uint8_t bLength; /* Descriptor size in bytes = 7U */
uint8_t bDescriptorType; /* DEVICE CAPABILITY Descriptor type = 0x10U*/
uint8_t bDevCapabilityType; /*Length of this descriptor and all of its sub descriptors*/
uint8_t bmAttributes[4]; /*Bitmap encoding of supported device level features.*/
} usb_descriptor_usb20_extension_t;
typedef struct _usb_descriptor_super_speed_device_capability
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint8_t bmAttributes;
uint8_t wSpeedsSupported[2];
uint8_t bFunctionalitySupport;
uint8_t bU1DevExitLat;
uint8_t wU2DevExitLat[2];
} usb_bos_device_capability_susperspeed_desc_t;
typedef union _usb_descriptor_union
{
usb_descriptor_common_t common; /* Common descriptor */
usb_descriptor_device_t device; /* Device descriptor */
usb_descriptor_configuration_t configuration; /* Configuration descriptor */
usb_descriptor_interface_t interface; /* Interface descriptor */
usb_descriptor_endpoint_t endpoint; /* Endpoint descriptor */
usb_descriptor_endpoint_companion_t endpointCompanion; /* Endpoint companion descriptor */
} usb_descriptor_union_t;
#endif /* __USB_SPEC_H__ */

View File

@ -0,0 +1,275 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb.h"
#include "fsl_device_registers.h"
#include "usb_phy.h"
void *USB_EhciPhyGetBase(uint8_t controllerId)
{
void *usbPhyBase = NULL;
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
uint32_t instance;
uint32_t newinstance = 0;
uint32_t usbphy_base_temp[] = USBPHY_BASE_ADDRS;
uint32_t usbphy_base[] = USBPHY_BASE_ADDRS;
if (controllerId < kUSB_ControllerEhci0)
{
return NULL;
}
if ((controllerId == kUSB_ControllerEhci0) || (controllerId == kUSB_ControllerEhci1))
{
controllerId = controllerId - kUSB_ControllerEhci0;
}
else if ((controllerId == kUSB_ControllerLpcIp3511Hs0) || (controllerId == kUSB_ControllerLpcIp3511Hs1))
{
controllerId = controllerId - kUSB_ControllerLpcIp3511Hs0;
}
else if ((controllerId == kUSB_ControllerIp3516Hs0) || (controllerId == kUSB_ControllerIp3516Hs1))
{
controllerId = controllerId - kUSB_ControllerIp3516Hs0;
}
else
{
}
for (instance = 0; instance < (sizeof(usbphy_base_temp) / sizeof(usbphy_base_temp[0])); instance++)
{
if (usbphy_base_temp[instance])
{
usbphy_base[newinstance++] = usbphy_base_temp[instance];
}
}
if (controllerId > newinstance)
{
return NULL;
}
usbPhyBase = (void *)usbphy_base[controllerId];
#endif
return usbPhyBase;
}
/*!
* @brief ehci phy initialization.
*
* This function initialize ehci phy IP.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] freq the external input clock.
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
*
* @retval kStatus_USB_Success cancel successfully.
* @retval kStatus_USB_Error the freq value is incorrect.
*/
uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return kStatus_USB_Error;
}
#if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U))
ANATOP->HW_ANADIG_REG_3P0.RW =
(ANATOP->HW_ANADIG_REG_3P0.RW &
(~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) |
ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK;
ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET =
ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK;
#endif
#if (defined USB_ANALOG)
USB_ANALOG->INSTANCE[controllerId - kUSB_ControllerEhci0].CHRG_DETECT_SET =
USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1);
#endif
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
#endif
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
/* PWD register provides overall control of the PHY power state */
usbPhyBase->PWD = 0U;
if ((kUSB_ControllerIp3516Hs0 == controllerId) || (kUSB_ControllerIp3516Hs1 == controllerId) ||
(kUSB_ControllerLpcIp3511Hs0 == controllerId) || (kUSB_ControllerLpcIp3511Hs0 == controllerId))
{
usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK;
usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK;
}
if (NULL != phyConfig)
{
/* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
usbPhyBase->TX =
((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
(USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
}
#endif
return kStatus_USB_Success;
}
/*!
* @brief ehci phy initialization for suspend and resume.
*
* This function initialize ehci phy IP for suspend and resume.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] freq the external input clock.
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
*
* @retval kStatus_USB_Success cancel successfully.
* @retval kStatus_USB_Error the freq value is incorrect.
*/
uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return kStatus_USB_Error;
}
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
#endif
#if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U))
usbPhyBase->CTRL |= USBPHY_CTRL_AUTORESUME_EN_MASK;
#else
usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK;
#endif
usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK;
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
/* PWD register provides overall control of the PHY power state */
usbPhyBase->PWD = 0U;
#if (defined USBPHY_ANACTRL_PFD_CLKGATE_MASK)
/* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD
* pfd clock = 480MHz*18/N, where N=18~35
* Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode
*/
usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24); /* N=24 */
usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */
usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK;
usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK;
while (!(usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK))
{
}
#endif
if (NULL != phyConfig)
{
/* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
usbPhyBase->TX =
((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
(USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
}
#endif
return kStatus_USB_Success;
}
/*!
* @brief ehci phy de-initialization.
*
* This function de-initialize ehci phy IP.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
*/
void USB_EhciPhyDeinit(uint8_t controllerId)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return;
}
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* power down PLL */
usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */
#endif
usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */
#endif
}
/*!
* @brief ehci phy disconnect detection enable or disable.
*
* This function enable/disable host ehci disconnect detection.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] enable
* 1U - enable;
* 0U - disable;
*/
void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return;
}
if (enable)
{
usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
}
else
{
usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK);
}
#endif
}
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U))
void USB_PhyDeviceForceEnterFSMode(uint8_t controllerId, uint8_t enable)
{
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return;
}
if (enable)
{
uint32_t delay = 1000000;
usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
while ((usbPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK) && (delay))
{
delay--;
}
usbPhyBase->USB1_LOOPBACK_SET = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
}
else
{
usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
usbPhyBase->USB1_LOOPBACK_CLR = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
}
}
#endif
#endif

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_PHY_H__
#define __USB_PHY_H__
/*******************************************************************************
* Definitions
******************************************************************************/
typedef struct _usb_phy_config_struct
{
uint8_t D_CAL; /* Decode to trim the nominal 17.78mA current source */
uint8_t TXCAL45DP; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DP output pin */
uint8_t TXCAL45DM; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DM output pin */
} usb_phy_config_struct_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief EHCI PHY get USB phy bass address.
*
* This function is used to get USB phy bass address.
*
* @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
*
* @retval USB phy bass address.
*/
extern void *USB_EhciPhyGetBase(uint8_t controllerId);
/*!
* @brief EHCI PHY initialization.
*
* This function initializes the EHCI PHY IP.
*
* @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
* @param[in] freq The external input clock.
*
* @retval kStatus_USB_Success Cancel successfully.
* @retval kStatus_USB_Error The freq value is incorrect.
*/
extern uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig);
/*!
* @brief ehci phy initialization for suspend and resume.
*
* This function initialize ehci phy IP for suspend and resume.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] freq the external input clock.
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
*
* @retval kStatus_USB_Success cancel successfully.
* @retval kStatus_USB_Error the freq value is incorrect.
*/
extern uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig);
/*!
* @brief EHCI PHY deinitialization.
*
* This function deinitializes the EHCI PHY IP.
*
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
*/
extern void USB_EhciPhyDeinit(uint8_t controllerId);
/*!
* @brief EHCI PHY disconnect detection enable or disable.
*
* This function enable/disable the host EHCI disconnect detection.
*
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
* @param[in] enable
* 1U - enable;
* 0U - disable;
*/
extern void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable);
/*!
* @brief Force the PHY enter FS Mode
*
* on RT500 and RT600, the device doesn't enter FS Mode after vbus is invalide and the controller works as HS.
*
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
* @param[in] enable
* 1U - enable;
* 0U - disable;
*/
extern void USB_PhyDeviceForceEnterFSMode(uint8_t controllerId, uint8_t enable);
#if defined(__cplusplus)
}
#endif
#endif /* __USB_PHY_H__ */

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2018 NXP
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_OS_ABSTRACTION_H_
#define _FSL_OS_ABSTRACTION_H_
/*!
* @addtogroup osa_adapter
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "fsl_os_abstraction_mbed.h"
/*
* alloc the temporary memory to store the status
*/
#define OSA_SR_ALLOC() uint32_t osaCurrentSr;
/*
* Enter critical mode
*/
#define OSA_ENTER_CRITICAL() OSA_EnterCritical(&osaCurrentSr)
/*
* Exit critical mode and retore the previous mode
*/
#define OSA_EXIT_CRITICAL() OSA_ExitCritical(osaCurrentSr)
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Enter critical with nesting mode.
*
* @param sr Store current status and return to caller.
*/
void OSA_EnterCritical(uint32_t *sr);
/*!
* @brief Exit critical with nesting mode.
*
* @param sr Previous status to restore.
*/
void OSA_ExitCritical(uint32_t sr);
/*! @}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif

View File

@ -0,0 +1,29 @@
/*! *********************************************************************************
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2020 NXP
* All rights reserved.
*
*
* This is the source file for the OS Abstraction layer for freertos.
*
* SPDX-License-Identifier: BSD-3-Clause
********************************************************************************** */
/*! *********************************************************************************
*************************************************************************************
* Include
*************************************************************************************
********************************************************************************** */
#include "fsl_common.h"
#include "fsl_os_abstraction_mbed.h"
void OSA_EnterCritical(uint32_t *sr)
{
core_util_critical_section_enter();
}
void OSA_ExitCritical(uint32_t sr)
{
core_util_critical_section_exit();
}

View File

@ -0,0 +1,26 @@
/*! *********************************************************************************
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
********************************************************************************** */
#if !defined(__FSL_OS_ABSTRACTION_MBED_H__)
#define __FSL_OS_ABSTRACTION_MBED_H__
#include "mbed_critical.h"
/*!
* @addtogroup os_abstraction_free_rtos
* @{
*/
/*******************************************************************************
* Declarations
******************************************************************************/
/*! @brief Constant to pass as timeout value in order to wait indefinitely. */
#define OSA_WAIT_FOREVER 0xFFFFFFFFU
/*! @brief OSA's time range in millisecond, OSA time wraps if exceeds this value. */
#define FSL_OSA_TIME_RANGE 0xFFFFFFFFU
#endif // __FSL_OS_ABSTRACTION_MBED_H__

View File

@ -4153,7 +4153,8 @@
"EVK",
"MIMXRT1050",
"IMX",
"NXP_EMAC"
"NXP_EMAC",
"USB"
],
"is_disk_virtual": true,
"macros": [
@ -4169,7 +4170,8 @@
"__STARTUP_INITIALIZE_RAMFUNCTION",
"__STARTUP_INITIALIZE_NONCACHEDATA",
"MBED_MPU_CUSTOM",
"MBED_TICKLESS"
"MBED_TICKLESS",
"DATA_SECTION_IS_CACHEABLE=1"
],
"components_add": [
"FLASHIAP"
@ -4201,7 +4203,8 @@
"STDIO_MESSAGES",
"TRNG",
"WATCHDOG",
"FLASH"
"FLASH",
"USBDEVICE"
],
"release_versions": [
"5"