| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
HIDClassDevice.c
Go to the documentation of this file.
1 /*
2 * @brief Device mode driver for the library USB HID Class driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * Copyright(C) Dean Camera, 2011, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33
34 #define __INCLUDE_FROM_USB_DRIVER
35 #include "../../Core/USBMode.h"
36
37 #if defined(USB_CAN_BE_DEVICE)
38
39 #define __INCLUDE_FROM_HID_DRIVER
40 #define __INCLUDE_FROM_HID_DEVICE_C
41 #include "HIDClassDevice.h"
42
43 void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
44 {
45 if (!(Endpoint_IsSETUPReceived(HIDInterfaceInfo->Config.PortNumber)))
46 return;
47
48 if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
49 return;
50
51 switch (USB_ControlRequest.bRequest)
52 {
53 case HID_REQ_GetReport:
54 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
55 {
56 uint16_t ReportSize = 0;
57 uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
58 uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
59 uint8_t ReportData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
60
61 memset(ReportData, 0, sizeof(ReportData));
62
63 CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType, ReportData, &ReportSize);
64
65 if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
66 {
67 memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData,
68 HIDInterfaceInfo->Config.PrevReportINBufferSize);
69 }
70
71 Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.PortNumber, ENDPOINT_CONTROLEP);
72
73 Endpoint_ClearSETUP(HIDInterfaceInfo->Config.PortNumber);
74 Endpoint_Write_Control_Stream_LE(HIDInterfaceInfo->Config.PortNumber, ReportData, ReportSize);
75 Endpoint_ClearOUT(HIDInterfaceInfo->Config.PortNumber);
76 }
77
78 break;
79 case HID_REQ_SetReport:
80 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
81 {
82 uint16_t ReportSize = USB_ControlRequest.wLength;
83 uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
84 uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
85 uint8_t ReportData[ReportSize];
86
87 Endpoint_ClearSETUP(HIDInterfaceInfo->Config.PortNumber);
88 Endpoint_Read_Control_Stream_LE(HIDInterfaceInfo->Config.PortNumber, ReportData, ReportSize);
89 Endpoint_ClearIN(HIDInterfaceInfo->Config.PortNumber);
90
91 CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType,
92 &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));
93 }
94
95 break;
96 case HID_REQ_GetProtocol:
97 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
98 {
99 Endpoint_ClearSETUP(HIDInterfaceInfo->Config.PortNumber);
100 Endpoint_Write_8(HIDInterfaceInfo->Config.PortNumber, HIDInterfaceInfo->State.UsingReportProtocol);
101 Endpoint_ClearIN(HIDInterfaceInfo->Config.PortNumber);
102 Endpoint_ClearStatusStage(HIDInterfaceInfo->Config.PortNumber);
103 }
104
105 break;
106 case HID_REQ_SetProtocol:
107 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
108 {
109 Endpoint_ClearSETUP(HIDInterfaceInfo->Config.PortNumber);
110 Endpoint_ClearStatusStage(HIDInterfaceInfo->Config.PortNumber);
111
112 HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
113 }
114
115 break;
116 case HID_REQ_SetIdle:
117 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
118 {
119 Endpoint_ClearSETUP(HIDInterfaceInfo->Config.PortNumber);
120 Endpoint_ClearStatusStage(HIDInterfaceInfo->Config.PortNumber);
121
122 HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
123 }
124
125 break;
126 case HID_REQ_GetIdle:
127 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
128 {
129 Endpoint_ClearSETUP(HIDInterfaceInfo->Config.PortNumber);
130 Endpoint_Write_8(HIDInterfaceInfo->Config.PortNumber, HIDInterfaceInfo->State.IdleCount >> 2);
131 Endpoint_ClearIN(HIDInterfaceInfo->Config.PortNumber);
132 Endpoint_ClearStatusStage(HIDInterfaceInfo->Config.PortNumber);
133 }
134
135 break;
136 }
137 }
138
139 bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
140 {
141 memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
142 HIDInterfaceInfo->State.UsingReportProtocol = true;
143 HIDInterfaceInfo->State.IdleCount = 500;
144
145 if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->Config.PortNumber, HIDInterfaceInfo->Config.ReportINEndpointNumber, EP_TYPE_INTERRUPT,
146 ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize,
147 HIDInterfaceInfo->Config.ReportINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
148 {
149 return false;
150 }
151
152 return true;
153 }
154
155 void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
156 {
157 if (USB_DeviceState[HIDInterfaceInfo->Config.PortNumber] != DEVICE_STATE_Configured)
158 return;
159
160 Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.PortNumber, HIDInterfaceInfo->Config.ReportINEndpointNumber);
161
162 if (Endpoint_IsReadWriteAllowed(HIDInterfaceInfo->Config.PortNumber))
163 {
164 uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
165 uint8_t ReportID = 0;
166 uint16_t ReportINSize = 0;
167
168 memset(ReportINData, 0, sizeof(ReportINData));
169
170 bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In,
171 ReportINData, &ReportINSize);
172 bool StatesChanged = false;
173 bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
174
175 if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
176 {
177 StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
178 memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
179 }
180
181 if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
182 {
183 HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
184
185 Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.PortNumber, HIDInterfaceInfo->Config.ReportINEndpointNumber);
186
187 if (ReportID)
188 Endpoint_Write_8(HIDInterfaceInfo->Config.PortNumber, ReportID);
189
190 Endpoint_Write_Stream_LE(HIDInterfaceInfo->Config.PortNumber, ReportINData, ReportINSize, NULL);
191
192 Endpoint_ClearIN(HIDInterfaceInfo->Config.PortNumber);
193 }
194 }
195 }
196
197 #endif
198