示例#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;
}
示例#2
0
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
{
	if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
	  return PIPE_RWSTREAM_DeviceDisconnected;

	uint8_t ErrorCode;

	Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address);
	Pipe_Unfreeze();

	if (Pipe_BytesInPipe())
	{
		Pipe_ClearOUT();

		if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
		{
			Pipe_Freeze();
			return ErrorCode;
		}
	}

	Pipe_Freeze();

	return PIPE_READYWAIT_NoError;
}
示例#3
0
文件: MassStorage.c 项目: Eih3/v0.83
static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
                                   MS_CommandBlockWrapper_t* const SCSICommandBlock,
                                   const void* const BufferPtr)
{
	uint8_t ErrorCode = PIPE_RWSTREAM_NoError;

	SCSICommandBlock->Signature = MS_CBW_SIGNATURE;
	SCSICommandBlock->Tag       = ++MSInterfaceInfo->State.TransactionTag;

	if (MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF)
	  MSInterfaceInfo->State.TransactionTag = 1;

	Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
	Pipe_Unfreeze();

	if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t),
	                                      NULL)) != PIPE_RWSTREAM_NoError)
	  return ErrorCode;

	Pipe_ClearOUT();
	Pipe_WaitUntilReady();

	Pipe_Freeze();

	if ((BufferPtr != NULL) &&
	    ((ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr)) != PIPE_RWSTREAM_NoError))
	{
		Pipe_Freeze();
		return ErrorCode;
	}

	return ErrorCode;
}
示例#4
0
uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
							#if !defined(NO_STREAM_CALLBACKS)
                                 , uint8_t (* const Callback)(void)
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)(Buffer + 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;
		}

		*(DataStream--) = Pipe_Read_Byte();
		Length--;
		
		if (!(USB_IsConnected))
		  return PIPE_RWSTREAM_ERROR_DeviceDisconnected;
		else if (Pipe_IsStalled())
		  return PIPE_RWSTREAM_ERROR_PipeStalled;
	}
	
	return PIPE_RWSTREAM_ERROR_NoError;
}
示例#5
0
uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer,
                            uint16_t Length,
                            uint16_t* const BytesProcessed)
{
	uint8_t* DataStream      = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));
	uint16_t BytesInTransfer = 0;
	uint8_t  ErrorCode;

	Pipe_SetPipeToken(TEMPLATE_TOKEN);

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

	if (BytesProcessed != NULL)
	{
		Length -= *BytesProcessed;
		TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed);
	}

	while (Length)
	{
		if (!(Pipe_IsReadWriteAllowed()))
		{
			TEMPLATE_CLEAR_PIPE();

			if (BytesProcessed != NULL)
			{
				*BytesProcessed += BytesInTransfer;
				return PIPE_RWSTREAM_IncompleteTransfer;
			}

			if ((ErrorCode = Pipe_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
			TEMPLATE_TRANSFER_BYTE(DataStream);
			TEMPLATE_BUFFER_MOVE(DataStream, 1);
			Length--;
			BytesInTransfer++;
		}
	}

	return PIPE_RWSTREAM_NoError;
}
示例#6
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_8(0);
			
			Length--;
			BytesInTransfer++;
		}
	}

	return PIPE_RWSTREAM_NoError;
}
示例#7
0
文件: CDCHost.c 项目: TomMD/teensy
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;
}
/** Sends the given data directly to the printer via the data endpoints, for the sending of print commands in printer
 *  languages accepted by the attached printer (e.g. PCL).
 *
 *  \param[in] PrinterCommands  Pointer to the data to send to the attached printer
 *  \param[in] CommandSize  Size of the data to send to the attached printer
 *
 *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
 */
uint8_t Printer_SendData(const void* const PrinterCommands,
                         const uint16_t CommandSize)
{
	uint8_t ErrorCode;

	Pipe_SelectPipe(PRINTER_DATA_OUT_PIPE);
	Pipe_Unfreeze();

	if ((ErrorCode = Pipe_Write_Stream_LE(PrinterCommands, CommandSize, NULL)) != PIPE_RWSTREAM_NoError)
	  return ErrorCode;

	Pipe_ClearOUT();

	Pipe_WaitUntilReady();

	Pipe_Freeze();

	return PIPE_RWSTREAM_NoError;
}
示例#9
0
/** Sends a packet to the remote device on the specified channel.
 *
 * \param[in] Data        Pointer to a buffer where the data is to be sourced from
 * \param[in] DataLen     Length of the data to send
 * \param[in] ACLChannel  ACL channel information structure containing the destination channel's information, NULL
 *                        to send to the remote device's signaling channel
 *
 * \return A value from the \ref BT_SendPacket_ErrorCodes_t enum
 */
uint8_t Bluetooth_SendPacket(void* Data,
                             const uint16_t DataLen,
                             Bluetooth_Channel_t* const ACLChannel)
{
	BT_ACL_Header_t        ACLPacketHeader;
	BT_DataPacket_Header_t DataHeader;

	/* A remote device must be connected before a packet transmission is attempted */
	if (!(Bluetooth_Connection.IsConnected))
	  return BT_SENDPACKET_NotConnected;

	/* If the destination channel is not the signaling channel and it is not currently fully open, abort */
	if ((ACLChannel != NULL) && (ACLChannel->State != BT_Channel_Open))
	  return BT_SENDPACKET_ChannelNotOpen;

	/* Fill out the packet's header from the remote device connection information structure */
	ACLPacketHeader.ConnectionHandle      = (Bluetooth_Connection.ConnectionHandle | BT_ACL_FIRST_AUTOFLUSH);
	ACLPacketHeader.DataLength            = sizeof(DataHeader) + DataLen;
	DataHeader.PayloadLength              = DataLen;
	DataHeader.DestinationChannel         = (ACLChannel == NULL) ? BT_CHANNEL_SIGNALING : ACLChannel->RemoteNumber;

	Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);

	Pipe_WaitUntilReady();
	Pipe_Unfreeze();

	/* Write the packet contents to the pipe so that it can be sent to the remote device */
	Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
	Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
	Pipe_Write_Stream_LE(Data, DataLen);
	Pipe_ClearOUT();

	Pipe_Freeze();

	BT_ACL_DEBUG(2, "");
	BT_ACL_DEBUG(2, "Packet Sent");
	BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
	BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
	BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
	BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader.PayloadLength);

	return BT_SENDPACKET_NoError;
}
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
{
	uint8_t portnum = MIDIInterfaceInfo->Config.PortNumber;
	uint8_t ErrorCode;
	if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
	  return PIPE_RWSTREAM_DeviceDisconnected;

	Pipe_SelectPipe(portnum,MIDIInterfaceInfo->Config.DataOUTPipeNumber);

	if (Pipe_BytesInPipe(portnum))
	{
		Pipe_ClearOUT(portnum);

		if ((ErrorCode = Pipe_WaitUntilReady(portnum)) != PIPE_READYWAIT_NoError)
		  return ErrorCode;
	}

	return PIPE_READYWAIT_NoError;
}
示例#11
0
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
{
	if (USB_HostState != HOST_STATE_Configured)
	  return PIPE_RWSTREAM_DeviceDisconnected;
	
	uint8_t ErrorCode;

	Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber);

	if (Pipe_BytesInPipe())
	{
		Pipe_ClearOUT();

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

	return PIPE_READYWAIT_NoError;
}
示例#12
0
/** Routine to send the current CBW to the device, and increment the Tag value as needed.
 *
 *  \param[in] SCSICommandBlock  Pointer to a SCSI command block structure to send to the attached device
 *  \param[in,out] BufferPtr     Pointer to a buffer for the data to send or receive to/from the device, or NULL if no data
 *
 *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
 */
static uint8_t MassStore_SendCommand(CommandBlockWrapper_t* const SCSICommandBlock,
                                     void* BufferPtr)
{
	uint8_t ErrorCode = PIPE_RWSTREAM_NoError;

	/* Each transmission should have a unique tag value, increment before use */
	SCSICommandBlock->Tag = ++MassStore_Tag;

	/* Wrap Tag value when invalid - MS class defines tag values of 0 and 0xFFFFFFFF to be invalid */
	if (MassStore_Tag == 0xFFFFFFFF)
	  MassStore_Tag = 1;

	/* Select the OUT data pipe for CBW transmission */
	Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);
	Pipe_Unfreeze();

	/* Write the CBW command to the OUT pipe */
	if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(CommandBlockWrapper_t))) != PIPE_RWSTREAM_NoError)
	  return ErrorCode;

	/* Send the data in the OUT pipe to the attached device */
	Pipe_ClearOUT();

	/* Wait until command has been sent */
	Pipe_WaitUntilReady();

	/* Freeze pipe after use */
	Pipe_Freeze();

	/* Send data if any */
	if ((BufferPtr != NULL) &&
	    ((ErrorCode = MassStore_SendReceiveData(SCSICommandBlock, BufferPtr)) != PIPE_READYWAIT_NoError))
	{
		Pipe_Freeze();
		return ErrorCode;
	}

	return ErrorCode;
}
示例#13
0
文件: CDCHost.c 项目: TomMD/teensy
static int CDC_getchar(FILE *stream)
{
	int c;

	Pipe_SelectPipe(CDC_DATAPIPE_IN);
	
	for (;;)
	{
		if (Pipe_WaitUntilReady())
		  return -1;
	
		if (!(Pipe_BytesInPipe()))
		{
			Pipe_ClearOUT();
		}
		else
		{
			c = Pipe_Read_Byte();
			break;
		}
	}
	
	return c;
}
示例#14
0
uint8_t Pipe_Discard_Stream(uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                            , StreamCallbackPtr_t Callback
#endif
                            )
{
	uint8_t  ErrorCode;
	
	Pipe_SetPipeToken(PIPE_TOKEN_IN);

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

	#if defined(FAST_STREAM_TRANSFERS)
	uint8_t BytesRemToAlignment = (Pipe_BytesInPipe() & 0x07);

	if (Length >= 8)
	{
		Length -= BytesRemToAlignment;

		switch (BytesRemToAlignment)
		{
			default:
				do
				{
					if (!(Pipe_IsReadWriteAllowed()))
					{
						Pipe_ClearIN();
							
						#if !defined(NO_STREAM_CALLBACKS)
						if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
						  return PIPE_RWSTREAM_CallbackAborted;
						#endif

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

					Length -= 8;
					
					Pipe_Discard_Byte();
			case 7: Pipe_Discard_Byte();
			case 6: Pipe_Discard_Byte();
			case 5: Pipe_Discard_Byte();
			case 4: Pipe_Discard_Byte();
			case 3: Pipe_Discard_Byte();
			case 2: Pipe_Discard_Byte();
			case 1:	Pipe_Discard_Byte();
				} while (Length >= 8);	
		}
	}
	#endif

	while (Length)
	{
		if (!(Pipe_IsReadWriteAllowed()))
		{
			Pipe_ClearIN();
				
			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return PIPE_RWSTREAM_CallbackAborted;
			#endif

			if ((ErrorCode = Pipe_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
			Pipe_Discard_Byte();
			Length--;
		}
	}

	return PIPE_RWSTREAM_NoError;
}
uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
{
	uint8_t ErrorCode;
	
	uint16_t AccessoryProtocol;
	if ((ErrorCode = AOA_Host_GetAccessoryProtocol(&AccessoryProtocol)) != HOST_WAITERROR_Successful)
	  return ErrorCode;

	if (AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV1))
	  return AOA_ERROR_LOGICAL_CMD_FAILED;

	for (uint8_t PropertyIndex = 0; PropertyIndex < AOA_STRING_TOTAL_STRINGS; PropertyIndex++)
	{
		if ((ErrorCode = AOA_Host_SendPropertyString(AOAInterfaceInfo, PropertyIndex)) != HOST_WAITERROR_Successful)
		  return ErrorCode;
	}

	USB_ControlRequest = (USB_Request_Header_t)
	{
		.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE),
		.bRequest      = AOA_REQ_StartAccessoryMode,
		.wValue        = 0,
		.wIndex        = 0,
		.wLength       = 0,
	};

	Pipe_SelectPipe(PIPE_CONTROLPIPE);
	return USB_Host_SendControlRequest(NULL);	
}

static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol)
{
	USB_ControlRequest = (USB_Request_Header_t)
	{
		.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE),
		.bRequest      = AOA_REQ_GetAccessoryProtocol,
		.wValue        = 0,
		.wIndex        = 0,
		.wLength       = sizeof(uint16_t),
	};

	Pipe_SelectPipe(PIPE_CONTROLPIPE);
	return USB_Host_SendControlRequest(Protocol);
}

static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
                                           const uint8_t StringIndex)
{	
	const char* String = ((char**)&AOAInterfaceInfo->Config.PropertyStrings)[StringIndex];
	
	if (String == NULL)
	  String = "";

	USB_ControlRequest = (USB_Request_Header_t)
	{
		.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE),
		.bRequest      = AOA_REQ_SendString,
		.wValue        = 0,
		.wIndex        = StringIndex,
		.wLength       = (strlen(String) + 1),
	};

	Pipe_SelectPipe(PIPE_CONTROLPIPE);
	return USB_Host_SendControlRequest((char*)String);
}

uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
                          const uint8_t* const Buffer,
                          const uint16_t Length)
{
	if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
	  return PIPE_READYWAIT_DeviceDisconnected;

	uint8_t ErrorCode;

	Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber);

	Pipe_Unfreeze();
	ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL);
	Pipe_Freeze();

	return ErrorCode;
}

uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
                            const char* const String)
{
	if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
	  return PIPE_READYWAIT_DeviceDisconnected;

	uint8_t ErrorCode;

	Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber);

	Pipe_Unfreeze();
	ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL);
	Pipe_Freeze();

	return ErrorCode;
}

uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
                          const uint8_t Data)
{
	if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
	  return PIPE_READYWAIT_DeviceDisconnected;

	uint8_t ErrorCode;

	Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber);
	Pipe_Unfreeze();

	if (!(Pipe_IsReadWriteAllowed()))
	{
		Pipe_ClearOUT();

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

	Pipe_Write_8(Data);
	Pipe_Freeze();

	return PIPE_READYWAIT_NoError;
}

uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
{
	if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
	  return 0;

	Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipeNumber);
	Pipe_Unfreeze();

	if (Pipe_IsINReceived())
	{
		if (!(Pipe_BytesInPipe()))
		{
			Pipe_ClearIN();
			Pipe_Freeze();
			return 0;
		}
		else
		{
			Pipe_Freeze();
			return Pipe_BytesInPipe();
		}
	}
	else
	{
		Pipe_Freeze();

		return 0;
	}
}

int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
{
	if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
	  return -1;

	int16_t ReceivedByte = -1;

	Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipeNumber);
	Pipe_Unfreeze();

	if (Pipe_IsINReceived())
	{
		if (Pipe_BytesInPipe())
		  ReceivedByte = Pipe_Read_8();

		if (!(Pipe_BytesInPipe()))
		  Pipe_ClearIN();
	}

	Pipe_Freeze();

	return ReceivedByte;
}

uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
{
	if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
	  return PIPE_READYWAIT_DeviceDisconnected;

	uint8_t ErrorCode;

	Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber);
	Pipe_Unfreeze();

	if (!(Pipe_BytesInPipe()))
	  return PIPE_READYWAIT_NoError;

	bool BankFull = !(Pipe_IsReadWriteAllowed());

	Pipe_ClearOUT();

	if (BankFull)
	{
		if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
		  return ErrorCode;

		Pipe_ClearOUT();
	}

	Pipe_Freeze();

	return PIPE_READYWAIT_NoError;
}

#if defined(FDEV_SETUP_STREAM)
void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
                           FILE* const Stream)
{
	*Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar, _FDEV_SETUP_RW);
	fdev_set_udata(Stream, AOAInterfaceInfo);
}

void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
                                   FILE* const Stream)
{
	*Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar_Blocking, _FDEV_SETUP_RW);
	fdev_set_udata(Stream, AOAInterfaceInfo);
}