LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 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 
44 {
45  if (!(Endpoint_IsSETUPReceived()))
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:
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 
72 
74  Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
76  }
77 
78  break;
79  case HID_REQ_SetReport:
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 
88  Endpoint_Read_Control_Stream_LE(ReportData, ReportSize);
90 
91  CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType,
92  &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));
93  }
94 
95  break;
98  {
100  Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol);
103  }
104 
105  break;
106  case HID_REQ_SetProtocol:
108  {
111 
112  HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
113  }
114 
115  break;
116  case HID_REQ_SetIdle:
118  {
121 
122  HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
123  }
124 
125  break;
126  case HID_REQ_GetIdle:
128  {
130  Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2);
133  }
134 
135  break;
136  }
137 }
138 
140 {
141  memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
142  HIDInterfaceInfo->State.UsingReportProtocol = true;
143  HIDInterfaceInfo->State.IdleCount = 500;
144 
146  ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize,
148  {
149  return false;
150  }
151 
152  return true;
153 }
154 
155 void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
156 {
158  return;
159 
161 
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 
186 
187  if (ReportID)
188  Endpoint_Write_8(ReportID);
189 
190  Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NULL);
191 
193  }
194  }
195 }
196 
197 #endif
198