770 lines
24 KiB
C
770 lines
24 KiB
C
/*
|
|
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016 - 2017, 2019 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include "usb_device_config.h"
|
|
#include "usb.h"
|
|
#include "usb_device.h"
|
|
|
|
#include "usb_device_hid.h"
|
|
#include "usb_device_ch9.h"
|
|
#include "usb_device_descriptor.h"
|
|
|
|
#include "fsl_device_registers.h"
|
|
#include "mouse.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 */
|
|
|
|
#include "usb_phy.h"
|
|
#include "fsl_pit.h"
|
|
#include "fsl_gpc.h"
|
|
#include "fsl_adapter_timer.h"
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
void USB_WaitClockLocked(void);
|
|
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_DeviceHidMouseAction(void);
|
|
static usb_status_t USB_DeviceHidInterruptIn(usb_device_handle deviceHandle,
|
|
usb_device_endpoint_callback_message_struct_t *event,
|
|
void *arg);
|
|
static void USB_DeviceApplicationInit(void);
|
|
|
|
void BOARD_InitPins(void);
|
|
void BOARD_DeinitPins(void);
|
|
void SW_IntControl(uint8_t enable);
|
|
char *SW_GetName(void);
|
|
void HW_TimerControl(uint8_t enable);
|
|
void USB_LowpowerModeInit(void);
|
|
void USB_PreLowpowerMode(void);
|
|
uint8_t USB_EnterLowpowerMode(void);
|
|
void USB_PostLowpowerMode(void);
|
|
void USB_ControllerSuspended(void);
|
|
void USB_WaitClockLocked(void);
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
#define TIMER_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_OscClk)
|
|
extern usb_hid_mouse_struct_t g_UsbDeviceHidMouse;
|
|
uint32_t g_halTimerHandle[(HAL_TIMER_HANDLE_SIZE + 3) / 4];
|
|
#if ((defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE)) && (FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE > 0U))
|
|
static uint32_t g_savedPrimask;
|
|
#endif
|
|
|
|
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_SetupOutBuffer[8];
|
|
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_MouseBuffer[USB_HID_MOUSE_REPORT_LENGTH];
|
|
usb_hid_mouse_struct_t g_UsbDeviceHidMouse;
|
|
|
|
extern uint8_t g_UsbDeviceCurrentConfigure;
|
|
extern uint8_t g_UsbDeviceInterface[USB_HID_MOUSE_INTERFACE_COUNT];
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
|
|
/*!
|
|
* @brief De-initialize all pins used in this example
|
|
*
|
|
* @param disablePortClockAfterInit disable port clock after pin
|
|
* initialization or not.
|
|
*/
|
|
void BOARD_DeinitPins(void)
|
|
{
|
|
}
|
|
void BOARD_USER_BUTTON_IRQ_HANDLER(void)
|
|
{
|
|
/* Clear external interrupt flag. */
|
|
GPIO_PortClearInterruptFlags(BOARD_USER_BUTTON_GPIO, 1U << BOARD_USER_BUTTON_GPIO_PIN);
|
|
g_UsbDeviceHidMouse.selfWakeup = 1U;
|
|
}
|
|
void SW_IntControl(uint8_t enable)
|
|
{
|
|
}
|
|
void SW_Callback(void *param)
|
|
{
|
|
g_UsbDeviceHidMouse.selfWakeup = 1U;
|
|
SW_IntControl(0);
|
|
}
|
|
void SW_Init(void)
|
|
{
|
|
NVIC_SetPriority(BOARD_USER_BUTTON_IRQ, 1U);
|
|
NVIC_EnableIRQ(BOARD_USER_BUTTON_IRQ);
|
|
}
|
|
char *SW_GetName(void)
|
|
{
|
|
return BOARD_USER_BUTTON_NAME;
|
|
}
|
|
void HW_TimerCallback(void *param)
|
|
{
|
|
g_UsbDeviceHidMouse.hwTick++;
|
|
USB_DeviceUpdateHwTick(g_UsbDeviceHidMouse.deviceHandle, g_UsbDeviceHidMouse.hwTick);
|
|
}
|
|
void HW_TimerInit(void)
|
|
{
|
|
hal_timer_config_t halTimerConfig;
|
|
halTimerConfig.timeout = 1000;
|
|
halTimerConfig.srcClock_Hz = TIMER_SOURCE_CLOCK;
|
|
halTimerConfig.instance = 0U;
|
|
hal_timer_handle_t halTimerHandle = &g_halTimerHandle[0];
|
|
HAL_TimerInit(halTimerHandle, &halTimerConfig);
|
|
HAL_TimerInstallCallback(halTimerHandle, HW_TimerCallback, NULL);
|
|
}
|
|
void HW_TimerControl(uint8_t enable)
|
|
{
|
|
if (enable)
|
|
{
|
|
HAL_TimerEnable(g_halTimerHandle);
|
|
}
|
|
else
|
|
{
|
|
HAL_TimerDisable(g_halTimerHandle);
|
|
}
|
|
}
|
|
void USB_LowpowerModeInit(void)
|
|
{
|
|
#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_PHY) && (FSL_FEATURE_SIM_OPT_HAS_USB_PHY > 0))
|
|
SIM->SOPT2 |= SIM_SOPT2_USBSLSRC_MASK;
|
|
#endif
|
|
SW_Init();
|
|
HW_TimerInit();
|
|
}
|
|
void USB_PreLowpowerMode(void)
|
|
{
|
|
}
|
|
/*
|
|
* Execute the instrument to enter low power.
|
|
*/
|
|
#if ((defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE)) && (FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE > 0U))
|
|
AT_QUICKACCESS_SECTION_CODE(void stop(void));
|
|
#endif
|
|
void stop(void)
|
|
{
|
|
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
|
#if ((defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE)) && (FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE > 0U))
|
|
g_savedPrimask = DisableGlobalIRQ();
|
|
__DSB();
|
|
__ISB();
|
|
#endif
|
|
__asm("WFI");
|
|
#if ((defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE)) && (FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE > 0U))
|
|
CCM_ANALOG->PFD_480 |= CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK;
|
|
CCM_ANALOG->PFD_480 &= ~CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK;
|
|
EnableGlobalIRQ(g_savedPrimask);
|
|
__DSB();
|
|
__ISB();
|
|
#endif
|
|
}
|
|
/*
|
|
* Enter the LowPower mode.
|
|
*/
|
|
void APP_LowPower_EnterLowPower(void)
|
|
{
|
|
#if ((defined USB_SUSPEND_RESUME_WAKEUP_SYSTEM_RESET) && (USB_SUSPEND_RESUME_WAKEUP_SYSTEM_RESET))
|
|
CLOCK_SetMode(kCLOCK_ModeWait);
|
|
#else
|
|
CLOCK_SetMode(kCLOCK_ModeStop);
|
|
#endif
|
|
stop();
|
|
}
|
|
uint8_t USB_EnterLowpowerMode(void)
|
|
{
|
|
APP_LowPower_EnterLowPower();
|
|
return 0;
|
|
}
|
|
void USB_WaitClockLocked(void)
|
|
{
|
|
}
|
|
void USB_PostLowpowerMode(void)
|
|
{
|
|
USB_WaitClockLocked();
|
|
}
|
|
void USB_ControllerSuspended(void)
|
|
{
|
|
}
|
|
|
|
void USB_OTG1_IRQHandler(void)
|
|
{
|
|
USB_DeviceEhciIsrFunction(g_UsbDeviceHidMouse.deviceHandle);
|
|
}
|
|
|
|
void USB_OTG2_IRQHandler(void)
|
|
{
|
|
USB_DeviceEhciIsrFunction(g_UsbDeviceHidMouse.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_EhciLowPowerPhyInit(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
|
|
|
|
/* Update mouse pointer location. Draw a rectangular rotation*/
|
|
static usb_status_t USB_DeviceHidMouseAction(void)
|
|
{
|
|
static int8_t x = 0U;
|
|
static int8_t y = 0U;
|
|
enum
|
|
{
|
|
RIGHT,
|
|
DOWN,
|
|
LEFT,
|
|
UP
|
|
};
|
|
static uint8_t dir = RIGHT;
|
|
|
|
switch (dir)
|
|
{
|
|
case RIGHT:
|
|
/* Move right. Increase X value. */
|
|
g_UsbDeviceHidMouse.buffer[1] = 2U;
|
|
g_UsbDeviceHidMouse.buffer[2] = 0U;
|
|
x++;
|
|
if (x > 99U)
|
|
{
|
|
dir++;
|
|
}
|
|
break;
|
|
case DOWN:
|
|
/* Move down. Increase Y value. */
|
|
g_UsbDeviceHidMouse.buffer[1] = 0U;
|
|
g_UsbDeviceHidMouse.buffer[2] = 2U;
|
|
y++;
|
|
if (y > 99U)
|
|
{
|
|
dir++;
|
|
}
|
|
break;
|
|
case LEFT:
|
|
/* Move left. Discrease X value. */
|
|
g_UsbDeviceHidMouse.buffer[1] = (uint8_t)(-2);
|
|
g_UsbDeviceHidMouse.buffer[2] = 0U;
|
|
x--;
|
|
if (x < 2U)
|
|
{
|
|
dir++;
|
|
}
|
|
break;
|
|
case UP:
|
|
/* Move up. Discrease Y value. */
|
|
g_UsbDeviceHidMouse.buffer[1] = 0U;
|
|
g_UsbDeviceHidMouse.buffer[2] = (uint8_t)(-2);
|
|
y--;
|
|
if (y < 2U)
|
|
{
|
|
dir = RIGHT;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
/* Send mouse report to the host */
|
|
return USB_DeviceSendRequest(g_UsbDeviceHidMouse.deviceHandle, USB_HID_MOUSE_ENDPOINT_IN,
|
|
g_UsbDeviceHidMouse.buffer, USB_HID_MOUSE_REPORT_LENGTH);
|
|
}
|
|
|
|
/* HID mouse interrupt IN pipe callback */
|
|
static usb_status_t USB_DeviceHidInterruptIn(usb_device_handle deviceHandle,
|
|
usb_device_endpoint_callback_message_struct_t *event,
|
|
void *arg)
|
|
{
|
|
/* Resport sent */
|
|
if (g_UsbDeviceHidMouse.attach)
|
|
{
|
|
/* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
|
|
if ((NULL != event) && (event->length == USB_CANCELLED_TRANSFER_LENGTH))
|
|
{
|
|
return kStatus_USB_Error;
|
|
}
|
|
return USB_DeviceHidMouseAction();
|
|
}
|
|
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
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;
|
|
|
|
switch (event)
|
|
{
|
|
case kUSB_DeviceEventBusReset:
|
|
{
|
|
/* USB bus reset signal detected */
|
|
/* Initialize the control IN and OUT pipes */
|
|
USB_DeviceControlPipeInit(g_UsbDeviceHidMouse.deviceHandle);
|
|
g_UsbDeviceHidMouse.attach = 0U;
|
|
g_UsbDeviceHidMouse.remoteWakeup = 0U;
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseIdle;
|
|
g_UsbDeviceHidMouse.isResume = 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_DeviceGetStatus(g_UsbDeviceHidMouse.deviceHandle, kUSB_DeviceStatusSpeed,
|
|
&g_UsbDeviceHidMouse.speed))
|
|
{
|
|
USB_DeviceSetSpeed(g_UsbDeviceHidMouse.speed);
|
|
}
|
|
#endif
|
|
}
|
|
break;
|
|
#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
|
|
case kUSB_DeviceEventAttach:
|
|
{
|
|
error = kStatus_USB_Success;
|
|
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) || \
|
|
(defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U))
|
|
#else
|
|
/*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_UsbDeviceHidMouse.deviceHandle);
|
|
#endif
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventDetach:
|
|
{
|
|
g_UsbDeviceHidMouse.attach = 0;
|
|
error = kStatus_USB_Success;
|
|
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) || \
|
|
(defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U))
|
|
|
|
#else
|
|
USB_DeviceStop(g_UsbDeviceHidMouse.deviceHandle);
|
|
#endif
|
|
}
|
|
break;
|
|
#endif
|
|
case kUSB_DeviceEventSuspend:
|
|
{
|
|
/* USB device bus suspend signal detected */
|
|
if (g_UsbDeviceHidMouse.attach)
|
|
{
|
|
usb_echo("USB device start suspend\r\n");
|
|
USB_ControllerSuspended();
|
|
g_UsbDeviceHidMouse.startTick = g_UsbDeviceHidMouse.hwTick;
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseStartSuspend;
|
|
error = kStatus_USB_Success;
|
|
}
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventResume:
|
|
{
|
|
/* USB device bus resume signal detected */
|
|
if ((g_UsbDeviceHidMouse.attach) && (kStatus_MouseIdle != g_UsbDeviceHidMouse.suspend))
|
|
{
|
|
g_UsbDeviceHidMouse.isResume = 1U;
|
|
usb_echo("USB device start resume\r\n");
|
|
error = kStatus_USB_Success;
|
|
}
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventSetConfiguration:
|
|
if (USB_HID_MOUSE_CONFIGURE_INDEX == (*temp8))
|
|
{
|
|
/* If the confguration is valid, initliaze the HID mouse interrupt IN pipe */
|
|
usb_device_endpoint_init_struct_t epInitStruct;
|
|
usb_device_endpoint_callback_struct_t epCallback;
|
|
|
|
epCallback.callbackFn = USB_DeviceHidInterruptIn;
|
|
epCallback.callbackParam = handle;
|
|
|
|
epInitStruct.zlt = 0U;
|
|
epInitStruct.transferType = USB_ENDPOINT_INTERRUPT;
|
|
epInitStruct.endpointAddress =
|
|
USB_HID_MOUSE_ENDPOINT_IN | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
|
|
if (USB_SPEED_HIGH == g_UsbDeviceHidMouse.speed)
|
|
{
|
|
epInitStruct.maxPacketSize = HS_HID_MOUSE_INTERRUPT_IN_PACKET_SIZE;
|
|
epInitStruct.interval = HS_HID_MOUSE_INTERRUPT_IN_INTERVAL;
|
|
}
|
|
else
|
|
{
|
|
epInitStruct.maxPacketSize = FS_HID_MOUSE_INTERRUPT_IN_PACKET_SIZE;
|
|
epInitStruct.interval = FS_HID_MOUSE_INTERRUPT_IN_INTERVAL;
|
|
}
|
|
|
|
USB_DeviceInitEndpoint(g_UsbDeviceHidMouse.deviceHandle, &epInitStruct, &epCallback);
|
|
|
|
g_UsbDeviceHidMouse.attach = 1U;
|
|
error = USB_DeviceHidMouseAction(); /* run the cursor movement code */
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventSetInterface:
|
|
error = kStatus_USB_Success;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
/* Get setup buffer */
|
|
usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer)
|
|
{
|
|
/* Keep the setup is 4-byte aligned */
|
|
static uint32_t hid_mouse_setup[2];
|
|
if (NULL == setupBuffer)
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
*setupBuffer = (usb_setup_struct_t *)&hid_mouse_setup;
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/* Configure device remote wakeup */
|
|
usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
|
|
{
|
|
if (g_UsbDeviceHidMouse.attach)
|
|
{
|
|
g_UsbDeviceHidMouse.remoteWakeup = enable;
|
|
usb_echo("USB device remote wakeup state: %d\r\n", g_UsbDeviceHidMouse.remoteWakeup);
|
|
return kStatus_USB_Success;
|
|
}
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
|
|
/* Configure the endpoint status (idle or stall) */
|
|
usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
|
|
{
|
|
if (status)
|
|
{
|
|
if ((USB_HID_MOUSE_ENDPOINT_IN == (ep & USB_ENDPOINT_NUMBER_MASK)) &&
|
|
(ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK))
|
|
{
|
|
return USB_DeviceStallEndpoint(handle, ep);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((USB_HID_MOUSE_ENDPOINT_IN == (ep & USB_ENDPOINT_NUMBER_MASK)) &&
|
|
(ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK))
|
|
{
|
|
return USB_DeviceUnstallEndpoint(handle, ep);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
|
|
/* Get class-specific request buffer */
|
|
usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle,
|
|
usb_setup_struct_t *setup,
|
|
uint32_t *length,
|
|
uint8_t **buffer)
|
|
{
|
|
if ((NULL == buffer) || ((*length) > sizeof(s_SetupOutBuffer)))
|
|
{
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
*buffer = s_SetupOutBuffer;
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/* Handle class-specific request */
|
|
usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle,
|
|
usb_setup_struct_t *setup,
|
|
uint32_t *length,
|
|
uint8_t **buffer)
|
|
{
|
|
usb_status_t error = kStatus_USB_InvalidRequest;
|
|
|
|
if (setup->wIndex != USB_HID_MOUSE_INTERFACE_INDEX)
|
|
{
|
|
return error;
|
|
}
|
|
|
|
switch (setup->bRequest)
|
|
{
|
|
case USB_DEVICE_HID_REQUEST_GET_REPORT:
|
|
break;
|
|
case USB_DEVICE_HID_REQUEST_GET_IDLE:
|
|
break;
|
|
case USB_DEVICE_HID_REQUEST_GET_PROTOCOL:
|
|
break;
|
|
case USB_DEVICE_HID_REQUEST_SET_REPORT:
|
|
break;
|
|
case USB_DEVICE_HID_REQUEST_SET_IDLE:
|
|
break;
|
|
case USB_DEVICE_HID_REQUEST_SET_PROTOCOL:
|
|
break;
|
|
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 mouse default state */
|
|
g_UsbDeviceHidMouse.speed = USB_SPEED_FULL;
|
|
g_UsbDeviceHidMouse.attach = 0U;
|
|
g_UsbDeviceHidMouse.deviceHandle = NULL;
|
|
g_UsbDeviceHidMouse.buffer = s_MouseBuffer;
|
|
g_UsbDeviceHidMouse.remoteWakeup = 0U;
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseIdle;
|
|
g_UsbDeviceHidMouse.selfWakeup = 0U;
|
|
g_UsbDeviceHidMouse.isResume = 0U;
|
|
|
|
/* Initialize the usb stack and class drivers */
|
|
if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &g_UsbDeviceHidMouse.deviceHandle))
|
|
{
|
|
usb_echo("USB device mouse failed\r\n");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
usb_echo("USB device HID mouse demo\r\n");
|
|
}
|
|
|
|
/* Install isr, set priority, and enable IRQ. */
|
|
USB_DeviceIsrEnable();
|
|
|
|
/* Start USB device HID mouse */
|
|
/*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_UsbDeviceHidMouse.deviceHandle);
|
|
}
|
|
|
|
void USB_PowerPreSwitchHook(void)
|
|
{
|
|
HW_TimerControl(0U);
|
|
|
|
DbgConsole_Deinit();
|
|
|
|
BOARD_DeinitPins();
|
|
|
|
USB_PreLowpowerMode();
|
|
}
|
|
|
|
void USB_PowerPostSwitchHook(void)
|
|
{
|
|
USB_WaitClockLocked();
|
|
USB_PostLowpowerMode();
|
|
BOARD_InitPins();
|
|
BOARD_InitDebugConsole();
|
|
HW_TimerControl(1U);
|
|
}
|
|
|
|
void USB_DeviceSuspendResumeTask(void)
|
|
{
|
|
if (g_UsbDeviceHidMouse.isResume)
|
|
{
|
|
g_UsbDeviceHidMouse.isResume = 0U;
|
|
if (kStatus_MouseIdle != g_UsbDeviceHidMouse.suspend)
|
|
{
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseResumed;
|
|
}
|
|
}
|
|
|
|
switch (g_UsbDeviceHidMouse.suspend)
|
|
{
|
|
case kStatus_MouseIdle:
|
|
break;
|
|
case kStatus_MouseStartSuspend:
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseSuspending;
|
|
break;
|
|
case kStatus_MouseSuspending:
|
|
usb_echo("USB device suspended.\r\n");
|
|
if (g_UsbDeviceHidMouse.remoteWakeup)
|
|
{
|
|
usb_echo("Please Press wakeup switch(%s) to remote wakeup the host.\r\n", SW_GetName());
|
|
}
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseSuspended;
|
|
break;
|
|
case kStatus_MouseSuspended:
|
|
USB_PowerPreSwitchHook();
|
|
if (g_UsbDeviceHidMouse.remoteWakeup)
|
|
{
|
|
SW_IntControl(1);
|
|
}
|
|
|
|
USB_DeviceSetStatus(g_UsbDeviceHidMouse.deviceHandle, kUSB_DeviceStatusBusSuspend, NULL);
|
|
if (kStatus_Success != USB_EnterLowpowerMode())
|
|
{
|
|
g_UsbDeviceHidMouse.selfWakeup = 1U;
|
|
USB_PowerPostSwitchHook();
|
|
usb_echo("Enter VLPS mode failed!\r\n");
|
|
}
|
|
else
|
|
{
|
|
USB_PowerPostSwitchHook();
|
|
}
|
|
if (g_UsbDeviceHidMouse.remoteWakeup)
|
|
{
|
|
SW_IntControl(0);
|
|
}
|
|
|
|
if (g_UsbDeviceHidMouse.attach)
|
|
{
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseStartResume;
|
|
}
|
|
else
|
|
{
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseIdle;
|
|
}
|
|
break;
|
|
case kStatus_MouseStartResume:
|
|
if (g_UsbDeviceHidMouse.selfWakeup)
|
|
{
|
|
g_UsbDeviceHidMouse.selfWakeup = 0U;
|
|
if (g_UsbDeviceHidMouse.remoteWakeup)
|
|
{
|
|
if (kStatus_USB_Success ==
|
|
USB_DeviceSetStatus(g_UsbDeviceHidMouse.deviceHandle, kUSB_DeviceStatusBusResume, NULL))
|
|
{
|
|
usb_echo("Remote wakeup the host.\r\n");
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseResuming;
|
|
}
|
|
else
|
|
{
|
|
usb_echo("Send resume signal failed.\r\n");
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseStartResume;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseResuming;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseResumed;
|
|
}
|
|
break;
|
|
case kStatus_MouseResuming:
|
|
break;
|
|
case kStatus_MouseResumed:
|
|
usb_echo("USB device resumed.\r\n");
|
|
if (g_UsbDeviceHidMouse.attach)
|
|
{
|
|
USB_DeviceHidMouseAction();
|
|
}
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseIdle;
|
|
break;
|
|
default:
|
|
g_UsbDeviceHidMouse.suspend = kStatus_MouseIdle;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#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();
|
|
|
|
/* Set PERCLK_CLK source to OSC_CLK*/
|
|
CLOCK_SetMux(kCLOCK_PerclkMux, 1U);
|
|
/* Set PERCLK_CLK divider to 1 */
|
|
CLOCK_SetDiv(kCLOCK_PerclkDiv, 0U);
|
|
|
|
/* Define the initialization structure for the input switch pin. */
|
|
gpio_pin_config_t sw_config = {
|
|
kGPIO_DigitalInput,
|
|
0,
|
|
kGPIO_IntRisingEdge,
|
|
};
|
|
/* Initialize input switch GPIO. */
|
|
GPIO_PinInit(BOARD_USER_BUTTON_GPIO, BOARD_USER_BUTTON_GPIO_PIN, &sw_config);
|
|
|
|
/* Enable GPIO pin interrupt */
|
|
GPIO_PortEnableInterrupts(BOARD_USER_BUTTON_GPIO, 1U << BOARD_USER_BUTTON_GPIO_PIN);
|
|
EnableIRQ(BOARD_USER_BUTTON_IRQ);
|
|
|
|
GPC_EnableIRQ(GPC, BOARD_USER_BUTTON_IRQ);
|
|
|
|
#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
|
|
USB_LowpowerModeInit();
|
|
#endif
|
|
|
|
USB_DeviceApplicationInit();
|
|
|
|
#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
|
|
HW_TimerControl(1);
|
|
#endif
|
|
|
|
while (1U)
|
|
{
|
|
#if USB_DEVICE_CONFIG_USE_TASK
|
|
USB_DeviceTaskFn(g_UsbDeviceHidMouse.deviceHandle);
|
|
#endif
|
|
USB_DeviceSuspendResumeTask();
|
|
}
|
|
}
|