Add new Incomplete device subdirectory for work-in-progress demos. Add incomplete...
[pub/USBasp.git] / Demos / Device / Incomplete / Sideshow / Sideshow.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2009.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 /*
32 SideShow Class demonstration application. This give a reference
33 for implementing Microsoft SideShow compatible devices in an
34 embedded environment. SideShow allows for gadget data displayed
35 on a Vista machine to also be displayed on an externally connected
36 interactive display. Upon enumeration on a Vista system, this will
37 appear as a new SideShow device which can have gadgets loaded onto
38 it.
39
40 Note that while the incomming content is buffered in packet struct
41 form, the data is not actually displayed. It is left to the user to
42 write sufficient code to read out the packed data for display to a
43 screen.
44
45 Installed gadgets can be accessed through the InstalledApplications
46 array, with entries that have their InUse flag set being active. As
47 only the active content is displayed on the device due to memory
48 constraints, new content can be requested as needed.
49 */
50
51 /*
52 USB Mode: Device
53 USB Class: Sideshow Device (Microsoft Only)
54 USB Subclass: Bulk Only
55 Relevant Standards: Microsoft Sideshow Specification
56 Microsoft OS Descriptors Specification
57 XML Specification
58 Usable Speeds: Full Speed Mode
59 */
60
61 #include "Sideshow.h"
62
63 /* Project Tags, for reading out using the ButtLoad project */
64 BUTTLOADTAG(ProjName, "LUFA Sideshow App");
65 BUTTLOADTAG(BuildTime, __TIME__);
66 BUTTLOADTAG(BuildDate, __DATE__);
67 BUTTLOADTAG(LUFAVersion, "LUFA V" LUFA_VERSION_STRING);
68
69 /* Scheduler Task List */
70 TASK_LIST
71 {
72 { Task: USB_USBTask , TaskStatus: TASK_STOP },
73 { Task: USB_Sideshow , TaskStatus: TASK_STOP },
74 };
75
76 int main(void)
77 {
78 /* Disable watchdog if enabled by bootloader/fuses */
79 MCUSR &= ~(1 << WDRF);
80 wdt_disable();
81
82 /* Disable Clock Division */
83 SetSystemClockPrescaler(0);
84
85 /* Hardware Initialization */
86 SerialStream_Init(9600, false);
87 LEDs_Init();
88 HWB_Init();
89
90 /* Indicate USB not ready */
91 LEDs_SetAllLEDs(LEDS_LED1 | LEDS_LED3);
92
93 /* Initialize Scheduler so that it can be used */
94 Scheduler_Init();
95
96 /* Initialize USB Subsystem */
97 USB_Init();
98
99 /* Scheduling - routine never returns, so put this last in the main function */
100 Scheduler_Start();
101 }
102
103 EVENT_HANDLER(USB_Connect)
104 {
105 /* Start USB management task */
106 Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
107
108 /* Indicate USB enumerating */
109 LEDs_SetAllLEDs(LEDS_LED1 | LEDS_LED4);
110 }
111
112 EVENT_HANDLER(USB_Disconnect)
113 {
114 /* Stop running mass storage and USB management tasks */
115 Scheduler_SetTaskMode(USB_Sideshow, TASK_STOP);
116 Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
117
118 /* Indicate USB not ready */
119 LEDs_SetAllLEDs(LEDS_LED1 | LEDS_LED3);
120 }
121
122 EVENT_HANDLER(USB_ConfigurationChanged)
123 {
124 /* Setup Sideshow In and Out Endpoints */
125 Endpoint_ConfigureEndpoint(SIDESHOW_IN_EPNUM, EP_TYPE_BULK,
126 ENDPOINT_DIR_IN, SIDESHOW_IO_EPSIZE,
127 ENDPOINT_BANK_SINGLE);
128
129 Endpoint_ConfigureEndpoint(SIDESHOW_OUT_EPNUM, EP_TYPE_BULK,
130 ENDPOINT_DIR_OUT, SIDESHOW_IO_EPSIZE,
131 ENDPOINT_BANK_SINGLE);
132
133 /* Indicate USB connected and ready */
134 LEDs_SetAllLEDs(LEDS_LED2 | LEDS_LED4);
135
136 /* Start Sideshow task */
137 Scheduler_SetTaskMode(USB_Sideshow, TASK_RUN);
138 }
139
140 EVENT_HANDLER(USB_UnhandledControlPacket)
141 {
142 /* Process UFI specific control requests */
143 switch (bRequest)
144 {
145 case REQ_GetOSFeatureDescriptor:
146 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE))
147 {
148 uint16_t wValue = Endpoint_Read_Word_LE();
149 uint16_t wIndex = Endpoint_Read_Word_LE();
150 uint16_t wLength = Endpoint_Read_Word_LE();
151
152 void* DescriptorPointer;
153 uint16_t DescriptorSize;
154
155 bool SendZLP = true;
156
157 if (!(USB_GetOSFeatureDescriptor(wValue, wIndex, &DescriptorPointer, &DescriptorSize)))
158 return;
159
160 Endpoint_ClearSetupReceived();
161
162 if (wLength > DescriptorSize)
163 wLength = DescriptorSize;
164
165 while (wLength && (!(Endpoint_IsSetupOUTReceived())))
166 {
167 while (!(Endpoint_IsSetupINReady()));
168
169 while (wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
170 {
171 #if defined(USE_RAM_DESCRIPTORS)
172 Endpoint_Write_Byte(*((uint8_t*)DescriptorPointer++));
173 #elif defined (USE_EEPROM_DESCRIPTORS)
174 Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++));
175 #else
176 Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++));
177 #endif
178
179 wLength--;
180 }
181
182 SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
183 Endpoint_ClearSetupIN();
184 }
185
186 if (Endpoint_IsSetupOUTReceived())
187 {
188 Endpoint_ClearSetupOUT();
189 return;
190 }
191
192 if (SendZLP)
193 {
194 while (!(Endpoint_IsSetupINReady()));
195 Endpoint_ClearSetupIN();
196 }
197
198 while (!(Endpoint_IsSetupOUTReceived()));
199 Endpoint_ClearSetupOUT();
200 }
201
202 break;
203 }
204 }
205
206 TASK(USB_Sideshow)
207 {
208 /* Check if the USB System is connected to a Host */
209 if (USB_IsConnected)
210 {
211 /* Select the SideShow data out endpoint */
212 Endpoint_SelectEndpoint(SIDESHOW_OUT_EPNUM);
213
214 /* Check to see if a new SideShow message has been received */
215 if (Endpoint_ReadWriteAllowed())
216 {
217 /* Process the received SideShow message */
218 Sideshow_ProcessCommandPacket();
219 }
220 }
221 }