MCUXpresso_LPC55S69/boards/lpcxpresso55s69/demo_apps/multi_peripherals_test/cm33_core0/mouse.c

565 lines
22 KiB
C

/*
* Copyright 2020 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_class.h"
#include "usb_device_hid.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#include "mouse.h"
#include "fsl_device_registers.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include <stdio.h>
#include <stdlib.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
#include "demo_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
extern void USB_DeviceClockInit(void);
extern void USB_DeviceIsrEnable(void);
static void mouse_task(void *pvParameters);
static usb_status_t USB_DeviceHidMouseAction(void);
static usb_status_t USB_DeviceHidMouseCallback(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);
#if defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0)
void USB_DeviceTask(void *handle)
#endif /* USB_DEVICE_CONFIG_USE_TASK */
/*******************************************************************************
* Variables
******************************************************************************/
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 usb_device_class_struct_t g_UsbDeviceHidMouseConfig;
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
usb_device_dcd_charging_time_t g_UsbDeviceDcdTimingConfig;
#endif
/* Set class configurations */
usb_device_class_config_struct_t g_UsbDeviceHidConfig[1] = {{
USB_DeviceHidMouseCallback, /* HID mouse class callback pointer */
(class_handle_t)NULL, /* The HID class handle, This field is set by USB_DeviceClassInit */
&g_UsbDeviceHidMouseConfig, /* 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 mouse_init(void)
{
if (xTaskCreate(mouse_task, "Mouse Task", 5000UL / sizeof(portSTACK_TYPE), NULL, 4U, NULL) != pdPASS)
{
PRINTF("Mouse Task creation failed!\r\n");
while (1)
;
}
}
/* 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_DeviceHidSend(g_UsbDeviceHidMouse.hidHandle, USB_HID_MOUSE_ENDPOINT_IN, g_UsbDeviceHidMouse.buffer,
USB_HID_MOUSE_REPORT_LENGTH);
}
/* The hid class callback */
static usb_status_t USB_DeviceHidMouseCallback(class_handle_t handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_InvalidRequest;
usb_device_endpoint_callback_message_struct_t *message = (usb_device_endpoint_callback_message_struct_t *)param;
switch (event)
{
case kUSB_DeviceHidEventSendResponse:
/* Resport sent */
if (g_UsbDeviceHidMouse.attach)
{
if ((NULL != message) && (message->length == USB_UNINITIALIZED_VAL_32))
{
return error;
}
error = USB_DeviceHidMouseAction();
}
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;
uint16_t *temp16 = (uint16_t *)param;
uint8_t *temp8 = (uint8_t *)param;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
/* USB bus reset signal detected */
g_UsbDeviceHidMouse.attach = 0U;
g_UsbDeviceHidMouse.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_UsbDeviceHidMouse.speed))
{
USB_DeviceSetSpeed(handle, g_UsbDeviceHidMouse.speed);
}
#endif
}
break;
#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
case kUSB_DeviceEventAttach:
{
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
g_UsbDeviceHidMouse.vReginInterruptDetected = 1;
g_UsbDeviceHidMouse.vbusValid = 1;
#else
usb_echo("USB device attached.\r\n");
USB_DeviceRun(g_UsbDeviceHidMouse.deviceHandle);
#endif
error = kStatus_USB_Success;
}
break;
case kUSB_DeviceEventDetach:
{
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
g_UsbDeviceHidMouse.vReginInterruptDetected = 1;
g_UsbDeviceHidMouse.vbusValid = 0;
g_UsbDeviceHidMouse.attach = 0;
#else
usb_echo("USB device detached.\r\n");
g_UsbDeviceHidMouse.attach = 0;
USB_DeviceStop(g_UsbDeviceHidMouse.deviceHandle);
#endif
error = kStatus_USB_Success;
}
break;
#endif
case kUSB_DeviceEventSetConfiguration:
if (0U == (*temp8))
{
g_UsbDeviceHidMouse.attach = 0;
g_UsbDeviceHidMouse.currentConfiguration = 0U;
error = kStatus_USB_Success;
}
else if (USB_HID_MOUSE_CONFIGURE_INDEX == (*temp8))
{
/* Set device configuration request */
g_UsbDeviceHidMouse.attach = 1U;
g_UsbDeviceHidMouse.currentConfiguration = *temp8;
error = USB_DeviceHidMouseAction();
}
else
{
/* no action */
}
break;
case kUSB_DeviceEventSetInterface:
if (g_UsbDeviceHidMouse.attach)
{
/* Set device interface request */
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU);
if (interface < USB_HID_MOUSE_INTERFACE_COUNT)
{
g_UsbDeviceHidMouse.currentInterfaceAlternateSetting[interface] = alternateSetting;
if (alternateSetting == 0U)
{
error = USB_DeviceHidMouseAction();
}
}
}
break;
case kUSB_DeviceEventGetConfiguration:
if (param)
{
/* Get current configuration request */
*temp8 = g_UsbDeviceHidMouse.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 (interface < USB_HID_MOUSE_INTERFACE_COUNT)
{
*temp16 = (*temp16 & 0xFF00U) | g_UsbDeviceHidMouse.currentInterfaceAlternateSetting[interface];
error = kStatus_USB_Success;
}
}
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;
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_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
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
case kUSB_DeviceEventDcdTimeOut:
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusVBUSDetect)
{
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusTimeOut;
}
break;
case kUSB_DeviceEventDcdUnknownType:
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusVBUSDetect)
{
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusUnknownType;
}
break;
case kUSB_DeviceEventSDPDetected:
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusVBUSDetect)
{
g_UsbDeviceHidMouse.dcdPortType = kUSB_DeviceDCDPortTypeSDP;
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusDetectFinish;
}
break;
case kUSB_DeviceEventChargingPortDetected:
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusVBUSDetect)
{
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusChargingPortDetect;
}
break;
case kUSB_DeviceEventChargingHostDetected:
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusVBUSDetect)
{
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusDetectFinish;
g_UsbDeviceHidMouse.dcdPortType = kUSB_DeviceDCDPortTypeCDP;
}
break;
case kUSB_DeviceEventDedicatedChargerDetected:
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusVBUSDetect)
{
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusDetectFinish;
g_UsbDeviceHidMouse.dcdPortType = kUSB_DeviceDCDPortTypeDCP;
}
break;
#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 mouse to default state. */
g_UsbDeviceHidMouse.speed = USB_SPEED_FULL;
g_UsbDeviceHidMouse.attach = 0U;
g_UsbDeviceHidMouse.hidHandle = (class_handle_t)NULL;
g_UsbDeviceHidMouse.deviceHandle = NULL;
g_UsbDeviceHidMouse.buffer = s_MouseBuffer;
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusDetached;
g_UsbDeviceDcdTimingConfig.dcdSeqInitTime = USB_DEVICE_DCD_SEQ_INIT_TIME;
g_UsbDeviceDcdTimingConfig.dcdDbncTime = USB_DEVICE_DCD_DBNC_MSEC;
g_UsbDeviceDcdTimingConfig.dcdDpSrcOnTime = USB_DEVICE_DCD_VDPSRC_ON_MSEC;
g_UsbDeviceDcdTimingConfig.dcdTimeWaitAfterPrD = USB_DEVICE_DCD_TIME_WAIT_AFTER_PRI_DETECTION;
g_UsbDeviceDcdTimingConfig.dcdTimeDMSrcOn = USB_DEVICE_DCD_TIME_DM_SRC_ON;
#endif
/* Initialize the usb stack and class drivers */
if (kStatus_USB_Success !=
USB_DeviceClassInit(CONTROLLER_ID, &g_UsbDeviceHidConfigList, &g_UsbDeviceHidMouse.deviceHandle))
{
usb_echo("USB device mouse failed\r\n");
return;
}
else
{
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
usb_echo("USB device DCD + HID mouse demo\r\n");
#else
usb_echo("USB device HID mouse test\r\n");
usb_echo("Plug-in the device, which is running mouse test, into the PC.");
usb_echo("A HID-compliant mouse is enumerated in the Device Manager.\r\n");
usb_echo("The mouse arrow is moving on PC screen in the rectangular rotation.\r\n");
#endif
/* Get the HID mouse class handle */
g_UsbDeviceHidMouse.hidHandle = g_UsbDeviceHidConfigList.config->classHandle;
}
USB_DeviceIsrEnable();
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
#else
/* Start USB device HID mouse */
USB_DeviceRun(g_UsbDeviceHidMouse.deviceHandle);
#endif
}
#if defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0)
void USB_DeviceTask(void *handle)
{
while (1U)
{
USB_DeviceTaskFn(handle);
}
}
#endif
static void mouse_task(void *pvParameters)
{
USB_DeviceApplicationInit();
#if USB_DEVICE_CONFIG_USE_TASK
if (g_UsbDeviceHidMouse.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_UsbDeviceHidMouse.deviceHandle, /* optional task startup argument */
5U, /* initial priority */
&g_UsbDeviceHidMouse.deviceTaskHandle /* optional task handle to create */
) != pdPASS)
{
usb_echo("usb device task create failed!\r\n");
return;
}
}
#endif
while (1U)
{
#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)) || \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
if (g_UsbDeviceHidMouse.vReginInterruptDetected)
{
g_UsbDeviceHidMouse.vReginInterruptDetected = 0;
if (g_UsbDeviceHidMouse.vbusValid)
{
usb_echo("USB device attached.\r\n");
USB_DeviceDcdInitModule(g_UsbDeviceHidMouse.deviceHandle, &g_UsbDeviceDcdTimingConfig);
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusVBUSDetect;
}
else
{
usb_echo("USB device detached.\r\n");
USB_DeviceDcdDeinitModule(g_UsbDeviceHidMouse.deviceHandle);
USB_DeviceStop(g_UsbDeviceHidMouse.deviceHandle);
g_UsbDeviceHidMouse.dcdPortType = kUSB_DeviceDCDPortTypeNoPort;
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusDetached;
}
}
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusChargingPortDetect) /* This is only for BC1.1 */
{
USB_DeviceRun(g_UsbDeviceHidMouse.deviceHandle);
}
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusTimeOut)
{
usb_echo("Timeout error.\r\n");
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusComplete;
}
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusUnknownType)
{
usb_echo("Unknown port type.\r\n");
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusComplete;
}
if (g_UsbDeviceHidMouse.dcdDevStatus == kUSB_DeviceDCDDevStatusDetectFinish)
{
if (g_UsbDeviceHidMouse.dcdPortType == kUSB_DeviceDCDPortTypeSDP)
{
usb_echo("The device has been connected to a facility which is SDP(Standard Downstream Port).\r\n");
USB_DeviceRun(
g_UsbDeviceHidMouse.deviceHandle); /* If the facility attached is SDP, start enumeration */
}
else if (g_UsbDeviceHidMouse.dcdPortType == kUSB_DeviceDCDPortTypeCDP)
{
usb_echo("The device has been connected to a facility which is CDP(Charging Downstream Port).\r\n");
USB_DeviceRun(
g_UsbDeviceHidMouse.deviceHandle); /* If the facility attached is CDP, start enumeration */
}
else if (g_UsbDeviceHidMouse.dcdPortType == kUSB_DeviceDCDPortTypeDCP)
{
usb_echo("The device has been connected to a facility which is DCP(Dedicated Charging Port).\r\n");
}
g_UsbDeviceHidMouse.dcdDevStatus = kUSB_DeviceDCDDevStatusComplete;
}
#endif
}
}