aboutsummaryrefslogtreecommitdiff
path: root/lib/lufa/LUFA/Drivers/USB/Class/Device
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lufa/LUFA/Drivers/USB/Class/Device')
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c197
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h396
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c362
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h386
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c211
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h210
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c131
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h175
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c215
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h161
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c314
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h293
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c508
-rw-r--r--lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h207
14 files changed, 3766 insertions, 0 deletions
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c
new file mode 100644
index 000000000..08cbeb706
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c
@@ -0,0 +1,197 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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_AUDIO_DRIVER
37#define __INCLUDE_FROM_AUDIO_DEVICE_C
38#include "AudioClassDevice.h"
39
40void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
41{
42 if (!(Endpoint_IsSETUPReceived()))
43 return;
44
45 if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
46 {
47 uint8_t InterfaceIndex = (USB_ControlRequest.wIndex & 0xFF);
48
49 if ((InterfaceIndex != AudioInterfaceInfo->Config.ControlInterfaceNumber) &&
50 (InterfaceIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber))
51 {
52 return;
53 }
54 }
55 else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
56 {
57 uint8_t EndpointAddress = (USB_ControlRequest.wIndex & 0xFF);
58
59 if ((EndpointAddress != AudioInterfaceInfo->Config.DataINEndpoint.Address) &&
60 (EndpointAddress != AudioInterfaceInfo->Config.DataOUTEndpoint.Address))
61 {
62 return;
63 }
64 }
65
66 switch (USB_ControlRequest.bRequest)
67 {
68 case REQ_SetInterface:
69 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
70 {
71 Endpoint_ClearSETUP();
72 Endpoint_ClearStatusStage();
73
74 AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
75 EVENT_Audio_Device_StreamStartStop(AudioInterfaceInfo);
76 }
77
78 break;
79 case AUDIO_REQ_GetStatus:
80 if ((USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) ||
81 (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT)))
82 {
83 Endpoint_ClearSETUP();
84 Endpoint_ClearStatusStage();
85 }
86
87 break;
88 case AUDIO_REQ_SetCurrent:
89 case AUDIO_REQ_SetMinimum:
90 case AUDIO_REQ_SetMaximum:
91 case AUDIO_REQ_SetResolution:
92 if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
93 {
94 uint8_t EndpointProperty = USB_ControlRequest.bRequest;
95 uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex;
96 uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8);
97
98 if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
99 EndpointControl, NULL, NULL))
100 {
101 uint16_t ValueLength = USB_ControlRequest.wLength;
102 uint8_t Value[ValueLength];
103
104 Endpoint_ClearSETUP();
105 Endpoint_Read_Control_Stream_LE(Value, ValueLength);
106 Endpoint_ClearIN();
107
108 CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
109 EndpointControl, &ValueLength, Value);
110 }
111 }
112 else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
113 {
114 uint8_t Property = USB_ControlRequest.bRequest;
115 uint8_t Entity = (USB_ControlRequest.wIndex >> 8);
116 uint16_t Parameter = USB_ControlRequest.wValue;
117
118 if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
119 Parameter, NULL, NULL))
120 {
121 uint16_t ValueLength = USB_ControlRequest.wLength;
122 uint8_t Value[ValueLength];
123
124 Endpoint_ClearSETUP();
125 Endpoint_Read_Control_Stream_LE(Value, ValueLength);
126 Endpoint_ClearIN();
127
128 CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
129 Parameter, &ValueLength, Value);
130 }
131 }
132
133 break;
134 case AUDIO_REQ_GetCurrent:
135 case AUDIO_REQ_GetMinimum:
136 case AUDIO_REQ_GetMaximum:
137 case AUDIO_REQ_GetResolution:
138 if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
139 {
140 uint8_t EndpointProperty = USB_ControlRequest.bRequest;
141 uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex;
142 uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8);
143 uint16_t ValueLength = USB_ControlRequest.wLength;
144 uint8_t Value[ValueLength];
145
146 if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
147 EndpointControl, &ValueLength, Value))
148 {
149 Endpoint_ClearSETUP();
150 Endpoint_Write_Control_Stream_LE(Value, ValueLength);
151 Endpoint_ClearOUT();
152 }
153 }
154 else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
155 {
156 uint8_t Property = USB_ControlRequest.bRequest;
157 uint8_t Entity = (USB_ControlRequest.wIndex >> 8);
158 uint16_t Parameter = USB_ControlRequest.wValue;
159 uint16_t ValueLength = USB_ControlRequest.wLength;
160 uint8_t Value[ValueLength];
161
162 if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
163 Parameter, &ValueLength, Value))
164 {
165 Endpoint_ClearSETUP();
166 Endpoint_Write_Control_Stream_LE(Value, ValueLength);
167 Endpoint_ClearOUT();
168 }
169 }
170
171 break;
172 }
173}
174
175bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
176{
177 memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
178
179 AudioInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_ISOCHRONOUS;
180 AudioInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_ISOCHRONOUS;
181
182 if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataINEndpoint, 1)))
183 return false;
184
185 if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataOUTEndpoint, 1)))
186 return false;
187
188 return true;
189}
190
191void Audio_Device_Event_Stub(void)
192{
193
194}
195
196#endif
197
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h
new file mode 100644
index 000000000..ca63511b2
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h
@@ -0,0 +1,396 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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/** \file
32 * \brief Device mode driver for the library USB Audio 1.0 Class driver.
33 *
34 * Device mode driver for the library USB Audio 1.0 Class driver.
35 *
36 * \note This file should not be included directly. It is automatically included as needed by the USB module driver
37 * dispatch header located in LUFA/Drivers/USB.h.
38 */
39
40/** \ingroup Group_USBClassAudio
41 * \defgroup Group_USBClassAudioDevice Audio 1.0 Class Device Mode Driver
42 *
43 * \section Sec_USBClassAudioDevice_Dependencies Module Source Dependencies
44 * The following files must be built with any user project that uses this module:
45 * - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
46 *
47 * \section Sec_USBClassAudioDevice_ModDescription Module Description
48 * Device Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver.
49 *
50 * @{
51 */
52
53#ifndef _AUDIO_CLASS_DEVICE_H_
54#define _AUDIO_CLASS_DEVICE_H_
55
56 /* Includes: */
57 #include "../../USB.h"
58 #include "../Common/AudioClassCommon.h"
59
60 /* Enable C linkage for C++ Compilers: */
61 #if defined(__cplusplus)
62 extern "C" {
63 #endif
64
65 /* Preprocessor Checks: */
66 #if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
67 #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
68 #endif
69
70 /* Public Interface - May be used in end-application: */
71 /* Type Defines: */
72 /** \brief Audio Class Device Mode Configuration and State Structure.
73 *
74 * Class state structure. An instance of this structure should be made for each Audio interface
75 * within the user application, and passed to each of the Audio class driver functions as the
76 * \c AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information.
77 */
78 typedef struct
79 {
80 struct
81 {
82 uint8_t ControlInterfaceNumber; /**< Index of the Audio Control interface within the device this
83 * structure controls.
84 */
85 uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this
86 * structure controls.
87 */
88
89 USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
90 USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
91 } Config; /**< Config data for the USB class interface within the device. All elements in this section
92 * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
93 */
94 struct
95 {
96 bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
97 * of the Audio Streaming interface.
98 */
99 } State; /**< State data for the USB class interface within the device. All elements in this section
100 * are reset to their defaults when the interface is enumerated.
101 */
102 } USB_ClassInfo_Audio_Device_t;
103
104 /* Function Prototypes: */
105 /** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library
106 * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
107 * given Audio interface is selected.
108 *
109 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
110 *
111 * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
112 */
113 bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
114
115 /** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be
116 * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
117 *
118 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
119 */
120 void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
121
122 /** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented
123 * in the user application to handle property manipulations on streaming audio endpoints.
124 *
125 * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for
126 * the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations
127 * to indicate the size of the retrieved data.
128 *
129 * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value
130 * of the \c DataLength parameter.
131 *
132 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
133 * \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t.
134 * \param[in] EndpointAddress Address of the streaming endpoint whose property is being referenced.
135 * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t.
136 * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum
137 * length of the retrieved data. When NULL, the function should return whether the given property
138 * and parameter is valid for the requested endpoint without reading or modifying the Data buffer.
139 * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where
140 * the retrieved data is to be stored for GET operations.
141 *
142 * \return Boolean \c true if the property GET/SET was successful, \c false otherwise
143 */
144 bool CALLBACK_Audio_Device_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
145 const uint8_t EndpointProperty,
146 const uint8_t EndpointAddress,
147 const uint8_t EndpointControl,
148 uint16_t* const DataLength,
149 uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1);
150
151 /** Audio class driver callback for the setting and retrieval of streaming interface properties. This callback must be implemented
152 * in the user application to handle property manipulations on streaming audio interfaces.
153 *
154 * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for
155 * the given entity and should return as fast as possible. When non-NULL, this value may be altered for GET operations
156 * to indicate the size of the retrieved data.
157 *
158 * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value
159 * of the \c DataLength parameter.
160 *
161 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
162 * \param[in] Property Property of the interface to get or set, a value from \ref Audio_ClassRequests_t.
163 * \param[in] EntityAddress Address of the audio entity whose property is being referenced.
164 * \param[in] Parameter Parameter of the entity to get or set, specific to each type of entity (see USB Audio specification).
165 * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum
166 * length of the retrieved data. When NULL, the function should return whether the given property
167 * and parameter is valid for the requested endpoint without reading or modifying the Data buffer.
168 * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where
169 * the retrieved data is to be stored for GET operations.
170 *
171 * \return Boolean \c true if the property GET/SET was successful, \c false otherwise
172 */
173 bool CALLBACK_Audio_Device_GetSetInterfaceProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
174 const uint8_t Property,
175 const uint8_t EntityAddress,
176 const uint16_t Parameter,
177 uint16_t* const DataLength,
178 uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1);
179
180 /** Audio class driver event for an Audio Stream start/stop change. This event fires each time the device receives a stream enable or
181 * disable control request from the host, to start and stop the audio stream. The current state of the stream can be determined by the
182 * State.InterfaceEnabled value inside the Audio interface structure passed as a parameter.
183 *
184 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
185 */
186 void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
187
188 /* Inline Functions: */
189 /** General management task for a given Audio class interface, required for the correct operation of the interface. This should
190 * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
191 *
192 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
193 */
194 static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
195 ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
196 static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
197 {
198 (void)AudioInterfaceInfo;
199 }
200
201 /** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming
202 * OUT endpoint ready for reading.
203 *
204 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
205 * the call will fail.
206 *
207 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
208 *
209 * \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise.
210 */
211 static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
212 ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
213 static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
214 {
215 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
216 return false;
217
218 Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpoint.Address);
219 return Endpoint_IsOUTReceived();
220 }
221
222 /** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects
223 * the streaming IN endpoint ready for writing.
224 *
225 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
226 * the call will fail.
227 *
228 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
229 *
230 * \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise.
231 */
232 static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
233 ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
234 static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
235 {
236 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
237 return false;
238
239 Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpoint.Address);
240 return Endpoint_IsINReady();
241 }
242
243 /** Reads the next 8-bit audio sample from the current audio interface.
244 *
245 * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
246 * that the correct endpoint is selected and ready for data.
247 *
248 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
249 *
250 * \return Signed 8-bit audio sample from the audio interface.
251 */
252 static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
253 ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
254 static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
255 {
256 int8_t Sample;
257
258 (void)AudioInterfaceInfo;
259
260 Sample = Endpoint_Read_8();
261
262 if (!(Endpoint_BytesInEndpoint()))
263 Endpoint_ClearOUT();
264
265 return Sample;
266 }
267
268 /** Reads the next 16-bit audio sample from the current audio interface.
269 *
270 * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
271 * that the correct endpoint is selected and ready for data.
272 *
273 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
274 *
275 * \return Signed 16-bit audio sample from the audio interface.
276 */
277 static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
278 ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
279 static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
280 {
281 int16_t Sample;
282
283 (void)AudioInterfaceInfo;
284
285 Sample = (int16_t)Endpoint_Read_16_LE();
286
287 if (!(Endpoint_BytesInEndpoint()))
288 Endpoint_ClearOUT();
289
290 return Sample;
291 }
292
293 /** Reads the next 24-bit audio sample from the current audio interface.
294 *
295 * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
296 * that the correct endpoint is selected and ready for data.
297 *
298 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
299 *
300 * \return Signed 24-bit audio sample from the audio interface.
301 */
302 static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
303 ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
304 static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
305 {
306 int32_t Sample;
307
308 (void)AudioInterfaceInfo;
309
310 Sample = (((uint32_t)Endpoint_Read_8() << 16) | Endpoint_Read_16_LE());
311
312 if (!(Endpoint_BytesInEndpoint()))
313 Endpoint_ClearOUT();
314
315 return Sample;
316 }
317
318 /** Writes the next 8-bit audio sample to the current audio interface.
319 *
320 * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
321 * ensure that the correct endpoint is selected and ready for data.
322 *
323 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
324 * \param[in] Sample Signed 8-bit audio sample.
325 */
326 static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
327 const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
328 static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
329 const int8_t Sample)
330 {
331 Endpoint_Write_8(Sample);
332
333 if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
334 Endpoint_ClearIN();
335 }
336
337 /** Writes the next 16-bit audio sample to the current audio interface.
338 *
339 * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
340 * ensure that the correct endpoint is selected and ready for data.
341 *
342 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
343 * \param[in] Sample Signed 16-bit audio sample.
344 */
345 static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
346 const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
347 static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
348 const int16_t Sample)
349 {
350 Endpoint_Write_16_LE(Sample);
351
352 if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
353 Endpoint_ClearIN();
354 }
355
356 /** Writes the next 24-bit audio sample to the current audio interface.
357 *
358 * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
359 * ensure that the correct endpoint is selected and ready for data.
360 *
361 * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
362 * \param[in] Sample Signed 24-bit audio sample.
363 */
364 static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
365 const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
366 static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
367 const int32_t Sample)
368 {
369 Endpoint_Write_16_LE(Sample);
370 Endpoint_Write_8(Sample >> 16);
371
372 if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
373 Endpoint_ClearIN();
374 }
375
376 /* Private Interface - For use in library only: */
377 #if !defined(__DOXYGEN__)
378 /* Function Prototypes: */
379 #if defined(__INCLUDE_FROM_AUDIO_DEVICE_C)
380 void Audio_Device_Event_Stub(void) ATTR_CONST;
381
382 void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
383 ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(Audio_Device_Event_Stub);
384 #endif
385
386 #endif
387
388 /* Disable C linkage for C++ Compilers: */
389 #if defined(__cplusplus)
390 }
391 #endif
392
393#endif
394
395/** @} */
396
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
new file mode 100644
index 000000000..867548c00
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
@@ -0,0 +1,362 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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_CDC_DRIVER
37#define __INCLUDE_FROM_CDC_DEVICE_C
38#include "CDCClassDevice.h"
39
40void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
41{
42 if (!(Endpoint_IsSETUPReceived()))
43 return;
44
45 if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
46 return;
47
48 switch (USB_ControlRequest.bRequest)
49 {
50 case CDC_REQ_GetLineEncoding:
51 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
52 {
53 Endpoint_ClearSETUP();
54
55 while (!(Endpoint_IsINReady()));
56
57 Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
58 Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat);
59 Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType);
60 Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits);
61
62 Endpoint_ClearIN();
63 Endpoint_ClearStatusStage();
64 }
65
66 break;
67 case CDC_REQ_SetLineEncoding:
68 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
69 {
70 Endpoint_ClearSETUP();
71
72 while (!(Endpoint_IsOUTReceived()))
73 {
74 if (USB_DeviceState == DEVICE_STATE_Unattached)
75 return;
76 }
77
78 CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE();
79 CDCInterfaceInfo->State.LineEncoding.CharFormat = Endpoint_Read_8();
80 CDCInterfaceInfo->State.LineEncoding.ParityType = Endpoint_Read_8();
81 CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8();
82
83 Endpoint_ClearOUT();
84 Endpoint_ClearStatusStage();
85
86 EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
87 }
88
89 break;
90 case CDC_REQ_SetControlLineState:
91 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
92 {
93 Endpoint_ClearSETUP();
94 Endpoint_ClearStatusStage();
95
96 CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
97
98 EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
99 }
100
101 break;
102 case CDC_REQ_SendBreak:
103 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
104 {
105 Endpoint_ClearSETUP();
106 Endpoint_ClearStatusStage();
107
108 EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue);
109 }
110
111 break;
112 }
113}
114
115bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
116{
117 memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
118
119 CDCInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
120 CDCInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
121 CDCInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
122
123 if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataINEndpoint, 1)))
124 return false;
125
126 if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataOUTEndpoint, 1)))
127 return false;
128
129 if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.NotificationEndpoint, 1)))
130 return false;
131
132 return true;
133}
134
135void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
136{
137 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
138 return;
139
140 #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
141 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
142
143 if (Endpoint_IsINReady())
144 CDC_Device_Flush(CDCInterfaceInfo);
145 #endif
146}
147
148uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
149 const char* const String)
150{
151 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
152 return ENDPOINT_RWSTREAM_DeviceDisconnected;
153
154 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
155 return Endpoint_Write_Stream_LE(String, strlen(String), NULL);
156}
157
158uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
159 const char* const String)
160{
161 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
162 return ENDPOINT_RWSTREAM_DeviceDisconnected;
163
164 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
165 return Endpoint_Write_PStream_LE(String, strlen_P(String), NULL);
166}
167
168uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
169 const void* const Buffer,
170 const uint16_t Length)
171{
172 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
173 return ENDPOINT_RWSTREAM_DeviceDisconnected;
174
175 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
176 return Endpoint_Write_Stream_LE(Buffer, Length, NULL);
177}
178
179uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
180 const void* const Buffer,
181 const uint16_t Length)
182{
183 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
184 return ENDPOINT_RWSTREAM_DeviceDisconnected;
185
186 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
187 return Endpoint_Write_PStream_LE(Buffer, Length, NULL);
188}
189
190uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
191 const uint8_t Data)
192{
193 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
194 return ENDPOINT_RWSTREAM_DeviceDisconnected;
195
196 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
197
198 if (!(Endpoint_IsReadWriteAllowed()))
199 {
200 Endpoint_ClearIN();
201
202 uint8_t ErrorCode;
203
204 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
205 return ErrorCode;
206 }
207
208 Endpoint_Write_8(Data);
209 return ENDPOINT_READYWAIT_NoError;
210}
211
212uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
213{
214 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
215 return ENDPOINT_RWSTREAM_DeviceDisconnected;
216
217 uint8_t ErrorCode;
218
219 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
220
221 if (!(Endpoint_BytesInEndpoint()))
222 return ENDPOINT_READYWAIT_NoError;
223
224 bool BankFull = !(Endpoint_IsReadWriteAllowed());
225
226 Endpoint_ClearIN();
227
228 if (BankFull)
229 {
230 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
231 return ErrorCode;
232
233 Endpoint_ClearIN();
234 }
235
236 return ENDPOINT_READYWAIT_NoError;
237}
238
239uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
240{
241 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
242 return 0;
243
244 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address);
245
246 if (Endpoint_IsOUTReceived())
247 {
248 if (!(Endpoint_BytesInEndpoint()))
249 {
250 Endpoint_ClearOUT();
251 return 0;
252 }
253 else
254 {
255 return Endpoint_BytesInEndpoint();
256 }
257 }
258 else
259 {
260 return 0;
261 }
262}
263
264int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
265{
266 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
267 return -1;
268
269 int16_t ReceivedByte = -1;
270
271 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address);
272
273 if (Endpoint_IsOUTReceived())
274 {
275 if (Endpoint_BytesInEndpoint())
276 ReceivedByte = Endpoint_Read_8();
277
278 if (!(Endpoint_BytesInEndpoint()))
279 Endpoint_ClearOUT();
280 }
281
282 return ReceivedByte;
283}
284
285void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
286{
287 if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
288 return;
289
290 Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpoint.Address);
291
292 USB_Request_Header_t Notification = (USB_Request_Header_t)
293 {
294 .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
295 .bRequest = CDC_NOTIF_SerialState,
296 .wValue = CPU_TO_LE16(0),
297 .wIndex = CPU_TO_LE16(0),
298 .wLength = CPU_TO_LE16(sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost)),
299 };
300
301 Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
302 Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
303 sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
304 NULL);
305 Endpoint_ClearIN();
306}
307
308#if defined(FDEV_SETUP_STREAM)
309void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
310 FILE* const Stream)
311{
312 *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
313 fdev_set_udata(Stream, CDCInterfaceInfo);
314}
315
316void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
317 FILE* const Stream)
318{
319 *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
320 fdev_set_udata(Stream, CDCInterfaceInfo);
321}
322
323static int CDC_Device_putchar(char c,
324 FILE* Stream)
325{
326 return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
327}
328
329static int CDC_Device_getchar(FILE* Stream)
330{
331 int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
332
333 if (ReceivedByte < 0)
334 return _FDEV_EOF;
335
336 return ReceivedByte;
337}
338
339static int CDC_Device_getchar_Blocking(FILE* Stream)
340{
341 int16_t ReceivedByte;
342
343 while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0)
344 {
345 if (USB_DeviceState == DEVICE_STATE_Unattached)
346 return _FDEV_EOF;
347
348 CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
349 USB_USBTask();
350 }
351
352 return ReceivedByte;
353}
354#endif
355
356void CDC_Device_Event_Stub(void)
357{
358
359}
360
361#endif
362
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h
new file mode 100644
index 000000000..9d5c4e5a0
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h
@@ -0,0 +1,386 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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/** \file
32 * \brief Device mode driver for the library USB CDC Class driver.
33 *
34 * Device mode driver for the library USB CDC Class driver.
35 *
36 * \note This file should not be included directly. It is automatically included as needed by the USB module driver
37 * dispatch header located in LUFA/Drivers/USB.h.
38 */
39
40/** \ingroup Group_USBClassCDC
41 * \defgroup Group_USBClassCDCDevice CDC Class Device Mode Driver
42 *
43 * \section Sec_USBClassCDCDevice_Dependencies Module Source Dependencies
44 * The following files must be built with any user project that uses this module:
45 * - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
46 *
47 * \section Sec_USBClassCDCDevice_ModDescription Module Description
48 * Device Mode USB Class driver framework interface, for the CDC USB Class driver.
49 *
50 * \note There are several major drawbacks to the CDC-ACM standard USB class, however
51 * it is very standardized and thus usually available as a built-in driver on
52 * most platforms, and so is a better choice than a proprietary serial class.
53 *
54 * One major issue with CDC-ACM is that it requires two Interface descriptors,
55 * which will upset most hosts when part of a multi-function "Composite" USB
56 * device. This is because each interface will be loaded into a separate driver
57 * instance, causing the two interfaces be become unlinked. To prevent this, you
58 * should use the "Interface Association Descriptor" addendum to the USB 2.0 standard
59 * which is available on most OSes when creating Composite devices.
60 *
61 * Another major oversight is that there is no mechanism for the host to notify the
62 * device that there is a data sink on the host side ready to accept data. This
63 * means that the device may try to send data while the host isn't listening, causing
64 * lengthy blocking timeouts in the transmission routines. It is thus highly recommended
65 * that the virtual serial line DTR (Data Terminal Ready) signal be used where possible
66 * to determine if a host application is ready for data.
67 *
68 * @{
69 */
70
71#ifndef _CDC_CLASS_DEVICE_H_
72#define _CDC_CLASS_DEVICE_H_
73
74 /* Includes: */
75 #include "../../USB.h"
76 #include "../Common/CDCClassCommon.h"
77
78 #include <stdio.h>
79
80 /* Enable C linkage for C++ Compilers: */
81 #if defined(__cplusplus)
82 extern "C" {
83 #endif
84
85 /* Preprocessor Checks: */
86 #if !defined(__INCLUDE_FROM_CDC_DRIVER)
87 #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
88 #endif
89
90 /* Public Interface - May be used in end-application: */
91 /* Type Defines: */
92 /** \brief CDC Class Device Mode Configuration and State Structure.
93 *
94 * Class state structure. An instance of this structure should be made for each CDC interface
95 * within the user application, and passed to each of the CDC class driver functions as the
96 * CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information.
97 */
98 typedef struct
99 {
100 struct
101 {
102 uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */
103
104 USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
105 USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
106 USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */
107 } Config; /**< Config data for the USB class interface within the device. All elements in this section
108 * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
109 */
110 struct
111 {
112 struct
113 {
114 uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_*
115 * masks. This value is updated each time \ref CDC_Device_USBTask() is called.
116 */
117 uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_*
118 * masks - to notify the host of changes to these values, call the
119 * \ref CDC_Device_SendControlLineStateChange() function.
120 */
121 } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
122
123 CDC_LineEncoding_t LineEncoding; /**< Line encoding used in the virtual serial port, for the device's information.
124 * This is generally only used if the virtual serial port data is to be
125 * reconstructed on a physical UART.
126 */
127 } State; /**< State data for the USB class interface within the device. All elements in this section
128 * are reset to their defaults when the interface is enumerated.
129 */
130 } USB_ClassInfo_CDC_Device_t;
131
132 /* Function Prototypes: */
133 /** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library
134 * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
135 * the given CDC interface is selected.
136 *
137 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
138 *
139 * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
140 */
141 bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
142
143 /** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be
144 * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
145 *
146 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
147 */
148 void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
149
150 /** General management task for a given CDC class interface, required for the correct operation of the interface. This should
151 * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
152 *
153 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
154 */
155 void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
156
157 /** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
158 * line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
159 * user program by declaring a handler function with the same name and parameters listed here. The new line encoding
160 * settings are available in the \c LineEncoding structure inside the CDC interface structure passed as a parameter.
161 *
162 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
163 */
164 void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
165
166 /** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
167 * control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
168 * user program by declaring a handler function with the same name and parameters listed here. The new control line states
169 * are available in the \c ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as
170 * a mask of \c CDC_CONTROL_LINE_OUT_* masks.
171 *
172 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
173 */
174 void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
175
176 /** CDC class driver event for a send break request sent to the device from the host. This is generally used to separate
177 * data or to indicate a special condition to the receiving device.
178 *
179 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
180 * \param[in] Duration Duration of the break that has been sent by the host, in milliseconds.
181 */
182 void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
183 const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
184
185 /** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
186 * called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
187 * becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
188 * for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
189 *
190 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
191 * the call will fail.
192 *
193 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
194 * \param[in] Buffer Pointer to a buffer containing the data to send to the device.
195 * \param[in] Length Length of the data to send to the host.
196 *
197 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
198 */
199 uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
200 const void* const Buffer,
201 const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
202
203 /** Sends a given data buffer from PROGMEM space to the attached USB host, if connected. If a host is not connected when the
204 * function is called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint
205 * bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
206 * for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
207 *
208 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
209 * the call will fail.
210 *
211 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
212 * \param[in] Buffer Pointer to a buffer containing the data to send to the device.
213 * \param[in] Length Length of the data to send to the host.
214 *
215 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
216 */
217 uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
218 const void* const Buffer,
219 const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
220
221 /** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
222 * the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
223 * the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
224 * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
225 *
226 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
227 * the call will fail.
228 *
229 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
230 * \param[in] String Pointer to the null terminated string to send to the host.
231 *
232 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
233 */
234 uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
235 const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
236
237 /** Sends a given null terminated string from PROGMEM space to the attached USB host, if connected. If a host is not connected
238 * when the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
239 * the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
240 * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
241 *
242 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
243 * the call will fail.
244 *
245 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
246 * \param[in] String Pointer to the null terminated string to send to the host.
247 *
248 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
249 */
250 uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
251 const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
252
253 /** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
254 * byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
255 * \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
256 * packed into a single endpoint packet, increasing data throughput.
257 *
258 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
259 * the call will fail.
260 *
261 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
262 * \param[in] Data Byte of data to send to the host.
263 *
264 * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
265 */
266 uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
267 const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
268
269 /** Determines the number of bytes received by the CDC interface from the host, waiting to be read. This indicates the number
270 * of bytes in the OUT endpoint bank only, and thus the number of calls to \ref CDC_Device_ReceiveByte() which are guaranteed to
271 * succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint
272 * bank will not be released back to the USB controller until all bytes are read.
273 *
274 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
275 * the call will fail.
276 *
277 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
278 *
279 * \return Total number of buffered bytes received from the host.
280 */
281 uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
282
283 /** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
284 * returns a negative value. The \ref CDC_Device_BytesReceived() function may be queried in advance to determine how many
285 * bytes are currently buffered in the CDC interface's data receive endpoint bank, and thus how many repeated calls to this
286 * function which are guaranteed to succeed.
287 *
288 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
289 * the call will fail.
290 *
291 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
292 *
293 * \return Next received byte from the host, or a negative value if no data received.
294 */
295 int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
296
297 /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
298 *
299 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
300 * the call will fail.
301 *
302 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
303 *
304 * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
305 */
306 uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
307
308 /** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
309 * control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist
310 * until they are cleared via a second notification. This should be called each time the CDC class driver's
311 * \c ControlLineStates.DeviceToHost value is updated to push the new states to the USB host.
312 *
313 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
314 * the call will fail.
315 *
316 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
317 */
318 void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
319
320 #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__)
321 /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular
322 * functions in the standard <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created
323 * stream is bidirectional and can be used for both input and output functions.
324 *
325 * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
326 * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
327 * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
328 * line buffering.
329 *
330 * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions
331 * to the given CDC interface.
332 * \n\n
333 *
334 * \note This function is not available on all microcontroller architectures.
335 *
336 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
337 * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
338 */
339 void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
340 FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
341
342 /** Identical to \ref CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
343 * the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
344 *
345 * \note This function is not available on all microcontroller architectures.
346 *
347 * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
348 * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
349 */
350 void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
351 FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
352 #endif
353
354 /* Private Interface - For use in library only: */
355 #if !defined(__DOXYGEN__)
356 /* Function Prototypes: */
357 #if defined(__INCLUDE_FROM_CDC_DEVICE_C)
358 #if defined(FDEV_SETUP_STREAM)
359 static int CDC_Device_putchar(char c,
360 FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
361 static int CDC_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
362 static int CDC_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
363 #endif
364
365 void CDC_Device_Event_Stub(void) ATTR_CONST;
366
367 void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
368 ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
369 void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
370 ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
371 void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
372 const uint8_t Duration) ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1)
373 ATTR_ALIAS(CDC_Device_Event_Stub);
374 #endif
375
376 #endif
377
378 /* Disable C linkage for C++ Compilers: */
379 #if defined(__cplusplus)
380 }
381 #endif
382
383#endif
384
385/** @} */
386
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c
new file mode 100644
index 000000000..a8a6e8b50
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c
@@ -0,0 +1,211 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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 "HIDClassDevice.h"
39
40void 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
72 if (ReportID)
73 Endpoint_Write_8(ReportID);
74
75 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
76 Endpoint_ClearOUT();
77 }
78
79 break;
80 case HID_REQ_SetReport:
81 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
82 {
83 uint16_t ReportSize = USB_ControlRequest.wLength;
84 uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
85 uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
86 uint8_t ReportData[ReportSize];
87
88 Endpoint_ClearSETUP();
89 Endpoint_Read_Control_Stream_LE(ReportData, ReportSize);
90 Endpoint_ClearIN();
91
92 CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType,
93 &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));
94 }
95
96 break;
97 case HID_REQ_GetProtocol:
98 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
99 {
100 Endpoint_ClearSETUP();
101 while (!(Endpoint_IsINReady()));
102 Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol);
103 Endpoint_ClearIN();
104 Endpoint_ClearStatusStage();
105 }
106
107 break;
108 case HID_REQ_SetProtocol:
109 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
110 {
111 Endpoint_ClearSETUP();
112 Endpoint_ClearStatusStage();
113
114 HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
115 }
116
117 break;
118 case HID_REQ_SetIdle:
119 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
120 {
121 Endpoint_ClearSETUP();
122 Endpoint_ClearStatusStage();
123
124 HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
125 }
126
127 break;
128 case HID_REQ_GetIdle:
129 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
130 {
131 Endpoint_ClearSETUP();
132 while (!(Endpoint_IsINReady()));
133 Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2);
134 Endpoint_ClearIN();
135 Endpoint_ClearStatusStage();
136 }
137
138 break;
139 }
140}
141
142bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
143{
144 memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
145 HIDInterfaceInfo->State.UsingReportProtocol = true;
146 HIDInterfaceInfo->State.IdleCount = 500;
147
148 HIDInterfaceInfo->Config.ReportINEndpoint.Type = EP_TYPE_INTERRUPT;
149
150 if (!(Endpoint_ConfigureEndpointTable(&HIDInterfaceInfo->Config.ReportINEndpoint, 1)))
151 return false;
152
153 return true;
154}
155
156void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
157{
158 if (USB_DeviceState != DEVICE_STATE_Configured)
159 return;
160
161 if (HIDInterfaceInfo->State.PrevFrameNum == USB_Device_GetFrameNumber())
162 {
163 #if defined(USB_DEVICE_OPT_LOWSPEED)
164 if (!(USB_Options & USB_DEVICE_OPT_LOWSPEED))
165 return;
166 #else
167 return;
168 #endif
169 }
170
171 Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address);
172
173 if (Endpoint_IsReadWriteAllowed())
174 {
175 uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
176 uint8_t ReportID = 0;
177 uint16_t ReportINSize = 0;
178
179 memset(ReportINData, 0, sizeof(ReportINData));
180
181 bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In,
182 ReportINData, &ReportINSize);
183 bool StatesChanged = false;
184 bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
185
186 if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
187 {
188 StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
189 memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
190 }
191
192 if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
193 {
194 HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
195
196 Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address);
197
198 if (ReportID)
199 Endpoint_Write_8(ReportID);
200
201 Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NULL);
202
203 Endpoint_ClearIN();
204 }
205
206 HIDInterfaceInfo->State.PrevFrameNum = USB_Device_GetFrameNumber();
207 }
208}
209
210#endif
211
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h
new file mode 100644
index 000000000..ae628c87d
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h
@@ -0,0 +1,210 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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/** \file
32 * \brief Device mode driver for the library USB HID Class driver.
33 *
34 * Device mode driver for the library USB HID Class driver.
35 *
36 * \note This file should not be included directly. It is automatically included as needed by the USB module driver
37 * dispatch header located in LUFA/Drivers/USB.h.
38 */
39
40/** \ingroup Group_USBClassHID
41 * \defgroup Group_USBClassHIDDevice HID Class Device Mode Driver
42 *
43 * \section Sec_USBClassHIDDevice_Dependencies Module Source Dependencies
44 * The following files must be built with any user project that uses this module:
45 * - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
46 *
47 * \section Sec_USBClassHIDDevice_ModDescription Module Description
48 * Device Mode USB Class driver framework interface, for the HID USB Class driver.
49 *
50 * @{
51 */
52
53#ifndef _HID_CLASS_DEVICE_H_
54#define _HID_CLASS_DEVICE_H_
55
56 /* Includes: */
57 #include "../../USB.h"
58 #include "../Common/HIDClassCommon.h"
59
60 /* Enable C linkage for C++ Compilers: */
61 #if defined(__cplusplus)
62 extern "C" {
63 #endif
64
65 /* Preprocessor Checks: */
66 #if !defined(__INCLUDE_FROM_HID_DRIVER)
67 #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
68 #endif
69
70 /* Public Interface - May be used in end-application: */
71 /* Type Defines: */
72 /** \brief HID Class Device Mode Configuration and State Structure.
73 *
74 * Class state structure. An instance of this structure should be made for each HID interface
75 * within the user application, and passed to each of the HID class driver functions as the
76 * \c HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information.
77 *
78 * \note Due to technical limitations, the HID device class driver does not utilize a separate OUT
79 * endpoint for host->device communications. Instead, the host->device data (if any) is sent to
80 * the device via the control endpoint.
81 */
82 typedef struct
83 {
84 struct
85 {
86 uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device. */
87
88 USB_Endpoint_Table_t ReportINEndpoint; /**< Data IN HID report endpoint configuration table. */
89
90 void* PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be
91 * stored by the driver, for comparison purposes to detect report changes that
92 * must be sent immediately to the host. This should point to a buffer big enough
93 * to hold the largest HID input report sent from the HID interface. If this is set
94 * to \c NULL, it is up to the user to force transfers when needed in the
95 * \ref CALLBACK_HID_Device_CreateHIDReport() callback function.
96 *
97 * \note Due to the single buffer, the internal driver can only correctly compare
98 * subsequent reports with identical report IDs. In multiple report devices,
99 * this buffer should be set to \c NULL and the decision to send reports made
100 * by the user application instead.
101 */
102 uint8_t PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a
103 * second buffer of the same size within the driver so that subsequent reports
104 * can be compared. If the user app is to determine when reports are to be sent
105 * exclusively (i.e. \c PrevReportINBuffer is \c NULL) this value must still be
106 * set to the size of the largest report the device can issue to the host.
107 */
108 } Config; /**< Config data for the USB class interface within the device. All elements in this section
109 * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
110 */
111 struct
112 {
113 bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode. */
114 uint16_t PrevFrameNum; /**< Frame number of the previous HID report packet opportunity. */
115 uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host. */
116 uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this
117 * should be decremented by the user application if non-zero each millisecond. */
118 } State; /**< State data for the USB class interface within the device. All elements in this section
119 * are reset to their defaults when the interface is enumerated.
120 */
121 } USB_ClassInfo_HID_Device_t;
122
123 /* Function Prototypes: */
124 /** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library
125 * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
126 * containing the given HID interface is selected.
127 *
128 * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
129 *
130 * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
131 */
132 bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
133
134 /** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be
135 * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
136 *
137 * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
138 */
139 void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
140
141 /** General management task for a given HID class interface, required for the correct operation of the interface. This should
142 * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
143 *
144 * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
145 */
146 void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
147
148 /** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either
149 * HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
150 * user is responsible for the creation of the next HID input report to be sent to the host.
151 *
152 * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
153 * \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero,
154 * this should be set to the report ID of the generated HID input report (if any). If multiple
155 * reports are not sent via the given HID interface, this parameter should be ignored.
156 * \param[in] ReportType Type of HID report to generate, either \ref HID_REPORT_ITEM_In or \ref HID_REPORT_ITEM_Feature.
157 * \param[out] ReportData Pointer to a buffer where the generated HID report should be stored.
158 * \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent.
159 *
160 * \return Boolean \c true to force the sending of the report even if it is identical to the previous report and still within
161 * the idle period (useful for devices which report relative movement), \c false otherwise.
162 */
163 bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
164 uint8_t* const ReportID,
165 const uint8_t ReportType,
166 void* ReportData,
167 uint16_t* const ReportSize) ATTR_NON_NULL_PTR_ARG(1)
168 ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5);
169
170 /** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to
171 * either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
172 * the user is responsible for the processing of the received HID output report from the host.
173 *
174 * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
175 * \param[in] ReportID Report ID of the received output report. If multiple reports are not received via the given HID
176 * interface, this parameter should be ignored.
177 * \param[in] ReportType Type of received HID report, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature.
178 * \param[in] ReportData Pointer to a buffer where the received HID report is stored.
179 * \param[in] ReportSize Size in bytes of the received report from the host.
180 */
181 void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
182 const uint8_t ReportID,
183 const uint8_t ReportType,
184 const void* ReportData,
185 const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(4);
186
187 /* Inline Functions: */
188 /** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
189 * decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
190 * that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via
191 * \ref USB_Device_EnableSOFEvents().
192 *
193 * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
194 */
195 static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_ALWAYS_INLINE ATTR_NON_NULL_PTR_ARG(1);
196 static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
197 {
198 if (HIDInterfaceInfo->State.IdleMSRemaining)
199 HIDInterfaceInfo->State.IdleMSRemaining--;
200 }
201
202 /* Disable C linkage for C++ Compilers: */
203 #if defined(__cplusplus)
204 }
205 #endif
206
207#endif
208
209/** @} */
210
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c
new file mode 100644
index 000000000..a35c4082b
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c
@@ -0,0 +1,131 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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_MIDI_DRIVER
37#define __INCLUDE_FROM_MIDI_DEVICE_C
38#include "MIDIClassDevice.h"
39
40bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
41{
42 memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
43
44 MIDIInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
45 MIDIInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
46
47 if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataINEndpoint, 1)))
48 return false;
49
50 if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataOUTEndpoint, 1)))
51 return false;
52
53 return true;
54}
55
56void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
57{
58 if (USB_DeviceState != DEVICE_STATE_Configured)
59 return;
60
61 #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
62 Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
63
64 if (Endpoint_IsINReady())
65 MIDI_Device_Flush(MIDIInterfaceInfo);
66 #endif
67}
68
69uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
70 const MIDI_EventPacket_t* const Event)
71{
72 if (USB_DeviceState != DEVICE_STATE_Configured)
73 return ENDPOINT_RWSTREAM_DeviceDisconnected;
74
75 uint8_t ErrorCode;
76
77 Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
78
79 if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != ENDPOINT_RWSTREAM_NoError)
80 return ErrorCode;
81
82 if (!(Endpoint_IsReadWriteAllowed()))
83 Endpoint_ClearIN();
84
85 return ENDPOINT_RWSTREAM_NoError;
86}
87
88uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
89{
90 if (USB_DeviceState != DEVICE_STATE_Configured)
91 return ENDPOINT_RWSTREAM_DeviceDisconnected;
92
93 uint8_t ErrorCode;
94
95 Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
96
97 if (Endpoint_BytesInEndpoint())
98 {
99 Endpoint_ClearIN();
100
101 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
102 return ErrorCode;
103 }
104
105 return ENDPOINT_READYWAIT_NoError;
106}
107
108bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
109 MIDI_EventPacket_t* const Event)
110{
111 if (USB_DeviceState != DEVICE_STATE_Configured)
112 return false;
113
114 Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpoint.Address);
115
116 if (!(Endpoint_IsOUTReceived()))
117 return false;
118
119 if (!(Endpoint_IsReadWriteAllowed()))
120 return false;
121
122 Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL);
123
124 if (!(Endpoint_IsReadWriteAllowed()))
125 Endpoint_ClearOUT();
126
127 return true;
128}
129
130#endif
131
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h
new file mode 100644
index 000000000..ee2efd7c1
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h
@@ -0,0 +1,175 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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/** \file
32 * \brief Device mode driver for the library USB MIDI Class driver.
33 *
34 * Device mode driver for the library USB MIDI Class driver.
35 *
36 * \note This file should not be included directly. It is automatically included as needed by the USB module driver
37 * dispatch header located in LUFA/Drivers/USB.h.
38 */
39
40/** \ingroup Group_USBClassMIDI
41 * \defgroup Group_USBClassMIDIDevice MIDI Class Device Mode Driver
42 *
43 * \section Sec_USBClassMIDIDevice_Dependencies Module Source Dependencies
44 * The following files must be built with any user project that uses this module:
45 * - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
46 *
47 * \section Sec_USBClassMIDIDevice_ModDescription Module Description
48 * Device Mode USB Class driver framework interface, for the MIDI USB Class driver.
49 *
50 * @{
51 */
52
53#ifndef _MIDI_CLASS_DEVICE_H_
54#define _MIDI_CLASS_DEVICE_H_
55
56 /* Includes: */
57 #include "../../USB.h"
58 #include "../Common/MIDIClassCommon.h"
59
60 /* Enable C linkage for C++ Compilers: */
61 #if defined(__cplusplus)
62 extern "C" {
63 #endif
64
65 /* Preprocessor Checks: */
66 #if !defined(__INCLUDE_FROM_MIDI_DRIVER)
67 #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
68 #endif
69
70 /* Public Interface - May be used in end-application: */
71 /* Type Define: */
72 /** \brief MIDI Class Device Mode Configuration and State Structure.
73 *
74 * Class state structure. An instance of this structure should be made for each MIDI interface
75 * within the user application, and passed to each of the MIDI class driver functions as the
76 * \c MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information.
77 */
78 typedef struct
79 {
80 struct
81 {
82 uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls. */
83
84 USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
85 USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
86 } Config; /**< Config data for the USB class interface within the device. All elements in this section
87 * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
88 */
89
90 struct
91 {
92 uint8_t RESERVED; // No state information for this class
93 } State; /**< State data for the USB class interface within the device. All elements in this section
94 * are reset to their defaults when the interface is enumerated.
95 */
96 } USB_ClassInfo_MIDI_Device_t;
97
98 /* Function Prototypes: */
99 /** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library
100 * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
101 * containing the given MIDI interface is selected.
102 *
103 * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
104 *
105 * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
106 */
107 bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
108
109 /** General management task for a given MIDI class interface, required for the correct operation of the interface. This should
110 * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
111 *
112 * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
113 */
114 void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
115
116 /** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the
117 * endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple
118 * MIDI events to be packed into a single endpoint packet, increasing data throughput.
119 *
120 * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
121 * call will fail.
122 *
123 * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
124 * \param[in] Event Pointer to a populated \ref MIDI_EventPacket_t structure containing the MIDI event to send.
125 *
126 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
127 */
128 uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
129 const MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
130
131
132 /** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the
133 * \ref MIDI_Device_SendEventPacket() function's packing behavior, to flush queued events.
134 *
135 * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
136 *
137 * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
138 */
139 uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
140
141 /** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains
142 * multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event.
143 *
144 * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
145 * call will fail.
146 *
147 * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
148 * \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed.
149 *
150 * \return Boolean \c true if a MIDI event packet was received, \c false otherwise.
151 */
152 bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
153 MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
154
155 /* Inline Functions: */
156 /** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be
157 * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
158 *
159 * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
160 */
161 static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
162 static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
163 {
164 (void)MIDIInterfaceInfo;
165 }
166
167 /* Disable C linkage for C++ Compilers: */
168 #if defined(__cplusplus)
169 }
170 #endif
171
172#endif
173
174/** @} */
175
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c
new file mode 100644
index 000000000..1ea30f7cb
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c
@@ -0,0 +1,215 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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_MS_DRIVER
37#define __INCLUDE_FROM_MASSSTORAGE_DEVICE_C
38#include "MassStorageClassDevice.h"
39
40void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
41{
42 if (!(Endpoint_IsSETUPReceived()))
43 return;
44
45 if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber)
46 return;
47
48 switch (USB_ControlRequest.bRequest)
49 {
50 case MS_REQ_MassStorageReset:
51 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
52 {
53 Endpoint_ClearSETUP();
54 Endpoint_ClearStatusStage();
55
56 MSInterfaceInfo->State.IsMassStoreReset = true;
57 }
58
59 break;
60 case MS_REQ_GetMaxLUN:
61 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
62 {
63 Endpoint_ClearSETUP();
64 while (!(Endpoint_IsINReady()));
65 Endpoint_Write_8(MSInterfaceInfo->Config.TotalLUNs - 1);
66 Endpoint_ClearIN();
67 Endpoint_ClearStatusStage();
68 }
69
70 break;
71 }
72}
73
74bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
75{
76 memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
77
78 MSInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
79 MSInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
80
81 if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataINEndpoint, 1)))
82 return false;
83
84 if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataOUTEndpoint, 1)))
85 return false;
86
87 return true;
88}
89
90void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
91{
92 if (USB_DeviceState != DEVICE_STATE_Configured)
93 return;
94
95 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
96
97 if (Endpoint_IsOUTReceived())
98 {
99 if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
100 {
101 if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
102 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
103
104 bool SCSICommandResult = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo);
105
106 MSInterfaceInfo->State.CommandStatus.Status = (SCSICommandResult) ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail;
107 MSInterfaceInfo->State.CommandStatus.Signature = CPU_TO_LE32(MS_CSW_SIGNATURE);
108 MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag;
109 MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;
110
111 if (!(SCSICommandResult) && (le32_to_cpu(MSInterfaceInfo->State.CommandStatus.DataTransferResidue)))
112 Endpoint_StallTransaction();
113
114 MS_Device_ReturnCommandStatus(MSInterfaceInfo);
115 }
116 }
117
118 if (MSInterfaceInfo->State.IsMassStoreReset)
119 {
120 Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
121 Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
122
123 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
124 Endpoint_ClearStall();
125 Endpoint_ResetDataToggle();
126 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
127 Endpoint_ClearStall();
128 Endpoint_ResetDataToggle();
129
130 MSInterfaceInfo->State.IsMassStoreReset = false;
131 }
132}
133
134static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
135{
136 uint16_t BytesProcessed;
137
138 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
139
140 BytesProcessed = 0;
141 while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock,
142 (sizeof(MS_CommandBlockWrapper_t) - 16), &BytesProcessed) ==
143 ENDPOINT_RWSTREAM_IncompleteTransfer)
144 {
145 if (MSInterfaceInfo->State.IsMassStoreReset)
146 return false;
147 }
148
149 if ((MSInterfaceInfo->State.CommandBlock.Signature != CPU_TO_LE32(MS_CBW_SIGNATURE)) ||
150 (MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) ||
151 (MSInterfaceInfo->State.CommandBlock.Flags & 0x1F) ||
152 (MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0) ||
153 (MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16))
154 {
155 Endpoint_StallTransaction();
156 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
157 Endpoint_StallTransaction();
158
159 return false;
160 }
161
162 BytesProcessed = 0;
163 while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData,
164 MSInterfaceInfo->State.CommandBlock.SCSICommandLength, &BytesProcessed) ==
165 ENDPOINT_RWSTREAM_IncompleteTransfer)
166 {
167 if (MSInterfaceInfo->State.IsMassStoreReset)
168 return false;
169 }
170
171 Endpoint_ClearOUT();
172
173 return true;
174}
175
176static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
177{
178 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
179
180 while (Endpoint_IsStalled())
181 {
182 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
183 USB_USBTask();
184 #endif
185
186 if (MSInterfaceInfo->State.IsMassStoreReset)
187 return;
188 }
189
190 Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
191
192 while (Endpoint_IsStalled())
193 {
194 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
195 USB_USBTask();
196 #endif
197
198 if (MSInterfaceInfo->State.IsMassStoreReset)
199 return;
200 }
201
202 uint16_t BytesProcessed = 0;
203 while (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus,
204 sizeof(MS_CommandStatusWrapper_t), &BytesProcessed) ==
205 ENDPOINT_RWSTREAM_IncompleteTransfer)
206 {
207 if (MSInterfaceInfo->State.IsMassStoreReset)
208 return;
209 }
210
211 Endpoint_ClearIN();
212}
213
214#endif
215
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h
new file mode 100644
index 000000000..12b54f8df
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h
@@ -0,0 +1,161 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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/** \file
32 * \brief Device mode driver for the library USB Mass Storage Class driver.
33 *
34 * Device mode driver for the library USB Mass Storage Class driver.
35 *
36 * \note This file should not be included directly. It is automatically included as needed by the USB module driver
37 * dispatch header located in LUFA/Drivers/USB.h.
38 */
39
40/** \ingroup Group_USBClassMS
41 * \defgroup Group_USBClassMSDevice Mass Storage Class Device Mode Driver
42 *
43 * \section Sec_USBClassMSDevice_Dependencies Module Source Dependencies
44 * The following files must be built with any user project that uses this module:
45 * - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
46 *
47 * \section Sec_USBClassMSDevice_ModDescription Module Description
48 * Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
49 *
50 * @{
51 */
52
53#ifndef _MS_CLASS_DEVICE_H_
54#define _MS_CLASS_DEVICE_H_
55
56 /* Includes: */
57 #include "../../USB.h"
58 #include "../Common/MassStorageClassCommon.h"
59
60 /* Enable C linkage for C++ Compilers: */
61 #if defined(__cplusplus)
62 extern "C" {
63 #endif
64
65 /* Preprocessor Checks: */
66 #if !defined(__INCLUDE_FROM_MS_DRIVER)
67 #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
68 #endif
69
70 /* Public Interface - May be used in end-application: */
71 /* Type Defines: */
72 /** \brief Mass Storage Class Device Mode Configuration and State Structure.
73 *
74 * Class state structure. An instance of this structure should be made for each Mass Storage interface
75 * within the user application, and passed to each of the Mass Storage class driver functions as the
76 * \c MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information.
77 */
78 typedef struct
79 {
80 struct
81 {
82 uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device. */
83
84 USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
85 USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
86
87 uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface. */
88 } Config; /**< Config data for the USB class interface within the device. All elements in this section
89 * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
90 */
91 struct
92 {
93 MS_CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI
94 * command from the host which is to be processed.
95 */
96 MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate
97 * the issued command's success or failure to the host.
98 */
99 volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
100 * and that all current Mass Storage operations should immediately abort.
101 */
102 } State; /**< State data for the USB class interface within the device. All elements in this section
103 * are reset to their defaults when the interface is enumerated.
104 */
105 } USB_ClassInfo_MS_Device_t;
106
107 /* Function Prototypes: */
108 /** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library
109 * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
110 * containing the given Mass Storage interface is selected.
111 *
112 * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
113 *
114 * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
115 */
116 bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
117
118 /** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be
119 * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
120 *
121 * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
122 */
123 void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
124
125 /** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should
126 * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
127 *
128 * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state.
129 */
130 void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
131
132 /** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
133 * host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
134 * for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure
135 * inside the Mass Storage class state structure passed as a parameter to the callback function.
136 *
137 * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
138 *
139 * \return Boolean \c true if the SCSI command was successfully processed, \c false otherwise.
140 */
141 bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
142
143 /* Private Interface - For use in library only: */
144 #if !defined(__DOXYGEN__)
145 /* Function Prototypes: */
146 #if defined(__INCLUDE_FROM_MASSSTORAGE_DEVICE_C)
147 static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
148 static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
149 #endif
150
151 #endif
152
153 /* Disable C linkage for C++ Compilers: */
154 #if defined(__cplusplus)
155 }
156 #endif
157
158#endif
159
160/** @} */
161
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c
new file mode 100644
index 000000000..7209c452d
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c
@@ -0,0 +1,314 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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_PRINTER_DRIVER
37#define __INCLUDE_FROM_PRINTER_DEVICE_C
38#include "PrinterClassDevice.h"
39
40void PRNT_Device_ProcessControlRequest(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
41{
42 if (!(Endpoint_IsSETUPReceived()))
43 return;
44
45 if (USB_ControlRequest.wIndex != PRNTInterfaceInfo->Config.InterfaceNumber)
46 return;
47
48 switch (USB_ControlRequest.bRequest)
49 {
50 case PRNT_REQ_GetDeviceID:
51 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
52 {
53 Endpoint_ClearSETUP();
54
55 while (!(Endpoint_IsINReady()))
56 {
57 if (USB_DeviceState == DEVICE_STATE_Unattached)
58 return;
59 }
60
61 uint16_t IEEEStringLen = strlen(PRNTInterfaceInfo->Config.IEEE1284String);
62 Endpoint_Write_16_BE(IEEEStringLen);
63 Endpoint_Write_Control_Stream_LE(PRNTInterfaceInfo->Config.IEEE1284String, IEEEStringLen);
64 Endpoint_ClearStatusStage();
65 }
66
67 break;
68 case PRNT_REQ_GetPortStatus:
69 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
70 {
71 Endpoint_ClearSETUP();
72
73 while (!(Endpoint_IsINReady()))
74 {
75 if (USB_DeviceState == DEVICE_STATE_Unattached)
76 return;
77 }
78
79 Endpoint_Write_8(PRNTInterfaceInfo->State.PortStatus);
80 Endpoint_ClearStatusStage();
81 }
82
83 break;
84 case PRNT_REQ_SoftReset:
85 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
86 {
87 Endpoint_ClearSETUP();
88 Endpoint_ClearStatusStage();
89
90 PRNTInterfaceInfo->State.IsPrinterReset = true;
91
92 EVENT_PRNT_Device_SoftReset(PRNTInterfaceInfo);
93 }
94
95 break;
96 }
97}
98
99bool PRNT_Device_ConfigureEndpoints(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
100{
101 memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
102 PRNTInterfaceInfo->State.PortStatus = PRNT_PORTSTATUS_NOTERROR | PRNT_PORTSTATUS_SELECT;
103
104 PRNTInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
105 PRNTInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
106
107 if (!(Endpoint_ConfigureEndpointTable(&PRNTInterfaceInfo->Config.DataINEndpoint, 1)))
108 return false;
109
110 if (!(Endpoint_ConfigureEndpointTable(&PRNTInterfaceInfo->Config.DataOUTEndpoint, 1)))
111 return false;
112
113 return true;
114}
115
116void PRNT_Device_USBTask(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
117{
118 if (USB_DeviceState != DEVICE_STATE_Configured)
119 return;
120
121 #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
122 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
123
124 if (Endpoint_IsINReady())
125 PRNT_Device_Flush(PRNTInterfaceInfo);
126 #endif
127
128 if (PRNTInterfaceInfo->State.IsPrinterReset)
129 {
130 Endpoint_ResetEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
131 Endpoint_ResetEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
132
133 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
134 Endpoint_ClearStall();
135 Endpoint_ResetDataToggle();
136 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
137 Endpoint_ClearStall();
138 Endpoint_ResetDataToggle();
139
140 PRNTInterfaceInfo->State.IsPrinterReset = false;
141 }
142}
143
144uint8_t PRNT_Device_SendString(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
145 const char* const String)
146{
147 if (USB_DeviceState != DEVICE_STATE_Configured)
148 return ENDPOINT_RWSTREAM_DeviceDisconnected;
149
150 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
151 return Endpoint_Write_Stream_LE(String, strlen(String), NULL);
152}
153
154uint8_t PRNT_Device_SendData(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
155 const void* const Buffer,
156 const uint16_t Length)
157{
158 if (USB_DeviceState != DEVICE_STATE_Configured)
159 return ENDPOINT_RWSTREAM_DeviceDisconnected;
160
161 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
162 return Endpoint_Write_Stream_LE(Buffer, Length, NULL);
163}
164
165uint8_t PRNT_Device_SendByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
166 const uint8_t Data)
167{
168 if (USB_DeviceState != DEVICE_STATE_Configured)
169 return ENDPOINT_RWSTREAM_DeviceDisconnected;
170
171 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
172
173 if (!(Endpoint_IsReadWriteAllowed()))
174 {
175 Endpoint_ClearIN();
176
177 uint8_t ErrorCode;
178
179 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
180 return ErrorCode;
181 }
182
183 Endpoint_Write_8(Data);
184 return ENDPOINT_READYWAIT_NoError;
185}
186
187uint8_t PRNT_Device_Flush(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
188{
189 if (USB_DeviceState != DEVICE_STATE_Configured)
190 return ENDPOINT_RWSTREAM_DeviceDisconnected;
191
192 uint8_t ErrorCode;
193
194 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
195
196 if (!(Endpoint_BytesInEndpoint()))
197 return ENDPOINT_READYWAIT_NoError;
198
199 bool BankFull = !(Endpoint_IsReadWriteAllowed());
200
201 Endpoint_ClearIN();
202
203 if (BankFull)
204 {
205 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
206 return ErrorCode;
207
208 Endpoint_ClearIN();
209 }
210
211 return ENDPOINT_READYWAIT_NoError;
212}
213
214uint16_t PRNT_Device_BytesReceived(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
215{
216 if (USB_DeviceState != DEVICE_STATE_Configured)
217 return 0;
218
219 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
220
221 if (Endpoint_IsOUTReceived())
222 {
223 if (!(Endpoint_BytesInEndpoint()))
224 {
225 Endpoint_ClearOUT();
226 return 0;
227 }
228 else
229 {
230 return Endpoint_BytesInEndpoint();
231 }
232 }
233 else
234 {
235 return 0;
236 }
237}
238
239int16_t PRNT_Device_ReceiveByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
240{
241 if (USB_DeviceState != DEVICE_STATE_Configured)
242 return -1;
243
244 int16_t ReceivedByte = -1;
245
246 Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
247
248 if (Endpoint_IsOUTReceived())
249 {
250 if (Endpoint_BytesInEndpoint())
251 ReceivedByte = Endpoint_Read_8();
252
253 if (!(Endpoint_BytesInEndpoint()))
254 Endpoint_ClearOUT();
255 }
256
257 return ReceivedByte;
258}
259
260#if defined(FDEV_SETUP_STREAM)
261void PRNT_Device_CreateStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
262 FILE* const Stream)
263{
264 *Stream = (FILE)FDEV_SETUP_STREAM(PRNT_Device_putchar, PRNT_Device_getchar, _FDEV_SETUP_RW);
265 fdev_set_udata(Stream, PRNTInterfaceInfo);
266}
267
268void PRNT_Device_CreateBlockingStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
269 FILE* const Stream)
270{
271 *Stream = (FILE)FDEV_SETUP_STREAM(PRNT_Device_putchar, PRNT_Device_getchar_Blocking, _FDEV_SETUP_RW);
272 fdev_set_udata(Stream, PRNTInterfaceInfo);
273}
274
275static int PRNT_Device_putchar(char c,
276 FILE* Stream)
277{
278 return PRNT_Device_SendByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
279}
280
281static int PRNT_Device_getchar(FILE* Stream)
282{
283 int16_t ReceivedByte = PRNT_Device_ReceiveByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream));
284
285 if (ReceivedByte < 0)
286 return _FDEV_EOF;
287
288 return ReceivedByte;
289}
290
291static int PRNT_Device_getchar_Blocking(FILE* Stream)
292{
293 int16_t ReceivedByte;
294
295 while ((ReceivedByte = PRNT_Device_ReceiveByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream))) < 0)
296 {
297 if (USB_DeviceState == DEVICE_STATE_Unattached)
298 return _FDEV_EOF;
299
300 PRNT_Device_USBTask((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream));
301 USB_USBTask();
302 }
303
304 return ReceivedByte;
305}
306#endif
307
308void PRNT_Device_Event_Stub(void)
309{
310
311}
312
313#endif
314
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h
new file mode 100644
index 000000000..802c5912d
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h
@@ -0,0 +1,293 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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/** \file
32 * \brief Device mode driver for the library USB Printer Class driver.
33 *
34 * Device mode driver for the library USB Printer Class driver.
35 *
36 * \note This file should not be included directly. It is automatically included as needed by the USB module driver
37 * dispatch header located in LUFA/Drivers/USB.h.
38 */
39
40/** \ingroup Group_USBClassPrinter
41 * \defgroup Group_USBClassPrinterDevice Printer Class Device Mode Driver
42 *
43 * \section Sec_USBClassPrinterDevice_Dependencies Module Source Dependencies
44 * The following files must be built with any user project that uses this module:
45 * - LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
46 *
47 * \section Sec_USBClassPrinterDevice_ModDescription Module Description
48 * Device Mode USB Class driver framework interface, for the Printer USB Class driver.
49 *
50 * @{
51 */
52
53#ifndef _PRINTER_CLASS_DEVICE_H_
54#define _PRINTER_CLASS_DEVICE_H_
55
56 /* Includes: */
57 #include "../../USB.h"
58 #include "../Common/PrinterClassCommon.h"
59
60 #include <stdio.h>
61
62 /* Enable C linkage for C++ Compilers: */
63 #if defined(__cplusplus)
64 extern "C" {
65 #endif
66
67 /* Preprocessor Checks: */
68 #if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
69 #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
70 #endif
71
72 /* Public Interface - May be used in end-application: */
73 /* Type Defines: */
74 /** \brief Printer Class Device Mode Configuration and State Structure.
75 *
76 * Class state structure. An instance of this structure should be made for each Printer interface
77 * within the user application, and passed to each of the Printer class driver functions as the
78 * PRNTInterfaceInfo parameter. This stores each Printer interface's configuration and state information.
79 */
80 typedef struct
81 {
82 struct
83 {
84 uint8_t InterfaceNumber; /**< Interface number of the Printer interface within the device. */
85
86 USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
87 USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
88
89 char* IEEE1284String; /**< IEEE 1284 identification string, sent to the host during enumeration
90 * to identify the printer model, manufacturer and other characteristics.
91 */
92 } Config; /**< Config data for the USB class interface within the device. All elements in this section
93 * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
94 */
95 struct
96 {
97 uint8_t PortStatus; /**< Current status of the Printer virtual port, a collection of \c PRNT_PORTSTATUS_*
98 * bitmask values.
99 */
100
101 volatile bool IsPrinterReset; /**< Flag indicating that the host has requested that the Printer interface be reset
102 * and that all current Mass Storage operations should immediately abort.
103 */
104 } State; /**< State data for the USB class interface within the device. All elements in this section
105 * are reset to their defaults when the interface is enumerated.
106 */
107 } USB_ClassInfo_PRNT_Device_t;
108
109 /* Function Prototypes: */
110 /** Configures the endpoints of a given Printer interface, ready for use. This should be linked to the library
111 * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
112 * the given Printer interface is selected.
113 *
114 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
115 *
116 * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
117 */
118 bool PRNT_Device_ConfigureEndpoints(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
119
120 /** Processes incoming control requests from the host, that are directed to the given Printer class interface. This should be
121 * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
122 *
123 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
124 */
125 void PRNT_Device_ProcessControlRequest(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
126
127 /** General management task for a given Printer class interface, required for the correct operation of the interface. This should
128 * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
129 *
130 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
131 */
132 void PRNT_Device_USBTask(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
133
134 /** Printer class driver event for a soft reset request on a Printer interface. This event fires each time the host
135 * requests a reset of the printer interface's internal state, and may be hooked in the user program by declaring a
136 * handler function with the same name and parameters listed here.
137 *
138 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
139 */
140 void EVENT_PRNT_Device_SoftReset(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
141
142 /** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
143 * called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
144 * becomes full, or the \ref PRNT_Device_Flush() function is called to flush the pending data to the host. This allows
145 * for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
146 *
147 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
148 * the call will fail.
149 *
150 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
151 * \param[in] Buffer Pointer to a buffer containing the data to send to the device.
152 * \param[in] Length Length of the data to send to the host.
153 *
154 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
155 */
156 uint8_t PRNT_Device_SendData(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
157 const void* const Buffer,
158 const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
159
160 /** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
161 * the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
162 * the endpoint bank becomes full, or the \ref PRNT_Device_Flush() function is called to flush the pending data to
163 * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
164 *
165 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
166 * the call will fail.
167 *
168 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
169 * \param[in] String Pointer to the null terminated string to send to the host.
170 *
171 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
172 */
173 uint8_t PRNT_Device_SendString(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
174 const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
175
176 /** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
177 * byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
178 * \ref PRNT_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
179 * packed into a single endpoint packet, increasing data throughput.
180 *
181 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
182 * the call will fail.
183 *
184 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
185 * \param[in] Data Byte of data to send to the host.
186 *
187 * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
188 */
189 uint8_t PRNT_Device_SendByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
190 const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
191
192 /** Determines the number of bytes received by the Printer interface from the host, waiting to be read. This indicates the number
193 * of bytes in the OUT endpoint bank only, and thus the number of calls to \ref PRNT_Device_ReceiveByte() which are guaranteed to
194 * succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint
195 * bank will not be released back to the USB controller until all bytes are read.
196 *
197 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
198 * the call will fail.
199 *
200 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
201 *
202 * \return Total number of buffered bytes received from the host.
203 */
204 uint16_t PRNT_Device_BytesReceived(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
205
206 /** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
207 * returns a negative value. The \ref PRNT_Device_BytesReceived() function may be queried in advance to determine how many
208 * bytes are currently buffered in the Printer interface's data receive endpoint bank, and thus how many repeated calls to this
209 * function which are guaranteed to succeed.
210 *
211 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
212 * the call will fail.
213 *
214 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
215 *
216 * \return Next received byte from the host, or a negative value if no data received.
217 */
218 int16_t PRNT_Device_ReceiveByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
219
220 /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
221 *
222 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
223 * the call will fail.
224 *
225 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
226 *
227 * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
228 */
229 uint8_t PRNT_Device_Flush(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
230
231 #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__)
232 /** Creates a standard character stream for the given Printer Device instance so that it can be used with all the regular
233 * functions in the standard <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created
234 * stream is bidirectional and can be used for both input and output functions.
235 *
236 * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
237 * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
238 * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
239 * line buffering.
240 *
241 * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions
242 * to the given Printer interface.
243 * \n\n
244 *
245 * \note This function is not available on all microcontroller architectures.
246 *
247 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
248 * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
249 */
250 void PRNT_Device_CreateStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
251 FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
252
253 /** Identical to \ref PRNT_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
254 * the transfer. While blocking, the USB and Printer service tasks are called repeatedly to maintain USB communications.
255 *
256 * \note This function is not available on all microcontroller architectures.
257 *
258 * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
259 * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
260 */
261 void PRNT_Device_CreateBlockingStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
262 FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
263 #endif
264
265 /* Private Interface - For use in library only: */
266 #if !defined(__DOXYGEN__)
267 /* Function Prototypes: */
268 #if defined(__INCLUDE_FROM_PRINTER_DEVICE_C)
269 #if defined(FDEV_SETUP_STREAM)
270 static int PRNT_Device_putchar(char c,
271 FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
272 static int PRNT_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
273 static int PRNT_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
274 #endif
275
276 void PRNT_Device_Event_Stub(void) ATTR_CONST;
277
278 void EVENT_PRNT_Device_SoftReset(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
279 ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(PRNT_Device_Event_Stub);
280
281 #endif
282
283 #endif
284
285 /* Disable C linkage for C++ Compilers: */
286 #if defined(__cplusplus)
287 }
288 #endif
289
290#endif
291
292/** @} */
293
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c
new file mode 100644
index 000000000..45293b12f
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c
@@ -0,0 +1,508 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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_RNDIS_DRIVER
37#define __INCLUDE_FROM_RNDIS_DEVICE_C
38#include "RNDISClassDevice.h"
39
40static const uint32_t PROGMEM AdapterSupportedOIDList[] =
41 {
42 CPU_TO_LE32(OID_GEN_SUPPORTED_LIST),
43 CPU_TO_LE32(OID_GEN_PHYSICAL_MEDIUM),
44 CPU_TO_LE32(OID_GEN_HARDWARE_STATUS),
45 CPU_TO_LE32(OID_GEN_MEDIA_SUPPORTED),
46 CPU_TO_LE32(OID_GEN_MEDIA_IN_USE),
47 CPU_TO_LE32(OID_GEN_MAXIMUM_FRAME_SIZE),
48 CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
49 CPU_TO_LE32(OID_GEN_LINK_SPEED),
50 CPU_TO_LE32(OID_GEN_TRANSMIT_BLOCK_SIZE),
51 CPU_TO_LE32(OID_GEN_RECEIVE_BLOCK_SIZE),
52 CPU_TO_LE32(OID_GEN_VENDOR_ID),
53 CPU_TO_LE32(OID_GEN_VENDOR_DESCRIPTION),
54 CPU_TO_LE32(OID_GEN_CURRENT_PACKET_FILTER),
55 CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
56 CPU_TO_LE32(OID_GEN_MEDIA_CONNECT_STATUS),
57 CPU_TO_LE32(OID_GEN_XMIT_OK),
58 CPU_TO_LE32(OID_GEN_RCV_OK),
59 CPU_TO_LE32(OID_GEN_XMIT_ERROR),
60 CPU_TO_LE32(OID_GEN_RCV_ERROR),
61 CPU_TO_LE32(OID_GEN_RCV_NO_BUFFER),
62 CPU_TO_LE32(OID_802_3_PERMANENT_ADDRESS),
63 CPU_TO_LE32(OID_802_3_CURRENT_ADDRESS),
64 CPU_TO_LE32(OID_802_3_MULTICAST_LIST),
65 CPU_TO_LE32(OID_802_3_MAXIMUM_LIST_SIZE),
66 CPU_TO_LE32(OID_802_3_RCV_ERROR_ALIGNMENT),
67 CPU_TO_LE32(OID_802_3_XMIT_ONE_COLLISION),
68 CPU_TO_LE32(OID_802_3_XMIT_MORE_COLLISIONS),
69 };
70
71void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
72{
73 if (!(Endpoint_IsSETUPReceived()))
74 return;
75
76 if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
77 return;
78
79 switch (USB_ControlRequest.bRequest)
80 {
81 case RNDIS_REQ_SendEncapsulatedCommand:
82 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
83 {
84 Endpoint_ClearSETUP();
85 Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, USB_ControlRequest.wLength);
86 Endpoint_ClearIN();
87
88 RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
89 }
90
91 break;
92 case RNDIS_REQ_GetEncapsulatedResponse:
93 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
94 {
95 RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer;
96
97 if (!(MessageHeader->MessageLength))
98 {
99 RNDISInterfaceInfo->Config.MessageBuffer[0] = 0;
100 MessageHeader->MessageLength = CPU_TO_LE32(1);
101 }
102
103 Endpoint_ClearSETUP();
104 Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, le32_to_cpu(MessageHeader->MessageLength));
105 Endpoint_ClearOUT();
106
107 MessageHeader->MessageLength = CPU_TO_LE32(0);
108 }
109
110 break;
111 }
112}
113
114bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
115{
116 memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
117
118 RNDISInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
119 RNDISInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
120 RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
121
122 if (RNDISInterfaceInfo->Config.MessageBuffer == NULL)
123 return false;
124
125 if (RNDISInterfaceInfo->Config.MessageBufferLength < RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH)
126 return false;
127
128 if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1)))
129 return false;
130
131 if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataOUTEndpoint, 1)))
132 return false;
133
134 if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.NotificationEndpoint, 1)))
135 return false;
136
137 return true;
138}
139
140void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
141{
142 if (USB_DeviceState != DEVICE_STATE_Configured)
143 return;
144
145 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpoint.Address);
146
147 if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
148 {
149 USB_Request_Header_t Notification = (USB_Request_Header_t)
150 {
151 .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
152 .bRequest = RNDIS_NOTIF_ResponseAvailable,
153 .wValue = CPU_TO_LE16(0),
154 .wIndex = CPU_TO_LE16(0),
155 .wLength = CPU_TO_LE16(0),
156 };
157
158 Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
159
160 Endpoint_ClearIN();
161
162 RNDISInterfaceInfo->State.ResponseReady = false;
163 }
164}
165
166void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
167{
168 /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
169 this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
170
171 RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer;
172
173 switch (le32_to_cpu(MessageHeader->MessageType))
174 {
175 case REMOTE_NDIS_INITIALIZE_MSG:
176 RNDISInterfaceInfo->State.ResponseReady = true;
177
178 RNDIS_Initialize_Message_t* INITIALIZE_Message =
179 (RNDIS_Initialize_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
180 RNDIS_Initialize_Complete_t* INITIALIZE_Response =
181 (RNDIS_Initialize_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
182
183 INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT);
184 INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t));
185 INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
186 INITIALIZE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
187
188 INITIALIZE_Response->MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR);
189 INITIALIZE_Response->MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR);
190 INITIALIZE_Response->DeviceFlags = CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS);
191 INITIALIZE_Response->Medium = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
192 INITIALIZE_Response->MaxPacketsPerTransfer = CPU_TO_LE32(1);
193 INITIALIZE_Response->MaxTransferSize = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
194 INITIALIZE_Response->PacketAlignmentFactor = CPU_TO_LE32(0);
195 INITIALIZE_Response->AFListOffset = CPU_TO_LE32(0);
196 INITIALIZE_Response->AFListSize = CPU_TO_LE32(0);
197
198 RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
199 break;
200 case REMOTE_NDIS_HALT_MSG:
201 RNDISInterfaceInfo->State.ResponseReady = false;
202
203 MessageHeader->MessageLength = CPU_TO_LE32(0);
204
205 RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
206 break;
207 case REMOTE_NDIS_QUERY_MSG:
208 RNDISInterfaceInfo->State.ResponseReady = true;
209
210 RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
211 RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
212 uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid);
213
214 void* QueryData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
215 le32_to_cpu(QUERY_Message->InformationBufferOffset)];
216 void* ResponseData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Query_Complete_t)];
217 uint16_t ResponseSize;
218
219 QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT);
220
221 if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, le32_to_cpu(QUERY_Message->InformationBufferLength),
222 ResponseData, &ResponseSize))
223 {
224 QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
225 QUERY_Response->MessageLength = cpu_to_le32(sizeof(RNDIS_Query_Complete_t) + ResponseSize);
226
227 QUERY_Response->InformationBufferLength = CPU_TO_LE32(ResponseSize);
228 QUERY_Response->InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
229 }
230 else
231 {
232 QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED);
233 QUERY_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t));
234
235 QUERY_Response->InformationBufferLength = CPU_TO_LE32(0);
236 QUERY_Response->InformationBufferOffset = CPU_TO_LE32(0);
237 }
238
239 break;
240 case REMOTE_NDIS_SET_MSG:
241 RNDISInterfaceInfo->State.ResponseReady = true;
242
243 RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
244 RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
245 uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid);
246
247 SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT);
248 SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t));
249 SET_Response->RequestId = SET_Message->RequestId;
250
251 void* SetData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
252 le32_to_cpu(SET_Message->InformationBufferOffset)];
253
254 SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
255 le32_to_cpu(SET_Message->InformationBufferLength)) ?
256 REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
257 break;
258 case REMOTE_NDIS_RESET_MSG:
259 RNDISInterfaceInfo->State.ResponseReady = true;
260
261 RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
262
263 RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT);
264 RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t));
265 RESET_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
266 RESET_Response->AddressingReset = CPU_TO_LE32(0);
267
268 break;
269 case REMOTE_NDIS_KEEPALIVE_MSG:
270 RNDISInterfaceInfo->State.ResponseReady = true;
271
272 RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
273 (RNDIS_KeepAlive_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
274 RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
275 (RNDIS_KeepAlive_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
276
277 KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT);
278 KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t));
279 KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
280 KEEPALIVE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
281
282 break;
283 }
284}
285
286static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
287 const uint32_t OId,
288 void* const QueryData,
289 const uint16_t QuerySize,
290 void* ResponseData,
291 uint16_t* const ResponseSize)
292{
293 (void)QueryData;
294 (void)QuerySize;
295
296 switch (OId)
297 {
298 case OID_GEN_SUPPORTED_LIST:
299 *ResponseSize = sizeof(AdapterSupportedOIDList);
300
301 memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
302
303 return true;
304 case OID_GEN_PHYSICAL_MEDIUM:
305 *ResponseSize = sizeof(uint32_t);
306
307 /* Indicate that the device is a true ethernet link */
308 *((uint32_t*)ResponseData) = CPU_TO_LE32(0);
309
310 return true;
311 case OID_GEN_HARDWARE_STATUS:
312 *ResponseSize = sizeof(uint32_t);
313
314 *((uint32_t*)ResponseData) = CPU_TO_LE32(NDIS_HardwareStatus_Ready);
315
316 return true;
317 case OID_GEN_MEDIA_SUPPORTED:
318 case OID_GEN_MEDIA_IN_USE:
319 *ResponseSize = sizeof(uint32_t);
320
321 *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
322
323 return true;
324 case OID_GEN_VENDOR_ID:
325 *ResponseSize = sizeof(uint32_t);
326
327 /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
328 *((uint32_t*)ResponseData) = CPU_TO_LE32(0x00FFFFFF);
329
330 return true;
331 case OID_GEN_MAXIMUM_FRAME_SIZE:
332 case OID_GEN_TRANSMIT_BLOCK_SIZE:
333 case OID_GEN_RECEIVE_BLOCK_SIZE:
334 *ResponseSize = sizeof(uint32_t);
335
336 *((uint32_t*)ResponseData) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX);
337
338 return true;
339 case OID_GEN_VENDOR_DESCRIPTION:
340 *ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
341
342 memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
343
344 return true;
345 case OID_GEN_MEDIA_CONNECT_STATUS:
346 *ResponseSize = sizeof(uint32_t);
347
348 *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED);
349
350 return true;
351 case OID_GEN_LINK_SPEED:
352 *ResponseSize = sizeof(uint32_t);
353
354 /* Indicate 10Mb/s link speed */
355 *((uint32_t*)ResponseData) = CPU_TO_LE32(100000);
356
357 return true;
358 case OID_802_3_PERMANENT_ADDRESS:
359 case OID_802_3_CURRENT_ADDRESS:
360 *ResponseSize = sizeof(MAC_Address_t);
361
362 memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
363
364 return true;
365 case OID_802_3_MAXIMUM_LIST_SIZE:
366 *ResponseSize = sizeof(uint32_t);
367
368 /* Indicate only one multicast address supported */
369 *((uint32_t*)ResponseData) = CPU_TO_LE32(1);
370
371 return true;
372 case OID_GEN_CURRENT_PACKET_FILTER:
373 *ResponseSize = sizeof(uint32_t);
374
375 *((uint32_t*)ResponseData) = cpu_to_le32(RNDISInterfaceInfo->State.CurrPacketFilter);
376
377 return true;
378 case OID_GEN_XMIT_OK:
379 case OID_GEN_RCV_OK:
380 case OID_GEN_XMIT_ERROR:
381 case OID_GEN_RCV_ERROR:
382 case OID_GEN_RCV_NO_BUFFER:
383 case OID_802_3_RCV_ERROR_ALIGNMENT:
384 case OID_802_3_XMIT_ONE_COLLISION:
385 case OID_802_3_XMIT_MORE_COLLISIONS:
386 *ResponseSize = sizeof(uint32_t);
387
388 /* Unused statistic OIDs - always return 0 for each */
389 *((uint32_t*)ResponseData) = CPU_TO_LE32(0);
390
391 return true;
392 case OID_GEN_MAXIMUM_TOTAL_SIZE:
393 *ResponseSize = sizeof(uint32_t);
394
395 /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
396 *((uint32_t*)ResponseData) = CPU_TO_LE32(RNDISInterfaceInfo->Config.MessageBufferLength + ETHERNET_FRAME_SIZE_MAX);
397
398 return true;
399 default:
400 return false;
401 }
402}
403
404static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
405 const uint32_t OId,
406 const void* SetData,
407 const uint16_t SetSize)
408{
409 (void)SetSize;
410
411 switch (OId)
412 {
413 case OID_GEN_CURRENT_PACKET_FILTER:
414 RNDISInterfaceInfo->State.CurrPacketFilter = le32_to_cpu(*((uint32_t*)SetData));
415 RNDISInterfaceInfo->State.CurrRNDISState = (RNDISInterfaceInfo->State.CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Initialized;
416
417 return true;
418 case OID_802_3_MULTICAST_LIST:
419 /* Do nothing - throw away the value from the host as it is unused */
420
421 return true;
422 default:
423 return false;
424 }
425}
426
427bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
428{
429 if ((USB_DeviceState != DEVICE_STATE_Configured) ||
430 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
431 {
432 return false;
433 }
434
435 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
436 return Endpoint_IsOUTReceived();
437}
438
439uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
440 void* Buffer,
441 uint16_t* const PacketLength)
442{
443 if ((USB_DeviceState != DEVICE_STATE_Configured) ||
444 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
445 {
446 return ENDPOINT_RWSTREAM_DeviceDisconnected;
447 }
448
449 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
450
451 *PacketLength = 0;
452
453 if (!(Endpoint_IsOUTReceived()))
454 return ENDPOINT_RWSTREAM_NoError;
455
456 RNDIS_Packet_Message_t RNDISPacketHeader;
457 Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
458
459 if (le32_to_cpu(RNDISPacketHeader.DataLength) > ETHERNET_FRAME_SIZE_MAX)
460 {
461 Endpoint_StallTransaction();
462
463 return RNDIS_ERROR_LOGICAL_CMD_FAILED;
464 }
465
466 *PacketLength = (uint16_t)le32_to_cpu(RNDISPacketHeader.DataLength);
467
468 Endpoint_Read_Stream_LE(Buffer, *PacketLength, NULL);
469 Endpoint_ClearOUT();
470
471 return ENDPOINT_RWSTREAM_NoError;
472}
473
474uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
475 void* Buffer,
476 const uint16_t PacketLength)
477{
478 uint8_t ErrorCode;
479
480 if ((USB_DeviceState != DEVICE_STATE_Configured) ||
481 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
482 {
483 return ENDPOINT_RWSTREAM_DeviceDisconnected;
484 }
485
486 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpoint.Address);
487
488 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
489 return ErrorCode;
490
491 RNDIS_Packet_Message_t RNDISPacketHeader;
492
493 memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
494
495 RNDISPacketHeader.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG);
496 RNDISPacketHeader.MessageLength = cpu_to_le32(sizeof(RNDIS_Packet_Message_t) + PacketLength);
497 RNDISPacketHeader.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
498 RNDISPacketHeader.DataLength = cpu_to_le32(PacketLength);
499
500 Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
501 Endpoint_Write_Stream_LE(Buffer, PacketLength, NULL);
502 Endpoint_ClearIN();
503
504 return ENDPOINT_RWSTREAM_NoError;
505}
506
507#endif
508
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h
new file mode 100644
index 000000000..761bc2790
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h
@@ -0,0 +1,207 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2017 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 disclaims 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/** \file
32 * \brief Device mode driver for the library USB RNDIS Class driver.
33 *
34 * Device mode driver for the library USB RNDIS Class driver.
35 *
36 * \note This file should not be included directly. It is automatically included as needed by the USB module driver
37 * dispatch header located in LUFA/Drivers/USB.h.
38 */
39
40/** \ingroup Group_USBClassRNDIS
41 * \defgroup Group_USBClassRNDISDevice RNDIS Class Device Mode Driver
42 *
43 * \section Sec_USBClassRNDISDevice_Dependencies Module Source Dependencies
44 * The following files must be built with any user project that uses this module:
45 * - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
46 *
47 * \section Sec_USBClassRNDISDevice_ModDescription Module Description
48 * Device Mode USB Class driver framework interface, for the RNDIS USB Class driver.
49 *
50 * @{
51 */
52
53#ifndef _RNDIS_CLASS_DEVICE_H_
54#define _RNDIS_CLASS_DEVICE_H_
55
56 /* Includes: */
57 #include "../../USB.h"
58 #include "../Common/RNDISClassCommon.h"
59
60 /* Enable C linkage for C++ Compilers: */
61 #if defined(__cplusplus)
62 extern "C" {
63 #endif
64
65 /* Preprocessor Checks: */
66 #if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
67 #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
68 #endif
69
70 /* Public Interface - May be used in end-application: */
71 /* Type Defines: */
72 /** \brief RNDIS Class Device Mode Configuration and State Structure.
73 *
74 * Class state structure. An instance of this structure should be made for each RNDIS interface
75 * within the user application, and passed to each of the RNDIS class driver functions as the
76 * \c RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information.
77 */
78 typedef struct
79 {
80 struct
81 {
82 uint8_t ControlInterfaceNumber; /**< Interface number of the RNDIS control interface within the device. */
83
84 USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
85 USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
86 USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */
87
88 char* AdapterVendorDescription; /**< String description of the adapter vendor. */
89 MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */
90
91 uint8_t* MessageBuffer; /**< Buffer where RNDIS messages can be stored by the internal driver. This
92 * should be at least 132 bytes in length for minimal functionality. */
93 uint16_t MessageBufferLength; /**< Length in bytes of the \ref MessageBuffer RNDIS buffer. */
94 } Config; /**< Config data for the USB class interface within the device. All elements in this section
95 * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
96 */
97 struct
98 {
99 bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */
100 uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */
101 uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */
102 } State; /**< State data for the USB class interface within the device. All elements in this section
103 * are reset to their defaults when the interface is enumerated.
104 */
105 } USB_ClassInfo_RNDIS_Device_t;
106
107 /* Function Prototypes: */
108 /** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library
109 * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
110 * containing the given RNDIS interface is selected.
111 *
112 * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
113 *
114 * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
115 */
116 bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
117
118 /** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be
119 * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
120 *
121 * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
122 */
123 void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
124
125 /** General management task for a given RNDIS class interface, required for the correct operation of the interface. This should
126 * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
127 *
128 * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
129 */
130 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
131
132 /** Determines if a packet is currently waiting for the device to read in and process.
133 *
134 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
135 * call will fail.
136 *
137 * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state.
138 *
139 * \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise.
140 */
141 bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
142
143 /** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave
144 * only the packet contents for processing by the device in the nominated buffer.
145 *
146 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
147 * call will fail.
148 *
149 * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state.
150 * \param[out] Buffer Pointer to a buffer where the packer data is to be written to.
151 * \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored.
152 *
153 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
154 */
155 uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
156 void* Buffer,
157 uint16_t* const PacketLength) ATTR_NON_NULL_PTR_ARG(1);
158
159 /** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
160 *
161 * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
162 * call will fail.
163 *
164 * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state.
165 * \param[in] Buffer Pointer to a buffer where the packer data is to be read from.
166 * \param[in] PacketLength Length in bytes of the packet to send.
167 *
168 * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
169 */
170 uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
171 void* Buffer,
172 const uint16_t PacketLength) ATTR_NON_NULL_PTR_ARG(1);
173
174 /* Private Interface - For use in library only: */
175 #if !defined(__DOXYGEN__)
176 /* Macros: */
177 #define RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_Query_Complete_t)
178
179 /* Function Prototypes: */
180 #if defined(__INCLUDE_FROM_RNDIS_DEVICE_C)
181 static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
182 ATTR_NON_NULL_PTR_ARG(1);
183 static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
184 const uint32_t OId,
185 void* const QueryData,
186 const uint16_t QuerySize,
187 void* ResponseData,
188 uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1)
189 ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6);
190 static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
191 const uint32_t OId,
192 const void* SetData,
193 const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1)
194 ATTR_NON_NULL_PTR_ARG(3);
195 #endif
196
197 #endif
198
199 /* Disable C linkage for C++ Compilers: */
200 #if defined(__cplusplus)
201 }
202 #endif
203
204#endif
205
206/** @} */
207