Commit e7e1c21b authored by Dean Camera's avatar Dean Camera
Browse files

Clean up USBController.c/.h to more clearly seperate out host and device setup and reset paths.

Make USBInterrupt.c process all pending USB host mode interrupts before resetting the bus, so that no interrupts are lost when in UID auto-selection mode.
parent 01fecac0
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
*/ */
#define __INCLUDE_FROM_USB_DRIVER #define __INCLUDE_FROM_USB_DRIVER
#define __INCLUDE_FROM_USB_CONTROLLER_C
#include "USBController.h" #include "USBController.h"
#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) #if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY))
...@@ -55,58 +56,35 @@ void USB_Init( ...@@ -55,58 +56,35 @@ void USB_Init(
#endif #endif
) )
{ {
#if defined(USB_CAN_BE_BOTH)
USB_CurrentMode = Mode;
#endif
#if !defined(USE_STATIC_OPTIONS) #if !defined(USE_STATIC_OPTIONS)
USB_Options = Options; USB_Options = Options;
#endif #endif
#if defined(USB_CAN_BE_HOST) #if defined(USB_CAN_BE_BOTH)
USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; if (Mode == USB_MODE_UID)
#endif
#if defined(USB_DEVICE_ONLY) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
UHWCON |= (1 << UIMOD);
#elif defined(USB_HOST_ONLY)
UHWCON &= ~(1 << UIMOD);
#elif defined(USB_CAN_BE_BOTH)
if (Mode == USB_MODE_DEVICE)
{
UHWCON |= (1 << UIMOD);
}
else if (Mode == USB_MODE_HOST)
{ {
UHWCON &= ~(1 << UIMOD); UHWCON |= (1 << UIDE);
USB_INT_Enable(USB_INT_IDTI);
USB_CurrentMode = USB_GetUSBModeFromUID();
} }
else else
{ {
UHWCON |= (1 << UIDE); USB_CurrentMode = Mode;
} }
#endif #endif
USB_ResetInterface();
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
USB_OTGPAD_On();
#endif
USB_IsInitialized = true; USB_IsInitialized = true;
USB_ResetInterface();
} }
void USB_ShutDown(void) void USB_ShutDown(void)
{ {
USB_ResetInterface();
USB_Detach();
USB_Controller_Disable();
USB_INT_DisableAllInterrupts(); USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts(); USB_INT_ClearAllInterrupts();
#if defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) USB_Detach();
UHWCON &= ~(1 << UIMOD); USB_Controller_Disable();
#endif
if (!(USB_Options & USB_OPT_MANUAL_PLL)) if (!(USB_Options & USB_OPT_MANUAL_PLL))
USB_PLL_Off(); USB_PLL_Off();
...@@ -118,37 +96,25 @@ void USB_ShutDown(void) ...@@ -118,37 +96,25 @@ void USB_ShutDown(void)
#endif #endif
#if defined(USB_CAN_BE_BOTH) #if defined(USB_CAN_BE_BOTH)
UHWCON &= ~(1 << UIDE); USB_CurrentMode = USB_MODE_NONE;
#endif #endif
USB_IsInitialized = false; USB_IsInitialized = false;
#if defined(USB_CAN_BE_BOTH)
USB_CurrentMode = USB_MODE_NONE;
#endif
} }
void USB_ResetInterface(void) void USB_ResetInterface(void)
{ {
bool UIDModeSelectEnabled = ((UHWCON & (1 << UIDE)) != 0);
USB_INT_DisableAllInterrupts(); USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts(); USB_INT_ClearAllInterrupts();
#if defined(USB_CAN_BE_HOST) USB_Controller_Reset();
USB_HostState = HOST_STATE_Unattached;
#endif
#if defined(USB_CAN_BE_DEVICE)
USB_DeviceState = DEVICE_STATE_Unattached;
USB_ConfigurationNumber = 0;
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
USB_RemoteWakeupEnabled = false;
#endif
#if !defined(NO_DEVICE_SELF_POWER) if (!(USB_Options & USB_OPT_REG_DISABLED))
USB_CurrentlySelfPowered = false; USB_REG_On();
#endif else
#endif USB_REG_Off();
if (!(USB_Options & USB_OPT_MANUAL_PLL)) if (!(USB_Options & USB_OPT_MANUAL_PLL))
{ {
...@@ -160,37 +126,52 @@ void USB_ResetInterface(void) ...@@ -160,37 +126,52 @@ void USB_ResetInterface(void)
while (!(USB_PLL_IsReady())); while (!(USB_PLL_IsReady()));
} }
USB_Controller_Reset(); USB_CLK_Unfreeze();
#if defined(USB_CAN_BE_BOTH) #if defined(USB_DEVICE_ONLY) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
if (UHWCON & (1 << UIDE)) UHWCON |= (1 << UIMOD);
USB_Init_Device();
#elif defined(USB_HOST_ONLY)
UHWCON &= ~(1 << UIMOD);
USB_Init_Host();
#elif defined(USB_CAN_BE_BOTH)
if (UIDModeSelectEnabled)
{ {
USB_INT_Clear(USB_INT_IDTI); UHWCON |= (1 << UIDE);
USB_INT_Enable(USB_INT_IDTI); USB_INT_Enable(USB_INT_IDTI);
USB_CurrentMode = USB_GetUSBModeFromUID();
} }
#endif
if (!(USB_Options & USB_OPT_REG_DISABLED))
USB_REG_On();
else
USB_REG_Off();
USB_CLK_Unfreeze();
#if (defined(USB_CAN_BE_DEVICE) && (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)))
if (USB_CurrentMode == USB_MODE_DEVICE) if (USB_CurrentMode == USB_MODE_DEVICE)
{ {
if (USB_Options & USB_DEVICE_OPT_LOWSPEED) UHWCON |= (1 << UIMOD);
USB_Device_SetLowSpeed(); USB_Init_Device();
}
else else
USB_Device_SetFullSpeed(); {
UHWCON &= ~(1 << UIMOD);
USB_Init_Host();
} }
#endif #endif
#if (defined(USB_CAN_BE_DEVICE) && !defined(FIXED_CONTROL_ENDPOINT_SIZE)) USB_OTGPAD_On();
if (USB_CurrentMode == USB_MODE_DEVICE) USB_Attach();
{ }
#if defined(USB_CAN_BE_DEVICE)
static void USB_Init_Device(void)
{
USB_DeviceState = DEVICE_STATE_Unattached;
USB_ConfigurationNumber = 0;
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
USB_RemoteWakeupEnabled = false;
#endif
#if !defined(NO_DEVICE_SELF_POWER)
USB_CurrentlySelfPowered = false;
#endif
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
USB_Descriptor_Device_t* DeviceDescriptorPtr; USB_Descriptor_Device_t* DeviceDescriptorPtr;
if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
...@@ -203,59 +184,38 @@ void USB_ResetInterface(void) ...@@ -203,59 +184,38 @@ void USB_ResetInterface(void)
USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
#endif #endif
} }
}
#endif #endif
USB_Attach(); #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
#if defined(USB_DEVICE_ONLY) USB_Device_SetLowSpeed();
USB_INT_Clear(USB_INT_SUSPEND); else
USB_INT_Enable(USB_INT_SUSPEND); USB_Device_SetFullSpeed();
USB_INT_Clear(USB_INT_EORSTI);
USB_INT_Enable(USB_INT_EORSTI);
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
USB_INT_Enable(USB_INT_VBUS); USB_INT_Enable(USB_INT_VBUS);
#endif #endif
#elif defined(USB_HOST_ONLY)
USB_Host_HostMode_On();
USB_Host_VBUS_Auto_Off();
USB_OTGPAD_Off();
USB_Host_VBUS_Manual_Enable();
USB_Host_VBUS_Manual_On();
USB_INT_Enable(USB_INT_SRPI);
USB_INT_Enable(USB_INT_BCERRI);
#else
if (USB_CurrentMode == USB_MODE_DEVICE)
{
USB_INT_Clear(USB_INT_SUSPEND); USB_INT_Clear(USB_INT_SUSPEND);
USB_INT_Enable(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_SUSPEND);
USB_INT_Clear(USB_INT_EORSTI); USB_INT_Clear(USB_INT_EORSTI);
USB_INT_Enable(USB_INT_EORSTI); USB_INT_Enable(USB_INT_EORSTI);
}
#endif
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) #if defined(USB_CAN_BE_HOST)
USB_INT_Enable(USB_INT_VBUS); static void USB_Init_Host(void)
#endif {
USB_HostState = HOST_STATE_Unattached;
USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
ENDPOINT_BANK_SINGLE);
}
else if (USB_CurrentMode == USB_MODE_HOST)
{
USB_Host_HostMode_On(); USB_Host_HostMode_On();
USB_CLK_Unfreeze();
USB_Host_VBUS_Auto_Off(); USB_Host_VBUS_Auto_Off();
USB_OTGPAD_Off();
USB_Host_VBUS_Manual_Enable(); USB_Host_VBUS_Manual_Enable();
USB_Host_VBUS_Manual_On(); USB_Host_VBUS_Manual_On();
USB_INT_Enable(USB_INT_SRPI); USB_INT_Enable(USB_INT_SRPI);
USB_INT_Enable(USB_INT_BCERRI); USB_INT_Enable(USB_INT_BCERRI);
}
#endif
} }
#endif
...@@ -346,6 +346,17 @@ ...@@ -346,6 +346,17 @@
/* Private Interface - For use in library only: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_USB_CONTROLLER_C)
#if defined(USB_CAN_BE_DEVICE)
static void USB_Init_Device(void);
#endif
#if defined(USB_CAN_BE_HOST)
static void USB_Init_Host(void);
#endif
#endif
/* Inline Functions: */ /* Inline Functions: */
static inline void USB_PLL_On(void) ATTR_ALWAYS_INLINE; static inline void USB_PLL_On(void) ATTR_ALWAYS_INLINE;
static inline void USB_PLL_On(void) static inline void USB_PLL_On(void)
......
...@@ -168,6 +168,8 @@ ISR(USB_GEN_vect, ISR_BLOCK) ...@@ -168,6 +168,8 @@ ISR(USB_GEN_vect, ISR_BLOCK)
#endif #endif
#if defined(USB_CAN_BE_HOST) #if defined(USB_CAN_BE_HOST)
bool MustResetInterface = false;
if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI)) if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI))
{ {
USB_INT_Clear(USB_INT_DDISCI); USB_INT_Clear(USB_INT_DDISCI);
...@@ -176,7 +178,7 @@ ISR(USB_GEN_vect, ISR_BLOCK) ...@@ -176,7 +178,7 @@ ISR(USB_GEN_vect, ISR_BLOCK)
EVENT_USB_Host_DeviceUnattached(); EVENT_USB_Host_DeviceUnattached();
USB_ResetInterface(); MustResetInterface = true;
} }
if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI)) if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI))
...@@ -211,7 +213,7 @@ ISR(USB_GEN_vect, ISR_BLOCK) ...@@ -211,7 +213,7 @@ ISR(USB_GEN_vect, ISR_BLOCK)
EVENT_USB_Host_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0); EVENT_USB_Host_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0);
EVENT_USB_Host_DeviceUnattached(); EVENT_USB_Host_DeviceUnattached();
USB_ResetInterface(); MustResetInterface = true;
} }
if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI)) if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI))
...@@ -236,8 +238,11 @@ ISR(USB_GEN_vect, ISR_BLOCK) ...@@ -236,8 +238,11 @@ ISR(USB_GEN_vect, ISR_BLOCK)
USB_CurrentMode = USB_GetUSBModeFromUID(); USB_CurrentMode = USB_GetUSBModeFromUID();
EVENT_USB_UIDChange(); EVENT_USB_UIDChange();
USB_ResetInterface(); MustResetInterface = true;
} }
if (MustResetInterface)
USB_ResetInterface();
#endif #endif
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment