392 lines
13 KiB
C
392 lines
13 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>
|
||
|
#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 "composite.h"
|
||
|
|
||
|
#include "hid_mouse.h"
|
||
|
#include "hid_keyboard.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 */
|
||
|
|
||
|
#include "fsl_power.h"
|
||
|
#include "usb_phy.h"
|
||
|
/*******************************************************************************
|
||
|
* 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 void USB_DeviceApplicationInit(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Variables
|
||
|
******************************************************************************/
|
||
|
|
||
|
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_SetupOutBuffer[8];
|
||
|
extern uint8_t g_UsbDeviceCurrentConfigure;
|
||
|
extern uint8_t g_UsbDeviceInterface[USB_COMPOSITE_INTERFACE_COUNT];
|
||
|
|
||
|
usb_device_composite_struct_t g_UsbDeviceComposite;
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Code
|
||
|
******************************************************************************/
|
||
|
#if (defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U))
|
||
|
void USB0_IRQHandler(void)
|
||
|
{
|
||
|
USB_DeviceLpcIp3511IsrFunction(g_UsbDeviceComposite.deviceHandle);
|
||
|
}
|
||
|
#endif
|
||
|
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
|
||
|
void USB1_IRQHandler(void)
|
||
|
{
|
||
|
USB_DeviceLpcIp3511IsrFunction(g_UsbDeviceComposite.deviceHandle);
|
||
|
}
|
||
|
#endif
|
||
|
void USB_DeviceClockInit(void)
|
||
|
{
|
||
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
||
|
usb_phy_config_struct_t phyConfig = {
|
||
|
BOARD_USB_PHY_D_CAL,
|
||
|
BOARD_USB_PHY_TXCAL45DP,
|
||
|
BOARD_USB_PHY_TXCAL45DM,
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
||
|
/* enable USB IP clock */
|
||
|
CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFroHfFreq());
|
||
|
#if defined(FSL_FEATURE_USB_USB_RAM) && (FSL_FEATURE_USB_USB_RAM)
|
||
|
for (int i = 0; i < FSL_FEATURE_USB_USB_RAM; i++)
|
||
|
{
|
||
|
((uint8_t *)FSL_FEATURE_USB_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
||
|
/* enable USB IP clock */
|
||
|
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_UsbPhySrcExt, BOARD_XTAL0_CLK_HZ);
|
||
|
CLOCK_EnableUsbhs0DeviceClock(kCLOCK_UsbSrcUnused, 0U);
|
||
|
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ, &phyConfig);
|
||
|
#if defined(FSL_FEATURE_USBHSD_USB_RAM) && (FSL_FEATURE_USBHSD_USB_RAM)
|
||
|
for (int i = 0; i < FSL_FEATURE_USBHSD_USB_RAM; i++)
|
||
|
{
|
||
|
((uint8_t *)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
}
|
||
|
void USB_DeviceIsrEnable(void)
|
||
|
{
|
||
|
uint8_t irqNumber;
|
||
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
||
|
uint8_t usbDeviceIP3511Irq[] = USB_IRQS;
|
||
|
irqNumber = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Fs0];
|
||
|
#endif
|
||
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
||
|
uint8_t usbDeviceIP3511Irq[] = USBHSD_IRQS;
|
||
|
irqNumber = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Hs0];
|
||
|
#endif
|
||
|
/* 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)
|
||
|
{
|
||
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
||
|
USB_DeviceLpcIp3511TaskFunction(deviceHandle);
|
||
|
#endif
|
||
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
||
|
USB_DeviceLpcIp3511TaskFunction(deviceHandle);
|
||
|
#endif
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* Device callback */
|
||
|
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(handle);
|
||
|
g_UsbDeviceComposite.attach = 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(handle, kUSB_DeviceStatusSpeed, &g_UsbDeviceComposite.speed))
|
||
|
{
|
||
|
USB_DeviceSetSpeed(g_UsbDeviceComposite.speed);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
case kUSB_DeviceEventSetConfiguration:
|
||
|
if (USB_COMPOSITE_CONFIGURE_INDEX == (*temp8))
|
||
|
{
|
||
|
g_UsbDeviceComposite.attach = 1U;
|
||
|
/* If the confguration is valid, set HID keyboard */
|
||
|
USB_DeviceHidKeyboardSetConfigure(handle, (*temp8));
|
||
|
/* If the confguration is valid, set HID mouse */
|
||
|
USB_DeviceHidMouseSetConfigure(handle, (*temp8));
|
||
|
error = kStatus_USB_Success;
|
||
|
}
|
||
|
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 compositeSetup[2];
|
||
|
if (NULL == setupBuffer)
|
||
|
{
|
||
|
return kStatus_USB_InvalidParameter;
|
||
|
}
|
||
|
*setupBuffer = (usb_setup_struct_t *)&compositeSetup;
|
||
|
return kStatus_USB_Success;
|
||
|
}
|
||
|
|
||
|
usb_status_t USB_DeviceGetVendorReceiveBuffer(usb_device_handle handle,
|
||
|
usb_setup_struct_t *setup,
|
||
|
uint32_t *length,
|
||
|
uint8_t **buffer)
|
||
|
{
|
||
|
return kStatus_USB_Error;
|
||
|
}
|
||
|
|
||
|
usb_status_t USB_DeviceProcessVendorRequest(usb_device_handle handle,
|
||
|
usb_setup_struct_t *setup,
|
||
|
uint32_t *length,
|
||
|
uint8_t **buffer)
|
||
|
{
|
||
|
return kStatus_USB_InvalidRequest;
|
||
|
}
|
||
|
|
||
|
/* Configure device remote wakeup */
|
||
|
usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
|
||
|
{
|
||
|
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_KEYBOARD_ENDPOINT_IN == (ep & USB_ENDPOINT_NUMBER_MASK)) &&
|
||
|
(ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK))
|
||
|
{
|
||
|
return USB_DeviceHidKeyboardEndpointStall(handle, ep);
|
||
|
}
|
||
|
else if ((USB_HID_MOUSE_ENDPOINT_IN == (ep & USB_ENDPOINT_NUMBER_MASK)) &&
|
||
|
(ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK))
|
||
|
{
|
||
|
return USB_DeviceHidMouseEndpointStall(handle, ep);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((USB_HID_KEYBOARD_ENDPOINT_IN == (ep & USB_ENDPOINT_NUMBER_MASK)) &&
|
||
|
(ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK))
|
||
|
{
|
||
|
return USB_DeviceHidKeyboardEndpointUnstall(handle, ep);
|
||
|
}
|
||
|
else if ((USB_HID_MOUSE_ENDPOINT_IN == (ep & USB_ENDPOINT_NUMBER_MASK)) &&
|
||
|
(ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK))
|
||
|
{
|
||
|
return USB_DeviceHidMouseEndpointUnstall(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 (USB_HID_KEYBOARD_INTERFACE_INDEX == setup->wIndex)
|
||
|
{
|
||
|
return USB_DeviceHidKeyboardClassRequest(handle, setup, buffer, length);
|
||
|
}
|
||
|
else if (USB_HID_MOUSE_INTERFACE_INDEX == setup->wIndex)
|
||
|
{
|
||
|
return USB_DeviceHidMouseClassRequest(handle, setup, buffer, length);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
/* Application initialization */
|
||
|
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 composite device default state */
|
||
|
g_UsbDeviceComposite.speed = USB_SPEED_FULL;
|
||
|
g_UsbDeviceComposite.attach = 0U;
|
||
|
g_UsbDeviceComposite.deviceHandle = NULL;
|
||
|
|
||
|
/* Initialize the usb stack and class drivers */
|
||
|
if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &g_UsbDeviceComposite.deviceHandle))
|
||
|
{
|
||
|
usb_echo("USB device composite demo init failed\r\n");
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
usb_echo("USB device composite demo\r\n");
|
||
|
}
|
||
|
|
||
|
USB_DeviceHidKeyboardInit(&g_UsbDeviceComposite);
|
||
|
USB_DeviceHidMouseInit(&g_UsbDeviceComposite);
|
||
|
|
||
|
USB_DeviceIsrEnable();
|
||
|
|
||
|
/* Start USB device composite */
|
||
|
/*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_UsbDeviceComposite.deviceHandle);
|
||
|
}
|
||
|
|
||
|
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION)) || defined(__GNUC__)
|
||
|
int main(void)
|
||
|
#else
|
||
|
void main(void)
|
||
|
#endif
|
||
|
{
|
||
|
/* set BOD VBAT level to 1.65V */
|
||
|
POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
|
||
|
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
|
||
|
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
|
||
|
|
||
|
BOARD_InitBootPins();
|
||
|
BOARD_InitBootClocks();
|
||
|
BOARD_InitDebugConsole();
|
||
|
|
||
|
NVIC_ClearPendingIRQ(USB0_IRQn);
|
||
|
NVIC_ClearPendingIRQ(USB0_NEEDCLK_IRQn);
|
||
|
NVIC_ClearPendingIRQ(USB1_IRQn);
|
||
|
NVIC_ClearPendingIRQ(USB1_NEEDCLK_IRQn);
|
||
|
|
||
|
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB0 Phy */
|
||
|
POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /*< Turn on USB1 Phy */
|
||
|
|
||
|
/* reset the IP to make sure it's in reset state. */
|
||
|
RESET_PeripheralReset(kUSB0D_RST_SHIFT_RSTn);
|
||
|
RESET_PeripheralReset(kUSB0HSL_RST_SHIFT_RSTn);
|
||
|
RESET_PeripheralReset(kUSB0HMR_RST_SHIFT_RSTn);
|
||
|
RESET_PeripheralReset(kUSB1H_RST_SHIFT_RSTn);
|
||
|
RESET_PeripheralReset(kUSB1D_RST_SHIFT_RSTn);
|
||
|
RESET_PeripheralReset(kUSB1_RST_SHIFT_RSTn);
|
||
|
RESET_PeripheralReset(kUSB1RAM_RST_SHIFT_RSTn);
|
||
|
|
||
|
#if (defined USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS)
|
||
|
CLOCK_EnableClock(kCLOCK_Usbh1);
|
||
|
/* Put PHY powerdown under software control */
|
||
|
*((uint32_t *)(USBHSH_BASE + 0x50)) = USBHSH_PORTMODE_SW_PDCOM_MASK;
|
||
|
/* According to reference mannual, device mode setting has to be set by access usb host register */
|
||
|
*((uint32_t *)(USBHSH_BASE + 0x50)) |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
|
||
|
/* enable usb1 host clock */
|
||
|
CLOCK_DisableClock(kCLOCK_Usbh1);
|
||
|
#endif
|
||
|
#if (defined USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS)
|
||
|
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB Phy */
|
||
|
CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
|
||
|
CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
|
||
|
/* enable usb0 host clock */
|
||
|
CLOCK_EnableClock(kCLOCK_Usbhsl0);
|
||
|
/*According to reference mannual, device mode setting has to be set by access usb host register */
|
||
|
*((uint32_t *)(USBFSH_BASE + 0x5C)) |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
|
||
|
/* disable usb0 host clock */
|
||
|
CLOCK_DisableClock(kCLOCK_Usbhsl0);
|
||
|
#endif
|
||
|
|
||
|
USB_DeviceApplicationInit();
|
||
|
|
||
|
while (1U)
|
||
|
{
|
||
|
#if USB_DEVICE_CONFIG_USE_TASK
|
||
|
USB_DeviceTaskFn(g_UsbDeviceComposite.deviceHandle);
|
||
|
#endif
|
||
|
}
|
||
|
}
|