Added new USB_DeviceState variable to keep track of the current Device mode USB state.
[pub/USBasp.git] / LUFA / Drivers / USB / LowLevel / LowLevel.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 #include "LowLevel.h"
32
33 #if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY))
34 volatile uint8_t USB_CurrentMode = USB_MODE_NONE;
35 #endif
36
37 #if !defined(USE_STATIC_OPTIONS)
38 volatile uint8_t USB_Options;
39 #endif
40
41 void USB_Init(
42 #if defined(USB_CAN_BE_BOTH)
43 const uint8_t Mode
44 #endif
45
46 #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS))
47 ,
48 #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS))
49 void
50 #endif
51
52 #if !defined(USE_STATIC_OPTIONS)
53 const uint8_t Options
54 #endif
55 )
56 {
57 USB_ShutDown();
58
59 #if defined(USB_CAN_BE_BOTH)
60 USB_CurrentMode = Mode;
61 #endif
62
63 #if !defined(USE_STATIC_OPTIONS)
64 USB_Options = Options;
65 #endif
66
67 #if defined(USB_CAN_BE_HOST)
68 USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
69 #endif
70
71 #if defined(USB_DEVICE_ONLY) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
72 UHWCON |= (1 << UIMOD);
73 #elif defined(USB_HOST_ONLY)
74 UHWCON &= ~(1 << UIMOD);
75 #elif defined(USB_CAN_BE_BOTH)
76 if (Mode == USB_MODE_UID)
77 {
78 UHWCON |= (1 << UIDE);
79
80 USB_INT_Clear(USB_INT_IDTI);
81 USB_INT_Enable(USB_INT_IDTI);
82
83 USB_CurrentMode = USB_GetUSBModeFromUID();
84 }
85 else if (Mode == USB_MODE_DEVICE)
86 {
87 UHWCON |= (1 << UIMOD);
88 }
89 else if (Mode == USB_MODE_HOST)
90 {
91 UHWCON &= ~(1 << UIMOD);
92 }
93 else
94 {
95 EVENT_USB_InitFailure(USB_INITERROR_NoUSBModeSpecified);
96 return;
97 }
98 #endif
99
100 USB_ResetInterface();
101
102 #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
103 USB_OTGPAD_On();
104 #endif
105
106 USB_IsInitialized = true;
107
108 sei();
109 }
110
111 void USB_ShutDown(void)
112 {
113 #if defined(USB_CAN_BE_DEVICE)
114 if (USB_DeviceState != DEVICE_STATE_Unattached)
115 EVENT_USB_Disconnect();
116 #endif
117
118 #if defined(USB_CAN_BE_HOST)
119 if (USB_HostState != HOST_STATE_Unattached)
120 EVENT_USB_Disconnect();
121 #endif
122
123 USB_Detach();
124
125 USB_INT_DisableAllInterrupts();
126 USB_INT_ClearAllInterrupts();
127
128 USB_IsInitialized = false;
129
130 #if defined(USB_CAN_BE_HOST)
131 USB_HostState = HOST_STATE_Unattached;
132 #endif
133
134 #if defined(USB_CAN_BE_DEVICE)
135 USB_DeviceState = DEVICE_STATE_Unattached;
136 USB_ConfigurationNumber = 0;
137 USB_RemoteWakeupEnabled = false;
138 USB_CurrentlySelfPowered = false;
139 #endif
140
141 #if defined(CAN_BE_BOTH)
142 USB_CurrentMode = USB_MODE_NONE;
143 #endif
144
145 USB_Interface_Disable();
146 USB_PLL_Off();
147
148 #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
149 USB_OTGPAD_Off();
150 #endif
151
152 #if defined(USB_CAN_BE_BOTH)
153 UHWCON &= ~(1 << UIDE);
154 #endif
155 }
156
157 void USB_ResetInterface(void)
158 {
159 USB_INT_DisableAllInterrupts();
160 USB_INT_ClearAllInterrupts();
161
162 #if defined(USB_CAN_BE_HOST)
163 USB_HostState = HOST_STATE_Unattached;
164 #endif
165
166 #if defined(USB_CAN_BE_DEVICE)
167 USB_DeviceState = DEVICE_STATE_Unattached;
168 USB_ConfigurationNumber = 0;
169 USB_RemoteWakeupEnabled = false;
170 USB_CurrentlySelfPowered = false;
171 #endif
172
173 if (!(USB_Options & USB_OPT_MANUAL_PLL))
174 {
175 #if defined(USB_SERIES_4_AVR)
176 PLLFRQ = ((1 << PLLUSB) | (1 << PDIV3) | (1 << PDIV1));
177 #endif
178
179 USB_PLL_On();
180 while (!(USB_PLL_IsReady()));
181 }
182
183 USB_Interface_Reset();
184
185 #if defined(USB_CAN_BE_BOTH)
186 if (UHWCON & (1 << UIDE))
187 {
188 USB_INT_Clear(USB_INT_IDTI);
189 USB_INT_Enable(USB_INT_IDTI);
190 USB_CurrentMode = USB_GetUSBModeFromUID();
191 }
192 #endif
193
194 if (!(USB_Options & USB_OPT_REG_DISABLED))
195 USB_REG_On();
196 else
197 USB_REG_Off();
198
199 USB_CLK_Unfreeze();
200
201 #if (defined(USB_CAN_BE_DEVICE) && (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)))
202 if (USB_CurrentMode == USB_MODE_DEVICE)
203 {
204 if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
205 USB_Device_SetLowSpeed();
206 else
207 USB_Device_SetHighSpeed();
208
209 USB_INT_Enable(USB_INT_VBUS);
210 }
211 #endif
212
213 #if (defined(USB_CAN_BE_DEVICE) && !defined(FIXED_CONTROL_ENDPOINT_SIZE))
214 if (USB_CurrentMode == USB_MODE_DEVICE)
215 {
216 USB_Descriptor_Device_t* DeviceDescriptorPtr;
217
218 if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
219 {
220 #if defined(USE_RAM_DESCRIPTORS)
221 USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
222 #elif defined(USE_EEPROM_DESCRIPTORS)
223 USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
224 #else
225 USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
226 #endif
227 }
228 }
229 #endif
230
231 USB_Attach();
232
233 #if defined(USB_DEVICE_ONLY)
234 USB_INT_Enable(USB_INT_SUSPEND);
235 USB_INT_Enable(USB_INT_EORSTI);
236 #if defined(CONTROL_ONLY_DEVICE)
237 UENUM = ENDPOINT_CONTROLEP;
238 #endif
239
240 #elif defined(USB_HOST_ONLY)
241 USB_Host_HostMode_On();
242
243 USB_Host_VBUS_Auto_Off();
244 USB_OTGPAD_Off();
245
246 USB_Host_VBUS_Manual_Enable();
247 USB_Host_VBUS_Manual_On();
248
249 USB_INT_Enable(USB_INT_SRPI);
250 USB_INT_Enable(USB_INT_BCERRI);
251 #else
252 if (USB_CurrentMode == USB_MODE_DEVICE)
253 {
254 USB_INT_Enable(USB_INT_SUSPEND);
255 USB_INT_Enable(USB_INT_EORSTI);
256
257 #if defined(CONTROL_ONLY_DEVICE)
258 UENUM = ENDPOINT_CONTROLEP;
259 #endif
260 }
261 else if (USB_CurrentMode == USB_MODE_HOST)
262 {
263 USB_Host_HostMode_On();
264
265 USB_Host_VBUS_Auto_Off();
266 USB_OTGPAD_Off();
267
268 USB_Host_VBUS_Manual_Enable();
269 USB_Host_VBUS_Manual_On();
270
271 USB_INT_Enable(USB_INT_SRPI);
272 USB_INT_Enable(USB_INT_BCERRI);
273 }
274 #endif
275 }