Fixed interrupt driven HID device demos not clearing the interrupt flags in all circu...
[pub/USBasp.git] / Demos / BluetoothHost / BluetoothHost.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 Bluetooth Dongle host demo application.
33
34 ** NOT CURRENTLY FUNCTIONAL - DO NOT USE **
35 */
36
37 /*
38 USB Mode: Host
39 USB Class: Bluetooth USB Transport Class
40 USB Subclass: Bluetooth HCI USB Transport
41 Relevant Standards: Bluetooth 2.0 Standard
42 Bluetooth 2.0 HCI USB Transport Layer Addendum
43 Bluetooth Assigned Numbers (Baseband)
44 Usable Speeds: Full Speed Mode
45 */
46
47 #include "BluetoothHost.h"
48
49 /* Project Tags, for reading out using the ButtLoad project */
50 BUTTLOADTAG(ProjName, "LUFA BT Host App");
51 BUTTLOADTAG(BuildTime, __TIME__);
52 BUTTLOADTAG(BuildDate, __DATE__);
53 BUTTLOADTAG(LUFAVersion, "LUFA V" LUFA_VERSION_STRING);
54
55 /* Scheduler Task List */
56 TASK_LIST
57 {
58 { Task: USB_USBTask , TaskStatus: TASK_STOP },
59 { Task: USB_Bluetooth_Host , TaskStatus: TASK_STOP },
60 { Task: Bluetooth_Task , TaskStatus: TASK_STOP },
61 };
62
63 Bluetooth_Device_t Bluetooth_DeviceConfiguration =
64 {
65 Class: (DEVICE_CLASS_SERVICE_CAPTURING | DEVICE_CLASS_MAJOR_COMPUTER | DEVICE_CLASS_MINOR_COMPUTER_PALM),
66 PINCode: "0000",
67 Name: "LUFA Bluetooth Demo"
68 };
69
70
71 int main(void)
72 {
73 /* Disable watchdog if enabled by bootloader/fuses */
74 MCUSR &= ~(1 << WDRF);
75 wdt_disable();
76
77 /* Disable Clock Division */
78 SetSystemClockPrescaler(0);
79
80 /* Hardware Initialization */
81 SerialStream_Init(9600, false);
82 LEDs_Init();
83
84 /* Indicate USB not ready */
85 UpdateStatus(Status_USBNotReady);
86
87 /* Startup message */
88 puts_P(PSTR(ESC_RESET ESC_BG_WHITE ESC_INVERSE_ON ESC_ERASE_DISPLAY
89 "Bluetooth Host Demo running.\r\n" ESC_INVERSE_OFF));
90
91 /* Initialize Scheduler so that it can be used */
92 Scheduler_Init();
93
94 /* Initialize USB Subsystem */
95 USB_Init();
96
97 /* Scheduling routine never returns, so put this last in the main function */
98 Scheduler_Start();
99 }
100
101 EVENT_HANDLER(USB_DeviceAttached)
102 {
103 puts_P(PSTR("Device Attached.\r\n"));
104 UpdateStatus(Status_USBEnumerating);
105
106 /* Start USB management task to enumerate the device */
107 Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
108 }
109
110 EVENT_HANDLER(USB_DeviceUnattached)
111 {
112 /* Stop USB management and Bluetooth tasks */
113 Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
114 Scheduler_SetTaskMode(USB_Bluetooth_Host, TASK_STOP);
115 Scheduler_SetTaskMode(Bluetooth_Task, TASK_STOP);
116
117 puts_P(PSTR("\r\nDevice Unattached.\r\n"));
118 UpdateStatus(Status_USBNotReady);
119 }
120
121 EVENT_HANDLER(USB_DeviceEnumerationComplete)
122 {
123 /* Once device is fully enumerated, start the Bluetooth Host task */
124 Scheduler_SetTaskMode(USB_Bluetooth_Host, TASK_RUN);
125 Scheduler_SetTaskMode(Bluetooth_Task, TASK_RUN);
126
127 UpdateStatus(Status_USBReady);
128 }
129
130 EVENT_HANDLER(USB_HostError)
131 {
132 USB_ShutDown();
133
134 puts_P(PSTR(ESC_BG_RED "Host Mode Error\r\n"));
135 printf_P(PSTR(" -- Error Code %d\r\n"), ErrorCode);
136
137 UpdateStatus(Status_HardwareError);
138 for(;;);
139 }
140
141 EVENT_HANDLER(USB_DeviceEnumerationFailed)
142 {
143 puts_P(PSTR(ESC_BG_RED "Dev Enum Error\r\n"));
144 printf_P(PSTR(" -- Error Code %d\r\n"), ErrorCode);
145 printf_P(PSTR(" -- In State %d\r\n"), USB_HostState);
146
147 UpdateStatus(Status_EnumerationError);
148 }
149
150 TASK(USB_Bluetooth_Host)
151 {
152 uint8_t ErrorCode;
153
154 switch (USB_HostState)
155 {
156 case HOST_STATE_Addressed:
157 puts_P(PSTR("Getting Device Data.\r\n"));
158
159 /* Get and process the configuration descriptor data */
160 if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead)
161 {
162 if (ErrorCode == ControlErrorDuringDeviceRead)
163 puts_P(PSTR("Control Error (Get Device).\r\n"));
164 else
165 puts_P(PSTR("Invalid Device.\r\n"));
166
167 printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
168
169 /* Indicate error via status LEDs */
170 LEDs_SetAllLEDs(LEDS_LED1);
171
172 /* Wait until USB device disconnected */
173 while (USB_IsConnected);
174 break;
175 }
176
177 puts_P(PSTR("Bluetooth Dongle Detected.\r\n"));
178
179 /* Standard request to set the device configuration to configuration 1 */
180 USB_HostRequest = (USB_Host_Request_Header_t)
181 {
182 bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
183 bRequest: REQ_SetConfiguration,
184 wValue: 1,
185 wIndex: 0,
186 wLength: 0,
187 };
188
189 /* Send the request, display error and wait for device detatch if request fails */
190 if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
191 {
192 puts_P(PSTR("Control Error (Set Configuration).\r\n"));
193 printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
194
195 /* Indicate error via status LEDs */
196 LEDs_SetAllLEDs(LEDS_LED1);
197
198 /* Wait until USB device disconnected */
199 while (USB_IsConnected);
200 break;
201 }
202
203 USB_HostState = HOST_STATE_Configured;
204 break;
205 case HOST_STATE_Configured:
206 puts_P(PSTR("Getting Config Data.\r\n"));
207
208 /* Get and process the configuration descriptor data */
209 if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
210 {
211 if (ErrorCode == ControlErrorDuringConfigRead)
212 puts_P(PSTR("Control Error (Get Configuration).\r\n"));
213 else
214 puts_P(PSTR("Invalid Device.\r\n"));
215
216 printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
217
218 /* Indicate error via status LEDs */
219 LEDs_SetAllLEDs(LEDS_LED1);
220
221 /* Wait until USB device disconnected */
222 while (USB_IsConnected);
223 break;
224 }
225
226 puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n"));
227
228 USB_HostState = HOST_STATE_Ready;
229 break;
230 case HOST_STATE_Ready:
231 if (Bluetooth_HCIProcessingState != Bluetooth_ProcessEvents)
232 {
233 UpdateStatus(Status_BluetoothBusy);
234 }
235 else
236 {
237 if (Bluetooth_Connection.IsConnected)
238 UpdateStatus(Status_BluetoothConnected);
239 else
240 UpdateStatus(Status_USBReady);
241 }
242
243 break;
244 }
245 }
246
247 /** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
248 * log to a serial port, or anything else that is suitable for status updates.
249 *
250 * \param CurrentStatus Current status of the system, from the MouseHostViaInt_StatusCodes_t enum
251 */
252 void UpdateStatus(uint8_t CurrentStatus)
253 {
254 uint8_t LEDMask = LEDS_NO_LEDS;
255
256 /* Set the LED mask to the appropriate LED mask based on the given status code */
257 switch (CurrentStatus)
258 {
259 case Status_USBNotReady:
260 LEDMask = (LEDS_LED1);
261 break;
262 case Status_USBEnumerating:
263 LEDMask = (LEDS_LED1 | LEDS_LED2);
264 break;
265 case Status_USBReady:
266 LEDMask = (LEDS_LED2);
267 break;
268 case Status_EnumerationError:
269 case Status_HardwareError:
270 LEDMask = (LEDS_LED1 | LEDS_LED3);
271 break;
272 case Status_BluetoothConnected:
273 LEDMask = (LEDS_LED2 | LEDS_LED4);
274 break;
275 case Status_BluetoothBusy:
276 LEDMask = (LEDS_LED2 | LEDS_LED3 | LEDS_LED4);
277 break;
278 }
279
280 /* Set the board LEDs to the new LED mask */
281 LEDs_SetAllLEDs(LEDMask);
282 }