]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c
subtree docs
[qmk_firmware.git] / tmk_core / protocol / lufa / LUFA-git / LUFA / Drivers / USB / Core / AVR8 / USBController_AVR8.c
1 /*
2              LUFA Library
3      Copyright (C) Dean Camera, 2014.
4
5   dean [at] fourwalledcubicle [dot] com
6            www.lufa-lib.org
7 */
8
9 /*
10   Copyright 2014  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 #include "../../../../Common/Common.h"
32 #if (ARCH == ARCH_AVR8)
33
34 #define  __INCLUDE_FROM_USB_DRIVER
35 #define  __INCLUDE_FROM_USB_CONTROLLER_C
36 #include "../USBController.h"
37
38 #if defined(USB_CAN_BE_BOTH)
39 volatile uint8_t USB_CurrentMode = USB_MODE_None;
40 #endif
41
42 #if !defined(USE_STATIC_OPTIONS)
43 volatile uint8_t USB_Options;
44 #endif
45
46 void USB_Init(
47                #if defined(USB_CAN_BE_BOTH)
48                const uint8_t Mode
49                #endif
50
51                #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS))
52                ,
53                #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS))
54                void
55                #endif
56
57                #if !defined(USE_STATIC_OPTIONS)
58                const uint8_t Options
59                #endif
60                )
61 {
62         #if !defined(USE_STATIC_OPTIONS)
63         USB_Options = Options;
64         #endif
65
66         #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
67         /* Workaround for AVR8 bootloaders that fail to turn off the OTG pad before running
68          * the loaded application. This causes VBUS detection to fail unless we first force
69          * it off to reset it. */
70         USB_OTGPAD_Off();
71         #endif
72
73         if (!(USB_Options & USB_OPT_REG_DISABLED))
74           USB_REG_On();
75         else
76           USB_REG_Off();
77
78         if (!(USB_Options & USB_OPT_MANUAL_PLL))
79         {
80                 #if defined(USB_SERIES_4_AVR)
81                 PLLFRQ = (1 << PDIV2);
82                 #endif
83         }
84
85         #if defined(USB_CAN_BE_BOTH)
86         if (Mode == USB_MODE_UID)
87         {
88                 UHWCON |=  (1 << UIDE);
89                 USB_INT_Enable(USB_INT_IDTI);
90                 USB_CurrentMode = USB_GetUSBModeFromUID();
91         }
92         else
93         {
94                 UHWCON &= ~(1 << UIDE);
95                 USB_CurrentMode = Mode;
96         }
97         #endif
98
99         USB_IsInitialized = true;
100
101         USB_ResetInterface();
102 }
103
104 void USB_Disable(void)
105 {
106         USB_INT_DisableAllInterrupts();
107         USB_INT_ClearAllInterrupts();
108
109         USB_Detach();
110         USB_Controller_Disable();
111
112         if (!(USB_Options & USB_OPT_MANUAL_PLL))
113           USB_PLL_Off();
114
115         if (!(USB_Options & USB_OPT_REG_KEEP_ENABLED))
116           USB_REG_Off();
117
118         #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
119         USB_OTGPAD_Off();
120         #endif
121
122         #if defined(USB_CAN_BE_BOTH)
123         USB_CurrentMode = USB_MODE_None;
124         #endif
125
126         USB_IsInitialized = false;
127 }
128
129 void USB_ResetInterface(void)
130 {
131         #if defined(USB_CAN_BE_BOTH)
132         bool UIDModeSelectEnabled = ((UHWCON & (1 << UIDE)) != 0);
133         #endif
134
135         USB_INT_DisableAllInterrupts();
136         USB_INT_ClearAllInterrupts();
137
138         USB_Controller_Reset();
139
140         #if defined(USB_CAN_BE_BOTH)
141         if (UIDModeSelectEnabled)
142           USB_INT_Enable(USB_INT_IDTI);
143         #endif
144
145         USB_CLK_Unfreeze();
146
147         if (USB_CurrentMode == USB_MODE_Device)
148         {
149                 #if defined(USB_CAN_BE_DEVICE)
150                 #if (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
151                 UHWCON |=  (1 << UIMOD);
152                 #endif
153
154                 if (!(USB_Options & USB_OPT_MANUAL_PLL))
155                 {
156                         #if defined(USB_SERIES_2_AVR)
157                         USB_PLL_On();
158                         while (!(USB_PLL_IsReady()));
159                         #else
160                         USB_PLL_Off();
161                         #endif
162                 }
163
164                 USB_Init_Device();
165                 #endif
166         }
167         else if (USB_CurrentMode == USB_MODE_Host)
168         {
169                 #if defined(USB_CAN_BE_HOST)
170                 UHWCON &= ~(1 << UIMOD);
171
172                 if (!(USB_Options & USB_OPT_MANUAL_PLL))
173                 {
174                         #if defined(USB_CAN_BE_HOST)
175                         USB_PLL_On();
176                         while (!(USB_PLL_IsReady()));
177                         #endif
178                 }
179
180                 USB_Init_Host();
181                 #endif
182         }
183
184         #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
185         USB_OTGPAD_On();
186         #endif
187 }
188
189 #if defined(USB_CAN_BE_DEVICE)
190 static void USB_Init_Device(void)
191 {
192         USB_DeviceState                 = DEVICE_STATE_Unattached;
193         USB_Device_ConfigurationNumber  = 0;
194
195         #if !defined(NO_DEVICE_REMOTE_WAKEUP)
196         USB_Device_RemoteWakeupEnabled  = false;
197         #endif
198
199         #if !defined(NO_DEVICE_SELF_POWER)
200         USB_Device_CurrentlySelfPowered = false;
201         #endif
202
203         #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
204         USB_Descriptor_Device_t* DeviceDescriptorPtr;
205
206         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
207             !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
208         uint8_t DescriptorAddressSpace;
209
210         if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR)
211         {
212                 if (DescriptorAddressSpace == MEMSPACE_FLASH)
213                   USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
214                 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
215                   USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
216                 else
217                   USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
218         }
219         #else
220         if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
221         {
222                 #if defined(USE_RAM_DESCRIPTORS)
223                 USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
224                 #elif defined(USE_EEPROM_DESCRIPTORS)
225                 USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
226                 #else
227                 USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
228                 #endif
229         }
230         #endif
231         #endif
232
233         #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
234         if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
235           USB_Device_SetLowSpeed();
236         else
237           USB_Device_SetFullSpeed();
238
239         USB_INT_Enable(USB_INT_VBUSTI);
240         #endif
241
242         Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
243                                                            USB_Device_ControlEndpointSize, 1);
244
245         USB_INT_Clear(USB_INT_SUSPI);
246         USB_INT_Enable(USB_INT_SUSPI);
247         USB_INT_Enable(USB_INT_EORSTI);
248
249         USB_Attach();
250 }
251 #endif
252
253 #if defined(USB_CAN_BE_HOST)
254 static void USB_Init_Host(void)
255 {
256         USB_HostState                = HOST_STATE_Unattached;
257         USB_Host_ConfigurationNumber = 0;
258         USB_Host_ControlPipeSize     = PIPE_CONTROLPIPE_DEFAULT_SIZE;
259
260         USB_Host_HostMode_On();
261
262         USB_Host_VBUS_Auto_Off();
263         USB_Host_VBUS_Manual_Enable();
264         USB_Host_VBUS_Manual_On();
265
266         USB_INT_Enable(USB_INT_SRPI);
267         USB_INT_Enable(USB_INT_BCERRI);
268
269         USB_Attach();
270 }
271 #endif
272
273 #endif