📄 app_usb.c
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2005-2008
Part of BlueLab 4.0.1-release
FILE NAME
app_usb.c
DESCRIPTION
USB support code
NOTES
*/
#include "app_usb.h"
#include "app_private.h"
#include "app_device.h"
#include <boot.h>
#include <usb.h>
#include <panic.h>
#include <sink.h>
#include <source.h>
#include <stream.h>
#include <string.h>
#include <stdlib.h>
#include <message.h>
#ifdef APP_DEBUG
#include <stdio.h>
#define USB_PRINT(x) printf x
#else
#define USB_PRINT(x)
#endif
/* USB HID descriptor identifiers */
#define HID_DESCRIPTOR 0x21
#define HID_REPORT_DESCRIPTOR 0x22
#define HID_DESCRIPTOR_LENGTH (9)
#ifdef HID_MOUSE_SEND_WHEEL
#define HID_REPORT_DESCRIPTOR_LENGTH_MOUSE (63)
#else
#define HID_REPORT_DESCRIPTOR_LENGTH_MOUSE (61)
#endif
#define HID_REPORT_DESCRIPTOR_LENGTH_KEYBOARD (74)
/* USB HID class descriptor for the mouse. */
static const uint8 usb_hid_class_descriptor_mouse[HID_DESCRIPTOR_LENGTH] =
{
HID_DESCRIPTOR_LENGTH, /* bLength */
HID_DESCRIPTOR, /* bDescriptorType */
0x11, /* bcdHID */
0x01, /* bcdHID */
0, /* bCountryCode */
1, /* bNumDescriptors */
0x22, /* bDescriptorType */
HID_REPORT_DESCRIPTOR_LENGTH_MOUSE, /* wDescriptorLength */
0, /* wDescriptorLength */
};
/* USB HID report descriptor for the mouse. This is declared to be the same as
the USB and HID Boot Report to allow the same packet to be sent in HID Boot
and Report mode. */
static const uint8 usb_hid_report_descriptor_mouse[HID_REPORT_DESCRIPTOR_LENGTH_MOUSE] =
{
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x02, /* USAGE (Mouse) */
0xa1, 0x01, /* COLLECTION (Application) */
0x09, 0x01, /* USAGE (Pointer) */
0xa1, 0x00, /* COLLECTION (Physical) */
0x05, 0x09, /* USAGE_PAGE (Button) */
0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
0x29, 0x05, /* USAGE_MAXIMUM (Button 5) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x95, 0x05, /* REPORT_COUNT (5) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x03, /* REPORT_SIZE (3) */
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x30, /* USAGE (X) */
0x09, 0x31, /* USAGE (Y) */
#ifdef HID_MOUSE_SEND_WHEEL
0x09, 0x38, /* USAGE (WHEEL) */
#endif
0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
0x75, 0x08, /* REPORT_SIZE (8) */
#ifdef HID_MOUSE_SEND_WHEEL
0x95, 0x03, /* REPORT_COUNT (3) */
#else
0x95, 0x02, /* REPORT_COUNT (2) */
#endif
0x81, 0x06, /* INPUT (Data,Var,Rel) */
/* Feature report to enable Host Comms */
0x06, 0x00, 0xff, /* USAGE PAGE (Vendor 0xFF00) */
0x09, 0x01, /* USAGE (Vendor Page 1) */
0x95, 0x08, /* REPORT COUNT (8) */
0x75, 0x08, /* REPORT SIZE (8) */
0xB1, 0x02, /* FEATURE (Var) */
0xC0, /* END COLLECTION */
0xC0 /* END COLLECTION */
};
/* USB HID class descriptor for the keyboard. */
static const uint8 usb_hid_class_descriptor_keyboard[HID_DESCRIPTOR_LENGTH] =
{
HID_DESCRIPTOR_LENGTH, /* bLength */
HID_DESCRIPTOR, /* bDescriptorType */
0x11, /* bcdHID */
0x01, /* bcdHID */
0, /* bCountryCode */
1, /* bNumDescriptors */
0x22, /* bDescriptorType */
HID_REPORT_DESCRIPTOR_LENGTH_KEYBOARD, /* wDescriptorLength */
0, /* wDescriptorLength */
};
/*
USB HID report descriptor for the keyboard.
This is declared to be the same as the USB and HID Boot Report
to allow the same packet to be sent in HID Boot and Report mode.
*/
static const uint8 usb_hid_report_descriptor_keyboard[HID_REPORT_DESCRIPTOR_LENGTH_KEYBOARD] =
{
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x06, /* USAGE (Keyboard) */
0xa1, 0x01, /* COLLECTION (Application) */
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */
0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x95, 0x08, /* REPORT_COUNT (8) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
0x95, 0x05, /* REPORT_COUNT (5) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x05, 0x08, /* USAGE_PAGE (LEDs) */
0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x03, /* REPORT_SIZE (3) */
0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */
0x95, 0x06, /* REPORT_COUNT (6) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x65, /* LOGICAL_MAXIMUM (101) */
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */
0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */
0x81, 0x00, /* INPUT (Data,Ary,Abs) */
/* Feature report to enable Host Comms */
0x06, 0x00, 0xff, /* USAGE PAGE (Vendor 0xFF00) */
0x09, 0x01, /* USAGE (Vendor Page 1) */
0x95, 0x08, /* REPORT COUNT (8) */
0x75, 0x08, /* REPORT SIZE (8) */
0xB1, 0x02, /* FEATURE (Var) */
0xc0 /* END_COLLECTION */
};
/* USB HID keyboard endpoint information */
static const EndPointInfo usb_hid_endpoint_info_keyboard[] =
{
{
NULL,
0,
KEYBOARD_ENDPOINT_ADDRESS,
end_point_attr_int,
16,
TRUE
}
};
/* USB HID mouse endpoint information */
static const EndPointInfo usb_hid_endpoint_info_mouse[] =
{
{
NULL,
0,
MOUSE_ENDPOINT_ADDRESS,
end_point_attr_int,
16,
TRUE
}
};
static const UsbCodes codes_keyboard = {0x03, 0x01, 0x01};
static const UsbCodes codes_mouse = {0x03, 0x01, 0x02};
#ifdef USB_KEYBOARD
static UsbInterface ui_keyboard;
#endif
#ifdef USB_MOUSE
static UsbInterface ui_mouse;
#endif
/****************************************************************************
NAME
UsbHandleClassRequest
DESCRIPTION
RETURNS
void
*/
void UsbHandleClassRequest(appDeviceTaskData *theDevice)
{
uint16 packet_size;
Source source = theDevice->usb_source;
Sink sink = theDevice->usb_sink;
/* Check for outstanding class requests */
while ((packet_size = SourceBoundary(source)) != 0)
{
UsbResponse usb_response;
/* Build the response, it must contain the original request, so copy from
the source header. */
memcpy(&usb_response.original_request, SourceMapHeader(source), sizeof(UsbRequest));
/* Set the response fields to default values to make the code below simpler */
usb_response.success = TRUE;
usb_response.data_length = 0;
USB_PRINT(("USB request %d\n", usb_response.original_request.bRequest));
/* Process the request */
switch (usb_response.original_request.bRequest)
{
/* GET_REPORT */
case 0x01:
usb_response.success = appDeviceHidGetReport(theDevice, sink, &usb_response.data_length);
break;
/* GET_IDLE */
case 0x02:
usb_response.success = appDeviceHidGetIdle(theDevice, sink, &usb_response.data_length);
break;
/* GET_PROTOCOL */
case 0x03:
usb_response.success = appDeviceHidGetProtocol(theDevice, sink, &usb_response.data_length);
break;
/* SET_REPORT */
case 0x09:
usb_response.success = appDeviceHidSetReport(theDevice, packet_size, SourceMap(source));
break;
/* SET IDLE */
case 0x0a:
usb_response.success = appDeviceHidSetIdle(theDevice, usb_response.original_request.wValue >> 8);
break;
/* SET_PROTOCOL */
case 0x0b:
usb_response.success = appDeviceHidSetProtocol(theDevice, usb_response.original_request.wValue & 1);
break;
/* Unknown command, report failure */
default:
usb_response.success = FALSE;
break;
}
/* Send response, handle 0 length responses */
if (usb_response.data_length == 0)
{
/* Set length to minumum allowed */
usb_response.data_length = 1;
/* Sink packets can never be zero-length, so flush a dummy byte */
SinkClaim(sink, 1);
}
SinkFlushHeader(sink, usb_response.data_length, (uint16 *)&usb_response, sizeof(UsbResponse));
/* Discard the original request */
SourceDrop(source, packet_size);
}
}
/****************************************************************************
NAME
UsbInitInterfaceTimeCritical
DESCRIPTION
Time critical USB initialisation. Initialise USB by setting up the
descriptors to appear as a composite device containing a USB HID mouse
and USB HID keyboard.
RETURNS
void
*/
void UsbInitInterfaceTimeCritical(void)
{
#ifdef USB_KEYBOARD
/* Keyboard must be declared as first interface in composite device to support
some PC BIOS implementations. */
/* Add an HID Class Interface */
ui_keyboard = UsbAddInterface(&codes_keyboard, HID_DESCRIPTOR, usb_hid_class_descriptor_keyboard, HID_DESCRIPTOR_LENGTH);
if (ui_keyboard == usb_interface_error)
Panic();
/* Register HID keyboard report descriptor with the interface */
(void)PanicFalse(UsbAddDescriptor(ui_keyboard, HID_REPORT_DESCRIPTOR, usb_hid_report_descriptor_keyboard, HID_REPORT_DESCRIPTOR_LENGTH_KEYBOARD));
/* Add required endpoints to the interface */
(void)PanicFalse(UsbAddEndPoints(ui_keyboard, 1, usb_hid_endpoint_info_keyboard));
#endif
#ifdef USB_MOUSE
/* Add an HID Class Interface */
ui_mouse = UsbAddInterface(&codes_mouse, HID_DESCRIPTOR, usb_hid_class_descriptor_mouse, HID_DESCRIPTOR_LENGTH);
if (ui_mouse == usb_interface_error)
Panic();
/* Register HID Mouse report rescriptor with the interface */
(void)PanicFalse(UsbAddDescriptor(ui_mouse, HID_REPORT_DESCRIPTOR, usb_hid_report_descriptor_mouse, HID_REPORT_DESCRIPTOR_LENGTH_MOUSE));
/* Add required endpoints to the interface */
(void)PanicFalse(UsbAddEndPoints(ui_mouse, 1, usb_hid_endpoint_info_mouse));
#endif
}
#ifdef USB_KEYBOARD
void UsbInitKeyboardDevice(appDeviceTaskData *theDevice)
{
theDevice->usb_sink = StreamUsbClassSink(ui_keyboard);
theDevice->usb_source = StreamUsbClassSource(ui_keyboard);
MessageSinkTask(theDevice->usb_sink, &theDevice->task);
}
#endif
#ifdef USB_MOUSE
void UsbInitMouseDevice(appDeviceTaskData *theDevice)
{
theDevice->usb_sink = StreamUsbClassSink(ui_mouse);
theDevice->usb_source = StreamUsbClassSource(ui_mouse);
MessageSinkTask(theDevice->usb_sink, &theDevice->task);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -