source: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/device/HID/tusbd_hid.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 12.6 KB
Line 
1/*
2 * TOPPERS BASE PLATFORM MIDDLEWARE
3 *
4 * Copyright (C) 2017-2017 by TOPPERS PROJECT
5 * Educational Working Group.
6 *
7 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 * @(#) $Id$
37 */
38/*
39 * USB Device HID CLASS部
40 */
41
42#include "tusbd_hid.h"
43
44
45
46#define HID_VERSION_1_11 (0x0111)
47
48#define HID_INTERVAL_TIME 10
49
50#ifndef HID_INTERFCAE_PROTOCOL
51#define HID_INTERFCAE_PROTOCOL 0x02 /* 2:mouse 1:keyboard */
52#endif
53
54
55
56/*
57 * REPORT DESCRIPTOR
58 */
59static uint8_t reportDescriptor[] __attribute__ ((aligned (USB_DATA_ALIGN))) = {
60
61 USAGE_PAGE(1), 0x01,
62 USAGE(1), 0x02,
63
64 COLLECTION(1), 0x01,
65 USAGE(1), 0x01,
66
67 COLLECTION(1), 0x00,
68 USAGE_PAGE(1), 0x09,
69 USAGE_MINIMUM(1), 0x01,
70 USAGE_MAXIMUM(1), 0x03,
71 LOGICAL_MINIMUM(1), 0x00,
72 LOGICAL_MAXIMUM(1), 0x01,
73 REPORT_COUNT(1), 0x03,
74 REPORT_SIZE(1), 0x01,
75 INPUT(1), 0x02,
76 REPORT_COUNT(1), 0x01,
77 REPORT_SIZE(1), 0x05,
78 INPUT(1), 0x01,
79 USAGE_PAGE(1), 0x01,
80 USAGE(1), 0x30,
81 USAGE(1), 0x31,
82 USAGE(1), 0x38,
83
84 LOGICAL_MINIMUM(1), 0x81,
85 LOGICAL_MAXIMUM(1), 0x7F,
86 REPORT_SIZE(1), 0x08,
87 REPORT_COUNT(1), 0x03,
88
89 INPUT(1), 0x06,
90 END_COLLECTION(0),
91
92 USAGE(1), 0x3c,
93 USAGE_PAGE(1), 0xff,
94 USAGE(1), 0x01,
95 LOGICAL_MINIMUM(1), 0x00,
96 LOGICAL_MAXIMUM(1), 0x01,
97 REPORT_SIZE(1), 0x01,
98 REPORT_COUNT(1), 0x02,
99 FEATURE(1), 0x22,
100 REPORT_SIZE(1), 0x06,
101 REPORT_COUNT(1), 0x01,
102 FEATURE(1), 0x01,
103 END_COLLECTION(0)
104};
105
106/*
107 * USB HID DEVICE CONFIGURATION DESCRIPTOR
108 */
109uint8_t configurationHidDescriptor[TOTAL_HID_DESCRIPTOR_LENGTH] __attribute__ ((aligned (USB_DATA_ALIGN))) =
110{
111 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
112 CONFIGURATION_DESCRIPTOR, // bDescriptorType
113 (TOTAL_HID_DESCRIPTOR_LENGTH & 0xFF), // wTotalLength (LSB)
114 (TOTAL_HID_DESCRIPTOR_LENGTH >> 8), // wTotalLength (MSB)
115 0x01, // bNumInterfaces
116 0x01, // bConfigurationValue
117 0x00, // iConfiguration
118 C_RESERVED | C_SELF_POWERED | C_REMOTE_WAKEUP, // bmAttributes
119 C_POWER(100), // bMaxPower
120
121 INTERFACE_DESCRIPTOR_LENGTH, // bLength
122 INTERFACE_DESCRIPTOR, // bDescriptorType
123 0x00, // bInterfaceNumber
124 0x00, // bAlternateSetting
125 0x01, // bNumEndpoints
126 HID_CLASS, // bInterfaceClass
127 0x01, // bInterfaceSubClass : 1=BOOT, 0=no boot
128 HID_INTERFCAE_PROTOCOL, // bInterfaceProtocol
129 0x00, // iInterface
130
131 HID_DESCRIPTOR_LENGTH, // bLength
132 HID_DESCRIPTOR, // bDescriptorType
133 (HID_VERSION_1_11 & 0xFF), // bcdHID (LSB)
134 (HID_VERSION_1_11 >> 8), // bcdHID (MSB)
135 0x00, // bCountryCode
136 0x01, // bNumDescriptors
137 0x22, // bDescriptorType
138 (sizeof(reportDescriptor) & 0xFF), // wDescriptorLength (LSB)
139 (sizeof(reportDescriptor) >> 8), // wDescriptorLength (MSB)
140
141 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
142 ENDPOINT_DESCRIPTOR, // bDescriptorType
143 EPIN_ADDR, // bEndpointAddress
144 USB_EP_TYPE_INTR, // bmAttributes
145 (EPIN_SIZE & 0xFF), // wMaxPacketSize (LSB)
146 (EPIN_SIZE >> 8), // wMaxPacketSize (MSB)
147 HID_INTERVAL_TIME // bInterval (milliseconds)
148};
149
150/*
151 * USB HID DEVICE OTHER CONFIGURATION DESCRIPTOR
152 */
153uint8_t configurationHidOtherDescriptor[TOTAL_HID_DESCRIPTOR_LENGTH] __attribute__ ((aligned (USB_DATA_ALIGN))) =
154{
155 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
156 OTHER_SPEED_CONFIGURATION_DESC, // bDescriptorType
157 (TOTAL_HID_DESCRIPTOR_LENGTH & 0xFF), // wTotalLength (LSB)
158 (TOTAL_HID_DESCRIPTOR_LENGTH >> 8), // wTotalLength (MSB)
159 0x01, // bNumInterfaces
160 0x01, // bConfigurationValue
161 0x00, // iConfiguration
162 C_RESERVED | C_SELF_POWERED | C_REMOTE_WAKEUP, // bmAttributes
163 C_POWER(100), // bMaxPower
164
165 INTERFACE_DESCRIPTOR_LENGTH, // bLength
166 INTERFACE_DESCRIPTOR, // bDescriptorType
167 0x00, // bInterfaceNumber
168 0x00, // bAlternateSetting
169 0x01, // bNumEndpoints
170 HID_CLASS, // bInterfaceClass
171 0x01, // bInterfaceSubClass : 1=BOOT, 0=no boot*/
172 0x02, // bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
173 0x00, // iInterface
174
175 HID_DESCRIPTOR_LENGTH, // bLength
176 HID_DESCRIPTOR, // bDescriptorType
177 (HID_VERSION_1_11 & 0xFF), // bcdHID (LSB)
178 (HID_VERSION_1_11 >> 8), // bcdHID (MSB)
179 0x00, // bCountryCode
180 0x01, // bNumDescriptors
181 0x22, // bDescriptorType
182 (sizeof(reportDescriptor) & 0xFF), // wDescriptorLength (LSB)
183 (sizeof(reportDescriptor) >> 8), // wDescriptorLength (MSB)
184
185 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
186 ENDPOINT_DESCRIPTOR, // bDescriptorType
187 EPIN_ADDR, // bEndpointAddress
188 USB_EP_TYPE_INTR, // bmAttributes
189 (EPIN_SIZE & 0xFF), // wMaxPacketSize (LSB)
190 (EPIN_SIZE >> 8), // wMaxPacketSize (MSB)
191 HID_INTERVAL_TIME // bInterval (milliseconds)
192};
193
194static TUSBD_HID_Handle_t HID_CLASS_DATA __attribute__ ((aligned (USB_DATA_ALIGN)));
195
196
197/*
198 * USB DEVICE HID初期化
199 * parameter1 pdevice: USB DEVICEハンドラ
200 * parameter2 idx: Configuration index
201 * return TUSBD_ERCODE
202 */
203TUSBD_ERCODE
204tusbdHidInit(TUSBD_Handle_t *pdevice, uint8_t idx)
205{
206 tusbdDriverOpenEp(pdevice, EPIN_ADDR, USB_EP_TYPE_INTR, EPIN_SIZE);
207 memset(&HID_CLASS_DATA, 0, sizeof(TUSBD_HID_Handle_t));
208 HID_CLASS_DATA.datastate = HID_DATA_IDLE;
209
210 pdevice->pClassData = &HID_CLASS_DATA;
211 return TUSBD_E_OK;
212}
213
214/*
215 * USB DEVICE HIDクラス終了
216 * parameter1 pdevice: USB DEVICEハンドラ
217 * parameter2 idx: Configuration index
218 * return TUSBD_ERCODE
219 */
220TUSBD_ERCODE
221tusbdHidDeInit(TUSBD_Handle_t *pdevice, uint8_t idx)
222{
223 tusbdDriverCloseEp(pdevice, EPIN_ADDR);
224 pdevice->pClassData = NULL;
225 return TUSBD_E_OK;
226}
227
228/*
229 * USB DEVICE HIDクラスセットアップ
230 * parameter1 pdevice: USB DEVICEハンドラ
231 * parameter2 req: usb control requests
232 * return TUSBD_ERCODE
233 */
234void
235tusbdHidSetup(TUSBD_Handle_t *pdevice, UsbSetupRequest *req)
236{
237 TUSBD_HID_Handle_t *hhid = (TUSBD_HID_Handle_t*) pdevice->pClassData;
238 uint16_t len = 0;
239 volatile uint8_t *pbuf = NULL;
240 uint8_t *p;
241 uint32_t i;
242
243 switch (req->bmRequest & USB_REQUEST_TYPE_MASK){
244 case USB_REQUEST_TYPE_STANDARD:
245 switch (req->bRequest){
246 case GET_DESCRIPTOR:
247 if((req->wValue >> 8) == HID_REPORT_DESCRIPTOR){
248 len = sizeof(reportDescriptor);
249 pbuf = reportDescriptor;
250 }
251 else if((req->wValue >> 8) == HID_DESCRIPTOR){
252 pbuf = tusbdFindDescriptor(pdevice, HID_DESCRIPTOR);
253 if(pbuf != NULL){
254 p = pdevice->devData;
255 len = pbuf[0];
256 for(i = 0 ; i < len && i < 32 ; i++)
257 *p++ = *pbuf++;
258 pbuf = pdevice->devData;
259 }
260 }
261 if(len > 0){
262 if(len > req->wLength)
263 len = req->wLength;
264 tusbdControlSendData(pdevice, (uint8_t *)pbuf, len);
265 }
266 break;
267 case GET_INTERFACE:
268 pdevice->devData[0] = hhid->AltSetting;
269 tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
270 break;
271 case SET_INTERFACE:
272 hhid->AltSetting = (uint8_t)(req->wValue);
273 break;
274 }
275 break;
276 case USB_REQUEST_TYPE_CLASS:
277 switch (req->bRequest){
278 case USB_SET_PROTOCOL:
279 hhid->Protocol = (uint8_t)(req->wValue);
280 break;
281 case USB_GET_PROTOCOL:
282 pdevice->devData[0] = hhid->Protocol;
283 tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
284 break;
285 case USB_SET_IDLE:
286 hhid->IdleState = (uint8_t)(req->wValue >> 8);
287 break;
288 case USB_GET_IDLE:
289 pdevice->devData[0] = hhid->IdleState;
290 tusbdControlSendData(pdevice, (uint8_t *)pdevice->devData, 1);
291 break;
292 case USB_GET_REPORT:
293 len = sizeof(reportDescriptor);
294 pbuf = reportDescriptor;
295 if(len > req->wLength)
296 len = req->wLength;
297 tusbdControlSendData(pdevice, (uint8_t *)pbuf, len);
298 break;
299 case USB_SET_REPORT:
300 if(hhid->devReportLength > 0){
301 hhid->devReport[0] = req->wValue & 0xff;
302 len = hhid->devReportLength;
303 if(len > (req->wLength + 1))
304 len = req->wLength + 1;
305 p = pdevice->devData;
306 for(i = 0 ; i < len && i < 32 ; i++)
307 *p++ = hhid->devReport[i+1];
308 tusbdControlSendData(pdevice, pdevice->devData, len);
309 break;
310 }
311 default:
312 tusbdControlSendStall(pdevice, req);
313 return;
314 }
315 break;
316 }
317}
318
319/*
320 * USB DEVICE HIDクラスデータイン
321 * parameter1 pdevice: USB DEVICEハンドラ
322 * parameter2 epnum: Endpoint#
323 * return TUSBD_ERCODE
324 */
325void
326tusbdHidDataIn(TUSBD_Handle_t *pdevice, uint8_t epnum)
327{
328 ((TUSBD_HID_Handle_t *)pdevice->pClassData)->datastate = HID_DATA_IDLE;
329}
330
331/*
332 * USB DEVICE HIDクラスデータ送信
333 * parameter1 pdevice: USB DEVICEハンドラ
334 * parameter2 pdata: 送信データ
335 * parameter3 len: 送信データ長
336 * return TUSBD_ERCODE
337 */
338TUSBD_ERCODE
339tusbdHidSendData(TUSBD_Handle_t *pdevice, uint8_t *pdata, uint16_t len)
340{
341 TUSBD_HID_Handle_t *hhid = (TUSBD_HID_Handle_t*)pdevice->pClassData;
342 uint32_t i;
343
344 if(pdevice->dev_state == TUSBD_STATE_CONFIGURED){
345 if(hhid->datastate == HID_DATA_IDLE){
346 hhid->datastate = HID_DATA_BUSY;
347 for(i = 0 ; i < len && i < 32 ; i++)
348 hhid->hidData[i] = *pdata++;
349 tusbdDriverStartTransmit(pdevice, EPIN_ADDR, hhid->hidData, i);
350 return TUSBD_E_OK;
351 }
352 }
353 return TUSBD_E_BUSY;
354}
355
356/*
357 * USB DEVICE SETUP REPORT
358 * parameter1 pdevice: USB DEVICEハンドラ
359 * parameter2 report: 送信リポートデータ
360 * parameter3 len: 送信リポートデータ長
361 * return TUSBD_ERCODE
362 */
363TUSBD_ERCODE
364tusbdHidSetupReport(TUSBD_Handle_t *pdevice, uint8_t *report, uint16_t len)
365{
366 TUSBD_HID_Handle_t *hhid = (TUSBD_HID_Handle_t*)pdevice->pClassData;
367 uint32_t i;
368
369 for(i = 0 ; i < len && i < (NUM_MAX_OUTREPORT-1) ; i++)
370 hhid->devReport[i+1] = *report++;
371 hhid->devReportLength = i;
372 return 0;
373}
374
375
Note: See TracBrowser for help on using the repository browser.