Example #1
0
uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                                 , uint8_t (* const Callback)(void)
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)Data;
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Pipe_WaitUntilReady()))
	  return ErrorCode;

	while (Length--)
	{
		if (!(Pipe_ReadWriteAllowed()))
		{
			Pipe_ClearCurrentBank();
				
			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return PIPE_RWSTREAM_ERROR_CallbackAborted;
			#endif

			if ((ErrorCode = Pipe_WaitUntilReady()))
			  return ErrorCode;
		}

		Pipe_Write_Byte(*(DataStream++));
	}

	return PIPE_RWSTREAM_ERROR_NoError;
}
Example #2
0
uint8_t Pipe_Write_Stream_BE(const void* Data, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                                 , uint8_t (* const Callback)(void)
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)(Data + Length - 1);
	uint8_t  ErrorCode;
	
	while (Length)
	{
		if (!(Pipe_ReadWriteAllowed()))
		{
			Pipe_ClearCurrentBank();
				
			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
			#endif

			if ((ErrorCode = Pipe_WaitUntilReady()))
			  return ErrorCode;
		}

		Pipe_Write_Byte(*(DataStream--));
		Length--;
		
		if (!(USB_IsConnected))
		  return PIPE_RWSTREAM_ERROR_DeviceDisconnected;
		else if (Pipe_IsStalled())
		  return PIPE_RWSTREAM_ERROR_PipeStalled;
	}

	return PIPE_RWSTREAM_ERROR_NoError;
}
Example #3
0
static int CDC_putchar(char c, FILE *stream)
{	  
	Pipe_SelectPipe(CDC_DATAPIPE_OUT);
	
	if (Pipe_WaitUntilReady())
	  return -1;

	Pipe_Write_Byte(c);
	Pipe_ClearIN();
	
	return 0;
}
Example #4
0
uint8_t Pipe_Null_Stream(uint16_t Length,
                         uint16_t* const BytesProcessed)
{
	uint8_t  ErrorCode;
	uint16_t BytesInTransfer = 0;
	
	Pipe_SetPipeToken(PIPE_TOKEN_OUT);

	if ((ErrorCode = Pipe_WaitUntilReady()))
	  return ErrorCode;

	if (BytesProcessed != NULL)
	  Length -= *BytesProcessed;

	while (Length)
	{
		if (!(Pipe_IsReadWriteAllowed()))
		{
			Pipe_ClearOUT();
				
			if (BytesProcessed != NULL)
			{
				*BytesProcessed += BytesInTransfer;
				return PIPE_RWSTREAM_IncompleteTransfer;
			}
			
			USB_USBTask();

			if ((ErrorCode = Pipe_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
			Pipe_Write_Byte(0);
			
			Length--;
			BytesInTransfer++;
		}
	}

	return PIPE_RWSTREAM_NoError;
}
Example #5
0
/** Writes a report to the attached device.
 *
 *  \param[in] ReportOUTData  Buffer containing the report to send to the device
 *  \param[in] ReportIndex    Index of the report in the device (zero if the device does not use multiple reports)
 *  \param[in] ReportType     Type of report to send, either REPORT_TYPE_OUT or REPORT_TYPE_FEATURE
 *  \param[in] ReportLength   Length of the report to send
 */
void WriteNextReport(uint8_t* ReportOUTData,
                     const uint8_t ReportIndex,
                     const uint8_t ReportType,
                     uint16_t ReportLength)
{
	/* Select the HID data OUT pipe */
	Pipe_SelectPipe(HID_DATA_OUT_PIPE);

	/* Not all HID devices have an OUT endpoint (some require OUT reports to be sent over the
	 * control endpoint instead) - check to see if the OUT endpoint has been initialized */
	if (Pipe_IsConfigured() && (ReportType == REPORT_TYPE_OUT))
	{
		Pipe_Unfreeze();

		/* Ensure pipe is ready to be written to before continuing */
		if (!(Pipe_IsOUTReady()))
		{
			/* Refreeze the data OUT pipe */
			Pipe_Freeze();

			return;
		}

		/* If the report index is used, send it before the report data */
		if (ReportIndex)
		  Pipe_Write_Byte(ReportIndex);

		/* Write out HID report data */
		Pipe_Write_Stream_LE(ReportOUTData, ReportLength);

		/* Clear the OUT endpoint, send last data packet */
		Pipe_ClearOUT();

		/* Refreeze the data OUT pipe */
		Pipe_Freeze();
	}
	else
	{
		/* Class specific request to send a HID report to the device */
		USB_ControlRequest = (USB_Request_Header_t)
			{
				.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
				.bRequest      = HID_REQ_SetReport,
				.wValue        = ((ReportType << 8) | ReportIndex),
				.wIndex        = 0,
				.wLength       = ReportLength,
			};

		/* Select the control pipe for the request transfer */
		Pipe_SelectPipe(PIPE_CONTROLPIPE);

		/* Send the request to the device */
		USB_Host_SendControlRequest(ReportOUTData);
	}
}

/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
 *  HID reports from the device and to send reports if desired.
 */
void HID_Host_Task(void)
{
	uint8_t ErrorCode;

	/* Switch to determine what user-application handled host state the host state machine is in */
	switch (USB_HostState)
	{
		case HOST_STATE_Addressed:
			puts_P(PSTR("Getting Config Data.\r\n"));

			/* Get and process the configuration descriptor data */
			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
			{
				if (ErrorCode == ControlError)
				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
				else
				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error status */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error status */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			puts_P(PSTR("HID Device Enumerated.\r\n"));

			USB_HostState = HOST_STATE_Configured;
			break;
		case HOST_STATE_Configured:
			ReadNextReport();

			break;
	}
}
Example #6
0
uint8_t USB_Host_SendControlRequest(void* const BufferPtr)
{
	uint8_t* HeaderStream   = (uint8_t*)&USB_ControlRequest;
	uint8_t* DataStream     = (uint8_t*)BufferPtr;
	bool     BusSuspended   = USB_Host_IsBusSuspended();
	uint8_t  ReturnStatus   = HOST_SENDCONTROL_Successful;
	uint16_t DataLen        = USB_ControlRequest.wLength;

	USB_Host_ResumeBus();

	if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
	  goto End_Of_Control_Send;

	Pipe_SetPipeToken(PIPE_TOKEN_SETUP);
	Pipe_ClearErrorFlags();

	Pipe_Unfreeze();

	for (uint8_t HeaderByte = 0; HeaderByte < sizeof(USB_Request_Header_t); HeaderByte++)
	  Pipe_Write_Byte(*(HeaderStream++));

	Pipe_ClearSETUP();

	if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_SetupSent)) != HOST_SENDCONTROL_Successful)
	  goto End_Of_Control_Send;

	Pipe_Freeze();

	if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
	  goto End_Of_Control_Send;

	if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST)
	{
		Pipe_SetPipeToken(PIPE_TOKEN_IN);

		if (DataStream != NULL)
		{
			while (DataLen)
			{
				Pipe_Unfreeze();

				if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful)
				  goto End_Of_Control_Send;

				if (!(Pipe_BytesInPipe()))
				  DataLen = 0;

				while (Pipe_BytesInPipe() && DataLen)
				{
					*(DataStream++) = Pipe_Read_Byte();
					DataLen--;
				}

				Pipe_Freeze();
				Pipe_ClearIN();
			}
		}

		Pipe_SetPipeToken(PIPE_TOKEN_OUT);
		Pipe_Unfreeze();

		if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
		  goto End_Of_Control_Send;

		Pipe_ClearOUT();

		if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
		  goto End_Of_Control_Send;
	}
	else
	{
		if (DataStream != NULL)
		{
			Pipe_SetPipeToken(PIPE_TOKEN_OUT);
			Pipe_Unfreeze();

			while (DataLen)
			{
				if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
				  goto End_Of_Control_Send;

				while (DataLen && (Pipe_BytesInPipe() < USB_ControlPipeSize))
				{
					Pipe_Write_Byte(*(DataStream++));
					DataLen--;
				}

				Pipe_ClearOUT();
			}

			if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
			  goto End_Of_Control_Send;

			Pipe_Freeze();
		}

		Pipe_SetPipeToken(PIPE_TOKEN_IN);
		Pipe_Unfreeze();

		if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful)
		  goto End_Of_Control_Send;

		Pipe_ClearIN();
	}

End_Of_Control_Send:
	Pipe_Freeze();

	if (BusSuspended)
	  USB_Host_SuspendBus();

	Pipe_ResetPipe(PIPE_CONTROLPIPE);

	return ReturnStatus;
}