Statistics
| Branch: | Tag: | Revision:

root / LUFA / Drivers / USB / Class / Device / HID.c @ 978b99e5

History | View | Annotate | Download (6.52 KB)

1
/*
2
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7
*/
8

    
9
/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16
  permission notice and warranty disclaimer appear in supporting
17
  documentation, and that the name of the author not be used in
18
  advertising or publicity pertaining to distribution of the
19
  software without specific, written prior permission.
20

21
  The author disclaim all warranties with regard to this
22
  software, including all implied warranties of merchantability
23
  and fitness.  In no event shall the author be liable for any
24
  special, indirect or consequential damages or any damages
25
  whatsoever resulting from loss of use, data or profits, whether
26
  in an action of contract, negligence or other tortious action,
27
  arising out of or in connection with the use or performance of
28
  this software.
29
*/
30

    
31
#define  __INCLUDE_FROM_USB_DRIVER
32
#include "../../Core/USBMode.h"
33

    
34
#if defined(USB_CAN_BE_DEVICE)
35

    
36
#define  __INCLUDE_FROM_HID_DRIVER
37
#define  __INCLUDE_FROM_HID_DEVICE_C
38
#include "HID.h"
39

    
40
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
41
{
42
        if (!(Endpoint_IsSETUPReceived()))
43
          return;
44

    
45
        if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
46
          return;
47

    
48
        switch (USB_ControlRequest.bRequest)
49
        {
50
                case HID_REQ_GetReport:
51
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
52
                        {
53
                                uint16_t ReportSize = 0;
54
                                uint8_t  ReportID   = (USB_ControlRequest.wValue & 0xFF);
55
                                uint8_t  ReportType = (USB_ControlRequest.wValue >> 8) - 1;
56
                                uint8_t  ReportData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
57

    
58
                                memset(ReportData, 0, sizeof(ReportData));
59

    
60
                                CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType, ReportData, &ReportSize);
61

    
62
                                if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
63
                                {
64
                                        memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData,
65
                                               HIDInterfaceInfo->Config.PrevReportINBufferSize);
66
                                }
67
                                
68
                                Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
69

    
70
                                Endpoint_ClearSETUP();
71
                                Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
72
                                Endpoint_ClearOUT();
73
                        }
74

    
75
                        break;
76
                case HID_REQ_SetReport:
77
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
78
                        {
79
                                uint16_t ReportSize = USB_ControlRequest.wLength;
80
                                uint8_t  ReportID   = (USB_ControlRequest.wValue & 0xFF);
81
                                uint8_t  ReportType = (USB_ControlRequest.wValue >> 8) - 1;
82
                                uint8_t  ReportData[ReportSize];
83

    
84
                                Endpoint_ClearSETUP();
85
                                Endpoint_Read_Control_Stream_LE(ReportData, ReportSize);
86
                                Endpoint_ClearIN();
87
                                
88
                                CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType,
89
                                                                     &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));
90
                        }
91

    
92
                        break;
93
                case HID_REQ_GetProtocol:
94
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
95
                        {
96
                                Endpoint_ClearSETUP();
97
                                Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol);
98
                                Endpoint_ClearIN();
99
                                Endpoint_ClearStatusStage();
100
                        }
101

    
102
                        break;
103
                case HID_REQ_SetProtocol:
104
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
105
                        {
106
                                Endpoint_ClearSETUP();
107
                                Endpoint_ClearStatusStage();
108

    
109
                                HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
110
                        }
111

    
112
                        break;
113
                case HID_REQ_SetIdle:
114
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
115
                        {
116
                                Endpoint_ClearSETUP();
117
                                Endpoint_ClearStatusStage();
118

    
119
                                HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
120
                        }
121

    
122
                        break;
123
                case HID_REQ_GetIdle:
124
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
125
                        {
126
                                Endpoint_ClearSETUP();
127
                                Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2);
128
                                Endpoint_ClearIN();
129
                                Endpoint_ClearStatusStage();
130
                        }
131

    
132
                        break;
133
        }
134
}
135

    
136
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
137
{
138
        memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
139
        HIDInterfaceInfo->State.UsingReportProtocol = true;
140
        HIDInterfaceInfo->State.IdleCount           = 500;
141

    
142
        if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber, EP_TYPE_INTERRUPT,
143
                                                                         ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize,
144
                                                                         HIDInterfaceInfo->Config.ReportINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
145
        {
146
                return false;
147
        }
148

    
149
        return true;
150
}
151

    
152
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
153
{
154
        if (USB_DeviceState != DEVICE_STATE_Configured)
155
          return;
156

    
157
        Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
158

    
159
        if (Endpoint_IsReadWriteAllowed())
160
        {
161
                uint8_t  ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
162
                uint8_t  ReportID     = 0;
163
                uint16_t ReportINSize = 0;
164

    
165
                memset(ReportINData, 0, sizeof(ReportINData));
166

    
167
                bool ForceSend         = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In,
168
                                                                             ReportINData, &ReportINSize);
169
                bool StatesChanged     = false;
170
                bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
171

    
172
                if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
173
                {
174
                        StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
175
                        memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
176
                }
177

    
178
                if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
179
                {
180
                        HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
181

    
182
                        Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
183

    
184
                        if (ReportID)
185
                          Endpoint_Write_8(ReportID);
186

    
187
                        Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NULL);
188

    
189
                        Endpoint_ClearIN();
190
                }
191
        }
192
}
193

    
194
#endif
195