2022-04-08 14:46:35 +00:00
|
|
|
/*
|
|
|
|
* 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_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U))
|
|
|
|
#include "usb_device_mtp.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_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U))
|
|
|
|
{USB_DeviceMtpInit, USB_DeviceMtpDeinit, USB_DeviceMtpEvent, kUSB_DeviceClassTypeMtp},
|
|
|
|
#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
|
|
|
|
|
|
|
|
/* please make sure the following member is in the end of s_UsbDeviceClassInterfaceMap*/
|
|
|
|
{(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;
|
|
|
|
usb_status_t status = 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 < (ARRAY_SIZE(s_UsbDeviceClassInterfaceMap) - 1U); 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)
|
|
|
|
{
|
2024-03-18 15:15:10 +00:00
|
|
|
/* For composite device, it should return kStatus_USB_Success once a valid request has been handled
|
|
|
|
*/
|
|
|
|
if (kStatus_USB_Success == status)
|
|
|
|
{
|
|
|
|
return kStatus_USB_Success;
|
|
|
|
}
|
2022-04-08 14:46:35 +00:00
|
|
|
return kStatus_USB_InvalidRequest;
|
|
|
|
}
|
2024-03-18 15:15:10 +00:00
|
|
|
/* For composite device, save kStatus_USB_Success status once a valid request has been handled */
|
2022-04-08 14:46:35 +00:00
|
|
|
if (kStatus_USB_Success == errorReturn)
|
|
|
|
{
|
|
|
|
status = kStatus_USB_Success;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* @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 status;
|
|
|
|
|
|
|
|
/* Get the common class handle according to the device handle. */
|
|
|
|
status = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle);
|
|
|
|
if (kStatus_USB_Success != status)
|
|
|
|
{
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((uint32_t)kUSB_DeviceEventBusReset == event)
|
|
|
|
{
|
|
|
|
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
|
|
|
|
if ((kStatus_USB_Success != USB_DeviceControlPipeInit(handle, classHandle)) ||
|
|
|
|
(kStatus_USB_Success != USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle)))
|
|
|
|
{
|
|
|
|
return kStatus_USB_Error;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
/* Initialize the control pipes */
|
|
|
|
(void)USB_DeviceControlPipeInit(handle, classHandle);
|
|
|
|
|
|
|
|
/* Notify the classes the USB bus reset signal detected. */
|
|
|
|
(void)USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the application device callback function. deviceCallback is from the second parameter of
|
|
|
|
USB_DeviceClassInit */
|
|
|
|
status = classHandle->configList->deviceCallback(handle, event, param);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* @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;
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
|
|
|
|
if (((kStatus_USB_Success != USB_DeviceDeinit(classHandle->handle))) ||
|
|
|
|
(kStatus_USB_Success != USB_DeviceClassFreeHandle(controllerId)))
|
|
|
|
{
|
|
|
|
return kStatus_USB_Error;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void)USB_DeviceDeinit(classHandle->handle);
|
|
|
|
(void)USB_DeviceClassFreeHandle(controllerId);
|
|
|
|
#endif
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
|
|
|
|
error = s_UsbDeviceClassInterfaceMap[mapIndex].classInit(
|
|
|
|
controllerId, &classHandle->configList->config[classIndex],
|
|
|
|
&classHandle->configList->config[classIndex].classHandle);
|
|
|
|
if (kStatus_USB_Success != error)
|
|
|
|
{
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void)s_UsbDeviceClassInterfaceMap[mapIndex].classInit(
|
|
|
|
controllerId, &classHandle->configList->config[classIndex],
|
|
|
|
&classHandle->configList->config[classIndex].classHandle);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*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;
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
|
|
|
|
error = s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit(
|
|
|
|
classHandle->configList->config[classIndex].classHandle);
|
|
|
|
if (kStatus_USB_Success != error)
|
|
|
|
{
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void)s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit(
|
|
|
|
classHandle->configList->config[classIndex].classHandle);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* De-initialize the USB device stack. */
|
|
|
|
error = USB_DeviceDeinit(classHandle->handle);
|
|
|
|
if (kStatus_USB_Success == error)
|
|
|
|
{
|
|
|
|
/* Free the common class handle. */
|
|
|
|
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
|
|
|
|
if (kStatus_USB_Success != USB_DeviceClassFreeHandle(controllerId))
|
|
|
|
{
|
|
|
|
return kStatus_USB_Error;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void)USB_DeviceClassFreeHandle(controllerId);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
|
|
|
|
/*!
|
|
|
|
* @brief Get the USB SOF count.
|
|
|
|
*
|
|
|
|
* This function is used to get the USB SOF count.
|
|
|
|
*
|
|
|
|
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
|
|
|
|
* @param currentFrameCount It is an OUT parameter, return current sof count of the controller.
|
|
|
|
* HS: micro frame count, FS: frame count
|
|
|
|
*
|
|
|
|
* @return A USB error code or kStatus_USB_Success.
|
|
|
|
*/
|
|
|
|
usb_status_t USB_DeviceClassGetCurrentFrameCount(uint8_t controllerId, /*!< [IN] Controller ID */
|
|
|
|
uint32_t *currentFrameCount /*!< [OUT] Current frame count */
|
|
|
|
)
|
|
|
|
{
|
|
|
|
usb_device_common_class_struct_t *classHandle;
|
|
|
|
usb_status_t 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 frame count. */
|
|
|
|
error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusGetCurrentFrameCount, currentFrameCount);
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
#endif /* USB_DEVICE_CONFIG_GET_SOF_COUNT */
|
|
|
|
|
|
|
|
#endif /* USB_DEVICE_CONFIG_NUM */
|