Beispiel #1
0
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);
}
Beispiel #2
0
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;
		}
	}
}
Beispiel #3
0
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 (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;
		}
	}
}
Beispiel #4
0
/** 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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
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
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #12
0
/** 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;
}