MCUXpresso_MIMXRT1052xxxxB/boards/evkbimxrt1050/usb_examples/usb_device_hid_generic/freertos/hid_generic.c
2022-04-08 22:46:35 +08:00

485 lines
18 KiB
C

/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
/*${standard_header_anchor}*/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_hid.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#include "hid_generic.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
#include "fsl_sysmpu.h"
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#include "usb_phy.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
void BOARD_InitHardware(void);
void USB_DeviceClockInit(void);
void USB_DeviceIsrEnable(void);
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle);
#endif
static usb_status_t USB_DeviceHidGenericCallback(class_handle_t handle, uint32_t event, void *param);
static usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param);
static void USB_DeviceApplicationInit(void);
/*******************************************************************************
* Variables
******************************************************************************/
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint32_t s_GenericBuffer0[USB_HID_GENERIC_OUT_BUFFER_LENGTH >> 2];
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint32_t s_GenericBuffer1[USB_HID_GENERIC_OUT_BUFFER_LENGTH >> 2];
usb_hid_generic_struct_t g_UsbDeviceHidGeneric;
extern usb_device_class_struct_t g_UsbDeviceHidGenericConfig;
/* Set class configurations */
usb_device_class_config_struct_t g_UsbDeviceHidConfig[1] = {{
USB_DeviceHidGenericCallback, /* HID generic class callback pointer */
(class_handle_t)NULL, /* The HID class handle, This field is set by USB_DeviceClassInit */
&g_UsbDeviceHidGenericConfig, /* The HID mouse configuration, including class code, subcode, and protocol, class
type,
transfer type, endpoint address, max packet size, etc.*/
}};
/* Set class configuration list */
usb_device_class_config_list_struct_t g_UsbDeviceHidConfigList = {
g_UsbDeviceHidConfig, /* Class configurations */
USB_DeviceCallback, /* Device callback pointer */
1U, /* Class count */
};
/*******************************************************************************
* Code
******************************************************************************/
void USB_OTG1_IRQHandler(void)
{
USB_DeviceEhciIsrFunction(g_UsbDeviceHidGeneric.deviceHandle);
}
void USB_OTG2_IRQHandler(void)
{
USB_DeviceEhciIsrFunction(g_UsbDeviceHidGeneric.deviceHandle);
}
void USB_DeviceClockInit(void)
{
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL,
BOARD_USB_PHY_TXCAL45DP,
BOARD_USB_PHY_TXCAL45DM,
};
if (CONTROLLER_ID == kUSB_ControllerEhci0)
{
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
}
else
{
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
}
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ, &phyConfig);
}
void USB_DeviceIsrEnable(void)
{
uint8_t irqNumber;
uint8_t usbDeviceEhciIrq[] = USBHS_IRQS;
irqNumber = usbDeviceEhciIrq[CONTROLLER_ID - kUSB_ControllerEhci0];
/* Install isr, set priority, and enable IRQ. */
NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
EnableIRQ((IRQn_Type)irqNumber);
}
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle)
{
USB_DeviceEhciTaskFunction(deviceHandle);
}
#endif
/* The hid class callback */
static usb_status_t USB_DeviceHidGenericCallback(class_handle_t handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_InvalidRequest;
#if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
usb_device_endpoint_callback_message_struct_t *ep_cb_param;
ep_cb_param = (usb_device_endpoint_callback_message_struct_t *)param;
#endif
switch (event)
{
case kUSB_DeviceHidEventSendResponse:
error = kStatus_USB_Success;
break;
case kUSB_DeviceHidEventRecvResponse:
if (g_UsbDeviceHidGeneric.attach
#if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
&& (ep_cb_param->length != (USB_CANCELLED_TRANSFER_LENGTH))
#endif
)
{
USB_DeviceHidSend(g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_IN,
(uint8_t *)&g_UsbDeviceHidGeneric.buffer[g_UsbDeviceHidGeneric.bufferIndex][0],
USB_HID_GENERIC_OUT_BUFFER_LENGTH);
g_UsbDeviceHidGeneric.bufferIndex ^= 1U;
return USB_DeviceHidRecv(g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_OUT,
(uint8_t *)&g_UsbDeviceHidGeneric.buffer[g_UsbDeviceHidGeneric.bufferIndex][0],
USB_HID_GENERIC_OUT_BUFFER_LENGTH);
}
break;
case kUSB_DeviceHidEventGetReport:
case kUSB_DeviceHidEventSetReport:
case kUSB_DeviceHidEventRequestReportBuffer:
break;
case kUSB_DeviceHidEventGetIdle:
case kUSB_DeviceHidEventGetProtocol:
case kUSB_DeviceHidEventSetIdle:
case kUSB_DeviceHidEventSetProtocol:
error = kStatus_USB_Success;
break;
default:
break;
}
return error;
}
/* The device callback */
static usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t *temp8 = (uint8_t *)param;
uint16_t *temp16 = (uint16_t *)param;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
/* USB bus reset signal detected */
g_UsbDeviceHidGeneric.attach = 0U;
g_UsbDeviceHidGeneric.currentConfiguration = 0U;
error = kStatus_USB_Success;
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
/* Get USB speed to configure the device, including max packet size and interval of the endpoints. */
if (kStatus_USB_Success == USB_DeviceClassGetSpeed(CONTROLLER_ID, &g_UsbDeviceHidGeneric.speed))
{
USB_DeviceSetSpeed(handle, g_UsbDeviceHidGeneric.speed);
}
#endif
}
break;
case kUSB_DeviceEventSetConfiguration:
if (0U == (*temp8))
{
g_UsbDeviceHidGeneric.attach = 0U;
g_UsbDeviceHidGeneric.currentConfiguration = 0U;
error = kStatus_USB_Success;
}
else if (USB_HID_GENERIC_CONFIGURE_INDEX == (*temp8))
{
/* Set device configuration request */
g_UsbDeviceHidGeneric.attach = 1U;
g_UsbDeviceHidGeneric.currentConfiguration = *temp8;
error =
USB_DeviceHidRecv(g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_OUT,
(uint8_t *)&g_UsbDeviceHidGeneric.buffer[g_UsbDeviceHidGeneric.bufferIndex][0],
USB_HID_GENERIC_OUT_BUFFER_LENGTH);
}
else
{
/* no action required, the default return value is kStatus_USB_InvalidRequest. */
}
break;
case kUSB_DeviceEventSetInterface:
if (g_UsbDeviceHidGeneric.attach)
{
/* Set device interface request */
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU);
#if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
/* If a device only supports a default setting for the specified interface, then a STALL may
be returned in the Status stage of the request. */
if (1U == USB_HID_GENERIC_INTERFACE_ALTERNATE_COUNT)
{
return kStatus_USB_InvalidRequest;
}
else if (interface < USB_HID_GENERIC_INTERFACE_COUNT)
#else
if (interface < USB_HID_GENERIC_INTERFACE_COUNT)
#endif
{
if (alternateSetting < USB_HID_GENERIC_INTERFACE_ALTERNATE_COUNT)
{
g_UsbDeviceHidGeneric.currentInterfaceAlternateSetting[interface] = alternateSetting;
if (alternateSetting == USB_HID_GENERIC_INTERFACE_ALTERNATE_0)
{
error = USB_DeviceHidRecv(
g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_OUT,
(uint8_t *)&g_UsbDeviceHidGeneric.buffer[g_UsbDeviceHidGeneric.bufferIndex][0],
USB_HID_GENERIC_OUT_BUFFER_LENGTH);
}
}
}
#if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
else
{
/* no action */
}
#endif
}
break;
case kUSB_DeviceEventGetConfiguration:
if (param)
{
/* Get current configuration request */
*temp8 = g_UsbDeviceHidGeneric.currentConfiguration;
error = kStatus_USB_Success;
}
break;
case kUSB_DeviceEventGetInterface:
if (param)
{
/* Get current alternate setting of the interface request */
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
#if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
/* If a device only supports a default setting for the specified interface, then a STALL may
be returned in the Status stage of the request. */
if (1U == USB_HID_GENERIC_INTERFACE_ALTERNATE_COUNT)
{
return kStatus_USB_InvalidRequest;
}
else if (interface < USB_HID_GENERIC_INTERFACE_COUNT)
{
*temp16 = (*temp16 & 0xFF00U) | g_UsbDeviceHidGeneric.currentInterfaceAlternateSetting[interface];
error = kStatus_USB_Success;
}
else
{
/* no action */
}
#else
if (interface < USB_HID_GENERIC_INTERFACE_COUNT)
{
*temp16 = (*temp16 & 0xFF00U) | g_UsbDeviceHidGeneric.currentInterfaceAlternateSetting[interface];
error = kStatus_USB_Success;
}
#endif
}
break;
case kUSB_DeviceEventGetDeviceDescriptor:
if (param)
{
/* Get device descriptor request */
error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetConfigurationDescriptor:
if (param)
{
/* Get device configuration descriptor request */
error = USB_DeviceGetConfigurationDescriptor(handle,
(usb_device_get_configuration_descriptor_struct_t *)param);
}
break;
#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
case kUSB_DeviceEventGetDeviceQualifierDescriptor:
if (param)
{
/* Get device descriptor request */
error = USB_DeviceGetDeviceQualifierDescriptor(
handle, (usb_device_get_device_qualifier_descriptor_struct_t *)param);
}
break;
#endif
case kUSB_DeviceEventGetStringDescriptor:
if (param)
{
/* Get device string descriptor request */
error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetHidDescriptor:
if (param)
{
/* Get hid descriptor request */
error = USB_DeviceGetHidDescriptor(handle, (usb_device_get_hid_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetHidReportDescriptor:
if (param)
{
/* Get hid report descriptor request */
error =
USB_DeviceGetHidReportDescriptor(handle, (usb_device_get_hid_report_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetHidPhysicalDescriptor:
if (param)
{
/* Get hid physical descriptor request */
error = USB_DeviceGetHidPhysicalDescriptor(handle,
(usb_device_get_hid_physical_descriptor_struct_t *)param);
}
break;
#if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
case kUSB_DeviceEventSetRemoteWakeup:
if (param)
{
g_UsbDeviceHidGeneric.remoteWakeup = *temp8;
error = kStatus_USB_Success;
}
break;
#endif
#endif
default:
break;
}
return error;
}
static void USB_DeviceApplicationInit(void)
{
USB_DeviceClockInit();
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
SYSMPU_Enable(SYSMPU, 0);
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
/* Set HID generic to default state */
g_UsbDeviceHidGeneric.speed = USB_SPEED_FULL;
g_UsbDeviceHidGeneric.attach = 0U;
g_UsbDeviceHidGeneric.hidHandle = (class_handle_t)NULL;
g_UsbDeviceHidGeneric.deviceHandle = NULL;
g_UsbDeviceHidGeneric.buffer[0] = (uint8_t *)&s_GenericBuffer0[0];
g_UsbDeviceHidGeneric.buffer[1] = (uint8_t *)&s_GenericBuffer1[0];
/* Initialize the usb stack and class drivers */
if (kStatus_USB_Success !=
USB_DeviceClassInit(CONTROLLER_ID, &g_UsbDeviceHidConfigList, &g_UsbDeviceHidGeneric.deviceHandle))
{
usb_echo("USB device HID generic failed\r\n");
return;
}
else
{
usb_echo("USB device HID generic demo\r\n");
/* Get the HID mouse class handle */
g_UsbDeviceHidGeneric.hidHandle = g_UsbDeviceHidConfigList.config->classHandle;
}
USB_DeviceIsrEnable();
/* Start USB device HID generic */
/*Add one delay here to make the DP pull down long enough to allow host to detect the previous disconnection.*/
SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
USB_DeviceRun(g_UsbDeviceHidGeneric.deviceHandle);
}
#if defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0)
void USB_DeviceTask(void *handle)
{
while (1U)
{
USB_DeviceTaskFn(handle);
}
}
#endif
void APP_task(void *handle)
{
USB_DeviceApplicationInit();
#if USB_DEVICE_CONFIG_USE_TASK
if (g_UsbDeviceHidGeneric.deviceHandle)
{
if (xTaskCreate(USB_DeviceTask, /* pointer to the task */
"usb device task", /* task name for kernel awareness debugging */
5000L / sizeof(portSTACK_TYPE), /* task stack size */
g_UsbDeviceHidGeneric.deviceHandle, /* optional task startup argument */
5U, /* initial priority */
&g_UsbDeviceHidGeneric.deviceTaskHandle /* optional task handle to create */
) != pdPASS)
{
usb_echo("usb device task create failed!\r\n");
return;
}
}
#endif
while (1U)
{
}
}
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION)) || defined(__GNUC__)
int main(void)
#else
void main(void)
#endif
{
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
if (xTaskCreate(APP_task, /* pointer to the task */
"app task", /* task name for kernel awareness debugging */
5000L / sizeof(portSTACK_TYPE), /* task stack size */
&g_UsbDeviceHidGeneric, /* optional task startup argument */
4U, /* initial priority */
&g_UsbDeviceHidGeneric.applicationTaskHandle /* optional task handle to create */
) != pdPASS)
{
usb_echo("app task create failed!\r\n");
#if (defined(__CC_ARM) || (defined(__ARMCC_VERSION)) || defined(__GNUC__))
return 1U;
#else
return;
#endif
}
vTaskStartScheduler();
#if (defined(__CC_ARM) || (defined(__ARMCC_VERSION)) || defined(__GNUC__))
return 1U;
#endif
}