uint8_t Endpoint_WaitUntilReady(void) { uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; USB_INT_Clear(USB_INT_SOFI); for (;;) { if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) { if (Endpoint_IsINReady()) return ENDPOINT_READYWAIT_NoError; } else { if (Endpoint_IsOUTReceived()) return ENDPOINT_READYWAIT_NoError; } if (!(USB_IsConnected)) return ENDPOINT_READYWAIT_DeviceDisconnected; else if (Endpoint_IsStalled()) return ENDPOINT_READYWAIT_EndpointStalled; if (USB_INT_HasOccurred(USB_INT_SOFI)) { USB_INT_Clear(USB_INT_SOFI); if (!(TimeoutMSRem--)) return ENDPOINT_READYWAIT_Timeout; } } }
void USB_Host_ResetDevice(void) { bool BusSuspended = USB_Host_IsBusSuspended(); USB_INT_Disable(USB_INT_DDISCI); USB_Host_WaitMS(20); USB_Host_ResetBus(); while (!(USB_Host_IsResetBusDone())); USB_INT_Clear(USB_INT_HSOFI); USB_Host_ResumeBus(); for (uint8_t MSRem = 10; MSRem != 0; MSRem--) { /* Workaround for powerless-pullup devices. After a USB bus reset, all disconnection interrupts are supressed while a USB frame is looked for - if it is found within 10ms, the device is still present. */ if (USB_INT_HasOccurred(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_DDISCI); break; } _delay_ms(1); } if (BusSuspended) USB_Host_SuspendBus(); USB_INT_Enable(USB_INT_DDISCI); }
uint8_t Pipe_WaitUntilReady(void) { #if (USB_STREAM_TIMEOUT_MS < 0xFF) uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; #else uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; #endif for (;;) { if (Pipe_GetPipeToken() == PIPE_TOKEN_IN) { if (Pipe_IsINReceived()) return PIPE_READYWAIT_NoError; } else { if (Pipe_IsOUTReady()) return PIPE_READYWAIT_NoError; } if (Pipe_IsStalled()) return PIPE_READYWAIT_PipeStalled; else if (USB_HostState == HOST_STATE_Unattached) return PIPE_READYWAIT_DeviceDisconnected; if (USB_INT_HasOccurred(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_HSOFI); if (!(TimeoutMSRem--)) return PIPE_READYWAIT_Timeout; } } }
uint8_t USB_Host_WaitMS(uint8_t MS) { bool BusSuspended = USB_Host_IsBusSuspended(); uint8_t ErrorCode = HOST_WAITERROR_Successful; USB_INT_Clear(USB_INT_HSOFI); USB_Host_ResumeBus(); while (MS) { if (USB_INT_HasOccurred(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_HSOFI); MS--; } if ((USB_IsConnected == false) || (USB_CurrentMode == USB_MODE_DEVICE)) { ErrorCode = HOST_WAITERROR_DeviceDisconnect; break; } if (Pipe_IsError() == true) { Pipe_ClearError(); ErrorCode = HOST_WAITERROR_PipeError; break; } if (Pipe_IsStalled() == true) { Pipe_ClearStall(); ErrorCode = HOST_WAITERROR_SetupStalled; break; } } if (BusSuspended) USB_Host_SuspendBus(); return ErrorCode; }
/** Waits until the attached device is ready to accept data following a CBW, checking * to ensure that the device has not stalled the transaction. * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ static uint8_t MassStore_WaitForDataReceived(void) { uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS; /* Unfreeze the OUT pipe so that it can be checked */ Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Select the IN data pipe for data reception */ Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Wait until data received in the IN pipe */ while (!(Pipe_IsINReceived())) { /* Check to see if a new frame has been issued (1ms elapsed) */ if (USB_INT_HasOccurred(USB_INT_HSOFI)) { /* Clear the flag and decrement the timeout period counter */ USB_INT_Clear(USB_INT_HSOFI); TimeoutMSRem--; /* Check to see if the timeout period for the command has elapsed */ if (!(TimeoutMSRem)) return PIPE_RWSTREAM_Timeout; } Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ MassStore_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); return PIPE_RWSTREAM_PipeStalled; } Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ MassStore_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); return PIPE_RWSTREAM_PipeStalled; } /* Check to see if the device was disconnected, if so exit function */ if (!(USB_IsConnected)) return PIPE_RWSTREAM_DeviceDisconnected; }; return PIPE_RWSTREAM_NoError; }
ISR(USB_COM_vect, ISR_BLOCK) { uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); USB_USBTask(); USB_INT_Clear(USB_INT_ENDPOINT_SETUP); Endpoint_SelectEndpoint(PrevSelectedEndpoint); }
ISR(USB_COM_vect, ISR_BLOCK) { uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); USB_INT_Disable(USB_INT_RXSTPI); sei(); USB_USBTask(); USB_INT_Enable(USB_INT_RXSTPI); USB_INT_Clear(USB_INT_RXSTPI); Endpoint_SelectEndpoint(PrevSelectedEndpoint); }
uint8_t Endpoint_WaitUntilReady(void) { uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; USB_INT_Clear(USB_INT_SOFI); while (!(Endpoint_ReadWriteAllowed())) { if (!(USB_IsConnected)) return ENDPOINT_READYWAIT_DeviceDisconnected; else if (Endpoint_IsStalled()) return ENDPOINT_READYWAIT_EndpointStalled; if (USB_INT_HasOccurred(USB_INT_SOFI)) { USB_INT_Clear(USB_INT_SOFI); if (!(TimeoutMSRem--)) return ENDPOINT_READYWAIT_Timeout; } } return ENDPOINT_READYWAIT_NoError; }
uint8_t Pipe_WaitUntilReady(void) { uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; USB_INT_Clear(USB_INT_HSOFI); while (!(Pipe_ReadWriteAllowed())) { if (Pipe_IsStalled()) return PIPE_READYWAIT_PipeStalled; else if (!(USB_IsConnected)) return PIPE_READYWAIT_DeviceDisconnected; if (USB_INT_HasOccurred(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_HSOFI); if (!(TimeoutMSRem--)) return PIPE_READYWAIT_Timeout; } } return PIPE_READYWAIT_NoError; }
/** ISR for the general Pipe/Endpoint interrupt vector. This ISR fires when a control request has been issued to the control endpoint, * so that the request can be processed. As several elements of the Mass Storage implementation require asynchronous control requests * (such as endpoint stall clearing and Mass Storage Reset requests during data transfers) this is done via interrupts rather than * polling. */ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK) { /* Check if the control endpoint has received a request */ if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP)) { /* Clear the endpoint interrupt */ Endpoint_ClearEndpointInterrupt(ENDPOINT_CONTROLEP); /* Process the control request */ USB_USBTask(); /* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */ USB_INT_Clear(ENDPOINT_INT_SETUP); } }
static void USB_Init_Device(void) { USB_DeviceState = DEVICE_STATE_Unattached; USB_Device_ConfigurationNumber = 0; #if !defined(NO_DEVICE_REMOTE_WAKEUP) USB_Device_RemoteWakeupEnabled = false; #endif #if !defined(NO_DEVICE_SELF_POWER) USB_Device_CurrentlySelfPowered = false; #endif #if !defined(FIXED_CONTROL_ENDPOINT_SIZE) USB_Descriptor_Device_t* DeviceDescriptorPtr; if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; #endif if (USB_Options & USB_DEVICE_OPT_LOWSPEED) { USB_Device_SetLowSpeed(); } else { #if defined(USB_DEVICE_OPT_HIGHSPEED) if (USB_Options & USB_DEVICE_OPT_HIGHSPEED) USB_Device_SetHighSpeed(); else USB_Device_SetFullSpeed(); #else USB_Device_SetFullSpeed(); #endif } USB_INT_Enable(USB_INT_VBUSTI); Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize, ENDPOINT_BANK_SINGLE); USB_INT_Clear(USB_INT_SUSPI); USB_INT_Enable(USB_INT_SUSPI); USB_INT_Enable(USB_INT_EORSTI); USB_Attach(); }
uint8_t Endpoint_WaitUntilReady(void) { #if (USB_STREAM_TIMEOUT_MS < 0xFF) uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; #else uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; #endif for (;;) { if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) { if (Endpoint_IsINReady()) return ENDPOINT_READYWAIT_NoError; } else { if (Endpoint_IsOUTReceived()) return ENDPOINT_READYWAIT_NoError; } if (USB_DeviceState == DEVICE_STATE_Unattached) return ENDPOINT_READYWAIT_DeviceDisconnected; else if (USB_DeviceState == DEVICE_STATE_Suspended) return ENDPOINT_READYWAIT_BusSuspended; else if (Endpoint_IsStalled()) return ENDPOINT_READYWAIT_EndpointStalled; if (USB_INT_HasOccurred(USB_INT_SOFI)) { USB_INT_Clear(USB_INT_SOFI); if (!(TimeoutMSRem--)) return ENDPOINT_READYWAIT_Timeout; } } }
/** ISR for the general Pipe/Endpoint interrupt vector. This ISR fires when an endpoint's status changes (such as * a packet has been received) on an endpoint with its corresponding ISR enabling bits set. This is used to send * HID packets to the host each time the HID interrupt endpoints polling period elapses, as managed by the USB * controller. */ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK) { /* Save previously selected endpoint before selecting a new endpoint */ uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); #if defined(INTERRUPT_CONTROL_ENDPOINT) /* Check if the control endpoint has received a request */ if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP)) { /* Clear the endpoint interrupt */ Endpoint_ClearEndpointInterrupt(ENDPOINT_CONTROLEP); /* Process the control request */ USB_USBTask(); /* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */ USB_INT_Clear(ENDPOINT_INT_SETUP); } #endif #if defined(INTERRUPT_DATA_ENDPOINT) /* Check if Generic IN endpoint has interrupted */ if (Endpoint_HasEndpointInterrupted(GENERIC_IN_EPNUM)) { /* Select the Generic IN Report Endpoint */ Endpoint_SelectEndpoint(GENERIC_IN_EPNUM); /* Clear the endpoint IN interrupt flag */ USB_INT_Clear(ENDPOINT_INT_IN); /* Clear the Generic IN Report endpoint interrupt and select the endpoint */ Endpoint_ClearEndpointInterrupt(GENERIC_IN_EPNUM); /* Create a temporary buffer to hold the report to send to the host */ uint8_t GenericData[GENERIC_REPORT_SIZE]; /* Create Generic Report Data */ CreateGenericHIDReport(GenericData); /* Write Generic Report Data */ Endpoint_Write_Stream_LE(&GenericData, sizeof(GenericData)); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearIN(); } /* Check if Generic OUT endpoint has interrupted */ if (Endpoint_HasEndpointInterrupted(GENERIC_OUT_EPNUM)) { /* Select the Generic OUT Report Endpoint */ Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM); /* Clear the endpoint OUT Interrupt flag */ USB_INT_Clear(ENDPOINT_INT_OUT); /* Clear the Generic OUT Report endpoint interrupt and select the endpoint */ Endpoint_ClearEndpointInterrupt(GENERIC_OUT_EPNUM); /* Create a temporary buffer to hold the read in report from the host */ uint8_t GenericData[GENERIC_REPORT_SIZE]; /* Read Generic Report Data */ Endpoint_Read_Stream_LE(&GenericData, sizeof(GenericData)); /* Process Generic Report Data */ ProcessGenericHIDReport(GenericData); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearOUT(); } #endif /* Restore previously selected endpoint */ Endpoint_SelectEndpoint(PrevSelectedEndpoint); }
/** Function to receive a PIMA response container from the attached still image device. * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ uint8_t SImage_ReceiveBlockHeader(void) { uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS; /* Unfreeze the data IN pipe */ Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Wait until data received on the IN pipe */ while (!(Pipe_IsReadWriteAllowed())) { /* Check to see if a new frame has been issued (1ms elapsed) */ if (USB_INT_HasOccurred(USB_INT_HSOFI)) { /* Clear the flag and decrement the timeout period counter */ USB_INT_Clear(USB_INT_HSOFI); TimeoutMSRem--; /* Check to see if the timeout period for the command has elapsed */ if (!(TimeoutMSRem)) { /* Return error code */ return PIPE_RWSTREAM_Timeout; } } Pipe_Freeze(); Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ USB_Host_ClearPipeStall(SIMAGE_DATA_OUT_PIPE); /* Return error code and break out of the loop */ return PIPE_RWSTREAM_PipeStalled; } Pipe_Freeze(); Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ USB_Host_ClearPipeStall(SIMAGE_DATA_IN_PIPE); /* Return error code */ return PIPE_RWSTREAM_PipeStalled; } /* Check to see if the device was disconnected, if so exit function */ if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; } /* Load in the response from the attached device */ Pipe_Read_Stream_LE(&PIMA_ReceivedBlock, PIMA_COMMAND_SIZE(0)); /* Check if the returned block type is a response block */ if (PIMA_ReceivedBlock.Type == CType_ResponseBlock) { /* Determine the size of the parameters in the block via the data length attribute */ uint8_t ParamBytes = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0)); /* Check if the device has returned any parameters */ if (ParamBytes) { /* Read the PIMA parameters from the data IN pipe */ Pipe_Read_Stream_LE(&PIMA_ReceivedBlock.Params, ParamBytes); } /* Clear pipe bank after use */ Pipe_ClearIN(); } /* Freeze the IN pipe after use */ Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
ISR(USB_GEN_vect, ISR_BLOCK) { #if defined(USB_CAN_BE_DEVICE) #if !defined(NO_SOF_EVENTS) if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) { USB_INT_Clear(USB_INT_SOFI); EVENT_USB_Device_StartOfFrame(); } #endif #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) if (USB_INT_HasOccurred(USB_INT_VBUSTI) && USB_INT_IsEnabled(USB_INT_VBUSTI)) { USB_INT_Clear(USB_INT_VBUSTI); if (USB_VBUS_GetStatus()) { if (!(USB_Options & USB_OPT_MANUAL_PLL)) { USB_PLL_On(); while (!(USB_PLL_IsReady())); } USB_DeviceState = DEVICE_STATE_Powered; EVENT_USB_Device_Connect(); } else { if (!(USB_Options & USB_OPT_MANUAL_PLL)) USB_PLL_Off(); USB_DeviceState = DEVICE_STATE_Unattached; EVENT_USB_Device_Disconnect(); } } #endif if (USB_INT_HasOccurred(USB_INT_SUSPI) && USB_INT_IsEnabled(USB_INT_SUSPI)) { USB_INT_Disable(USB_INT_SUSPI); USB_INT_Enable(USB_INT_WAKEUPI); USB_CLK_Freeze(); if (!(USB_Options & USB_OPT_MANUAL_PLL)) USB_PLL_Off(); #if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) USB_DeviceState = DEVICE_STATE_Unattached; EVENT_USB_Device_Disconnect(); #else USB_DeviceState = DEVICE_STATE_Suspended; EVENT_USB_Device_Suspend(); #endif } if (USB_INT_HasOccurred(USB_INT_WAKEUPI) && USB_INT_IsEnabled(USB_INT_WAKEUPI)) { if (!(USB_Options & USB_OPT_MANUAL_PLL)) { USB_PLL_On(); while (!(USB_PLL_IsReady())); } USB_CLK_Unfreeze(); USB_INT_Clear(USB_INT_WAKEUPI); USB_INT_Disable(USB_INT_WAKEUPI); USB_INT_Enable(USB_INT_SUSPI); if (USB_Device_ConfigurationNumber) USB_DeviceState = DEVICE_STATE_Configured; else USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; #if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) EVENT_USB_Device_Connect(); #else EVENT_USB_Device_WakeUp(); #endif } if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI)) { USB_INT_Clear(USB_INT_EORSTI); USB_DeviceState = DEVICE_STATE_Default; USB_Device_ConfigurationNumber = 0; USB_INT_Clear(USB_INT_SUSPI); USB_INT_Disable(USB_INT_SUSPI); USB_INT_Enable(USB_INT_WAKEUPI); Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize, ENDPOINT_BANK_SINGLE); #if defined(INTERRUPT_CONTROL_ENDPOINT) USB_INT_Enable(USB_INT_RXSTPI); #endif EVENT_USB_Device_Reset(); } #endif #if defined(USB_CAN_BE_HOST) #if !defined(NO_SOF_EVENTS) if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_HSOFI); EVENT_USB_Host_StartOfFrame(); } #endif if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI)) { USB_INT_Clear(USB_INT_DDISCI); USB_INT_Clear(USB_INT_DCONNI); USB_INT_Disable(USB_INT_DDISCI); EVENT_USB_Host_DeviceUnattached(); USB_ResetInterface(); } if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI)) { USB_INT_Clear(USB_INT_VBERRI); USB_Host_VBUS_Manual_Off(); USB_Host_VBUS_Auto_Off(); EVENT_USB_Host_HostError(HOST_ERROR_VBusVoltageDip); EVENT_USB_Host_DeviceUnattached(); USB_HostState = HOST_STATE_Unattached; } if (USB_INT_HasOccurred(USB_INT_SRPI) && USB_INT_IsEnabled(USB_INT_SRPI)) { USB_INT_Clear(USB_INT_SRPI); USB_INT_Disable(USB_INT_SRPI); EVENT_USB_Host_DeviceAttached(); USB_INT_Enable(USB_INT_DDISCI); USB_HostState = HOST_STATE_Powered; } if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI)) { USB_INT_Clear(USB_INT_BCERRI); EVENT_USB_Host_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0); EVENT_USB_Host_DeviceUnattached(); USB_ResetInterface(); } #endif #if defined(USB_CAN_BE_BOTH) if (USB_INT_HasOccurred(USB_INT_IDTI) && USB_INT_IsEnabled(USB_INT_IDTI)) { USB_INT_Clear(USB_INT_IDTI); if (USB_DeviceState != DEVICE_STATE_Unattached) EVENT_USB_Device_Disconnect(); if (USB_HostState != HOST_STATE_Unattached) EVENT_USB_Host_DeviceUnattached(); USB_CurrentMode = USB_GetUSBModeFromUID(); USB_ResetInterface(); EVENT_USB_UIDChange(); } #endif }
static void USB_Init_Device(void) { USB_DeviceState = DEVICE_STATE_Unattached; USB_Device_ConfigurationNumber = 0; #if !defined(NO_DEVICE_REMOTE_WAKEUP) USB_Device_RemoteWakeupEnabled = false; #endif #if !defined(NO_DEVICE_SELF_POWER) USB_Device_CurrentlySelfPowered = false; #endif #if !defined(FIXED_CONTROL_ENDPOINT_SIZE) USB_Descriptor_Device_t* DeviceDescriptorPtr; #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) uint8_t DescriptorAddressSpace; if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR) { if (DescriptorAddressSpace == MEMSPACE_FLASH) USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); else if (DescriptorAddressSpace == MEMSPACE_EEPROM) USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); else USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; } #else if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) { #if defined(USE_RAM_DESCRIPTORS) USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; #elif defined(USE_EEPROM_DESCRIPTORS) USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); #else USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); #endif } #endif #endif #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) if (USB_Options & USB_DEVICE_OPT_LOWSPEED) USB_Device_SetLowSpeed(); else USB_Device_SetFullSpeed(); USB_INT_Enable(USB_INT_VBUSTI); #endif Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize, ENDPOINT_BANK_SINGLE); USB_INT_Clear(USB_INT_SUSPI); USB_INT_Enable(USB_INT_SUSPI); USB_INT_Enable(USB_INT_EORSTI); USB_Attach(); }
void USB_Init( #if defined(USB_CAN_BE_BOTH) const uint8_t Mode #endif #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) , #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) void #endif #if !defined(USE_STATIC_OPTIONS) const uint8_t Options #endif ) { #if defined(USB_CAN_BE_BOTH) USB_CurrentMode = Mode; #endif #if !defined(USE_STATIC_OPTIONS) USB_Options = Options; #endif #if defined(USB_CAN_BE_HOST) USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; #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_UID) { UHWCON |= (1 << UIDE); USB_INT_Clear(USB_INT_IDTI); USB_INT_Enable(USB_INT_IDTI); USB_CurrentMode = USB_GetUSBModeFromUID(); } else if (Mode == USB_MODE_DEVICE) { UHWCON |= (1 << UIMOD); } else if (Mode == USB_MODE_HOST) { UHWCON &= ~(1 << UIMOD); } else { EVENT_USB_InitFailure(USB_INITERROR_NoUSBModeSpecified); return; } #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; sei(); }
void USB_ResetInterface(void) { USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); #if defined(USB_CAN_BE_HOST) 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) USB_CurrentlySelfPowered = false; #endif #endif if (!(USB_Options & USB_OPT_MANUAL_PLL)) { #if defined(USB_SERIES_4_AVR) PLLFRQ = ((1 << PLLUSB) | (1 << PDIV3) | (1 << PDIV1)); #endif USB_PLL_On(); while (!(USB_PLL_IsReady())); } USB_Controller_Reset(); #if defined(USB_CAN_BE_BOTH) if (UHWCON & (1 << UIDE)) { USB_INT_Clear(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_Options & USB_DEVICE_OPT_LOWSPEED) USB_Device_SetLowSpeed(); else USB_Device_SetFullSpeed(); } #endif #if (defined(USB_CAN_BE_DEVICE) && !defined(FIXED_CONTROL_ENDPOINT_SIZE)) if (USB_CurrentMode == USB_MODE_DEVICE) { USB_Descriptor_Device_t* DeviceDescriptorPtr; if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) { #if defined(USE_RAM_DESCRIPTORS) USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; #elif defined(USE_EEPROM_DESCRIPTORS) USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); #else USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); #endif } } #endif USB_Attach(); #if defined(USB_DEVICE_ONLY) USB_INT_Clear(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_SUSPEND); 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); #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_Enable(USB_INT_SUSPEND); 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); #endif #if defined(CONTROL_ONLY_DEVICE) UENUM = ENDPOINT_CONTROLEP; #endif } else if (USB_CurrentMode == USB_MODE_HOST) { 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); } #endif }
void USB_Host_ProcessNextHostState(void) { uint8_t ErrorCode = HOST_ENUMERROR_NoError; uint8_t SubErrorCode = HOST_ENUMERROR_NoError; static uint16_t WaitMSRemaining; static uint8_t PostWaitState; switch (USB_HostState) { case HOST_STATE_WaitForDevice: if (WaitMSRemaining) { if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) { USB_HostState = PostWaitState; ErrorCode = HOST_ENUMERROR_WaitStage; break; } if (!(--WaitMSRemaining)) USB_HostState = PostWaitState; } break; case HOST_STATE_Powered: WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS; USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle; break; case HOST_STATE_Powered_WaitForDeviceSettle: if (WaitMSRemaining--) { _delay_ms(1); break; } else { USB_Host_VBUS_Manual_Off(); USB_OTGPAD_On(); USB_Host_VBUS_Auto_Enable(); USB_Host_VBUS_Auto_On(); USB_HostState = HOST_STATE_Powered_WaitForConnect; } break; case HOST_STATE_Powered_WaitForConnect: if (USB_INT_HasOccurred(USB_INT_DCONNI)) { USB_INT_Clear(USB_INT_DCONNI); USB_INT_Clear(USB_INT_DDISCI); USB_INT_Clear(USB_INT_VBERRI); USB_INT_Enable(USB_INT_VBERRI); USB_Host_ResumeBus(); Pipe_ClearPipes(); HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset); } break; case HOST_STATE_Powered_DoReset: USB_Host_ResetDevice(); HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe); break; case HOST_STATE_Powered_ConfigPipe: Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP, PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE); if (!(Pipe_IsConfigured())) { ErrorCode = HOST_ENUMERROR_PipeConfigError; SubErrorCode = 0; break; } USB_HostState = HOST_STATE_Default; break; case HOST_STATE_Default: USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), .bRequest = REQ_GetDescriptor, .wValue = (DTYPE_Device << 8), .wIndex = 0, .wLength = 8, }; uint8_t DataBuffer[8]; if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful) { ErrorCode = HOST_ENUMERROR_ControlError; break; } USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)]; USB_Host_ResetDevice(); HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset); break; case HOST_STATE_Default_PostReset: Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP, USB_ControlPipeSize, PIPE_BANK_SINGLE); if (!(Pipe_IsConfigured())) { ErrorCode = HOST_ENUMERROR_PipeConfigError; SubErrorCode = 0; break; } USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bRequest = REQ_SetAddress, .wValue = USB_HOST_DEVICEADDRESS, .wIndex = 0, .wLength = 0, }; if ((SubErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) { ErrorCode = HOST_ENUMERROR_ControlError; break; } HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet); break; case HOST_STATE_Default_PostAddressSet: USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS); EVENT_USB_Host_DeviceEnumerationComplete(); USB_HostState = HOST_STATE_Addressed; break; } if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached)) { EVENT_USB_Host_DeviceEnumerationFailed(ErrorCode, SubErrorCode); USB_Host_VBUS_Auto_Off(); EVENT_USB_Host_DeviceUnattached(); USB_ResetInterface(); } } uint8_t USB_Host_WaitMS(uint8_t MS) { bool BusSuspended = USB_Host_IsBusSuspended(); uint8_t ErrorCode = HOST_WAITERROR_Successful; bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); USB_INT_Disable(USB_INT_HSOFI); USB_INT_Clear(USB_INT_HSOFI); USB_Host_ResumeBus(); while (MS) { if (USB_INT_HasOccurred(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_HSOFI); MS--; } if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode != USB_MODE_Host)) { ErrorCode = HOST_WAITERROR_DeviceDisconnect; break; } if (Pipe_IsError() == true) { Pipe_ClearError(); ErrorCode = HOST_WAITERROR_PipeError; break; } if (Pipe_IsStalled() == true) { Pipe_ClearStall(); ErrorCode = HOST_WAITERROR_SetupStalled; break; } } if (BusSuspended) USB_Host_SuspendBus(); if (HSOFIEnabled) USB_INT_Enable(USB_INT_HSOFI); return ErrorCode; } static void USB_Host_ResetDevice(void) { bool BusSuspended = USB_Host_IsBusSuspended(); USB_INT_Disable(USB_INT_DDISCI); USB_Host_ResetBus(); while (!(USB_Host_IsBusResetComplete())); USB_Host_ResumeBus(); bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); USB_INT_Disable(USB_INT_HSOFI); USB_INT_Clear(USB_INT_HSOFI); for (uint8_t MSRem = 10; MSRem != 0; MSRem--) { /* Workaround for powerless-pull-up devices. After a USB bus reset, all disconnection interrupts are suppressed while a USB frame is looked for - if it is found within 10ms, the device is still present. */ if (USB_INT_HasOccurred(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_HSOFI); USB_INT_Clear(USB_INT_DDISCI); break; } _delay_ms(1); } if (HSOFIEnabled) USB_INT_Enable(USB_INT_HSOFI); if (BusSuspended) USB_Host_SuspendBus(); USB_INT_Enable(USB_INT_DDISCI); }
ISR(USB_GEN_vect, ISR_BLOCK) { #if defined(USB_CAN_BE_DEVICE) #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) if (USB_INT_HasOccurred(USB_INT_VBUS) && USB_INT_IsEnabled(USB_INT_VBUS)) { USB_INT_Clear(USB_INT_VBUS); RAISE_EVENT(USB_VBUSChange); if (USB_VBUS_GetStatus()) { RAISE_EVENT(USB_VBUSConnect); if (USB_IsConnected) RAISE_EVENT(USB_Disconnect); USB_ResetInterface(); USB_IsConnected = true; RAISE_EVENT(USB_Connect); } else { RAISE_EVENT(USB_Disconnect); USB_Detach(); USB_CLK_Freeze(); USB_PLL_Off(); USB_REG_Off(); USB_IsConnected = false; RAISE_EVENT(USB_VBUSDisconnect); USB_INT_Clear(USB_INT_VBUS); } } #endif if (USB_INT_HasOccurred(USB_INT_SUSPEND) && USB_INT_IsEnabled(USB_INT_SUSPEND)) { USB_INT_Clear(USB_INT_SUSPEND); USB_INT_Disable(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_WAKEUP); USB_CLK_Freeze(); if (!(USB_Options & USB_OPT_MANUAL_PLL)) USB_PLL_Off(); USB_IsSuspended = true; RAISE_EVENT(USB_Suspend); #if defined(USB_LIMITED_CONTROLLER) && !defined(NO_LIMITED_CONTROLLER_CONNECT) if (USB_IsConnected) { USB_IsConnected = false; RAISE_EVENT(USB_Disconnect); } #endif } if (USB_INT_HasOccurred(USB_INT_WAKEUP) && USB_INT_IsEnabled(USB_INT_WAKEUP)) { if (!(USB_Options & USB_OPT_MANUAL_PLL)) { USB_PLL_On(); while (!(USB_PLL_IsReady())); } USB_CLK_Unfreeze(); USB_INT_Clear(USB_INT_WAKEUP); USB_INT_Disable(USB_INT_WAKEUP); USB_INT_Enable(USB_INT_SUSPEND); #if defined(USB_LIMITED_CONTROLLER) && !defined(NO_LIMITED_CONTROLLER_CONNECT) if (!(USB_IsConnected)) { USB_IsConnected = true; RAISE_EVENT(USB_Connect); } #endif USB_IsSuspended = false; RAISE_EVENT(USB_WakeUp); } if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI)) { USB_INT_Clear(USB_INT_EORSTI); USB_ConfigurationNumber = 0; USB_INT_Clear(USB_INT_SUSPEND); USB_INT_Disable(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_WAKEUP); Endpoint_ClearEndpoints(); Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, ENDPOINT_DIR_OUT, USB_ControlEndpointSize, ENDPOINT_BANK_SINGLE); RAISE_EVENT(USB_Reset); } #endif #if defined(USB_CAN_BE_HOST) if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI)) { USB_INT_Clear(USB_INT_DDISCI); USB_INT_Clear(USB_INT_DCONNI); USB_INT_Disable(USB_INT_DDISCI); RAISE_EVENT(USB_DeviceUnattached); RAISE_EVENT(USB_Disconnect); USB_ResetInterface(); } if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI)) { USB_INT_Clear(USB_INT_VBERRI); USB_Host_VBUS_Manual_Off(); USB_Host_VBUS_Auto_Off(); RAISE_EVENT(USB_HostError, HOST_ERROR_VBusVoltageDip); RAISE_EVENT(USB_DeviceUnattached); USB_HostState = HOST_STATE_Unattached; } if (USB_INT_HasOccurred(USB_INT_SRPI) && USB_INT_IsEnabled(USB_INT_SRPI)) { USB_INT_Clear(USB_INT_SRPI); USB_INT_Disable(USB_INT_SRPI); RAISE_EVENT(USB_DeviceAttached); USB_INT_Enable(USB_INT_DDISCI); USB_HostState = HOST_STATE_Attached; } if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI)) { USB_INT_Clear(USB_INT_BCERRI); RAISE_EVENT(USB_DeviceEnumerationFailed, HOST_ENUMERROR_NoDeviceDetected, 0); RAISE_EVENT(USB_DeviceUnattached); if (USB_IsConnected) RAISE_EVENT(USB_Disconnect); USB_ResetInterface(); } #endif #if defined(USB_CAN_BE_BOTH) if (USB_INT_HasOccurred(USB_INT_IDTI) && USB_INT_IsEnabled(USB_INT_IDTI)) { USB_INT_Clear(USB_INT_IDTI); if (USB_IsConnected) { if (USB_CurrentMode == USB_MODE_HOST) RAISE_EVENT(USB_DeviceUnattached); else RAISE_EVENT(USB_Disconnect); } RAISE_EVENT(USB_UIDChange); USB_ResetInterface(); } #endif }
static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader) { uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS; Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); while (!(Pipe_IsReadWriteAllowed())) { if (USB_INT_HasOccurred(USB_INT_HSOFI)) { USB_INT_Clear(USB_INT_HSOFI); TimeoutMSRem--; if (!(TimeoutMSRem)) { return PIPE_RWSTREAM_Timeout; } } Pipe_Freeze(); Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if (Pipe_IsStalled()) { USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber); return PIPE_RWSTREAM_PipeStalled; } Pipe_Freeze(); Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); if (Pipe_IsStalled()) { USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber); return PIPE_RWSTREAM_PipeStalled; } if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; } Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK); if (PIMAHeader->Type == CType_ResponseBlock) { uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); if (ParamBytes) Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK); Pipe_ClearIN(); PIMAHeader->Code &= 0x0000000F; } Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
void USB_SetupInterface(void) { USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); USB_IsConnected = false; #if defined(USB_CAN_BE_BOTH) USB_IsInitialized = false; #endif #if defined(USB_CAN_BE_HOST) USB_HostState = HOST_STATE_Unattached; #endif #if defined(USB_CAN_BE_DEVICE) USB_ConfigurationNumber = 0; USB_RemoteWakeupEnabled = false; USB_CurrentlySelfPowered = false; #endif #if defined(USB_MODIFIED_FULL_CONTROLLER) && !defined(MANUAL_PLL_CONTROL) PLLFRQ = ((1 << PLLUSB) | (1 << PDIV3) | (1 << PDIV1)); #endif #if !defined(MANUAL_PLL_CONTROL) USB_PLL_On(); #endif while (!(USB_PLL_IsReady())); USB_Interface_Reset(); #if defined(USB_CAN_BE_BOTH) if (UHWCON & (1 << UIDE)) { USB_INT_Clear(USB_INT_IDTI); USB_INT_Enable(USB_INT_IDTI); USB_CurrentMode = USB_GetUSBModeFromUID(); } #elif defined(USB_DEVICE_ONLY) #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) USB_INT_Enable(USB_INT_VBUS); #endif #endif if (!(USB_Options & USB_OPT_REG_DISABLED)) USB_REG_On(); USB_CLK_Unfreeze(); #if (defined(USB_CAN_BE_DEVICE) && (defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER))) if (USB_CurrentMode == USB_MODE_DEVICE) { #ifdef CUL_V3 USB_Device_SetHighSpeed(); #else if (USB_Options & USB_DEVICE_OPT_LOWSPEED) USB_Device_SetLowSpeed(); else USB_Device_SetHighSpeed(); #endif USB_INT_Enable(USB_INT_VBUS); } #endif #if defined(USB_CAN_BE_HOST) USB_INT_Enable(USB_INT_VBERRI); if (USB_CurrentMode == USB_MODE_HOST) USB_Host_PrepareForDeviceConnect(); #endif #if defined(USB_CAN_BE_DEVICE) USB_Descriptor_Device_t* DeviceDescriptorPtr; uint16_t DeviceDescriptorSize; if (USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DeviceDescriptorSize) == true) { #if defined(USE_RAM_DESCRIPTORS) USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; #elif defined(USE_EEPROM_DESCRIPTORS) USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); #else USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); #endif } #endif USB_Attach(); #if defined(USB_DEVICE_ONLY) USB_INT_Enable(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_EORSTI); #elif defined(USB_HOST_ONLY) USB_Host_HostMode_On(); #else if (USB_CurrentMode == USB_MODE_DEVICE) { USB_INT_Enable(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_EORSTI); } else if (USB_CurrentMode == USB_MODE_HOST) { USB_Host_HostMode_On(); } #endif #if defined(USB_CAN_BE_BOTH) USB_InitTaskPointer(); #endif }
void USB_Init( #if defined(USB_CAN_BE_BOTH) const uint8_t Mode #endif #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) , #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) void #endif #if !defined(USE_STATIC_OPTIONS) const uint8_t Options #endif ) { if (USB_IsInitialized) USB_ShutDown(); #if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) USB_CurrentMode = Mode; #endif #if defined(USB_DEVICE_ONLY) #if defined(USB_FULL_CONTROLLER) UHWCON |= (1 << UIMOD); #endif #elif defined(USB_HOST_ONLY) UHWCON &= ~(1 << UIMOD); #else if (Mode == USB_MODE_NONE) { RAISE_EVENT(USB_PowerOnFail, POWERON_ERROR_NoUSBModeSpecified); return; } else if (Mode == USB_MODE_UID) { UHWCON |= (1 << UIDE); USB_INT_Clear(USB_INT_IDTI); USB_INT_Enable(USB_INT_IDTI); USB_CurrentMode = USB_GetUSBModeFromUID(); } else if (Mode == USB_MODE_DEVICE) { UHWCON |= (1 << UIMOD); } else if (Mode == USB_MODE_HOST) { UHWCON &= ~(1 << UIMOD); } #endif #if defined(USB_CAN_BE_BOTH) USB_InitTaskPointer(); #else USB_IsInitialized = true; #endif #if defined(USB_CAN_BE_HOST) USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; #endif #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) USB_OTGPAD_On(); #endif #if !defined(USE_STATIC_OPTIONS) USB_Options = Options; #endif #if defined(USB_DEVICE_ONLY) #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) USB_INT_Enable(USB_INT_VBUS); #else USB_SetupInterface(); #endif #elif defined(USB_HOST_ONLY) USB_SetupInterface(); #else if (USB_CurrentMode == USB_MODE_DEVICE) USB_INT_Enable(USB_INT_VBUS); else USB_SetupInterface(); #endif sei(); }